I Smell Packets

Solution to ‘What’s wrong with Smelly Widgets?’
October 20, 2009, 2:39 pm
Filed under: Packet Challenge, SANS, SQL injection, Wireshark

The winner of the “What’s wrong with Smelly Widgets packet challenge?” is . . . Arvind Doraiswamy.

Here’s Arvind’s solution.

Arvind writes:

1. A blank form with a login and a password is first displayed. The webserver is running on and an access attempt is made from

2. Attempt at logging in with a blank username and password is then done(Packet 9). This is insuccessful as shown in Packet 12 where a user is not allowed to login with empty credentials.

3. Packet 14 sees the user try to login with the username chris and an empty password. This too is insuccessful as shown in Packet 17 , a user must have something in the password field.

4. Packet 19 sees a third attempt at trying to login with the username chris and the password “password” . The attacker is trying out various common password combinations. This too is insuccessful as shown in Packet 22 and returns an error message of “Invalid credentials” . This means that you must enter something in both fields. So the attacker must now either find a valid combination or must try and bypass the login somehow. Well, he doesn’t have a valid combination so he decides on the latter.

5. At this point though there is another request for the home page on from He tries to login with the username of chris and a password of smellywidgets. This results in a successful login and displays order history. This is crucial…

6. On packet 37 we now see chris making another attempt to unsuccessfully login with username chris and password ismellpackets from the IP This again is unsuccessful.

7. The attacker on is now fed up and decides to try and get in without a valid username and password. On packet 42 he sends a request with username and password as follows:
username: ‘ OR 1=1–
passsword: password

This login is a success!! What happened here? Lets take a look at how a normal successful login would happen in the first place.


A website is hosted on a webserver. A login page is part of the website. When a user enters his username and password on the website, it is accepted as input by the website form and handed over to the code for further processing. The application code now must compare what the user entered with what is already stored in the database. If it didn’t do this — well , there wouldn’t be a need for a login form at all and everyone could see everyone’s data. Now how does the application actually do this?

The application needs to ask the database whether it has entries for the input that the user gave at the login page. So if we take the example of a successful login made by chris from the IP the application will ask the DB – “Do you have an entry for someone called chris , he’s entered a password called smellywidgets. Is this correct?” . The DB checks in its entries and says “yes that’s fine.. Chris indeed exists – allow him in”. Now the language that the application talks to the DB is called SQL – and when it asks a question – its said to be “querying” the database. So effectively the application queries the database in a language called SQL.

Now obviously there needs to be some structure to this SQL query. So while checking authentication is sends a query as follows:
SELECT username from users where ‘username’=’chris’ and ‘password’=’smellywidgets’ . SQL surrounds its userinput by single quotes, that’s part of the syntax.

The DB check the validity of the user chris , checks if his password is smellywidgets and then if it finds an entry like that, returns the username to the application. The application checks if the number of entries returned are not 0 (meaning there was a match) and then allows the user access. Great..now we know how a normal login happens. Now what happened when we typed ‘ OR 1=1– instead of chris? Again an SQL query is formed , but this time the query is as follows:
SELECT username from users where ‘username’=” OR 1=1– and ‘password’=’password’

Pay careful attention to the ” OR 1=1– . It effectively translates to .. “Please check is there is a user called ” (BLANK) OR check if 1=1 “. Huh? Now obviously there is no user called ” or BLANK in the DB but the second part 1=1 .. well that’s always going to be true ..right? 1 is always 1 and 2 is always 2 so that part will alwys be true. This means that the first part of checking the username has evaluated to TRUE and a successful message will be returned if the password is correct as well. Er..but I don’t know the password. No problem .. that’s where the — comes along.

A — in SQL means a comment , which means everything after the — is ignored by the DB engine thus resulting in the query which runs as :
SELECT username from users where ‘username’=” OR 1=1–

