2016 Codegate compress writeup
by St1tchProblem
import md5
def encode(input_string):
print input_string
h = md5.md5(input_string[:4]).hexdigest()
table = {
'a': 1,
'b': 2,
'c': 3,
'd': 4,
'e': 5,
'f': 6,
'g': 7,
'h': 8,
'i': 9,
'j': 0
}
out = ""
prev = ""
stage1 = []
stage2 = []
stage3 = ""
passbyte = -1
for ch in input_string:
if ch in table.keys():
stage1.append(table[ch])
else:
stage1.append(ch)
for index, ch in enumerate(stage1):
if len(stage1) <= index+1:
if index != passbyte:
stage2.append(ch)
break
if passbyte != -1 and passbyte == index:
continue
if type(ch) == int and type(stage1[index+1])==int:
tmp = ch << 4
tmp |= stage1[index+1]
stage2.append(tmp)
passbyte = index+1
else:
stage2.append(ch)
for ch in stage2:
if type(ch) == int:
stage3 += chr(ch)
else:
stage3 += ch
for index, ch in enumerate(stage3):
if index >= len(h):
choice = 0
else:
choice = index
out += chr(ord(ch) ^ ord(h[choice]))
print repr(out)
encoded = "~u/\x15mK\x11N`[^\x13E2JKj0K;3^D3\x18\x15g\xbc\\Gb\x14T\x19E"
encode(st)
Solve
hash값이 plaintext의 앞 4글자만 가지고 md5를 하기 때문에 첫 4글자만 맞추면 hash값을 알 수 있고, 디크립트 할 수 있다.
첫 4글자를 맞추기 위해 브루트포싱을 돌렸다.;;
import md5
def encode(input_string):
#print input_string
h = md5.md5(input_string[:4]).hexdigest()
table = {'a': 1,'b': 2,'c': 3,'d': 4,'e': 5,'f': 6,'g': 7,'h': 8,'i': 9,'j': 0 }
out = ""
prev = ""
stage1 = []
stage2 = []
stage3 = ""
passbyte = -1
for ch in input_string:
if ch in table.keys():
stage1.append(table[ch])
else:
stage1.append(ch)
for index, ch in enumerate(stage1):
if len(stage1) <= index+1:
if index != passbyte:
stage2.append(ch)
break
if passbyte != -1 and passbyte == index:
continue
if type(ch) == int and type(stage1[index+1])==int:
tmp = ch << 4
tmp |= stage1[index+1]
stage2.append(tmp)
passbyte = index+1
else:
stage2.append(ch)
for ch in stage2:
if type(ch) == int:
stage3 += chr(ch)
else:
stage3 += ch
for index, ch in enumerate(stage3):
if index >= len(h):
choice = 0
else:
choice = index
out += chr(ord(ch) ^ ord(h[choice]))
#print repr(out)
return out
encoded = "~u/\x15mK\x11N`[^\x13E2JKj0K;3^D3\x18\x15g\xbc\\Gb\x14T\x19E"
import string
maps = string.printable
for a1 in maps :
for a2 in maps :
for a3 in maps :
for a4 in maps :
st = a1 + a2 + a3 + a4
out = encode(st)
if encoded[:len(out)] == out :
print st
위의 브루트포싱 코드를 돌리면 FLag라는 글자가 나온다.
따라서 이 4글자가 첫글자라고 짐작하고 디크립트 코드를 짯다.
import md5
import string
def decode(s) :
table = {'a': 1,'b': 2,'c': 3,'d': 4,'e': 5,'f': 6,'g': 7,'h': 8,'i': 9,'j': 0}
v = table.values()
k = table.keys()
table.clear()
for x, y in zip(v, k) :
table[x] = y
a, b = divmod(ord(s), 16)
if a == 0 :
out = table[b]
else :
out = table[a] + table[b]
return out
if __name__ == '__main__' :
printable = string.printable[:-5]
encoded = "~u/\x15mK\x11N`[^\x13E2JKj0K;3^D3\x18\x15g\xbc\\Gb\x14T\x19E"
h = md5.md5('FLag').hexdigest()
flag = ''
l = []
for i in range( len(encoded) ):
if i >= len(h) :
l.append( chr(ord(h[0]) ^ ord(encoded[i] )))
else :
l.append( chr(ord(h[i]) ^ ord(encoded[i] )))
for s in l :
if s in printable :
flag += s
else :
flag += decode(s)
print flag
블로그의 정보
튜기's blogg(st1tch)
St1tch