Last active
July 20, 2016 14:26
-
-
Save sonickun/01515eaa48b4d9831e42df40164f7720 to your computer and use it in GitHub Desktop.
katagaitai勉強会(関東med)おまけ Plaid CTF 2014 Parlor Write-up
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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