Outbreak Labs

I can do anything I want to. And so can you.

Calculating the WPA2 PMK using C#

One of the features I've wanted to implement for Packet Gremlin is the ability to decrypt encrypted WiFi traffic. I only know of two tools capable of this: Airdecap-ng, which can't do it on a live capture, and Wireshark, which can't capture wireless traffic on Windows due to a limitation of WinPCap. One of the things needed for implementing this feature is to calculate the PMK (Pairwise Master Key). By studying the source code of airdecap-ng and various online resources, I found that this is actually trivial:

Update 6/1/14: The code as originally posted was technically correct, and did pass the AirCrack unit tests and validate with other tools, however I found that the result was causing me to generate invalid PTKs. It turns out that while the PMK can be generated to an arbitrary length, and the Aircrack unit test used 40 bytes, the length expected for use in PTK calculation is actually 32 bytes. I have updated the code with this option and default accordingly.
       
public static byte[] CalculatePMK(byte[] psk, byte[] ssid, int pmkLength = 32)
        {
            Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(psk, ssid, 4096);
            return pbkdf2.GetBytes(pmkLength);
        }


I was pleased to find a small set of unit tests accompany the aircrack suite, including one for PMK calculation. I ported it to C# and... it crashed. It turns out that, for reasons unknown to me, the Rfc2898DeriveBytes class requires that the salt (in this case, the ssid) be at least 8 bytes in length. Since ssids (including the one in this unit test) can be fewer than 8 bytes in length, I needed to work around this artificial limitation. I used Reflector to examine the source of this class, and found that the exception is thrown in the setter for the Salt property, which is invoked in the constructor. The setter does three things:

1. Validates the length of the salt
2. Copies the salt to the private byte[] m_salt
3. Calls the private method Initialize()

I found that the public method Reset calls the private method Initialize, but upon further inspection of the Initialize method itself, I realized that in this particular case, I don't need to do it since this is a fresh instance of the class. All I really needed to do was fill in m_salt.

I used an empty byte[8] as a placeholder for the salt in the constructor, then used reflection to get a reference to the private m_salt field, and set it with the ssid:

       
public static byte[] CalculatePMK(byte[] psk, byte[] ssid, int pmkLength = 32)
        {
            Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(psk, /*ssid*/ new byte[8], 4096);
            //This reflection is required because there's an arbitrary restriction that the salt must be at least 8 bytes
            var saltProp = pbkdf2.GetType().GetField("m_salt", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            saltProp.SetValue(pbkdf2, ssid);

            //pbkdf2.Reset(); 
            //To officially complete the reflection trick, the private method Initialize() should be called. That's all Reset() does. 
            //But I don't think it's needed because we haven't hashed anything yet.

            return pbkdf2.GetBytes(pmkLength);
        }


With that change, the unit test passed, and the PMK calculation was complete. In a subsequent post I will discuss the less trivial implementation of the PTK calculation.

Making Firefox like Opera

It's been a good run, but with Opera 15 being little more than a skin of Chrome, and with growing compatibility issues with popular websites (Google products, Gawker blogs, etc.) on Opera 12, it's time to jump ship. I know what you're thinking; You hate Firefox, you hate Chrome, and neither has the rich features that Opera does. That's true, but with the right combination of extensions I've managed to make Firefox pretty close to Opera in terms of user interaction and features. So, here's what you need to make Firefox act like Opera 12.

Extensions

Features unaccounted for

  • RSS/Mail
    • I'm currently using FeedDemon for RSS, which offers a toaster notification like Opera did, but I'm still looking for a browser-based solution.
  • IRC (I don't use this, so I won't be looking for it)
  • Torrent support (I don't use this, so I won't be looking for it)
  • Detailed page load info
    • The Extended Statusbar plugin is exactly what's needed, but it is incompatible with the current build of Firefox. Hopefully the author updates it.
    • In the mean time, I'm using app.telemetry Page Speed Monitor, which isn't quite the same info or as convenient.

Built in non-obvious features

  • Keyword searches ("g something" to search Google, "w something" to search Wikipedia...) are managed as bookmarks.
    • Add them by right clicking in a search field and clicking "Add a Keyword for this Search"
  • Importing bookmarks
    • I had some success exporting my Opera bookmarks as html, then importing with the Firefox bookmark manager. It was a bit messy and required cleanup.
  • Importing RSS
    • I still don't have a reader extension, but the OPML Support plugin can import as "Live Bookmarks" (what Firefox natively does with RSS) the OPML files that Opera can export. This will be useful later if/when I find a proper reader extension.
  • Speed dial on new tabs
    • I'm not totally sure why this is necessary, but set your home page to about:newtab to make sure you get the speed dial on new tabs.
  • Show protocol in address bar
    • In about:config change the browser.urlbar.trimURLs setting to false