It didn’t matter what password I entered, the DB just checked if 1=1 which is always TRUE, returned a message to the app saying.. hey this is TRUE. Go ahead and grant access, and the application duly did so. This technique is called SQL Injection where you modify a backend SQL query using your own input and retrieve data accordingly. Now back to the challenge!!


8. Packet 51 depicts a login successful message to the SQL injection request made on packet 42. Packet 53 shows each and every widget order that was placed by every user, this is clear because multiple credit card numbers are shown in the HTTP response. This has happened because the DB has returned the first entry which it found matched the user’s request – and this was the first user , who in this case was probably an admin user who could see all entries.

9.On packet 68 the user clicks the logout button and decides to logout of the application. Confirmation of his successful logout is shown in Packet 77 and 79.

10. The attacker starts another login process in Packet 81. The body of the HTTP POST request is split across so many packets because of the size of the __VIEWSTATE parameter which ASPX applications use to remember previous entries made by users in forms. This isn’t that relevant here though as of now. The request is so huge that you see the actual userinput only in packet 86 this time. This time the entry he has made is %27%3B+UPDATE+Orders+Set+Amount%3D0.01– . What does this mean now? Time for a little bit of background on what those funny characters are:

When you type a special character which isn’t alphanumeric the browser performs something called URL Encoding on it before sending it to the server. It effectively means – When you send data over the Internet , it doesn’t need to be encoded if its ASCII.. coz ASCII is an example of “WYSIWYG” (What you see is what you get). However that isn’t true of other characters like ‘ % and others – hence they are URL encoded before sending it out. A single space is encoded as %20 by the browser – hence if there’s a space in your data you must send it as a + instead. Now back to the challenge, what does this input say?

11. %27%3B+UPDATE+Orders+Set+Amount%3D0.01– translates to ‘; UPDATE Orders Set Amount=0.01– . Hmm ..things are getting interesting now. If you recall how we discussed SQL before – the backend query for this translates to: SELECT username from users where ‘username’=”; UPDATE Orders Set Amount=0.01– and ‘password’=’password’ . This tells the DB to check if the username is blank and the update all entries in the Amount column in the Orders table to 0.01. Now note …this isn’t going to successfully log you in to the DB – we don’t have a 1=1 like before but the SQL query will still work. Why? Because we know that the username field is vulnerable to SQL Injection I can not only log in by bypassing authentication — I can tell the application to send any query I want executed on the remote DB. In this case its an update query — I separate the original SELECT query and the UPDATE query with a ; — The UPDATE query won’t run unless you put the ; — That’s a separator incase you want to run multiple queries (batched queries they are called in SQL). Potentially I could run more queries by just putting in a ; between each of them. Phew ..lets move on.

12. Packet 98 – shows a failed login attempt for the UPDATE query..but that’s perfectly fine. You do not need to be “logged in” to do damage with a SQL injection. All you need is an entry point. That’s why its so dangerous. Going on then..

13. Now he tries to login with the ‘ OR 1=1– input which we discussed earlier..possibly to check whether what he did with the UPDATE succeeded or not. The complete Request body is in Packet 105.

14. Perfect!! Look at Packet 121 now.. You need to look directly at 121 because Wirshark has this feature called Reassembled TCP where it basically joins all the data split across packets into 1 long bit. if you don’t want to read inside Wireshark , you can right click paket 121 in Wireshark and do a Copy — Bytes Printable text only to a text editor. You can also copy from a FollowTCPStream. Here you can clearly see that the amounts of each and every widget is now 0.01 , meaning that the UPDATE query succeeded.. even without a successful login.

15. Packet 129 sees the attacker logout again..now that he’s confirmed that the SQL Injection has worked and Packet 140 shows him the login page again.

16. Things are now getting worse on Packet 147. By following the same methodology above you can see that the payload the attacker uses this time is:
INSERT INTO Users VALUES (100,’hacker’,’sniffthis’)– . He’s creating a new user with an ID of 100 a username of hackers and a password sniffthis. Again..the SQL will succeed..but he won’t be able to login. This shows that the ‘ OR 1=1– was primarily just a test to find out whether the field was vulnerable or not, the real juicy stuff is here. The hacker should now try and login with this new account..lets see if this happens. Packet 159 BTW predictably rejects the login attempt.

17. Yes, predictable the hacker now logs in with the username of hacker and the password of sniffthis in Packet 166 and Packet 170 shows a successful response. After the test login he logs out again on Packet 172.

18. Now he starts SQL injecting again this time using a batched SQL query (remember queries split by a ; ? ) to log in successfully with a ‘ OR 1=1– as well as add a new entry with the query :
‘ OR 1=1; INSERT INTO Orders (OrderId, Item, CreditCard) SELECT UserId,Username,Password FROM users–

Now there should be a new entry in the Orders table with the values 100,hacker,sniffthis .. right at the bottom. We’ve basically retrieved the hacker’s details from the users table and Inserted them into the orders table for some reasson. Lets see why..lets look at the response.

19. Yes , just like we thought. Have a look right at the bottom of Packet 206. We see a row 100 hacker sniffthis ; meaning that the attacker managed to successfully INSERT and VIEW his results. He then successfully logs out as can be seen in Packet 236. Now what?

20. He’s placed an entry into Orders , meaning he bought stuff without paying a cent, he’s changed all order prices , now he destroys the entire users table by SQL injecting again — ‘; drop table users– . This is on Packet 248. The by now familiar Invalid Credentials message comes in on packet 266… but he’s not bothered any more. His job is done.

21. Now there’s a connection again from the other IP . Remember the guy here successfully logged in once? Lets see what happens now. Yes, he tries again on Packet 276 with the same username and password with which he succeeded last time – Username: chris and Password: smellywidgets.

22. Disaster.. The Users table is not found…of course it won’t be – The ‘hacker’ user dropped it after he inserted a successful order. The response in packet 279 shows this error message clearly – ERROR: Failed to execute SQL command: Invalid object name ‘Users’

Maybe there will be guys who use clever scripting techniques to pull out all the data – but since the dump was just 280 packets I didn’t really spend too much time thinking on how I’d do that and stuck to good old Wireshark instead. Thnx for a nice challenge anyway though 🙂

Chris continues:

About the only thing I’d like to add to Arvind’s solution is that it’s sometimes nice to know what type of systems you’re dealing with. In this particular case, you can do this by following the TCP Stream and looking at Host Headers. Notice bold text in the following output:

GET / HTTP/1.1
Host: http://www.smellywidgets.com
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv: Gecko/2009042523 Ubuntu/8.10 (intrepid) Firefox/3.0.11
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.0
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
Date: Mon, 05 Oct 2009 17:51:57 GMT
Content-Length: 1922

Examining the above, we can see that this server appears to be running IIS 7 and ASP.NET. We can probably safely assume that this is a Windows 2008 server. Now, just because this is a new Windows 2008 server doesn’t mean that it’s immune to SQL injection. User input always needs to be sanitized. Filtering out characters like single quotes, double quotes, and semi-colons would have prevented this attack.

Just case you’re interested, this challenge was created using a Windows 2008 virtual machine, IIS, ASP.NET, Visual Web Developer 2008 Express, and SQL Server Express 2008.

Thanks to everyone for sending in all the write-ups. You all did a great job. It was really hard to choose a winner. Special shot out to Louw Smith for being the only one to mention the Beatles reference. It was also nice to have a couple of my former Sec 401:SANS Security Essentials students submit answers. You guys rock!

Speaking of Sec 401: SANS Security Essentials, I’ll be teaching it again in Sacramento, CA. January 28-30 and February 1-3. If you’re interested in attending please feel free to contact me. There are also some links on the left with more information.

That’s it for now. Again, congratulations to Arvind and thanks to everyone who sent in answers.

The following are some links to more information about this week’s challenge:

SecuriTeam – SQL Injection Walkthrough
SQL Injection Cheat Sheet
Cheat Sheets – pentestmonkey.net

‘What’s wrong with Smelly Widgets?’ – Packet Challenge
October 6, 2009, 4:07 pm
Filed under: Packet Challenge


Help! Something is wrong with the Smelly Widgets website. Can you find out what it is?
The capture file can be downloaded from the I Smell Packets Google group located at the following URL:


The filename is:


Best explanation wins. Send your answers to chris (dot) christianson (at) gmail (dot) com.

Winner of the Crypto Kitchen Packet Challenge
August 13, 2009, 2:25 pm
Filed under: Packet Challenge, Vigenere

The winner of the Crypto Kitchen packet challenge was David Langlands (@zerodave on twitter). The following is his write-up:

David writes:


Please keep posting these, they’re a lot of fun. Both the easy and hard questions have the same answer “Merchandise7X” which I’d love to say I didn’t need to Google… but alas, the gods of trivia skill failed me at a critical moment. Mother Google says that it’s the secret ingredient in Coca-Cola.

The packet stream is an SMTP transaction. Reassembling the message by following the TCP stream we see that the hard message is as follows:

Message-ID: <4A65E533.8090903@i.eat.packets>
Date: Tue, 21 Jul 2009 16:56:35 +0100
From: Foody McFood <really.hungry@i.eat.packets*gt;
User-Agent: Thunderbird (Windows/20090605)
MIME-Version: 1.0
To: newrecipe@recipes.on.line
Subject: Great new recipe
Content-Type: multipart/mixed;
This is a multi-part message in MIME format.
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit


Here’s that great salad dressing recipe I was talking about:


* 45 ml Olive Oil
* 1 Garlic Clove crushed
* 30 ml Balsamic vigenere
* 15 ml Basil shredded
* The Secret Ingredient!


1. Mix together all ingredients in a jar
2. Shake well.
3. Pour over the salad.

Don’t tell anyone about the secret ingredient – discretion is the key!


Foody McFood

A few things of note here, the easy file is the same message, with a different Message-ID: header. The easy message-id header stands out a bit, since most MTAs have a header that looks more closely like the hard version’s header. File that for future reference:

EASY -> Message-ID: <Pmjeyeglwfh7F@i.eat.packets>
HARD -> Message-ID: <4A65E533.8090903@i.eat.packets>

The hard pcap file also has a JPEG file which is base64 encoded. One method to decode the base64 content is:

1. Use “Follow TCP Stream” to reassemble the SMTP conversation
2. Cut and paste just the base64 text into a text file (I called mine chal9.txt), it begins with “/9j”
3. Use openssl to decode the base64 text:

openssl base64 -d -in chal9.txt -out isDecoded.jpg

4. Opened the file only to find a message “The secret ingredient is: “ and a very obfuscated swirl:


5. Dead end… must be Stegonography, a really bad captcha, or somehow have some text embedded in it.

Here, I’d love to say I went right for the simpler “embedded text”, but I ran this through a battery of stego tools, and even tried a few captcha decoders first.

6. Performing a ‘strings’ on the decoded jpg reveals a familiar string near the beginning of the file:


7. Further analysis revealed this string to be embedded in the JPEG EXIF header slot for Document Name
8. Re-reading the message we have two hints, the first one is “vigenere” instead of vinegar. Wikipedia informs us that Vigenere was a cryptographer, and although he didn’t invent the cipher that bears his name, I’d say it’s a pretty solid indication that we need to run the message through a vigenere decoder.
9. The SMTP message ends with “Don’t tell anyone the secret ingredient – discretion is the key”
10. The fine folks at sharkysoft have an online Vigenere cipher encoder/decoder at: http://sharkysoft.com/misc/vigenere/
11. Putting the whole text of the easy message into Sharky’s tool, the only recognizable words appear:


