David Wong

cryptologie.net

cryptography, security, and random thoughts

Hey! I'm David, cofounder of zkSecurity, advisor at Archetype, and author of the Real-World Cryptography book. I was previously a cryptography architect of Mina at O(1) Labs, the security lead for Libra/Diem at Facebook, and a security engineer at the Cryptography Services of NCC Group. Welcome to my blog about cryptography, security, and other related topics.

Where have I been?

blog

I’ve been on holidays, not doing much, mostly enjoying what is sadly my very last summer holiday sheds a tear.

But as usual, when I’m not productive I get all grumpy and I feel like I’m losing precious time.

Before holidays: “I’ll have plenty of time to learn and code!”
During holidays: “Man I’m just gonna watch another episode of this new tv show”

So these past few weeks I chose to put android, google glass, unity and oculus asides. I’ll deal with them later.

Now It’s time to learn. And you can’t create without learning the technologies first!

So the first thing I did was take a look at React and MongoDB. After spending a few hours with React I knew I didn’t need it and fell in love with Angular. MongoDB seems pretty cool and it’s my first time with a noSQL database (I followed the awesome Andrew Burgess tutorial on Tutsplus).

I’ve been reading a lot about Rails lately and I’m trying to gather all the info I need before starting my next project which will involve those technologies that I’ve never used before:

  • Ruby on Rails

  • Slim

  • Angular

  • CoffeeScript

I already have a simple but useful project in mind.

I start school on September the 1st and I also want to be able to spend a week with GOlang before having too many things to do what I want.

BadUSB

blog

An interesting read about how any usb device could be a potential threat. Some scary extracts:

Once reprogrammed, benign devices can turn malicious in many ways, including:

  • A device can emulate a keyboard and issue commands on behalf of the logged-in user, for example to exfiltrate files or install malware. Such malware, in turn, can infect the controller chips of other USB devices connected to the computer.
  • The device can also spoof a network card and change the computer’s DNS setting to redirect traffic.
  • A modified thumb drive or external hard disk can – when it detects that the computer is starting up – boot a small virus, which infects the computer’s operating system prior to boot.

And a scarier one…

No effective defenses from USB attacks are known.

Once infected, computers and their USB peripherals can never be trusted again.

Some proof of concept should be introduced in a week at the incoming Black Hat convention. This is gonna be good :)

EDIT:

There’s actually something similar that you can already buy: The USB Rubber Duck

rubber duck

I’ve always disliked paypal but after watching that video I have a new image of Elon Musk. The guy is pretty humble, clever and knows how to explain an idea. The opposite of a Linus Torvald.

What’s also really amazing to me is how diversified his vocabulary is. Here are some words I learned thanks to this video:

  • belabor: argue or elaborate (a subject) in excessive detail.

  • farcical: of or resembling a farce, especially because of absurd or ridiculous aspects.

If you’re a college student in the US today might be your lucky day. Coinbase is offering 10$ in bitcoin to students from some american universities. I guess if yours is not accepted you can ask them directly.

To support bitcoin awareness among college students, today we are announcing a bitcoin giveaway: we are gifting $10 worth of bitcoin to students who create a new Coinbase account using their .edu email address.

Here you go

suggested reads:

Bruteforce Apr1 hashes.

blog

One of my professor organized a Hacking Week this semester but I didn’t have time to do it. Since I’m in holidays I thought I would take a look at it and write a bit about how I solved them.

Here’s the Crypto Challenge number 2 (out of 5) from this CTF (Capture The Flag):

user0:apr1oTsx8NNn$bAjDZHpM7tCvHermlXKfZ0 user1:apr1UxOdpNtW$funTxZxL/8y3m8STvonWj0
user2:apr1w7YNTrjQ$0/71H7ze5o9/jCnKLt0mj0 user3:apr1AIw2h09/$Ti0TRlU9mDpCGm5zg.ZDP. user4:apr1048HynE6$io7TkN7FwrBk6PmMzMuyC. user5:apr1T2QG6cUw$eIPlGIXG6KZsn4ht/Kpff0 user6:apr12aLkQ0oD$YRb6aFYMkzPoUCj70lsdX0

