[ctf.show.reverse] 36D杯 BBBigEqSet

用ida打开程序发现程序巨大,F5都不工作了

一点点看汇编,发现似乎是机器生成的,先是输入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

这个东西就是线性代数里的行列式。一开始想用z3解,可0x80个式子和0x80个变量对于z3来说太大了。后来看风上说用numpy.linalg.solve()

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值