CTFshow Reverse 36D杯 BBBigEqSet wp

发布时间 2023-11-16 11:49:41作者: Ethan(ˊ˘ˋ*)

用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}