Skip to content

Instantly share code, notes, and snippets.

@sonickun
Last active July 20, 2016 14:26
Show Gist options
  • Select an option

  • Save sonickun/01515eaa48b4d9831e42df40164f7720 to your computer and use it in GitHub Desktop.

Select an option

Save sonickun/01515eaa48b4d9831e42df40164f7720 to your computer and use it in GitHub Desktop.
katagaitai勉強会(関東med)おまけ Plaid CTF 2014 Parlor Write-up
// Refered hash_extender: https://github.com/iagox86/hash_extender
#include <stdio.h>
#include <string.h>
#include <openssl/md5.h>
unsigned int extend(unsigned int A, unsigned int B, unsigned int C, unsigned int D, char *testhash2) {
MD5_CTX ctx;
unsigned char buffer[MD5_DIGEST_LENGTH];
int i;
MD5_Init(&ctx);
MD5_Update(&ctx, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 64);
ctx.A = htonl(A);
ctx.B = htonl(B);
ctx.C = htonl(C);
ctx.D = htonl(D);
MD5_Update(&ctx, "b", 1);
MD5_Final(buffer, &ctx);
char res[40];
for (i = 0; i < 16; i++) {
sprintf(&res[2*i], "%02x", buffer[i]);
}
if (!memcmp(res + 16, testhash2 + 16, 8)) {
return A;
}
return 0;
}
unsigned int brute(unsigned int A, unsigned int B, unsigned int C, unsigned int D, char *testhash2) {
unsigned int i;
for (i = 0; i < 1 << 28; i++) {
A = (A & 0xf) | (i << 4);
if ((i & 0xfffff) == 0)
printf("%08x\n", i);
unsigned int res = extend(A, B, C, D, testhash2);
if (res != 0) {
return res;
}
}
return 0;
}
import socket
import subprocess
import ctypes
import struct
import os
remoteip = "katagaitai.orz.hm"
remoteport = 4321
dll = ctypes.cdll.LoadLibrary("./my_hash_extender.so")
def sock(remoteip, remoteport):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((remoteip, remoteport))
return s, s.makefile('rw', bufsize=0)
def read_until(f, delim='\n'):
data = ''
while not data.endswith(delim):
data += f.read(1)
return data
def length_extension(x, y, test_hash):
cmd = 'hash_extender -d %s -a %s -s %s -l 16 -f md5' % (x, y, test_hash)
ret = subprocess.check_output(cmd.split(" "))
lines = ret.split("\n")
signature = lines[2].split(" ")[-1]
string = lines[3].split(" ")[-1].decode("hex")
return signature, string
s, f = sock(remoteip, remoteport)
print read_until(f, "quit")
s.send("1\n")
read_until(f, "100):")
s.send("100\n")
read_until(f, "quit")
s.send("3\n")
read_until(f, "round")
s.send("a")
read_until(f, "generated ")
suffix = int(read_until(f, ",")[:-1])
suffix = hex(suffix)[2:].strip("L").rjust(32, '0')
print "[+] suffix:", suffix
related_hash, related_str = length_extension('a', 'b', suffix)
s.send("3\n")
read_until(f, "round")
s.send(related_str)
read_until(f, "generated ")
related_suffix = int(read_until(f, ",")[:-1])
related_suffix = hex(related_suffix)[2:].strip("L").rjust(32, '0')
print "[+] related_suffix: ", related_suffix
A, B, C, D = struct.unpack(">4I", suffix.decode("hex"))
A = dll.brute(A, B, C, D, related_suffix)
full_hash = struct.pack(">4I", A, B, C, D).encode("hex")
print "[+] full_hash", full_hash
balance = 1000
while True:
add = os.urandom(8).encode("hex")
new_hash, new_str = length_extension('a', add, full_hash)
n = int(new_hash, 16)
odds = 0
while n % 2 == 0:
odds += 1
n >>= 1
if odds == 0:
continue
print read_until(f, "quit")
s.send("1\n")
print read_until(f, "100):")
s.send(str(odds)+ "\n")
print read_until(f, "quit")
s.send("2\n")
print read_until(f, "):")
s.send(str(balance)+ "\n")
print read_until(f, "quit")
s.send("3\n")
print read_until(f, "round")
s.send(new_str)
balance += odds * balance
s.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment