Skip to content

Instantly share code, notes, and snippets.

@vanhoavn
Created November 6, 2017 16:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vanhoavn/57596dc9c7bf037da0f99b274b3d6ed1 to your computer and use it in GitHub Desktop.
Save vanhoavn/57596dc9c7bf037da0f99b274b3d6ed1 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
from pwn import *
def pad(msg): return msg+chr(16-len(msg)%16)*(16-len(msg)%16)
def pad0(msg):return msg+chr(0)*(16-len(msg)%16)
def unpad(msg): return msg[:-ord(msg[-1])]
def xor(a, b): return ''.join(map(lambda (x,y): chr(x^y), zip(map(ord, a), map(ord, b))))
assert(xor("B"*7, "\x01"*7)=="C"*7)
#p = process(['python','./test.py'])
p = remote('52.193.157.19', 9999)
'''POW'''
if True:
data = p.recv()
print 'POW: ', data
suffix = data[data.find("+") + 1: data.find(")")]
h = data[data.find("= ") +2 :]
print suffix, h
p2 = process(['./sha256', 'aaaa'+suffix, h])
pp = p2.recv()
print "[+] pow:", pp
p.sendline(pp.strip())
s = p.readline()
print '>>', s
while not('Done' in s):
s = p.readline()
print '>> ', s
'''Main'''
welcome_txt = pad('Welcome!!')
welcome_enc = base64.b64decode(p.readline())
welcome_iv, welcome_cip = welcome_enc[:16], welcome_enc[16:]
assert(len(welcome_cip)==16)
p.sendline(base64.b64encode(xor(xor(welcome_iv, pad('get-flag')), welcome_txt) + welcome_cip))
flag_enc = base64.b64decode(p.readline())
flag_iv, flag_cip = flag_enc[:16], flag_enc[16:]
print 'Flag Enc: ', flag_enc.encode('hex')
#print ' [Local] should match', base64.b64decode('MmpwbUxvU3NPbFFycXlxRbbtTcX3aJlKP5kQJOoWD/eiN0MHN88804ayP2ALs9vT').encode('hex')
'''
Generate single-byte md5 table
'''
def generate_md5_table(prefix = ""):
cipher_plain = xor(welcome_txt, welcome_iv)
new_iv = welcome_iv
new_cip = welcome_cip + welcome_cip * 6
new_txt = welcome_txt + xor(cipher_plain, welcome_cip) * 6
enc_dict = {}
target = 'get-md5' + prefix + '\x00'
new_cip = list(new_cip)
new_cip[-17] = chr(ord(new_cip[-17]) ^ ord(new_txt[-1]) ^ ( len(new_txt) - len(target) ))
new_cip = ''.join(new_cip)
target = list(pad0(target))
for c in range(256):
if(chr(c).strip() != chr(c)):
continue
target[7 + len(prefix)] = chr(c)
p.send(base64.b64encode(xor(xor(new_iv, ''.join(target)), new_txt) + new_cip) + "\n")
c_enc = base64.b64decode(p.readline())
enc_dict[c_enc] = chr(c)
return enc_dict
enc_dict = generate_md5_table('')
print ' - number of enc entries', len(enc_dict)
print ' - test (v): ', enc_dict.get(base64.b64decode('MmpwbUxvU3NPbFFycXlxRZXZyJzVpQOCENUVu0WFPIwEgs3wNIfaPpr9/D3Cw3hK'), None)
print '[*] Find last byte'
'''
Find last byte
'''
prefix = 'hitcon{'
last_char = None
for try_char in range(256):
target = list('get-md5' + chr(try_char) + '\x00' * 7 + chr(0) )
assert len(target)==16
for c in range(256):
target[15] = chr(c)
# hitcon{abcdefghi
p.send(base64.b64encode(xor(xor(flag_iv, ''.join(target)), pad0(prefix)) + flag_cip[:16]) + "\n")
c_enc = base64.b64decode(p.readline())
if (c_enc in enc_dict):
print "Found last char: ", chr(c^8).encode('hex'), ' try char is ', chr(try_char), ' md5 matches to', enc_dict.get(c_enc).encode('hex')
last_char = chr(c^8)
break
if last_char is not None: break
sol = 'hitcon{'
last_enc = None
prefix = ''
while len(sol+prefix) < 15:
enc_dict = generate_md5_table(prefix)
target = list('get-md5' + prefix + "\x00" + "\x00" * 16 )[:16]
target[15] = chr((16 - len('get-md5' + prefix + "\x00")) ^ ord(last_char))
# hitcon{abcdefghi
p.send(base64.b64encode(xor(xor(flag_iv, ''.join(target)), pad0(sol+prefix)) + flag_cip[:16]) + "\n")
c_enc = base64.b64decode(p.readline())
if c_enc in enc_dict:
print "Found char: ", enc_dict.get(c_enc)
last_enc = c_enc
prefix += enc_dict.get(c_enc)
else:
print ":("
sys.exit(-1)
prefix += last_char
print "First block: ", sol + prefix
rest_blocks = flag_cip[16:]
rest_blocks = [rest_blocks[i:i+16] for i in range(0, len(rest_blocks), 16)]
print "Solving from prefix: ", prefix
os.system("rm -f log.txt")
flag_cip_i_base = 0
for block in rest_blocks:
middle_block_base = "\x00"*16
flag_injected_cip = flag_cip[:16] + middle_block_base + block
last_char = None
last_length = None
for c in range(256):
control = "\x00" * 31 + chr(c)
p.send(base64.b64encode(xor(flag_iv,pad0(xor('get-md5','hitcon{'))) + flag_injected_cip + control) + "\n")
c_enc = base64.b64decode(p.readline())
if (c_enc == last_enc):
print " /!\ Found last char", c, "that match to pad", len(flag_injected_cip + control) - 15
last_char = c
last_length = (len(flag_injected_cip + control) - 15)
break
assert last_char is not None
blr = ''
for i in range(16):
wsp = []
for c in range(256):
control = "0" * 32
flag_injected_cip = list(flag_cip[:16] + middle_block_base + block)
flag_injected_cip[16+i] = chr(c)
flag_injected_cip = ''.join(flag_injected_cip)
control = "\x00" * 15 + chr(last_length ^ len(flag_injected_cip + control) - 32 - i) + "\x00" * 15 + chr(last_char)
p.send(base64.b64encode(xor(flag_iv,pad0(xor('get-md5','hitcon{'))) + flag_injected_cip + control) + "\n")
c_enc_1 = base64.b64decode(p.readline())
control = "\x00" * 15 + chr(last_length ^ len(flag_injected_cip + control) - 33 - i) + "\x00" * 15 + chr(last_char)
p.send(base64.b64encode(xor(flag_iv,pad0(xor('get-md5','hitcon{'))) + flag_injected_cip + control) + "\n")
c_enc_2 = base64.b64decode(p.readline())
if (c_enc_1 == c_enc_2):
# print ' * Possible ',chr(c).encode('hex')
wsp.append(c)
for c in range(256):
if all([ chr(c ^ w ^ ord(flag_cip[flag_cip_i_base+i])).strip()=='' for w in wsp ]):
blr += chr(c)
print '! Found', c, chr(c), ' -> ', blr
flag_cip_i_base += 16
print len(enc_dict)
#'9e3669d19b675bd57058fd4664205d2a'
p.shutdown('send')
p.wait_for_close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment