Sunday, May 14, 2006

Javascript "Encryption"

Last night a friend pointed me at a forum where someone was 'daring' people to 'crack his encryption'. I absolutely love these challenges and always give them a try. In this case, the challenge wasn't so much 'cracking encryption' as making sense of some semi obfuscated javascript code. I've decided to explain some of the techniques I use to do this, incase anyone ever finds a good use for them :P

Alright, so the code is long and mungy, so rather than pasting it here I'll explain some of it and paste the main function so I can walk you through it.

First, two arrays are declared. A standard array called asciiasc and an associative array called asciichr. These are used to create an alphabet table in the following way:

asciichr["A"] = 65; asciichr["B"] = 66; asciichr["C"] = 67; asciichr["D"] = 68; ...
asciival[65] = "A"; asciival[66] = "B"; asciival[67] = "C"; asciival[68] = "D"; ...

each of these array contains 255 values.

Following this is a javascript function, I've added indentations for readability:

function synvb(text) {
var allchr, myfinal = "";
var textasc, allasc = 0;
var passasc = 137;
var i, j = 0;
var rep2 = "";
rep2 = /\\r/g;
text = text.replace(rep2,"\r");
rep2 = /\\n/g; text = text.replace(rep2,"\n");
for (i = 0; i < text.length; i++) {
textasc = asciichr[text.charAt(i)];
allasc = textasc - passasc;
if (allasc < 1) {
j = allasc + 255;
allchr = asciiasc[j];
} else {
allchr = asciiasc[allasc];
}
if (!allchr) {
allchr = " ";
}
myfinal = myfinal + allchr;
}
return myfinal;
}

First some variables are declared. The two replace()'s are done to unescape carriage retures (\r) and newlines (\n). Following this we are passed into a for loop.

for (i = 0; i < text.length; i++) {

A for loops peramaters can often contain enough information to allow us to make a preliminary hypothisis of what happens within the loop construction. In this case, the loops condition is based on the length of the string 'text' which is the paramater passed to this function. Having seen the webpage I know that text contains an 'encrypted' string. Knowing this, we can hypothesize that this loop will iterate over every character, and is therefor likely the 'decryption' routine.

textasc = asciichr[text.charAt(i)];
allasc = textasc - passasc;

In the first iteration of the loop we get the value for the 1st ascii character in 'text', and subract from that value 137. Ah, so this is a basic shift cipher! The conditional statements following this are used to 'wrap' the shift to accomodate for values of allasc less than 0. Finally we take our values and concatonate them in 'myfinal'.

Now that we know that this cipher shifts the alphabet by -137 it would be trivial to code a decryption function. Rather than doing this, however, we'll use the code already at our disposal. We can add a line here:

myfinal = myfinal + allchr;
> document.write(myfinal);

However, in the instance of the code I was looking at, this will not work. After running through it, nothing was displayed. But why? What kind of data could be passed to document.write and not be displayed in the content of the document? It must be code! maybe the value is something like: <!-- this is the decrypted text \-->. This would not be displayed. So how can we have it displayed? The <textarea> tag is a perfect perfect for this problem. Anything following this tag is considered data (not code) and placed inside a textarea box. So, the first time through our loop we want to document.write('<textarea>').

function synvb(text) {
var allchr, myfinal = "";
var textasc, allasc = 0;
var passasc = 137;
var i, j = 0;
var rep2 = "";
rep2 = /\\r/g;
text = text.replace(rep2,"\r");
rep2 = /\\n/g; text = text.replace(rep2,"\n");
for (i = 0; i < text.length; i++) {
textasc = asciichr[text.charAt(i)];
allasc = textasc - passasc;
if (allasc < 1) {
j = allasc + 255;
allchr = asciiasc[j];
} else {
allchr = asciiasc[allasc];
}
if (!allchr) {
allchr = " ";
}
--> if(!myfinal){document.write('<textarea>')}
myfinal = myfinal + allchr;
}
return myfinal;
}



Hope you like the technique :).

Dispelling Myths

Alright, so here's my beef. Someone claimed recently that they had developed a bandwidth consumption DoS. This, to me, is not a bad thing. Exploit developement can be positive and progressive. What bothers me is when 'developing a bandwidth consumption DoS' consists of nothing more than coming up with a simple idea, not testing it, not understanding the technologies involved, and propagating a rumour that it works. This is fear mongering. After asking around I found a good number of people who had heard of the DoS, and had just taken for granted that it was a big deal.

Basically, his theory is that by spoofing the IP address of a victim, and sending an HTTP GET request to a webserver for a file larger than the request he is achieving amplifacation. This is illustrated in the following diagram, A(C) represents the attacker (host A), spoofing the victims ip (host C) and requesting an image from the webserver (host B).



