SANS Holiday Challenge 2014
This document is a write up of the SANS 2014 Holiday Hacking challenge – their 11th installment of this challenge but the first one that I have participated in. The challenge was named ‘A Christmas Hacking Carol” and the backstory revolved around a hacker (Scrooge) that used to hack for good but has since lost his path. On Christmas Eve he is visited by three spirits and each of them delivers him a message that is supposed to make him change his ways. Our job is to solve three challenges that reveal what messages were delivered to Scrooge. For the whole story, visit http://pen-testing.sans.org/holiday-challenge/2014.
What secret did the Ghost of Hacking Past include on the system at 22.214.171.124?
The first thing I did was perform an Nmap scan on every port of this system, to see what services the target is running:
The target has a few open ports, but port 31124 seems to be the most interesting one. Nmap doesn’t know what is running on this port but whatever service it is, it is returning data. We can see from the Nmap output that it has a few different responses but the first one is “I AM ELIZA. WHAT’S ON YOUR MIND?” The backstory for this challenge mentioned a ‘friend’ named “Eliza” at this target, so the service on port 31124 was the one I focused on for this challenge.
I connected to the port using netcat, which opened up a conversation for me with Eliza:
There seems to be a program running on port 31124 that takes user input and then responds with a pre-programmed sentence. Based on my initial input (of which there was more than you see in the screenshot), it didn’t look like my input had an effect on what was sent back to me.
The wrong solution:
It seemed that every response was just random, so I figured I had to ‘break’ the service to get to the secret. I wanted to feed it a lot of input quickly to see if I could figure out some method to the output I was sent, so I issued the following command:
Here I am not actually sending the file line by line. Instead I am sending the entire contents of nmap.lst at once to the service, which makes the response interesting. Instead of sending me just one line back as a response for my input, it sends me several dozens of lines and some of them don’t make sense. For instance, the seventh response I get back is “REALLY—IF IT DOES ANY OF THE COMMENT FOLLOWING COMMENT O INTEGRATES SOURCE CODE FROM?”, which actually includes several words from commented out lines in nmap.lst. These results made me suspect that the program might be vulnerable to code injection.
To find out exactly what lines or characters make the program ‘break’ I again fed it the same file but this time instead of sending the entire file at once I sent it line by line:
The screenshot here is of course only a very small part of the output but the results showed that when fed the wordlist line by line, the program did not respond back to me with nonsensical strings like it did when the entire file was fed to it at once. However, I did notice some interesting responses that I had not seen before, some of which are shown below:
These two responses are clearly not random, but instead they are dependent on the input that was fed to the program. The first one echoes back some part of the input to the user -“it does any of the” – and the second one clearly triggered because my input contained the word “links” in it. These results made me suspect that trying to ‘break’ the program and attempting code injection was not the way to go. Maybe the responses to my input were not as random as I initially thought and I just needed to interact with the program to get to the secret.
The right solution:
One of the first questions I asked Eliza was “What is your secret?” The response I got immediately made me realize that interaction with the program, rather than breaking it, was the way to go to solve this challenge. It took me a while to figure out what words or sentences triggered certain responses in the program, but eventually I was able to figure out the most important ones. Below is a screenshot summarizing the conversation between Eliza and myself:
As you can see from this conversation, I had to provide the keyword “secret” three times before Eliza gave me clear instructions on what to do. The first two times I provided a URL, I got a random response back. It wasn’t until after I said “secret” three times, and I included the words “surf” and “url” along with the actual link that Eliza retrieved the website header of the actual page that I sent. I didn’t spend time trying to figure out the logic behind the program, or what keywords and sequences of events are necessary for Eliza to retrieve a website header – it was enough for me that I got it to work.
So now what? The program retrieved a website header from a URL that I provided, but how does that get us the secret? My first guess was that the secret might be included with the GET request that Eliza sends out, and this guess turned out to be correct. I retrieved my website access logs, searched for a request from 126.96.36.199, and found the following:
188.8.131.52 – – [30/Dec/2014:09:27:23 -0700] “GET www.gerbenkleijn.com [REDACTED] Eliza Secret: \”Machines take me by surprise with great frequency. -Alan Turing\”” [REDACTED]
The second challenge requires us to attack a website and find two secrets there. The website is www.scrooge-and-marley.com and we have permission to attack this site on port 80 and 443. Browsing to the URL shows a fairly simple website with a few pictures, a link or two, and an audio file. Inspecting the source code reveals nothing of interest. There is a phone number listed on the website with an extension: +1 641 715 3900 688365#. Calling this number plays a recorded message (in the same voice as the audio file on the website) that says Scrooge is not available and to please leave a message, which I did not do.
The main page also links to a contact page, with a contact form where a name, email address, and message can be filled out. Immediately I assumed I would have to perform some sort of injection attack here, but after firing up Burpsuite and intercepting a request I noticed that this information is not actually sent to the server.
I suspected that the program ‘submit.sh’ is somehow vulnerable to code injection but I would have to figure out how to inject code into it, since no parameters seem to be passed to the program. Alternatively, it’s possible that the GET request itself is vulnerable to an injection attack and a server command might be executed alongside the ‘submit.sh’ program. These are options that I did explore but before describing my code injection attempts I’ll describe how I obtained the first secret from the website on port 443.
Preliminary tests show that the webserver is running Apache 2.2.22, which is not the most recent version of Apache. This might mean that other services are also not updated to their most recent version. Since Apache uses OpenSSL for Transport Layer Security (TLS), and older versions of OpenSSL are vulnerable to what has become known as “HeartBleed”, I decided to see if this was the case here. First I tried to see if it’s possible to easily obtain the version of OpenSSL that the server is using. Some servers provide this information in their communication, and to see if this was the case I issues the following commands:
I did not receive the version of OpenSSL that the server is using – it would have been displayed under the “Server” header. I went ahead and tested for the HeartBleed vulnerability without knowing the version of OpenSSL, since it’s not a requirement for discovery or exploitation of this vulnerability.
Metasploit has an auxiliary scan module for HeartBleed, which I used against the server. I set “VERBOSE” to true so that the results don’t just show that the server is vulnerable, they will also show details about the communication and any information from the server’s memory that was compromised.
The results showed the following:
In the output it is clear to see the secret (URL Encoded):
Website Secret#1=Hacking can be noble.
So now let’s focus our attention on the potentially vulnerable shell script ‘submit.sh’. We already saw previously that filling out the contact form and hitting ‘submit’ doesn’t actually send the information to the server, so we can’t just inject some code into the forms and expect it to get executed by ‘submit.sh’.
The Wrong Solutions
First I’ll write about some things I tried that didn’t work. I include this because I learned a lot from the process of failing and hopefully someone else will find reading about my struggles educational as well.
Some testing revealed that it’s also not possible to perform code injection on the GET request itself:
I tried many more forms of injection into the GET request than just the one shown here (URL encoding, using pipes, etc.) but none of them proved successful.
Other scan techniques I tried to get to the secret were running Nikto and running Dirbuster. Nikto showed that the server had “MultiViews” enabled, which could allow for bruteforcing of filenames. Basically, with MultiViews the server will select a file with a matching name even if the extension doesn’t match what was requested. This can be used in an attack: By submitting an altered and invalid GET request for a resource, the server will respond with valid files that match the filename. In the screenshot below I am requesting the file “a”, and I changed the “Accept” header from ‘text/html,application/xhtml+xml,application/xml;q=0.9*/*;q=0.8’ to ‘text/html,application/xhtml+xml,application/xml;q=1’. The server responds with a 406 error and shows me all the valid files it has for “a”, which are “a.mp3” and “a.ogg”:
What I did next was run DirBuster with a custom header, formatted in the same invalid way (You can set these headers under advanced options). I also specified DirBuster to use a “blank extension”. I let it run for several hours, but it never found additional files beyond what was obviously there: and index page and a contact page, two audio files, four image files, and submit.sh.
The Right Solution
After having tried several methods that didn’t get me anywhere, it occurred to me that ‘submit.sh’ might be a hint to the right solution. ‘Submit.sh’ is a shell script – maybe I should look into exploiting the server through the Shellshock vulnerability.
I had never used the Shellshock exploit before so it took me a little while to get the syntax right. In fact, it took me so long to get it right that I doubted I was on the right path and started looking at other options again. Fortunately, eventually I returned to attempting the Shellshock exploit and I finally succeeded in getting information from the server with the following command:
Of course, the next commands I tried were ‘ls’, ‘cat’, ‘whoami’, and more basic commands to list files and directories and get information from the server. However, all of these commands returned nothing back to me, not even HTML code. From this I deduced that these server commands were all disabled, and I could only use the very basic of commands to find my way around.
I used ‘echo’ to find may way through the server’s directories and files:
As is clear in the output, there is a file or folder named ‘/secret’. Clearly that is where we should be looking. I tried to see if it was a file or folder we were dealing with by issuing the following commands:
Echoing “/secret/*” just echoes the same thing back to me, whereas echoing “/etc/*” gives me a list of files and folders in the /etc/ directory. Based on that difference in output, I deduced that /secret must be a file, not a folder.
Here’s where we go wrong again for a while. The right solution is a little further down.
Some Google research revealed a way to output file content with the ‘echo’ command, since we don’t have ‘cat’ available:
However, trying this on the “/secret” file gave me the following results:
It seems like the server is saying that there is no “/secret” file. To make sure that my command works, I also tried it on “/etc/passwd”:
These results made it seem like the command worked on the “/etc/passwd” file but not on the “/secret” file. Maybe “/secret” wasn’t a file after all. Maybe it’s a folder with a hidden file in it:
The first couple of commands on my local system show that ‘echo’ can reveal hidden files. However, trying the same command on the remote system again only echoed the command back to me, suggesting there are no hidden files. This is where I got stuck for a while. It seems like there is a secret file in the root directory of the web server, but there doesn’t seem to be a way for me to read it….
Eventually I decided not to try a different technique, but instead to try a different tool. I used BurpSuite to issue the exact same command, and to my surprise I got the secret echoed back to me immediately!
There it is!
Website Secret #2: Use your skills for good.
So why did the same command work over BurpSuite and not through Curl?? I really hate it when something suddenly works and I don’t understand why, so I decided to investigate this issue. I went back to using Curl, and set it to use BurpSuite as a proxy so that I might investigate what is actually sent to the server. The results are below:
As you can see, I never actually sent the right command to the server. Looking again at my Curl command, I immediately felt like an idiot. I was using double quotes inside of double quotes, so I ended my command early. The feedback “bash: /secret: No such file or directory” never came from the remote system; that feedback came from my own system and just happened to be in the same spot as where feedback from the remote system would be! This also explains why the command didn’t work for “/secret” but it did work for “/etc/passwd”, since my local system actually has an “/etc/passwd” file.
Once I changed the outer quotation marks to single quotes, the command worked just fine (remember, you can’t put single quotes inside double quotes but you can put double quotes inside single quotes):
This challenge required the retrieval of four secrets from the contents of a USB drive using forensic investigation techniques. After downloading the file, I inspected it with some of the tools in the Sleuth Kit (TSK). The first thing I did was issue the following command:
This provided me with general information about the USB drive, such as its filesystem (NTFS), serial number, name, cluster size, etc.
Next, I wanted to have a look at the contents of the USB drive, so I used another TSK command:
This showed me the allocated and deleted files on the USB drive. The USB drive seems to contain the following files:
Two things are interesting to note right off the bat from this list of files: Hh2014-chat.pcapng:Bed_Curtains.zip seems to be at the same location on the USB drive as Hh2014-chat.pcapng. The colon separating the first part of the file name from the second part suggests this file is hidden using alternate data streams. Secondly, Tiny_Tom_Crutches_Final.jpg seems to be a deleted file, as indicated by the asterisk in front on the metadata address.
I extracted the files from the USB drive using the following commands:
After some initial inspection of the files I decided to focus on letterfromjacktochuck.doc, because this is a text document. I figured if there was a secret hidden in this document, it might be easier to retrieve than a secret hidden in a jpg file or a network capture. Opening the file didn’t provide me with a secret – true to its file name it just contained a letter from Jack to Chuck. However, the following command showed me that there was actually a secret hidden in the file’s metadata:
USB Secret #1: “Your demise is a source of mirth.”
The second file I investigated was the PCAP file, which I opened using Wireshark. The file contains 2205 packets, sent over a time period of about six minutes. Several different protocols show up throughout the PCAP file but it quickly became clear that the traffic of interest consists of HTTP POST requests between two clients. The clients are both logged in to a chat service (chat.scrooge-and-marley.com) and messages are posted using the POST method. Filtering to show just the POST requests show the following conversation between the clients:
10.10.10.124 – “My Darling Husband, I do so appreciate your checking with Mr. Scrooge about the status of our debts. If he would grant us just one more month, we may be able to scrape together enough to meet him minimum payment and stay out of debtor’s prison. Please tell me of your progress, my love.”
10.10.10.123 – “As promised, I have indeed reached out to Mr. Scrooge to discuss our financial affairs with him, dear.”
10.10.10.124 – “Is it good… or bad?”
10.10.10.123 – “Bad.”
10.10.10.124 – “We are quite ruined.”
10.10.10.123 – “No. There is hope yet, Caroline.”
10.10.10.124 – “If he relents, there is. Nothing is past hope, if such a miracle has happened.”
10.10.10.123 – “He is past relenting. He is dead.”
10.10.10.124 – “That is wondrous news! To whom will our debts be transferred?”
10.10.10.123 – “I don’t know. But before that time we shall be ready with the money. And even if we are not, it would be a bad fortune indeed to find so merciless a creditor in his successor. We may sleep tonight with light hearts, Caroline!”
10.10.10.124 – “I’ve just told our children about Mr. Scrooge’s death, and all of their faces are brighter for it. We now have a very happy house. I so love you.”
10.10.10.123 – “I shall see you soon, my dear. Lovingly – Samuel.”
There is no secret hidden in these messages, but while going through the packets I did notice that packet number 2000 and packet number 2105 – both of which were part of this conversation – had comments to them.
The comment in packet number 2000 was:
The comment in packet 2105 was:
The second comment is a link to information on steganography, which we will use to retrieve another secret. The first comment seems to be encoded information. While the method for encoding could be anything, at first glance it looked like base64 encoding to me, so I entered the code into a base64 decoded online. The result revealed the second secret:
“USB Secret #2: Your demise is a source of relief.”
The third file that I decided to investigate was Bed_Curtains.zip which was hidden in the PCAP file. Had I investigated the USB drive using Windows, this file might have been more difficult to find. However, The Sleuth Kit immediately showed me the presence of this file and the necessary information to carve it out.
Unzipping the zip file showed me that a password was required:
In order to get to the zip file I need to find the password. Either the password is hidden somewhere else on the USB drive, or I might be able to bruteforce it by using a zip password cracking tool like fcrackzip. I decided to try the second options first.
I ran fcrackzip with smaller password lists first, such as password.lst from John the Ripper and nmap.lst because they don’t take as long to go through as a large password list like rockyou.txt. However, I didn’t find the password until I ran the program with the rockyou password list:
With the password I was able to unzip Bed_Curtains.zip, which gave me the file “Bed_Curtains.png”. This turned out to be an image file of a page in “A Christmas Carol”. The image itself didn’t contain a secret, but running the ‘strings’ command on the image file as was previously done on the text document did reveal the third secret:
“USB Secret #3: Your demise is a source of gain for others.”
This leaves one final file to inspect on the USB drive: Tiny_Tom_Crutches_Final.jpg. Opening the file reveals just a picture of crutches on a table – there is no information in the image itself that leads to the secret. Running the ‘strings’ command on the file also doesn’t reveal any information. I suspected that information was hidden in the file by the use of steganography, especially since a comment in the packet capture file earlier led to a site about the F5 steganography program.
I downloaded and compiled the program ‘stegdetect’ on Kali Linux, and I ran stegdetect on the JPG file.
As you can see from the results, stegdetect found F5 steganography embedded in the JPG file. Assuming there is no password protection, we should be able to use the F5 program to reveal the hidden information in the JPG file. I downloaded the F5 program, which is a Java (.jar) file, and ran it without a password, hoping that no password would be required:
“USB secret #4: You can prevent much grief and cause much joy. Hack for good, not evil or greed.”