Contenido principal

DNS Flag Day Colombia

Febrero 1, 2019

Los dominios colombianos (mil.co, gov.co, edu.co, org.co, com.co, net.co [+] nuevo) están preparados para el día del cambio mundial en los sistemas DNS que entrará a regir a partir del primero de febrero de 2019 y el cual es soportado por grandes servicios de DNS gratuitos como los ofrecidos por Google, Cisco OpenDNS, y CloudFlare.

Existe sin embargo una oportunidad de mejora en algunos de estos dominios, que según ciertas condiciones, podrán presentar problemas de servicios como interrupción en el acceso a sitios web y fallas en los sistemas de correo.

El análisis fue realizado sobre un total de 16.470 176.868 dominios colombianos, en donde 10.023 77.129 se encuentran configurados adecuadamente, 6.148 96.713 sin respuesta, y 299 3.026 no cumplen con las exigencias técnicas del estándar.

DNS Flag Day Colombia

El siguiente listado contiene los dominios colombianos afectados por el cambio en los sistemas DNS:

https://github.com/sinfocol/dnsflagday-colombia/blob/master/affected-domains.txt

04.com.co
04it.com.co
1.net.co
100pre.com.co
139my.com.co
...
zonajobs.com.co
zonaoriente.com.co
zoni.com.co
zukor.com.co
zuper.com.co

Archivado en: Seguridad | Comentarios (0)

KeePassLogger - KeePass Two-Channel Auto-Type Obfuscation Bypass

Febrero 3, 2016

Two-Channel Auto-Type obfuscation is a security mechanism from KeePass to protect auto-typed passwords from being captured by "standard" keyloggers. It uses clipboard and keyboard emulation as primary channels to transfer passwords to their final input:

KeePass TCATO Two-Channel Auto-Type Obfuscation

This scheme is secure while none or just one channel is compromised. We are going to focus on clipboard protection, the following section from KeePass TCATO FAQ was removed after the bug was reported and rejected:

KeePass Clipboard Event Blocker

The old way

Clipboard protection is heavily based on the old clipboard viewer chain from Windows, the diagram shows the windows message flow in the viewer chain, the flow must be followed by all the applications that want to listen to clipboard changes. The operating system sends a message to the first window, then each window is required to pass the message to the next one until there is no window left:

Windows Clipboard Viewer Chain

Here comes into play the Clipboard Event Blocker from KeePass, it first calls SetClipboardViewer to add himself as the first window in the viewer chain, and then when the WM_DRAWCLIPBOARD message is received it blocks this message from being passed to the next window:

Windows Clipboard Viewer Chain KeePass

There are two ways to bypass this protection:

:arrow: Add a window to the viewer chain after KeePass protection is executed
:arrow: Use newer API functions to listen to clipboard changes

The new way

A clipboard listener was introduced in Windows Vista as a new way to listen to clipboard changes, developers are encouraged to use the system-mantained clipboard format listener instead of the old one. The operating system is now responsible for sending the message to each window, preventing the flow to be blocked by applications:

Windows Clipboard Viewer Chain KeePass

KeePassLogger

Using the new clipboard listener and a standard keylogger we can retrieve the content of both channels and reassemble the secret. The next video shows a proof of concept for the "specialized" keylogger:

Source code

KeePassLogger source code:
:arrow: KeePassLogger github repository

Archivado en: Seguridad | Comentarios (0)

VirtualBox Disk Image Encryption password cracker

Julio 15, 2015

VirtualBox 5.0 was released the past July 9 with a new built-in disk image encryption feature which allows the user to encrypt virtual hard disk transparently.

With this feature a new tab is enabled in General configuration for each machine:

VBOXDIE Configuration

When the user sets a password, a new element called Property is added to the HardDisk element inside the machine configuration:

<HardDisk uuid="{b9f72e2c-7dde-412d-be98-6f07dbcabd41}" location="Encrypted.vdi" format="VDI" type="Normal">
  <Property name="CRYPT/KeyId" value="Encrypted"/>
  <Property name="CRYPT/KeyStore"
value="U0NORQABQUVTLVhUUzEyOC1QTEFJTjY0AAAAAAAAAAAAAAAAAABQQktERjItU0hB
MjU2AAAAAAAAAAAAAAAAAAAAAAAAACAAAAAJwd3SksjYgaKyVqNkFvSNya8SkGiz
kfuKYCB2xJk67SAAAACbTjDwMkoPESRduJWBXP4U+Tmtm3lj1k6kBlgeB42/NtAH
AACdTMPxXmuA+fiTrKHvuS+xFrYcbGj6SDa4uiUWV9WCU9AHAAAgAAAAq/tmzFGv
wmcIaYYgDxJidNRFk71JTjqUaKXS2wMuDVQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAA=="/>

</HardDisk>

The KeyStore is encoded using Base64, and it contains the information needed by the machine to verify the password each time the user wants to start a machine or change its password.

I made a tool called VBOXDIECracker as a proof of concept to crack weak passwords used in this new feature of VirtualBox, you can download it from:

https://github.com/sinfocol/vboxdie-cracker/

Following is a detailed explanation of how this new feature works:

KeyStore Format

First, we need to identify in someway the fields within the decoded keystore:

0000h: 53 43 4E 45 00 01 41 45 53 2D 58 54 53 32 35 36  SCNE..AES-XTS256
0010h: 2D 50 4C 41 49 4E 36 34 00 00 00 00 00 00 00 00  -PLAIN64........
0020h: 00 00 00 00 00 00 50 42 4B 44 46 32 2D 53 48 41  ......PBKDF2-SHA
0030h: 32 35 36 00 00 00 00 00 00 00 00 00 00 00 00 00  256.............
0040h: 00 00 00 00 00 00 40 00 00 00 12 02 78 97 DA CB  ......@.....x—ÚË
0050h: 3A 4C 4F EE F4 87 62 9D 68 A0 73 00 20 D9 B5 DE  :LOîô‡b h s. ÙµÞ
0060h: 74 94 40 8C 7A F9 9A F0 82 89 20 00 00 00 27 B5  t”@Œzùšð‚‰ ...'µ
0070h: 01 C3 16 F4 9F C2 96 B2 FE 32 85 57 35 16 73 81  .Ã.ôŸÂ–²þ2…W5.s.
0080h: AC 20 9F D1 C0 C8 3E 5E 41 B6 6F F3 C3 5A D0 07  ¬ ŸÑÀÈ>^A¶oóÃZÐ.
0090h: 00 00 8A 8F 4A 94 83 7E EC 1B B4 D6 9A 2E 7C 9F  ..Š J”ƒ~ì.´Öš.|Ÿ
00A0h: FA DC 5E 65 95 36 DF 45 A8 1C 46 66 2C F6 6B E9  úÜ^e•6ßE¨.Ff,öké
00B0h: 5E 58 D0 07 00 00 40 00 00 00 EA A5 55 F2 73 AE  ^XÐ...@...ê¥Uòs®
00C0h: AF 9F 11 57 12 8F D1 C3 51 7D 7C AE F4 3E C9 AA  ¯Ÿ.W. ÑÃQ}|®ô>ɪ
00D0h: A5 40 69 17 CD 13 72 C5 76 8C F8 85 7C 56 59 67  ¥@i.Í.rÅvŒø…|VYg
00E0h: 31 8C E1 81 24 0F C1 43 95 6E C2 FA C3 C4 EF 0E  1Œá $.ÁC•nÂúÃÄï.
00F0h: 62 9C 18 82 5D F2 28 E7 1E C2                    bœ.‚]ò(ç.Â

After some work we are able to identify each field:

VirtualBox KeyStore File Format
Offset Bytes Description
0 4 File header signature = 0x454E4353 (SCNE)
4 2 Version
6 32 EVP algorithm
38 32 PBKDF2 hash algorithm
70 4 Generic key length (used by PBKDF2 and AES-XTS)
74 32 Final hash where comparison is done
106 4 Key length used in the second call to PBKDF2
110 32 Salt used in the second call to PBKDF2
142 4 Iterations used in the second call to PBKDF2
146 32 Salt used in the first call to PBKDF2
178 4 Iterations used in the first call to PBKDF2
182 4 EVP input length
186 64 Encrypted password used in the second call to PBKDF2 (to be used as input in the call to AES-XTS)

VirtualBox Keystore 010 editor template

The following 010 Editor template could be used as a guide:

//--------------------------------------
//--- 010 Editor v6.0.2 Binary Template
//
// File:        VBOXDIEKeyStore.bt
// Author:      Daniel Correa
// URL:         http://www.sinfocol.org/
// Revision:    1.0
// Purpose:     Template for VirtualBox Disk Image Encryption KeyStore
//--------------------------------------

typedef struct vbox_die_keystore {
    int header <bgcolor=0xaabbcc, format=hex, name="Header">;

    if (header != 0x454E4353) {
        SetBackColor(0x0000ff);
        Warning("File is not a valid VBOX DIE KeyStore. Bad signature.");
        return -1;
    }

    uint16 version <bgcolor=0xccddee, name="Version">;
    char algorithm[32] <bgcolor=0x00ffee, name="EVP encryption algorithm">;
    char kdf[32] <bgcolor=0xffbbee, name="Key derivation function hash algorithm">;
    int generic_key_length <bgcolor=0x3399ee, name="Generic key length">;
    char final_hash[32] <bgcolor=0x4444ff, name="Final hash">;
    int pbkdf2_2_key_length <bgcolor=0x3399ee, name="Second PBKDF2 key length">;
    char pbkdf2_2_salt[32] <bgcolor=0x999999, name="Second PBKDF2 salt">;
    int pbkdf2_2_iterations <bgcolor=0xaa9933, name="Second PBKDF2 iterations">;
    char pbkdf2_1_salt[32] <bgcolor=0x999999, name="First PBKDF2 salt">;
    int pbkdf2_1_iterations <bgcolor=0xaa9933, name="First PBKDF2 iterations">;
    int evp_decrypt_input_length <bgcolor=0x3399ee, name="EVP decrypt input length">;
    char pbkdf2_2_encrypted_password[64] <bgcolor=0xff7777, name="Second PBKDF2 encrypted password">;
};

FSeek(0);
LittleEndian();
vbox_die_keystore VBOXDIE;

The result of running the template:

VBOXDIE 010 editor template 1

VBOXDIE 010 editor template 2

VirtualBox password storage algorithm

With the identification of the fields within the keystore we can now have an understanding of how the password storage algorithm works, and it is summarized in this way:


# 32 for AES-XTS128-PLAIN64
# 64 for AES-XTS256-PLAIN64
AES_key_length = 32 | 64
-------------------------
AES-password = PBKDF2(algorithm: SHA256,
password: user_password,
salt: random_salt_1,
iterations: 2000,
output_length: AES_key_length)
----------------------------------------------
PBKDF2-decrypted-password = AES_decrypt(key_size: AES_key_length,
mode: XTS,
data: random_data
password: AES-password,
type: raw,
iv: NULL)
-------------------------------------
Stored_hash = PBKDF2(algorithm: SHA256,
password: PBKDF2-decrypted-password,
salt: random_salt_2,
iterations: 2000,
output_length: 32)

The same process is performed each time the user wants to decrypt the machine disk. The stored hash (the one from keystore) is compared with the computed hash (the one from user input) in order to authenticate the user and let him use the machine.

VBOXDIECracker - the tool

With the appropriate format and algorithm we can emulate the password verification of VirtualBox and make a not-so-fast cracker with PHP (sorry guys, I did not find a standard package on python to use AES XTS), it is just a proof of concept, so you can develop another leet tools.

You can download it from this site or browse it from the repository.

This is a sample of the source code showing the main function which is the one who computes the final hash:

<?php

// redacted

/**
 * crack_keystore
 *
 * Makes a bruteforce to find the final hash contained in the KeyStore
 * Returns the plaintext password used to encrypt de disk of the virtual machine
 */
function crack_keystore($keystore, $wordlist) {
    $fp = fopen($wordlist, 'r');
    if (is_resource($fp)) {
        $hash = get_hash_algorithm($keystore);
        $method = get_openssl_method($keystore);

        while (!feof($fp)) {
            $user_password = trim(fgets($fp));

            $EVP_password = hash_pbkdf2($hash, $user_password, $keystore['pbkdf2_1_salt'], $keystore['pbkdf2_1_iterations'], $keystore['generic_key_length'], true);

            $decrypted_password = openssl_decrypt(substr($keystore['pbkdf2_2_encrypted_password'], 0, $keystore['evp_decrypt_input_length']), $method, $EVP_password, OPENSSL_RAW_DATA, '');
            if ($decrypted_password === false) {
                continue;
            }

            $final_hash = hash_pbkdf2($hash, $decrypted_password, $keystore['pbkdf2_2_salt'], $keystore['pbkdf2_2_iterations'], $keystore['pbkdf2_2_key_length'], true);
            if ($final_hash === $keystore['final_hash']) {
                return $user_password;
            }
        }

        return false;
    } else {
        return false;
    }
}

// redacted

And the final output with a recovered password:

$ php VBOXDIECracker.php
VirtualBox Disk Image Encryption cracker

Usage: VBOXDIECracker.php disk_image.vbox [wordlist]

$ php VBOXDIECracker.php Encrypted.vbox wordlist.txt
VirtualBox Disk Image Encryption cracker

[+] Reading data from: Encrypted.vbox
----------------------------------------------------------------
[+] Checking hard disk encryption for: Encrypted.vdi
[+] Hard disk is encrypted
[+] KeyStore encoded string:
        U0NORQABQUVTLVhUUzI1Ni1QTEFJTjY0AAAAAAAAAAAAAAAAAABQQktERjItU0hB
        MjU2AAAAAAAAAAAAAAAAAAAAAAAAAEAAAAASAniX2ss6TE/u9IdinWigcwAg2bXe
        dJRAjHr5mvCCiSAAAAAntQHDFvSfwpay/jKFVzUWc4GsIJ/RwMg+XkG2b/PDWtAH
        AACKj0qUg37sG7TWmi58n/rcXmWVNt9FqBxGZiz2a+leWNAHAABAAAAA6qVV8nOu
        r58RVxKP0cNRfXyu9D7JqqVAaRfNE3LFdoz4hXxWWWcxjOGBJA/BQ5VuwvrDxO8O
        YpwYgl3yKOcewg==
[+] KeyStore contents:
        Header                        454e4353 (SCNE)
        Version                       1
        Algorithm                     AES-XTS256-PLAIN64
        KDF                           PBKDF2-SHA256
        Key length                    64
        Final hash                    12027897dacb3a4c4feef487629d68a0730020d9b5de7494408c7af99af08289
        PBKDF2 2 Key length           32
        PBKDF2 2 Salt                 27b501c316f49fc296b2fe32855735167381ac209fd1c0c83e5e41b66ff3c35a
        PBKDF2 2 Iterations           2000
        PBKDF2 1 Salt                 8a8f4a94837eec1bb4d69a2e7c9ffadc5e659536df45a81c46662cf66be95e58
        PBKDF2 1 Iterations           2000
        EVP buffer length             64
        PBKDF2 2 encrypted password   eaa555f273aeaf9f1157128fd1c3517d7caef43ec9aaa5406917cd1372c5768c
                                      f8857c565967318ce181240fc143956ec2fac3c4ef0e629c18825df228e71ec2
[+] Cracking finished, measured time: 6.13035 seconds
[!] KeyStore password found: 123
----------------------------------------------------------------
[+] Checking hard disk encryption for: New_Disk.vdi
[-] Hard disk is not encrypted

Archivado en: Sin categoría | Comentarios (3)

Backdoor CTF 2015 - RSANNE

Abril 3, 2015

We are given with two files in this challenge: an encrypted file and a 4484 bit RSA public key. The challenge is to get the plaintext from the encrypted file.

The first step is to get the modulus from the PEM file:

# openssl rsa -inform PEM -pubin -text -modulus < id_rsa.pub
Public-Key: (4484 bit)
Modulus:
    0f:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff:ff:ff:fd:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    f8:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:01
Exponent: 65537 (0x10001)
Modulus=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFFFFF
FF80000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000001
writing RSA key
-----BEGIN PUBLIC KEY-----
MIICUjANBgkqhkiG9w0BAQEFAAOCAj8AMIICOgKCAjEP////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
//////////////////////////3////////////4AAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAECAwEAAQ==
-----END PUBLIC KEY-----

N is the product of two Mersenne primer numbers, so the second step is to make a script which is used to find them:

#!/usr/bin/env python

mersenne = [2, 3, 5, 7, 13, 17, 19, 31, 61, 89, 107, 127, 521, 607, 1279, 2203, 2281, 3217, 4253, 4423, 9689]

for n1 in mersenne:
    for n2 in mersenne:
        m1 = (2 ** n1)  - 1
        m2 = (2 ** n2) - 1
        if m1 * m2  == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFFFFFFF80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001:
            print "Match! ", m1, m2

The two prime numbers are: 22281 - 1 and 22203 - 1.

We use rsatool.py from ius to reconstruct the private key PEM file (which is used later to decrypt the content of the file using the OAEP padding scheme):

-----BEGIN RSA PRIVATE KEY-----
MIIKCAIBAAKCAjEP////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//3////////////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAECAwEAAQKCAjEIHnfhiB534Yged+GIHnfhiB534Yged+GIHnfhiB534Yged+GIHnfhiB534Yge
d+GIHnfhiB534Yged+GIHnfhiB534Yged+GIHnfhiB534Yged+GIHnfhiB534Yged+GIHnfhiB53
4Yged+GIHnfhiB534Yged+GIHnfhiB534Yged+GIHnfhiB534Yged+GIHnfhiB534Yged+GIHnfh
iB534Yged+GIHnfhiB534Yged+GIHnfhiB534Yged+GIHnfhiB534Yged+GIHnfhiB534Yged+GI
HnfhiB534Yged+GIHnfhiB534Yged+GIHnfhiB534Yged+GIHnfhiB534Yged+GIHnfhiB534Yge
d9+AgH9/gIB/f4B4YQee+GEHnvhhB574YQee+GEHnvhhB574YQee+GEHnvhhB574YQee+GEHnvhh
B574YQee+GEHnvhhB574YQee+GEHnvhhB574YQee+GEHnvhhB574YQee+GEHnvhhB574YQee+GEH
nvhhB574YQee+GEHnvhhB574YQee+GEHnvhhB574YQee+GEHnvhhB574YQee+GEHnvhhB574YQee
+GEHnvhhB574YQee+GEHnvhhB574YQee+GEHnvhhB574YQee+GEHnvhhB574YQee+GEHnvhhB574
YQee+GEHnvhhB574YQee+GEHnvhhB574YQee+GEHnvhhB574YQee+GEHnvhhB574YQee+GEHnvhh
B6ECggEeAf//////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
/////////wKCARQH////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//8CggEeAYCAf3+AgH9/gIB/f4CAf3+AgH9/gIB/f4CAf3+AgH9/gIB/f4CAf3+AgH9/gIB/f4CA
f3+AgH9/gIB/f4CAf3+AgH9/gIB/f4CAf3+AgH9/gIB/f4CAf3+AgH9/gIB/f4CAf3+AgH9/gIB/
f4CAf3+AgH9/gIB/f4CAf3+AgH9/gIB/f4CAf3+AgH9/gIB/f4CAf3+AgH9/gIB/f4CAf3+AgH9/
gIB/f4CAf3+AgH9/gIB/f4CAf3+AgH9/gIB/f4CAf3+AgH9/gIB/f4CAf3+AgH9/gIB/f4CAf3+A
gH9/gIB/f4CAf3+AgH9/gIB/f4CAf3+AgH9/gIB/f4CAf3+AgH9/gIB/f4CAf3+AgH9/gIB/f4CA
f3+AgH9/fwKCARQGWWmmlllpppZZaaaWWWmmlllpppZZaaaWWWmmlllpppZZaaaWWWmmlllpppZZ
aaaWWWmmlllpppZZaaaWWWmmlllpppZZaaaWWWmmlllpppZZaaaWWWmmlllpppZZaaaWWWmmlllp
ppZZaaaWWWmmlllpppZZaaaWWWmmlllpppZZaaaWWWmmlllpppZZaaaWWWmmlllpppZZaaaWWWmm
lllpppZZaaaWWWmmlllpppZZaaaWWWmmlllpppZZaaaWWWmmlllpppZZaaaWWWmmlllpppZZaaaW
WWmmlllpppZZaaaWWWmmlllpppZZaaaWWWmmlllpppZZaaaWWWmmlllpppZZaaaWWWmmlllpppZZ
aaUCggEeAKqqlVVSqqpVVUqqqlVVSqqpVVUqqqlVVSqqpVVUqqqlVVSqqpVVUqqqlVVSqqpVVUqq
qlVVSqqpVVUqqqlVVSqqpVVUqqqlVVSqqpVVUqqqlVVSqqpVVUqqqlVVSqqpVVUqqqlVVSqqpVVU
qqqlVVSqqpVVUqqqlVVSqqpVVUqqqlVVSqqpVVUqqqlVVSqqpVVUqqqlVVSqqpVVUqqqlVVSqqpV
VUqqqlVVSqqpVVUqqqlVVSqqpVVUqqqlVVSqqpVVUqqqlVVSqqpVVUqqqlVVSqqpVVUqqqlVVSqq
pVVUqqqlVVSqqpVVUqqqlVVSqqpVVUqqqlVVSqqpVVUqqqlVVSqqpVVUqqqlVVSqqpVVUqqqlVVS
qqpVVUqqqQ==
-----END RSA PRIVATE KEY-----

Final step is to decrypt the file:

# openssl rsautl -decrypt -in flag_d.bin -out plaintext.txt -inkey private.pem -oaep
Loading 'screen' into random state - done

# cat plaintext.txt
the_flag_is_e4972e14...

Archivado en: Criptografía, Retos informáticos | Comentarios (0)

B-Sides Vancouver CTF 2015 - garbage file

Marzo 18, 2015

Description

Your buddy Joey left a USB key with some data he needs your help with. He pulled it from the firewall logs at a 'secure file format'-as-a-Service provider, so he's pretty sure it might be protected or obfuscated somehow.

garbagefile.pcapng.gz

Solution

A PCAPNG file is provided, there we can see some UDP packets where the data is located:

We need to get all the data sent over UDP, we can do it by using tshark:

$ tshark -r garbagefile.pcapng -Y "udp" -T fields -e data
00026163636f756e742d646174612e62696e006f6374657400
00040000
0003000100004edf00002e77789c0173018cfe4435d00b168b...
00040001
00030002803434680f53d41a3d4068007a801a1ea0341a1ea7...
00040002
00030003142dfea2fb389f6ded40c310f8dcc905034127d07f...

Each message is composed by two short integers (first one to indicate which is sending the message + second one an incremental ID), and the data itself. I used this script on PHP to separate data from metadata and create bzip files (based on bzip headers found on the dump):

<?php

$file = file('data.txt');

$out = '';
for ($i = 2; $i < count($file); $i += 2) { // ignore first and second line, then each two
    $out .= hex2bin(substr(trim($file[$i]), 8)); // strip metadata
}

$i = 0;
$bzs = explode('BZh', $out);
foreach ($bzs as $bz) {
    file_put_contents('bzips/' . $i++, 'BZh' . $bz);
}
?>

Twenty two files are created, it is time to decompress them using python:

import bz2
import sys

for i in xrange(0,22):
    try:
        file = bz2.BZ2File(str(i), "r")
        print file.read()
    except:
        sys.stderr.write('file '+ str(i) + ' invalid\n')

There are only three "corrupted" files:

file 0 invalid
file 8 invalid
file 21 invalid

First file does not contain a bzip header, so it was skipped. Second file is the heaviest (20.8KB) and it is possible the file we are looking for. We are making a guess now, the file seems to have a Zlib header:

It is decompressed properly giving us a base64 encoded file:

iVBgMA0KNH0AAC56SUhqJQAALO0AAC4TCAIudwCpR3DoAC53AXN8MEIAgLkc6S53AAleP1lzLncL
Ey53CxMvd5qcNncAQC4+REF6DwHt83C8BWsCMPB7xwsIBH9SBQojRUGjPbH3OPolxPZlTYIDJj8T
Y3saExvhmNgfMRMLBOHERp5W2MAofwgoM9MqKqxXWL7RyXlvwZnM7FMM997V/ez88Ji+2ffuM2fg
... (cropped)
a0ANOm8oMH4XoMBu9tWlbty/38TVNdQQJ2Cg7jeBgSx0BQYkA6fAjrm700S/OVBO18BAr/YCAyuh
KAUoAr5GFRFAa463QIGvdQMFKH10p+7Xzrv9Hcg5fhegwG72gQItctYoK3F1vmhMZkBF18BAr/YC
AytxCnSJt6DOlaRqyBcnYKDuN4GBLHQF1gZyBnWQMTtmbhygwG72gQItcgYKWtDA/ymC2qJiimhr
73cAAC4+RU5q2UJgrA==

Final result is a PNG file encrypted with XOR using "00 00 2E 77" as key:

Flag

key{03087-08351-27H}

Archivado en: Miscelaneo, Retos informáticos, Seguridad | Comentarios (0)