CTFshow Reverse 36D杯 BBBigEqSet wp
用ida打开程序,一点点看汇编,发现似乎是机器生成的,先是输入0x80长的flag,然后有0x80段运算,运算的内容是每一个字符乘一个系数相加后与一个数比较。
查看代码
.text:0000000000001175 push rbp
.text:0000000000001176 mov rbp, rsp
.text:0000000000001179 sub rsp, 100h
.text:0000000000001180 lea rdi, format ; "Give me Flag:"
.text:0000000000001187 mov eax, 0
.text:000000000000118C call _printf
.text:0000000000001191 lea rax, [rbp+s]
.text:0000000000001198 mov rsi, rax
.text:000000000000119B lea rdi, a128s ; "%128s"
.text:00000000000011A2 mov eax, 0
.text:00000000000011A7 call ___isoc99_scanf
.text:00000000000011AC lea rax, [rbp+s]
.text:00000000000011B3 mov rdi, rax ; s
.text:00000000000011B6 call _strlen
.text:00000000000011BB cmp rax, 80h
.text:00000000000011C1 jnz loc_4965D
.text:00000000000011C7 movzx eax, [rbp+s]
.text:00000000000011CE movsx eax, al
.text:00000000000011D1 imul edx, eax, 9421h
.text:00000000000011D7 movzx eax, [rbp+var_FF]
.text:00000000000011DE movsx eax, al
.text:00000000000011E1 imul eax, 60CDh
.text:00000000000011E7 add edx, eax
.text:00000000000011E9 movzx eax, [rbp+var_FE]
.text:00000000000011F0 movsx eax, al
.text:00000000000011F3 imul eax, 4BCFh
第1步是要在程序里把这些数字取出来,由于这里的程序是完全相同的,只是数字不同。所以直接取的字节。
第2步把这些东西运行行列式运算,由于行列式的这种运算有固定解法(不是暴力)所以秒出结果。
这里需要注意一点,linalg运算结果是x[][] 并且结果是用浮点数表示,所以用round对其取整
def u32(a):
return a[3]<<24 | a[2]<<16 | a[1]<<8 | a[0]
#1
data = open('BBBigEqSet', 'rb').read()[0x11c7:0x11c7+ 0x909*0x80]
print(hex(len(data)))
taba = []
tabb = []
for i in range(0x80):
stab=[0]*0x80
ptr = 12
for j in range(0x80):
stab[j] = u32(data[ptr: ptr+4])
ptr+=18
if j==0:
ptr-=2
ptr -= 11
taba.append(stab)
tabb.append(u32(data[ptr: ptr+4]))
data = data[0x909:]
print(taba, tabb)
#2
import numpy as np
an = np.array(taba)
bn = np.array(tabb)
x = np.linalg.solve(an,bn)
print(x)
print(bytes([round(i) for i in x]))
得到flag{Soooo000_LooOOOOOOOOggO99g99_s1muLtaNeOus_EEEQuat10n5_Y0UUUUUUuuu_cAA44AANNnnN_SOOOOOOLVE_IT17TT11771ITIT!!!_8ShotDshP90ab}