Assuming the file big.jpg is bigger than the HTTP request packet, his transmission has been amplified, and since his IP has been spoofed big.jpg will be sent to the victim. A standard http get request from a browser can be anywhere from 100-500 bytes, but a lot of this information, the useragent, referrer, etc, is unnecessary. All we really need to send in this case is the request method, URI and HTTP version.

GET /big.jpg HTTP/1.1


This will end up being around 50 bytes. If the image we're requesting is 5k we've amplified our attack by 100x. Having a look at google's image search gives indication that images over 500k are not uncommon. Looks pretty dangerous, right? An attacker can send out 50 bytes of data and have a victim recieve 500000 bytes. Or can they?

The problem is that the designer of this DoS doesn't understand the technology he's attempting to exploit.

Problem 1: Fragmentation.

Even if he could get this exploit to work (he can't, but I'll get to that) his metrics are off. Webservers don't just send out 500000 byte packets. These will be fragmented into more manageable pieces. The standard maximum size for a packet is 1500 bytes. Each 1500 byte fragment has to be acknowledged by the recipient but since this fragment isn't expected by the victim host it is discarded and an RST packet is sent back to the webserver, reseting the connection. That chokes our amplification to a maximum of 1500 bytes for each request (1500 is the STANDARD mtu, but in certain circumstances can be modified). This minimizes the risk significantly.

Problem 2: TCP isn't stupid.

This attack tries to take advantage of the fact that an HTTP GET request is relatively small, but has the potential to force large responses from a server. He's got the right idea, but he's looking at the wrong transmission protocol. TCP is connection based, and as such any TCP service requires a full two-way connection. Spoofing packets is easy, but spoofing a full connection is not. In order to have the webserver accept and respond to the GET request for this image, the attacker has to first complete the tcp initiation process (or threeway handshake) posing as the victim like this:

A(C) >-------SYN-------> B
B >-----SYN/ACK-----> C
A(C) >-------ACK-------> A

Those who know TCP will know that this is not an easy thing to do. The attacker is faced with a number of problems, but first and foremost is sequence numbers. I'll illustrate:

A(C) >-------SYN------[S:1111111111 / A:0000000000]------> B
B >-----SYN/ACK----[S:2222222222 / A:1111111112]------> C
A(C) >-------ACK------[S:1111111112 / A:2222222223]------> A

This is what needs to happen, not what will happen. Here's what will happen.

A(C) >-------SYN------[S:1111111111 / A:0000000000]------> B
B >-----SYN/ACK----[S:2222222222 / A:1111111112]------> C
A(C) >-------ACK------[S:1111111112 / A:uhmmmmmmmm]------> A

Our attacker will have no way of knowing the sequence number generated by the webserver as it was sent to the victim, not him. This, of course, is debatable. Okay, so lets debate it.

Michael Zalewski did some excellent research on ISN (Initial Sequence Number) randomness in various operating systems. His research shows that there are a number of TCP implementations using weak, predictable ISNs. If the ISN can be predicted, than the TCP connection can be spoofed! But what does this mean for the DoS? Nothing. Weak ISN's can be predicted but very rarely to absolute precision. This means that multiple guesses have to be made.

A(C) >-------SYN------[S:1111111111 / A:0000000000]------> B
B >-----SYN/ACK----[S:2222222222 / A:1111111112]------> C
A(C) >-------ACK------[S:1111111112 / A:1111111110]------> A
A(C) >-------ACK------[S:1111111112 / A:1111111111]------> A
A(C) >-------ACK------[S:1111111112 / A:1111111112]------> A
A(C) >-------ACK------[S:1111111112 / A:1111111113]------> A
...

Some of the weakest ISN's still require around 5000 guesses, meaning 5000 packets. ACK packets are usually about 50 bytes. Thats 250000 bytes of data being sent for every 1500 bytes reflected.

Now, not to add insult to injury, but lets say our attacker CAN guess the sequence number without having to send more than 1500 bytes. I mean, I suppose its feasable that he finds a webserver on a network generating absolutely predictable ISNs. (barely, but we're scientists.) there's something ELSE he's missing. When the webserver (host B) sends the SYN/ACK to the victim (host C), the victim's machine knows it didn't request a connection, assumes the webserver has malfunctioned and sends an RST back. This tips off the webserver, causing it to not send the 1500 byte fragment of our image.

A(C) >-------SYN-------> B
B >-----SYN/ACK-----> C
C >-------RST-------> B

The only way to effectively spoof a full connection, is if you can "gag" the host who's address you're spoofing, so that it can't reply. So, really... you have to DoS the victim in order to use this DoS against them! The attack is entirely superfluous.

Now, if you're looking for this kind of reflective amplification DoS, try looking at UDP services with the same small request/large reply type features.

;)

Wednesday, May 10, 2006