You have 7 different users with their respective password hashed and you have to find them. It’s just the 2nd out of 5 crypto problems, it’s pretty basic, but I never brute forced passwords for real before (I remember using John The Ripper when I was in middle school but that’s for script kiddies).

What’s Apr1 ? It’s a hash function that uses md5. And md5 is pretty weak, lots of rainbow tables on google.

This is how Apr1 looks in PHP according to Wikipedia, also the passwords are supposed to be alpha (a to z) in lowercase.

function apr1(<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>m</mi><mi>d</mi><mi>p</mi><mo>&#x0002C;</mo></mrow></math>salt) {
    <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>m</mi><mi>a</mi><mi>x</mi><mo>&#x0003D;</mo><mi>s</mi><mi>t</mi><mi>r</mi><mi>l</mi><mi>e</mi><mi>n</mi><mo stretchy="false">&#x00028;</mo></mrow></math>mdp);
    <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>c</mi><mi>o</mi><mi>n</mi><mi>t</mi><mi>e</mi><mi>x</mi><mi>t</mi><mo>&#x0003D;</mo></mrow></math>mdp.'<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>a</mi><mi>p</mi><mi>r</mi><mn>1</mn></mrow></math>'.$salt;
    <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>b</mi><mi>i</mi><mi>n</mi><mi>a</mi><mi>r</mi><mi>y</mi><mo>&#x0003D;</mo><mi>p</mi><mi>a</mi><mi>c</mi><mi>k</mi><msup><mo stretchy="false">&#x00028;</mo><mi>&#x02032;</mi></msup><mi>H</mi><msup><mn>32</mn><mi>&#x02032;</mi></msup><mo>&#x0002C;</mo><mi>m</mi><mi>d</mi><mn>5</mn><mo stretchy="false">&#x00028;</mo></mrow></math>mdp.<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>s</mi><mi>a</mi><mi>l</mi><mi>t</mi><mo>&#x0002E;</mo></mrow></math>mdp));
    for(<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>i</mi><mo>&#x0003D;</mo></mrow></math>max; <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>i</mi><mo>&#x0003E;</mo><mn>0</mn><mi>;</mi></mrow></math>i-=16)
        <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>c</mi><mi>o</mi><mi>n</mi><mi>t</mi><mi>e</mi><mi>x</mi><mi>t</mi><mo>&#x0002E;</mo><mo>&#x0003D;</mo><mi>s</mi><mi>u</mi><mi>b</mi><mi>s</mi><mi>t</mi><mi>r</mi><mo stretchy="false">&#x00028;</mo></mrow></math>binary, 0, min(16, $i));
    for(<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>i</mi><mo>&#x0003D;</mo></mrow></math>max; <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>i</mi><mo>&#x0003E;</mo><mn>0</mn><mi>;</mi></mrow></math>i>>=1)
        <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>c</mi><mi>o</mi><mi>n</mi><mi>t</mi><mi>e</mi><mi>x</mi><mi>t</mi><mo>&#x0002E;</mo><mo>&#x0003D;</mo><mo stretchy="false">&#x00028;</mo></mrow></math>i & 1) ? chr(0) : $mdp{0};
    <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>b</mi><mi>i</mi><mi>n</mi><mi>a</mi><mi>r</mi><mi>y</mi><mo>&#x0003D;</mo><mi>p</mi><mi>a</mi><mi>c</mi><mi>k</mi><msup><mo stretchy="false">&#x00028;</mo><mi>&#x02032;</mi></msup><mi>H</mi><msup><mn>32</mn><mi>&#x02032;</mi></msup><mo>&#x0002C;</mo><mi>m</mi><mi>d</mi><mn>5</mn><mo stretchy="false">&#x00028;</mo></mrow></math>context));
    for(<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>i</mi><mo>&#x0003D;</mo><mn>0</mn><mi>;</mi></mrow></math>i<1000; $i++) {
        <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>n</mi><mi>e</mi><mi>w</mi><mo>&#x0003D;</mo><mo stretchy="false">&#x00028;</mo></mrow></math>i & 1) ? <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>m</mi><mi>d</mi><mi>p</mi><mi>:</mi></mrow></math>binary;
        if(<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>i</mi></mrow></math>new .= $salt;
        if(<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>i</mi></mrow></math>new .= $mdp;
        <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>n</mi><mi>e</mi><mi>w</mi><mo>&#x0002E;</mo><mo>&#x0003D;</mo><mo stretchy="false">&#x00028;</mo></mrow></math>i & 1) ? <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>b</mi><mi>i</mi><mi>n</mi><mi>a</mi><mi>r</mi><mi>y</mi><mi>:</mi></mrow></math>mdp;
        <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>b</mi><mi>i</mi><mi>n</mi><mi>a</mi><mi>r</mi><mi>y</mi><mo>&#x0003D;</mo><mi>p</mi><mi>a</mi><mi>c</mi><mi>k</mi><msup><mo stretchy="false">&#x00028;</mo><mi>&#x02032;</mi></msup><mi>H</mi><msup><mn>32</mn><mi>&#x02032;</mi></msup><mo>&#x0002C;</mo><mi>m</mi><mi>d</mi><mn>5</mn><mo stretchy="false">&#x00028;</mo></mrow></math>new));
    }
     $hash = '';
    for (<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>i</mi><mo>&#x0003D;</mo><mn>0</mn><mi>;</mi></mrow></math>i < 5; $i++) {
        <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>k</mi><mo>&#x0003D;</mo></mrow></math>i+6;
        <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>j</mi><mo>&#x0003D;</mo></mrow></math>i+12;
        if(<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>j</mi><mo>&#x0003D;</mo><mo>&#x0003D;</mo><mn>16</mn><mo stretchy="false">&#x00029;</mo></mrow></math>j = 5;
        <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>h</mi><mi>a</mi><mi>s</mi><mi>h</mi><mo>&#x0003D;</mo></mrow></math>binary{<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>i</mi><mi>}</mi><mo>&#x0002E;</mo></mrow></math>binary{<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>k</mi><mi>}</mi><mo>&#x0002E;</mo></mrow></math>binary{<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>j</mi><mi>}</mi><mo>&#x0002E;</mo></mrow></math>hash;
    }
    <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>h</mi><mi>a</mi><mi>s</mi><mi>h</mi><mo>&#x0003D;</mo><mi>c</mi><mi>h</mi><mi>r</mi><mo stretchy="false">&#x00028;</mo><mn>0</mn><mo stretchy="false">&#x00029;</mo><mo>&#x0002E;</mo><mi>c</mi><mi>h</mi><mi>r</mi><mo stretchy="false">&#x00028;</mo><mn>0</mn><mo stretchy="false">&#x00029;</mo><mo>&#x0002E;</mo></mrow></math>binary{11}.$hash;
    $hash = strtr(
        strrev(substr(base64_encode($hash), 2)),
        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
        './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
    );
    return '<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>a</mi><mi>p</mi><mi>r</mi><mn>1</mn></mrow></math>'.<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>s</mi><mi>a</mi><mi>l</mi><mi>t</mi><msup><mo>&#x0002E;</mo><mi>&#x02032;</mi></msup></mrow></math>'.$hash;
}

It seems pretty difficult to reverse. Let’s not forget that hashes are one-way functions and that they also lose information. I don’t know if they do lose information on a 7-letters-password though, but it seemed quite stupid to go down this road when I could just brute force it.

What language offers a good library to hash with Apr1? Well I didn’t know, and I felt like maybe Unix could do it well for me.

Turns out that OpenSSL has a command line for it:

openssl passwd -apr1 -salt SALT PASSWD

A quick bash script later:

#!/bin/bash

test[1]='<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>a</mi><mi>p</mi><mi>r</mi><mn>1</mn></mrow></math>oTsx8NNn$bAjDZHpM7tCvHermlXKfZ0'
salt[1]='oTsx8NNn'

test[2]='<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>a</mi><mi>p</mi><mi>r</mi><mn>1</mn></mrow></math>UxOdpNtW$funTxZxL/8y3m8STvonWj0'
salt[2]='UxOdpNtW'

test[3]='<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>a</mi><mi>p</mi><mi>r</mi><mn>1</mn></mrow></math>w7YNTrjQ$0/71H7ze5o9/jCnKLt0mj0'
salt[3]='w7YNTrjQ'

test[4]='<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>a</mi><mi>p</mi><mi>r</mi><mn>1</mn></mrow></math>AIw2h09/$Ti0TRlU9mDpCGm5zg.ZDP.'
salt[4]='AIw2h09/'

test[5]='<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>a</mi><mi>p</mi><mi>r</mi><mn>1</mn></mrow></math>048HynE6$io7TkN7FwrBk6PmMzMuyC.'
salt[5]='048HynE6'

test[6]='<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>a</mi><mi>p</mi><mi>r</mi><mn>1</mn></mrow></math>T2QG6cUw$eIPlGIXG6KZsn4ht/Kpff0'
salt[6]='T2QG6cUw'

test[7]='<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>a</mi><mi>p</mi><mi>r</mi><mn>1</mn></mrow></math>2aLkQ0oD$YRb6aFYMkzPoUCj70lsdX0'
salt[7]='2aLkQ0oD'

while read line          
do          
    if [ "${#line}" == 7 ]
    then
    for num in {1..7}
    do
        noob=<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mo stretchy="false">&#x00028;</mo><mi>o</mi><mi>p</mi><mi>e</mi><mi>n</mi><mi>s</mi><mi>s</mi><mi>l</mi><mi>p</mi><mi>a</mi><mi>s</mi><mi>s</mi><mi>w</mi><mi>d</mi><mo>&#x02212;</mo><mi>a</mi><mi>p</mi><mi>r</mi><mn>1</mn><mo>&#x02212;</mo><mi>s</mi><mi>a</mi><mi>l</mi><mi>t</mi></mrow></math>salt[<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>n</mi><mi>u</mi><mi>m</mi><mo stretchy="false">]</mo></mrow></math>line)
        if [ "<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>n</mi><mi>o</mi><mi>o</mi><mi>b</mi><mi>"</mi><mo>&#x0003D;</mo><mo>&#x0003D;</mo><mi>"</mi></mrow></math>test[$num]" ];
        then
        echo $line;
        fi
    done
    fi
done < /usr/share/dict/words

I read the /user/share/dict/words that contains a simple dictionary of words on Unix, I try only the 7-letters-words.

The test ran in a few minutes and gave me nothing.

Well, I guess with a 7 letters password they must have used gibberish words. Let’s try a real bruteforce:

for a in {a..z}
do
    for b in {a..z}
    do
        for c in {a..z}
        do
            for d in {a..z}
            do
                for e in {a..z}
                do
                    for f in {a..z}
                    do
                        for g in {a..z}
                        do
                            truc=<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>a</mi></mrow></math>b<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>c</mi></mrow></math>d<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>e</mi></mrow></math>f$g;

                            for num in {1..7}
                            do
                            noob=<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mo stretchy="false">&#x00028;</mo><mi>o</mi><mi>p</mi><mi>e</mi><mi>n</mi><mi>s</mi><mi>s</mi><mi>l</mi><mi>p</mi><mi>a</mi><mi>s</mi><mi>s</mi><mi>w</mi><mi>d</mi><mo>&#x02212;</mo><mi>a</mi><mi>p</mi><mi>r</mi><mn>1</mn><mo>&#x02212;</mo><mi>s</mi><mi>a</mi><mi>l</mi><mi>t</mi></mrow></math>salt[<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>n</mi><mi>u</mi><mi>m</mi><mo stretchy="false">]</mo></mrow></math>truc)
                            if [ "<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>n</mi><mi>o</mi><mi>o</mi><mi>b</mi><mi>"</mi><mo>&#x0003D;</mo><mo>&#x0003D;</mo><mi>"</mi></mrow></math>test[$num]" ];
                            then
                                echo $truc;
                            fi
                            done
                        done
                    done
                done
            done
        done
    done
done

It ran and ran and… nothing.

Well. Let’s not spend too much on this. There is John The Ripper that does this well and even oclHashcat that does this with the GPU.

Let’s create a john.conf with the following to limit the password to 7 letters:

[Incremental:Alpha7]
File = $JOHN/alpha.chr
MinLen = 7
MaxLen = 7
CharCount = 26

Let’s launch John:

john -i=Alpha7 hackingweek.txt

(don’t forget to put the hashed password in hackingweek.txt).

Wait and wait and wait.. and get the passwords =)

suggested reads:

I got asked this question in an interview. And I knew this question beforehands, and that it had to deal with hashtables, but never got to dig into it since I thought nobody would asked me that for a simple internship.

I didn’t know how to answer, in my mind I just had a simple php script that would have looked like this:

$arr = array(-5, 5, 3, 1, 7, 8);
$target = 8;

for(<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>i</mi><mo>&#x0003D;</mo><mn>0</mn><mi>;</mi></mrow></math>i < sizeof(<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>a</mi><mi>r</mi><mi>r</mi><mo stretchy="false">&#x00029;</mo><mo>&#x02212;</mo><mn>1</mn><mi>;</mi></mrow></math>i++)
{
    for(<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>j</mi><mo>&#x0003D;</mo></mrow></math>i + 1; <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>j</mi><mo>&#x0003C;</mo><mi>s</mi><mi>i</mi><mi>z</mi><mi>e</mi><mi>o</mi><mi>f</mi><mo stretchy="false">&#x00028;</mo></mrow></math>arr); $j++)
    {
    if(<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>a</mi><mi>r</mi><mi>r</mi><mo stretchy="false">[</mo></mrow></math>i] + <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>a</mi><mi>r</mi><mi>r</mi><mo stretchy="false">[</mo></mrow></math>j] == $target)
        echo "pair found: <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mrow><mi>a</mi><mi>r</mi><mi>r</mi><mo stretchy="false">[</mo><mi>i</mi><mo stretchy="false">]</mo></mrow><mo>&#x0002C;</mo></mrow></math>{arr[j]}";
    }   
}

But it’s pretty slow, it’s mathematically correct, but it’s more of a CS-oriented question. How to implement that quickly for machines? The answer is hash tables. Which are implemented as arrays in PHP (well, arrays are like super hash tables) and as dictionaries in Python.

I came up with this simple example in python:

arr = (-5, 5, 3, 1, 7, 8)
target = 8

dic = {}

for i, item in enumerate(arr):
    dic[item] = i

    if dic.has_key(target - item) and dic[target - item] != i:
        print item, (target - item)
  1. iterate the list
  2. assign the hash of the value to the index of the value in the array
  3. to avoid finding a pair twice, we do this in the same for loop:
    we do the difference of the target sum and the number we’re on, we hash it, if we find that in the hash table that’s good!
  4. but it could also be the number itself, so we check for its index, and it has to be different than its own index.

Voilà! We avoid the n-1! additions and comparisons of the first idea with hash tables (I actually have no idea how fast they are but since most things use hash tables in IT, I guess that it is pretty fast).

📖 my book
Real-World Cryptography is available from Manning Publications.
A practical guide to applied cryptography for developers and security professionals.
🎙️ my podcast
Two And A Half Coins on Spotify.
Discussing cryptocurrencies, databases, banking, and distributed systems.
📺 my youtube
Cryptography videos on YouTube.
Video explanations of cryptographic concepts and security topics.
page info:
page 50 of 63
622 posts total