【CTF】Reverse Writeup Win API逆向,Python字节码 OLLVM,rc4 换表base64 2022DASCTF Oct 逆向学习

CTF · 2022-10-31 · 1185 人浏览

Win API逆向 反调试, Python字节码 ,OLLVM rc4 换表base64

贪玩ctf

TlsCallback_0有个Isdebuggerpresent反调试 直接nop就行

image-20221023181007509

这边messagebox有个小技巧,把中文显示出来,选这个直接显示中文 非常的方便

image-20221023181052434

image-20221023181123721

通过中文定位到关键代码发现有个加密

image-20221023181253371

往下翻可以看到可疑加密函数

image-20221023181352319

进入后可以发现频繁调用sbox进行加密操作 并且有两个sbox 猜测为aes 实际动调后发现256字节的两个sbox

image-20221023181444035

回到前面先把account解出来

image-20221023181619686

acc = [0x04, 0x1F, 0x1F, 0x1E, 0x43, 0x4B, 0x43, 0x45,
       0x44, 0x00, 0x16, 0x10, 0x55, 0x17, 0x12, 0x73]
for i in range(len(acc)-1):
    acc[i] ^= acc[15]
    print(chr(acc[i]), end='')
print(chr(acc[15]), end='')
#wllm08067sec&das

然后拿到密码的密文,这边动调能看到其实是pass的位置。

image-20221023181721558

image-20221023181725251

找了一阵子没找到aes的key 但是想着key和account位数好像一致,直接拿去赛博厨子试一下 然后出了

image-20221023182011863

flag账号密码拼起来就行

pycode

队友做的 逆一下字节码然后用z3解就行了

from Crypto.Util import number
from Crypto.Util.number import *

m=b""
from z3 import *
def solve(x):
    a, b, c, d = BitVecs("a b c d", 35)
    s = Solver()
    s.add((a >> 11) ^ a == b)
    s.add(((b << 7) & 0x78866191) ^ b == c)
    s.add(((c << 15) & 2323163360) ^ c == d)
    s.add((d >> 18) ^ d == x)
    an = s.check()
    print(an)
    return long_to_bytes(s.model()[a].as_long()^(2**35-1))

enc = "8b2e4e858126bc8478d6a6a485215f03"
enc=bytes.fromhex(enc)
for i in range(len(enc) // 4):
    t = enc[i*4:i*4+4]
    t = number.bytes_to_long(t)
    m+=solve(t)
print(bytes.hex(m))

challenge

改一下变量名字 断到memset前面可以发现上面一堆是把input的奇数位偶数位单独分开拿出来

image-20221023182215274

然后往下看 第一个函数sub4059f0没对input操作 不用管 往下看enc1这个 传了偶数位和sbox进去

点进去纯纯的控制流平坦化,D-810一把梭,但是还是很丑(后续发现可能是我d810的插件的z3寄了 没去除完整?)

image-20221023182454378

image-20221023182520286

但是看到这个,纯纯的rc4

image-20221023182538396

rc4对称加密那直接断点到这个函数前面,然后随便输入点东西,然后用插件把内存里面数据直接改成密文,断点到这个地方,直接看密文即可(不可以断到函数外面,因为下面有引起异常的,程序直接结束了)

image-20221023182615299

得到"ACFg0Gw1Jo5Ix9C}"

try catch调不了enc2咋整 断点在这个位置直接改eip或者直接nop掉call enc1 让程序直接jmp到catch里面也行

image-20221023183106207

但是我们目的根本就不是看enc2是啥 enc2一眼丁真base64换表。目的只是拿到catch块里面换掉的表而已

这里有个if,实际调起来会发现会直接退出 那jnz改成jz就行了 暴力一点

image-20221023183339431

image-20221023183343912

然后断到这里直接看表即可

image-20221023183413624

当然你直接c跑出来表也行 毕竟代码都给了

image-20221023183525882

拿到表 直接赛博厨子一把梭

image-20221023183629222

最后拼起来就行了

a = 'ACFg0Gw1Jo5Ix9C}'
b = 'DST{Wo7Xj5Ad8Nx8'
flag = ''
for i in range(16):
    flag += b[i]
    flag += a[i]
print(flag)
RE
  1. enllus1on 2022-11-04

    1919810

Theme Jasmine by Kent Liao