12. Obviously, you don’t need to plug the whole message into the decoder, just the ‘Pmjeyeglwf7F’ string.
13. Merchandise7X is known to KO insiders as “Pig’s Blood”, or the secret ingredient in Coke (thanks again, Google!)

Very fun. Thanks again to you and Alec R Waters for making it a fun challenge!



Chris writes:

David, you rock! You were the only one who came up with the correct answer to this challenge. And thanks for the kudos too, but Alec gets all the credit for this one. Until next time everyone.

Solution to The Crypto Kitchen Packet Challenge (Easy Version)
August 11, 2009, 4:19 am
Filed under: Packet Challenge, Vigenere

Here is the solution to the easy version of the Crypto Kitchen Packet Challenge from Alec R Waters (@alecrwaters on twitter). Thanks for the challenge Alec. By the way, Alec’s blog is http://wirewatcher.wordpress.com.

Alec writes:

Everything needed to discover the secret ingredient is in the email,
hidden in plain sight – all we have to do is look hard enough!

The first thing to notice is amongst the list of ingredients. The recipe
calls for:

“30 ml Balsamic vigenere”

“Vigenere”, huh? That’s not an ingredient, that’s a cipher!

Now we have to look for something that could be ciphertext. The most
likely thing is the Message-ID:

Message-ID: <Pmjeyeglwfh7F@i.eat.packets>

So our current theory is that Pmjeyeglwfh7F is the product of a Vigenere
cipher. All we need is the key (or enough time to brute-force it!)

Fortunately, the key is provided in the message too:

“discretion is the key”

Decrypting Pmjeyeglwfh7F using the Vigenere cipher and a key of
“discretion” gives us:


…which is apparently the secret ingredient in a certain brand of soft drink 🙂

Chris continues:

I’ll post the solution to the hard version tomorrow.

The Crypto Kitchen – Packet Challenge
August 3, 2009, 3:55 pm
Filed under: Packet Challenge

Here’s another packet challenge for you guys. This one is courtesy of Alec R Waters (@alecrwaters on twitter). It’s called ‘The Crypto Kitchen.’ There is an easy and a hard version. I think you’ll all enjoy this one.

The capture file can be download from the I Smell Packets Google group located at the following URL:


The filenames are:


Send your answers to chris (dot) christianson (at) gmail (dot) com.

Another Solution to Where in The World is Chris?
July 28, 2009, 5:22 pm
Filed under: Berlin, Packet Challenge, WinHex, Wireshark

I wanted to share another solution I received to the ‘Where in The World is Chris?’ packet challenge. This one comes from Justin Acquaro.

Justin writes:

Short Answer:

Mohrenstrabe 30
10117 Berlin, Germany

The long answer:

Using wireshark it appears that the packet is a http session to twitter ( http://twitter/cchristianson )


Follow the TCP stream shows this conversation followed by a GZIP download:


Using the save as function I save the file to packets.bin I then open packets.bin up in a hex editor (winHex). According to the RFC for gzip (http://tools.ietf.org/html/rfc1952) the start of a gzip file is always “1f 8b”. I then locate these two values in WinHex.


I then deleted all the data above this magic value and saved the results as packets.bin.gz


When I opened the file I was presented with the original contents.


Opening the file up it appears to be the HTML source of a twitter page.


Rendering the HTML yields:


Which once plugged into google maps yields:


Chris writes:

Thanks for the write-up Justin (jacquaro on twitter.)
If anyone else would like share how they solved this or any of the other challenges, please feel free to send me a message. It’s always nice to see how others go about it.

Solution to Where in The World is Chris?
July 23, 2009, 2:34 pm
Filed under: Berlin, Brandenburg Gate, Packet Challenge, Wireshark

I’m back from vacation. It was a blast! Where was I? Here is the solution to last week’s packet challenge.

Opening up the pcap file in Wireshark we see the following:


A quick glance at the fourth packet reveals that this is a HTTP request to twitter.com. Note that in the Packet List Pane the fourth packet has been selected. In the Packet Details Pane the Hypertext Transfer Protocol field section has been expanded. In particular, this is a request to twitter.com for /cchristianson.

Another thing to take note of, is that there is also only one connection or flow in this particular capture. We know this because there is only one set of IP addresses, source port, and destination port combonation. In this case, it’s the one from <->

Back to the question at hand, ‘where in the world is Chris?’ Most of us are familiar with Twitter. One of Twitter’s features is the ability for a user to update their Location. This Location field is displayed on every user’s page. In this instance, this field reveals exactly where I am.

Looking through all these packets for my location would be a little tedious. To assist us in our efforts to find the right packet, Wireshark does have a nifty little search feature. To access the Search feature, go to the Edit Menu and select Find Packet. Search for the string ‘Location’ in the ‘Packet Details’ like so:


This highlights the packet that contains my location. Selecting that packet and then expanding the Line-based text data: text/html section at the bottom, reveals all the content of the web page. Scrolling through that information will reveal the Location field as well as some numbers.


The numbers are of course GPS coordinates. Inserting those coordinates into Google Maps or any other mapping software will reveal my exact location at the time, the Hilton Hotel in Berlin. Berlin is fantastic by the way.

Lot’s of people got this one right. Congratulations to Jorge Orchilles (@jorgeorchilles on twitter) for being the first. Thanks to everyone else for playing and following along.

I’ll be in Las Vegas next week attending Blackhat and Defcon. Send me a tweet or an email if you’d like to meet.

Before I go, here is one of the pictures I took while I was there. It’s of the Brandenburg Gate in Berlin.



The TCP/IP Guide
Wireshark User’s Guide
Brandenburg Gate

Where in the World is Chris? – Packet Challenge
July 16, 2009, 8:15 am
Filed under: Packet Challenge

Hello! I’m off on vacation, so I thought I’d post a quick packet challenge and let you try to find out where. The winner needs to answer the question, where in the world is Chris?

The capture file can be download from the I Smell Packets Google group located at the following URL:


The filename is:


Send your answers to chris (dot) christianson (at) gmail (dot) com.

Solution to the Name That Exploit Packet Challenge
June 30, 2009, 2:14 pm
Filed under: Metasploit, Packet Challenge, snort, tcpflow

Sorry for the delay in posting the solution to last week’s challenge. The good news is that the delay allowed more people a chance to submit their answers. That was good. Perhaps from now on, when I post a challenge; I’ll wait a week before posting a solution.

So without further ado, here is how I made the challenge.

For this packet challenge I decided to capture an exploit traveling across the network. To do this, I setup two machines. One machine to use as an attacker, the other to use as a victim. I then started a packet capture. The victim machine in this case was an unpatched Windows 2000 server that was vulnerable to a buffer overrun in the server service. So, I ran Metasploit from the attacker machine and chose the MS06_040_netapi exploit. After the exploit and the payload ran, I then had shell access to the victim machine. Once I had access, I created an account on the box and added myself to the Administrators group.

This brings us to the challenge. By looking at the capture, how can you tell that this is what I did? The first question in particular that I asked was, which exploit did I use? There are a number of different ways to do this, but here is what I did.

Using Snort with a recent ruleset, run the following command:

snort -r 7.pcap -c my-snort.conf -l /tmp

In the above command the -r option specifies the name of file to read. The next option, the -c option, specifies the Snort configuration file to use. Finally the -l option specifies the directory to log.

Depending upon the the configuration and the rules used, there should be some alerts. On my system there were three alerts generated. These alerts are sent to an alert file which will be located in the log directory that was specified. The following is the output from the alert file that was created by Snort:

[**] [1:7250:8] NETBIOS SMB-DS srvsvc NetrPathCanonicalize WriteAndX little endian overflow attempt [**]
[Classification: Attempted Administrator Privilege Gain] [Priority: 1] 
06/20-17:31:47.011637 ->
TCP TTL:64 TOS:0x0 ID:2994 IpLen:20 DgmLen:1114 DF
***AP*** Seq: 0x8EA7338C Ack: 0xB47F07B3 Win: 0x8218 TcpLen: 32
TCP Options (3) => NOP NOP TS: 97799385 21705 
[Xref => http://www.microsoft.com/technet/security/bulletin/MS06-040.mspx][Xref => http://cve.mitre.org/cgi-bin/cvename.cgi?name=2006-3439][Xref => http://www.securityfocus.com/bid/19409]

[**] [1:7250:8] NETBIOS SMB-DS srvsvc NetrPathCanonicalize WriteAndX little endian overflow attempt [**]
[Classification: Attempted Administrator Privilege Gain] [Priority: 1] 
06/20-17:31:47.019978 ->
TCP TTL:240 TOS:0x10 ID:0 IpLen:20 DgmLen:1259
***AP*** Seq: 0x0 Ack: 0x0 Win: 0x0 TcpLen: 20
[Xref => http://www.microsoft.com/technet/security/bulletin/MS06-040.mspx][Xref => http://cve.mitre.org/cgi-bin/cvename.cgi?name=2006-3439][Xref => http://www.securityfocus.com/bid/19409]

[**] [1:2123:4] ATTACK-RESPONSES Microsoft cmd.exe banner [**]
[Classification: Successful Administrator Privilege Gain] [Priority: 1] 
06/20-17:31:47.470358 ->
TCP TTL:128 TOS:0x0 ID:279 IpLen:20 DgmLen:157 DF
***AP*** Seq: 0xB481E281 Ack: 0x41E39895 Win: 0x4296 TcpLen: 32
TCP Options (3) => NOP NOP TS: 21710 97799389 
[Xref => http://cgi.nessus.org/plugins/dump.php3?id=11633]

Looking at the above alerts, you can see that the Xref mentioned in the first two alerts refers to the MS06-040 exploit.

As for the second part of the challenge, I asked you to tell me what I did after gaining access to the machine. This was easy. To see what happened, simply open the the capture in Wireshark and look at the payloads of the packets. You should be able see me creating an account and then adding it to the Administrators group. The following are the two commands I used to do so:

net user chris ismellpackets /add

net localgroup administrators chris /add

Viewing the payload of each packet can be a pain and it’s definitely not pretty. For pretty output, in Wireshark, select any of the packets near the bottom of the capture. Then, to see the whole session decoded, goto the Analyze Menu and select Follow TCP Stream.

This can also be done from another neat little utility called tcpflow. Tcpflow can reconstruct the actual data streams and stores each flow in a separate file. To run tcpflow type:

tcpflow -r 7.pcap

Tcpflow will create a file for each of the flows in the capture. These files will have names such as:

The contents of the above file would be the data transmitted from port 4444, to port 52555. This is the stream we are looking for. The file can be viewed with any editor. For example:



Microsoft Windows 2000 [Version 5.00.2195]
(C) Copyright 1985-1999 Microsoft Corp.

C:\WINNT\system32>net user chris ismellpackets /add
The command completed successfully.

C:\WINNT\system32>net localgroup administrators chris /add
The command completed successfully.


There you have it. A little Snort, a little tcpflow, and you’ve got your answer. There were lots of answers sent in this time. The only one who got it exactly right was Alec R Waters (@alecrwaters on twitter) Congratulations to Alec for being the first person to win twice, and back to back wins at that. Maybe we should start keeping score.

Thanks to everyone else for sending in your answers. Hope you all enjoyed it. Until next time, keep smelling packets.

The following are some links to more information about this week’s challenge:

Microsoft Security Bulletin MS06-040
Vulnerability in Server Service Could Allow Remote Code Execution (921883)

tcpflow — A TCP Flow Recorder
Manpage of tcpflow