Ein Blog

Posts mit Tag "bnd"

BND-CTF: RSA Key Generation

Der BND hat mal wieder einen öffentlichen Einstellungstest, dem wir uns erfreuen dürfen. Ideal, um sich mal etwas in CTF-Writeups zu probieren!

Aus der Kategorie Cryptography schauen wir uns mal die (einzige) Challenge an: Analysieren einer Backdoor in einem RSA-Schlüsselerzeugungsalgorithmus.

Folgender Code wurde uns bereitgestellt:

SageMath-Code {%- highlight c linenos -%} ### Excerpt from utils.py (used to encode / decode the message) def encode(msg): """ Convert a message to a number.
Example:
>>> hex(encode(b'ABCD'))
'0x41424344'
"""
return int.from_bytes(msg, byteorder='big')

def decode(msg): """ Convert a number back to a message.

Example:
>>> decode(0x41424344)
b'ABCD'
"""
return int(msg).to_bytes(length=len(hex(msg))//2-1, byteorder='big')

Excerpt from RSA.py

x = 0xbb31781a2436fd6833597b61f91b94fba8cc5be702c7084de28625d96823102daf48dd84244fe41d180452a900388d1666ff59981f0912c6640977684c20bcfdcbf365dfcb68c0c5a9fd02576134a0e94ab9e20bbacffb4df5c9c27ae7f5022f6609aefeb9f5249387925ad13ce80a13

def rsa_keygen(): def a(x, y): z = 1 while True: if is_prime(xz + y): return xz + y z += 1

p = a(x, random_prime(2^128, None, 2^127))
q = a(x, random_prime(2^128, None, 2^127))

N = p * q
e = 65537

d = inverse_mod(e, (p-1) * (q-1))

return e, d, N

def rsa_crypt(m, k, n): return lift(Mod(m, n) ^ k) {%- endhighlight -%}

(wer kein SageMath installiert hat, kann diese Online-Version verwenden)

Zu dem Code haben wir folgende Zahlen enthalten, die wir entschlüsseln sollen:

BND-CTF: 86-GBE Message Service

Der nächste Writeup aus den BND-CTFs. Nach der Backdoor in der RSA-Schlüsselerzeugung, dieses Mal aus der Kategorie Binary Exploitation.

Das Ziel:

Exploit a binary to gain a remote shell.

Wir bekommen die server.c, sowie die auf dem Server genutzte libc.

Server-Code {%- highlight c linenos -%} // gcc server.c -o server -g -ggdb -Wl,-z,norelro -fstack-protector-all

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h>

int my_read(FILE *fd, char *buf, size_t max) { int read = 0; while (read < max && !feof(fd)) { int ch = getc(fd); if (ch == ‘\n’) { break; } else { buf[read] = ch; read++; } } buf[read] = 0;

return read;

}

char rot13(char ch) { if (ch >= ‘a’ && ch <= ‘z’) { return ((ch - ‘a’ + 13) % 26) + ‘a’; } else if (ch >= ‘A’ && ch <= ‘Z’) { return ((ch - ‘A’ + 13) % 26) + ‘A’; } else if (ch >= ‘0’ && ch <= ‘9’) { return ((ch - ‘0’ + 5) % 10) + ‘0’; } else { return ch; } }

int main(int argc, char** argv) { setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0);

char inp[0x100];
char cc;

puts("Welcome to our 86-GBE service!");
puts("Enter your message and press return.");
puts("Enter quit to exit.");

unsigned char len;
for (;;) {
	len = my_read(stdin, inp, sizeof (inp) - 1);
	if (strcmp(inp, "quit") == 0) {
		exit(0);
	}

	for (int i = 0; i < len; i++) {
		inp[i] = rot13(inp[i]);
	}

	for (int i = 0; i < len / 2; i++) {
		cc = inp[i];
		inp[i] = inp[len -i -1];
		inp[len - i - 1] = cc;
	}

	printf(inp);
	putc('\n', stdout);
}

exit(0);

} {%- endhighlight -%}

Nehmt Euch am Besten etwas Zeit, um den Code erstmal anzuschauen.

Falls Ihr das nachstellen wollt, die Sha1-Hashes der beiden Shared-Objects und der bereitgestellten server-Executable sind: