April 22, 2014

Measuring Entropy to Detect Unencrypted Data

With the recent Heartbleed vulnerability scramble, there have been discussions on detecting the vulnerability in the wild. This is a quick write up to explain entropy testing and to help explain what the characteristics of encrypted vs. unencrypted traffic really are.
To start with, we'll analyze a binary as it sits on a system versus that same binary after being encrypted. In this example I used /bin/bash. Below is a quick perl script to measure the occurrence of all bytes between 0x00 and 0xff.
BASH Binary Unencrypted
bsmall@bsmall-vm-debian:~/Documents/entropy_example$ perl -e 'do { local $/ = undef; $blah = ; }; %b; foreach my $i (split(//, $blah)) { $b{$i}++; } foreach my $k (0..255) { printf("%02x,%0d\n", $k, $b{chr($k)} ? $b{chr($k)} : 0) } ' < bash
00,159246
01,16628
02,7081
03,4459
04,21912
05,4461
06,2125
07,1898
08,31585
...
BASH Binary Encrypted with GPG
bsmall@bsmall-vm-debian:~/Documents/entropy_example$ perl -e 'do { local $/ = undef; $blah = ; }; %b; foreach my $i (split(//, $blah)) { $b{$i}++; } foreach my $k (0..255) { printf("%02x,%0d\n", $k, $b{chr($k)} ? $b{chr($k)} : 0) } ' < bash.gpg
00,1839
01,1723
02,1749
03,1797
04,1790
05,1860
06,1743
07,1749
08,1777
...

The goal of the script is to dump a table that we can use to generate a histogram and get visual representation how often a particular byte occurs in the binary. Right away we can see the variance between each byte is drastically different. Per the output, the encrypted binary has 1,839 occurrences of the byte sequence 0x00, where the unencrypted binary has 159,246 occurrences of 0x00.
Plotted on a histogram, the results are as so:
The visual representation of the data shows a clear difference in the distribution of bytes. Running these binaries through one of the few algorithms listed here, we can measure the entropy in the files as as score:
bsmall@bsmall-vm-debian:~/Documents/entropy_example$ python entropy_test.py < bash.gpg .[Results]. Length 451478 Entropy: 7.99960058661
bsmall@bsmall-vm-debian:~/Documents/entropy_example$ python entropy_test.py < bash .[Results]. Length 941252 Entropy: 6.36049396951
These scores will line up with confidence tables described in this document.

November 12, 2010

Web Session Hijacking

FireSheep

A few weeks ago a clever fellow named Eric Butler released a firefox plugin that, when active, sniffs the network for common web services so that it may hijack web sessions. That sounds like a bad thing, but his intentions are good. Session hijacking isn't a new exploit just cooked up a month ago. In fact information security professionals have been talking about it for years. The problem is the proof of concepts and pleas with web service providers for more secure web practices seems to have fallen on def ears. Firesheep makes executing this sort of attack beautifully simple. Load the plugin, click a button, and wait. As soon as an already authenticated user within your collision domain browses to an insecure web service the user, the website, and often times an avatar will appear in the Firesheep console. Depending on the service, facebook for example, clicking on one of these stolen sessions will take you to the victims homapage. Congratulations, you've successfully completed a man-in-the-middle attack with out even having to type.


FireShepherd

In response to Firesheep, a student at the University of Iceland, Gunnar Sigurdsson, wrote a small app called FireShepherd. The app is pretty basic; once every couple of seconds the app makes a connection to Facebook and sends a fake HTTP request containing a forged session cookie. This cookie causes Firesheep to error out and stop sniffing, preventing a would be attacker from stealing your session data. There's been some reviews on the web pointing out some flaws with the app. By definition, Gunnar's app is a DoS against facebook. Do I believe that FireShepherd will DoS Facebook? Probably not. There's potential, but I doubt ii will get the number of users required to successfully DoS anybody. Regardless, it's completely unnecessary to ever make a full connection to break firesheep's sniffing session.


CamelSpit

My first thought when I saw the reviews for FireShepherd was, why make a full connection anyway? I like Facebook. I use it all the time. Why would I want to DoS them? So I took Gunnar's forged cookie and set out to write a quick perl script to spoof the sniff-session-ending packet onto the wire.All one needs is perl, the RawIP module, and the will to run the app. The spoofed packet has a low ttl value which causes the packet to be dropped long before it reaches any webservice, but not before a would be attacker sniffs it off the wire ending their snoop session. I haven't tested it on a windows box, but it should work just fine on *nix systems. If anything it's at least a proof of concept demonstrating how to achieve Gunnar's goal with out negatively impacting a webservice.

September 30, 2010

Synchronous getJSON jquery call

What a pain. Here's an easy way to make a synchronous getJSON call with jquery:

var jsonObjectInstance = $.parseJSON(
    $.ajax({
         url: "json_data_plz.cgi", 
         async: false, 
         dataType: 'json'
        }
    ).responseText
);

September 2, 2010

MySQL to CSV

Here's a quick example how to dump a MySQL query to CSV

mysql  -e 'SHOW VARIABLES' | 
  perl -F'\t' -lane 'print "\"" . join("\",\"", map { $_ =~ s/"/\"/g; $_ =~ s/\n/\\n/g; $_; } @F) . "\""' > mysql_variables.csv 

August 31, 2010

So how do you really feel? (mmm perl)

So a while back I was playing with map+grep+anonymous arrays when I realized how quickly code can manifest with the "right-to-left" flow you can use in perl. As fast as I could think, this code was on the page. Obviously I had to write a quick one liner to encode the message that is "$the_truth", but that was easy enough.

(Originally this was on one line, but it looks terrible on the blog that way... I've already spent, easily, 10 times the amount of time trying to format the code than I did writing the code)
use strict; 
use warnings; 
my $the_truth = "0a796177796e6120656d2065766f6c20756f7920747562202c6472656e2061206d49"; 

my $tell = sub { 
  return join("",
    map { chr(hex($_)) } 
    grep { $_ } 
    reverse(split(/(.{2})/, $_[0]))) 
}; 

print $tell->($the_truth);