Unleash the Beast!

CTFなどのメモに使います

ENCRYPT CTF 2019 - ham-me-baby(Misc 75)

f:id:imurasheen:20190405114132p:plain

Maybe the problem is replaced ham-me-baby -> ham-me-baby2

The result is an error despite the execution of the ham-me-baby script.

 

Maybe sometime the CODE which sent from the server is wrong.

So I should detect it and it is necessary to submit the DATA corrected by the Hamming code.

To understanding it, I should read following wiki.

Hamming(7,4) - Wikipedia

I defined the 7 bits given by CODE as follows.

P1 P2 D1 P3 D2 D3 D4

P:Parity bit / D:Data bit

And I made the judgement syntax referring to this site.

http://www.kmiura.net/archives/4662487.html

D1 XOR D3 XOR D4 XOR P1 = 0 //Syntax1
D1 XOR D2 XOR D4 XOR P2 = 0 //Syntax2
D1 XOR D2 XOR D3 XOR P3 = 0 //Syntax3

if all syntaxes are 1 ->D1 is wrong.

if only Syntax1 is 0 and others are 1 -> D2 is wrong.

if only Syntax2 is 0 and others are 1 -> D3 is wrong. 

if only Syntax3 is 0 and others are 1 -> D4 is wrong.

I rewrite the script according to above logic.

Curiously, the logic is correct, but the script result is error...

 

So I think that the data sequence of CODE is different from what I expected.

I changed the handling of the bits of CODE as following.

P1 P2 D4 P3 D3 D2 D1 -> reverse the sequence of Data bits.

It is correct challenge.

 

The script is following.

import socket

def humming_validate(code):
d4 = int(code[2])
d3 = int(code[4])
d2 = int(code[5])
d1 = int(code[6])

p1 = int(code[0])
p2 = int(code[1])
p3 = int(code[3])

code_result=code

result1 = d1^d3^d4^p1
result2 = d1^d2^d4^p2
result3 = d1^d2^d3^p3

if result1==1 and result2==1 and result3==1:
#d1 is error
print "d1 is error"
if d1==0:
rep = '1'
else:
rep = '0'
code_result = code_result[:6]+ rep #+code_result[3:]

elif result1==0 and result2==1 and result3==1:
#d2 is error
print "d2 is error"
if d2==0:
rep = '1'
else:
rep = '0'
code_result = code_result[:5]+ rep +code_result[6:]

elif result1==1 and result2==0 and result3==1:
#d3 is error
print "d3 is error"
if d3==0:
rep = '1'
else:
rep = '0'
code_result = code_result[:4]+ rep +code_result[5:]

elif result1==1 and result2==1 and result3==0:
#d4 is error
print "d4 is error"
if d4==0:
rep ='1'
else:
rep ='0'
code_result = code_result[:2]+ rep +code_result[3:]

return code_result

def recvuntil(s, tail):
data = ''
while True:
if tail in data:
return data
data += s.recv(1)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect*1

data = recvuntil(s, 'bits.\n').strip()
print data
data = recvuntil(s, '\n').strip()
print data
#data = recvuntil(s, '\n').strip()
#print data

for i in range(100):
data = recvuntil(s, '\n').strip()
print data
if data == 'CODE VALIDATED':
print 'Round %d' % (i+1)
data = recvuntil(s, '\n').strip()
print data
code = data.split(': ')[1]
code_result = humming_validate(code)
d = code_result[2] + code_result[-3:]
data = recvuntil(s, ': ')
print data + d
s.sendall(d + '\n')

data = recvuntil(s, '\n').strip()
print data

data = recvuntil(s, '\n').strip()
print data

 

So I got the flag.

flag is: encryptCTF{1t_w4s_h4rd3r_th4n_1_th0ught}

 

*1:'104.154.106.182', 6969