a few more Bookmarklets

So, I decided to write a few more bookmarklets to help with some basic web application auditing. here they are:

methodToggle for toggling the method of a form.

noMax for ditching the maxlength restriction on text fields

hidden2text for changing hidden inputs to text inputs. After trying to get this one to work for about an hour I started googling to see if anyone else had done it. Thanks to Jesse from Squarefree.com for this, I modified it slightly so that the text inputs it creates to replace the hidden ones actually submit regularly with the form :)

Tuesday, May 09, 2006

Cookie Hacking Bookmarklet

A little while back Chris Shiflett posted on his blog about a quick and dirty way to modify cookies on-the-fly for pen testing web apps.

He talked about having to manually escape the data for it to work, and soon after Mike Willbanks commented about using a javascript prompt to simplify the method.

Here's a little bookmarklet I wrote for this:

modcookie

Happy Hacking!

Monday, May 08, 2006

Weekend Pen Test.

As I mentioned on Friday a friend came to visit this weekend. While he was here we were asked to do some basic penetration testing on a website. We found a few interesting things that I'd like to discuss here.

First of all, when can webstatistics applications become an attack vector? If your webstatistics application lists accessed URL's or referer's, there is a potential risk of information disclosure when passing sensitive data through GET variables. The worst case scenario would be a login form that passes the username and password as GET variables, which are recorded as accessed URL's in the webstatistics output. Most of the really popular examples (Webalizer, AWStats, Modlogan) do not record get variables as part of the urls, but even this does not completely eliminate the problem. In certain circumstances the use of mod_rewrite can cause get variables to mask themselves as paths. In this case, they would show in your stats. This has been confirmed with the three examples of stats software given.

Next, if you're escaping characters manually DONT FORGET TO ESCAPE THE BACKSLASH. Now, I know at first it doesn't seem like there's much that can be done with a backslash but here's the only reason you'll ever need.

after escaping:
' becomes \'
effectively removing any syntactical relevance from the singlequote for any back end processing. BUT:
\' becomes \\'
Now, the first backslash escapes the second backslash and the singlequote is left alone.

Last but not least, NEVER EVEN LOOK at a file with a user defined variable name unless you've verified the filename good. Often developers will check if the file exists, then check its relevance before opening the file.

if (file_exists($filename)) {
switch ($filename) {
case "1.txt":
fopen($filename, 'r');
...;
break;
case "2.txt":
fopen($filename, 'r');
...;
break;
default
echo "invalid file, back off hacker.";
}
} else { echo "file doesnt exist"; }

This gives an attacker the ability to verify the existence of any file on the server (within the context of the webservers permissions.)

Seasonally Exclusive Environmental Incompatibility

Hay fever.

Late April and early May seem to be the worst for me. I've read that in April and May the offending pollen is from tree's, from may to july its from grass and after that its mostly ragweed pollen.

I'm considering trying an old remedy. Apparently, chewing honeycomb from local beehives helps build an immunity to local pollen. I'll post an update on how it works :)

Friday, May 05, 2006

Geeks Love Geek Company.

One of my oldest, most haxerish friends is coming for a visit. He'll be here in a few hours.
I'm QUITE excited.

Thursday, May 04, 2006

01:02:03 04.05.06

Thanks to Mikko from F-Secure, I may have never noticed

An hour and two minutes after midnight tonight the clock will tick: 01:02:03 04:05:06

This wont happen for another thousand years.



Neat?






MSN Display Pic Recovery

Have you ever noticed that once you use an image as your display pic in MSN Messenger, it stays in the display pic list even after the image has been deleted? Well it does, and this entry will explain how to recover them. (FYI, these images are modified to fit msn's display pic window.)

Today I decided to put a picture of myself in my blogger profile. Unfortunately the one I wanted to use had been innexplicably deleted. The only place that picture still existed was in MSN Messenger's list of recently used display pictures. So I fired up Mark Russinovich's brilliant tool filemon (systernals.com) and had a quick look at where these pictures were being retrieved from.



As illustrated, the images are being called from :

C:\Documents and Settings\USERNAME\Application Data\Microsoft\MSN Messenger\1385319040\UserTile

The files in that directory are as follows:

...
04/04/2006 01:31 AM 7,652 TFR2C4.dat
04/04/2006 01:12 PM 11,357 TFR2D9.dat
04/04/2006 04:16 PM 7,238 TFR2F0.dat
04/04/2006 04:17 PM 10,316 TFR2F2.dat
03/31/2006 04:46 PM 15,663 TFR38.dat
04/05/2006 02:28 PM 12,713 TFR48.dat
04/05/2006 02:29 PM 12,631 TFR4A.dat
03/31/2006 05:07 PM 16,388 TFR51.dat
03/31/2006 10:28 PM 17,312 TFR69.dat
04/29/2006 06:09 PM 20,672 TFRAA.dat
25 File(s) 369,659 bytes
2 Dir(s) 20,108,455,936 bytes free

There are 25 files in this directory 24 of which are in the format TFR[2]xx.dat where xx is a hexidecimal number, and 1 called map.dat. This corresponds nicely to the fact that there are 24 images in my display pics list. In hopes that these files might just be backups of the profile images, I run a strings analysis against them.

Strings v2.2
Copyright (C) 1999-2005 Mark Russinovich
Sysinternals - www.sysinternals.com

PNG
IHDR
IDATx
NRK-
#`v
rf8{
1Bf

...

Note the first recognizable ascii string in the file is PNG, which is a wellknown image format.
Renaming the file to image.png and opening it in a PNG compatible image viewer confirms that these ARE infact PNG files as it properly loads one of my profile pics.

In order to see what the nubmer 1385319040 represents, I search the registry for any reference to it:



the string is found here:

HKEY_CURRENT_USER\Software\Microsoft\MSNMessenger\PerPassportSettings\1385319040

This path holds keys representing settings for my particular msn account. One of these keys, called "MessageLogPath" actually contains my msn username. This is useful. Using this information we can recover images.

We open regedit, navigate to:

HKEY_CURRENT_USER\Software\Microsoft\MSNMessenger\PerPassportSettings

and run a search for our msn name. If it locates our name within that path, we will have the number corresponding to our passport profile. We can then go to

C:\Documents and Settings\USERNAME\Application Data\Microsoft\MSN Messenger\thatnumbergoeshere\usertile

and start renaming tfr*.dat files to .png files, there appears to be no order to how they are displayed in msn.

Automated Script Injection, Additional Applications.

I've been thinking a lot lately about samy's myspace worm. A few weeks before samy's worm started making headlines a friend and I had designed something similar for a browser based sci fi mmorpg. In the game you role-play the part of a merchant ship captain, traveling from planet to planet buying and selling commodities. When docked at a planet the browser based interface displays, among other things, a list of other ships also docked there. After a little bit of hacking around we realized that the HTTP POST form that allows a player to change the name of his ship was handled insecurely.

  • A) the handling for the form was not POST strict, meaning that POST and GET variables are accepted interchangeably. This is not in and of itself a vulnerability, however it can provide an attacker with unnecessary flexibility.
  • B) the developer doesn't understand how to securely cleanse user input. Rather than stripping out or escaping non-alphanumeric characters (which are really unnecessary for naming a ship) the developer attempts to detect and modify 'bad input'. For instance, the string <script> is detected and nuetered, becoming script>. This system is flawed. Due to the nature of how the modification is processed the string <<script> will be modified to: <script>. If you don't get why, read it a couple of times. The real problem though is that 'bad input' refers to an everchanging array of variable length. We will never know every possible 'bad input' and therefore cannot effectively detect it. As a rule, force good input rather than detecting bad input.



We modified our ships name to include javascript code that, when executed, would append 'assimilated by borg' plus the javascript iteslf to the end of the shipname of the user viewing it. because the name is displayed to every users browser docked at the same planet as you, it spread virally accross the virtual galaxy.

Though samy's methodology was superior to mine in its technical hackery, the concept is similar. Both he and I used features of the system we were attacking (myspace for samy, the sci fi rpg for me) to automate an attack through persistent script injection vectors. It would have been easy for samy to use his code maliciously. Harvest email addresses, ruin reputations, even systematically delete accounts. Just as I could have used my code to cheat at the game (thats right, could have.)

These are all good reasons to pay more attention to xss but i've been thinking about another application for automated script injection. Considering the growing popularity of social networking communities such as myspace and livejournal (there are plenty more) it would be trivial for marketing agencies to use viral xss for very fast very large scale market research projects. As an example, when we were playing with the sci-fi mmorpg we decided to try and get an idea of how many users were using IE vs mozilla or safari. Along with our code we injected an <img> with the src pointing to a php we had written which grabbed and stored the user agent to an sql db. It wouldn't be difficult to chart where the users were located geographically based on hostnames. This is just scratching the surface, but you see where I'm going. An interesting point to take note of is that the system is being attacked rather than the users, making it impossible or at least very difficult for users to protect themselves. The nature of these community sites makes the propagation of these xss worms very fast. I would be surprised if someone doesn't take advantage of this for monetary gain soon.

Monday, May 01, 2006

Pressure Crack.

I know, I know... a really late start for the blog fad.

I held off for as long as I could, but a lot of people were suggesting I keep a journal of all my nerd work. So I signed up for blogger. I'm actually pretty interested to see what neat little css tricks I can play with the layout template I picked. I'm expecting this to be a fun little archive of trixy little hacker bits. Here's hoping!