SECCON CTF 2022

[rev]babycmp

In [12]:
%matplotlib inline
v12=1
c=b'\x04 /  #\x1eYD\x1a\x7f5u6-+'+b'\x11\x17Z\x03mP6\x07\x15<\t\x01\x04G+6'+b'\x41\x0a\x38'
ind=[]
while v12<64:
    v14=v12//0x16+2*(v12//0x16+(((0x2E8BA2E8BA2E8BA3 *v12) >> 64) & 0xFFFFFFFFFFFFFFFC))
    v14&=0xffffffffffffffff
    v15=v12
    v12+=1
    ind.append(v15-2*v14)
k=b'Welcome to SECCON 2022\x00'
r=[c[0]^0x57]
for i in range(1,len(c)):
    r.append(c[i]^k[ind[i-1]])
bytes(r)
Out[12]:
b'SECCON{y0u_f0und_7h3_baby_flag_YaY}'

[rev]eguite

下来确定是一个rust程序,找找rust gui库,发现是一个egui程序

直接函数列表搜eguite,找到了onclick

最终比对

if ( *(_DWORD *)input ^ 'CCES' | *(_DWORD *)(input + 3) ^ '{NOC' || input[42] != '}' ) // SECCON{},长度为43
    return 0;
// 应该是什么字符解码
// input[19]=='-'
// input[26]=='-'
// input[33]=='-'
if ( v29 + v26 == 0x8B228BF35F6ALL
    && v31 + v29 == 0xE78241
    && v33 + v31 == 0xFA4C1A9FLL
    && v33 + v26 == 152984677251016LL )
  {
    return (v33 ^ v29 ^ v31) == 4184371021LL;
  }
In [6]:
from z3 import *
import struct
v=[BitVec("v%d"%i,64) for i in range(4)]
s=Solver()
s.add(v[0]+v[1]==0x8B228BF35F6A)
s.add(v[2]+v[1]==0xE78241)
s.add(v[3]+v[2]==0xFA4C1A9F)
s.add(v[3]+v[0]==152984677251016)
s.add(v[3]^v[2]^v[1]==4184371021)
s.add(v[0]&0xffff000000000000==0)
s.add(v[1]&0xffffffffff000000==0)
s.add(v[2]&0xffffffffff000000==0)
s.add(v[3]&0xffffffff00000000==0)
# s[7:19]--12 s[20:26]--6 s[27:33]--6 s[34:42]--8
if s.check()==sat:
    v=[s.model()[i].as_long() for i in v]
    r='SECCON{'
    r+=hex(v[0])[2:]+"-"
    r+=hex(v[1])[2:]+'-'
    r+=hex(v[2])[2:]+'-'
    r+=hex(v[3])[2:]+'}'
    print(r)
SECCON{8b228b98e458-5a7b12-8d072f-f9bf1370}

[rev]Devil Hunter

是clamscan的bytecode数据库格式 https://github.com/Cisco-Talos/clamav-bytecode-compiler ,查看给出的手册,其中包含bytecode的格式

尝试clambc的选项,看到一个-p,结果不给,于是只能clambc -t -c flag.cbc

长度37,sext--signed extend

In [10]:
data=[0x739e80a2,0x3aae80a3,0x3ba4e79f,0x78bac1f3,0x5ef9c1f3,0x3bb9ec9f,0x558683f4,0x55fad594,0x6cbfdd9f]
key=0xacab3c0
def decrypt(c,k):
    r=[]
    k=struct.pack('<I',k)
    c=struct.pack('<I',c)
    r.append(k[0]^c[0])
    r.append(k[3]^c[3])
    r.append(k[2]^c[2])
    r.append(k[1]^c[1])
    return r
flag=[]
for d in data:
    flag+=decrypt(d,key)
bytes(flag)
Out[10]:
b'byT3c0d3_1nT3rpr3T3r_1s_4_L0T_0f_fun'

[rev]DoroboH

主函数导出key并传输,然后接收来自服务器的RC4密钥并加密传输数据。

流量中过滤:ip.dst==192.168.3.6 or ip.src==192.168.3.6

发送长度:0x50,发送数据:0602000002aa0000004448310002000046a717b1d54537e862f6ba6f809aed0021afc44b8c95c9bec809518f10001cc96489ad8914e1d4e008aa60be8fe36f9b156e358940bbc1aa709098d93957e637

接收长度0x50,接收数据:0602000002aa00000044483100020000288f76749ec20b9ab18c618418ae9a70722618dc685e667fc0c19b906a6aa3a571f473ea0eaada269f29860d55ddcba0367ee6f7a1fac83d2d7395482930b3b8

又接收两次数据 0x67:8c28c20d027aa8bc9a71b107022421e907340de0f9a4c540611f2d95b560f8435fdb44ecb38876ddab1fe3ffcaf26aeb65b7f7f4d1d0bc6ceec521c77c27cd0ffba4a9d007228c478288b906b64d832be9822e123ec4a5abbc155a24b63a8c657c05ff6148124f

0x66:8c28c20d027aa8bc9a6bd436240c1df73e2714bfabaefb7d340635df9174e24719dd3bcce89572ddad49ac8c93f122aa61ada3f3cb8aa1288bab33957169fd04c482a797556ff067ccb2b031b64c9b03e586142015d5bfa6a1194b0cb939832c2609f3184f18

参考:https://github.com/sprushed/seccon2022_writeups/tree/master/reverse/DoroboH

首先应理解HCRYPTKEY的内存排布,,包含加密的指向下一个内部结构的指针,指针中包含密钥的offset。指针通过xor 0xA2491D83D96214A0进行加密,找到的方法是搜索内存,找指向dssenh_CPDecrypt函数的指针,一共有3个,其中一个指向rc4 key。

In [13]:
k1=bytes.fromhex('0602000002aa0000004448310002000046a717b1d54537e862f6ba6f809aed0021afc44b8c95c9bec809518f10001cc96489ad8914e1d4e008aa60be8fe36f9b156e358940bbc1aa709098d93957e637')
print([i for i in k1])
[6, 2, 0, 0, 2, 170, 0, 0, 0, 68, 72, 49, 0, 2, 0, 0, 70, 167, 23, 177, 213, 69, 55, 232, 98, 246, 186, 111, 128, 154, 237, 0, 33, 175, 196, 75, 140, 149, 201, 190, 200, 9, 81, 143, 16, 0, 28, 201, 100, 137, 173, 137, 20, 225, 212, 224, 8, 170, 96, 190, 143, 227, 111, 155, 21, 110, 53, 137, 64, 187, 193, 170, 112, 144, 152, 217, 57, 87, 230, 55]

[rev]ElderCmp

参考 https://www.nec.com/en/global/rd/tg/code/symenc/pdf/twine_LC11.pdf

https://github.com/sprushed/seccon2022_writeups/tree/master/reverse/ElderCMP

会进入__detect_debugger,并进行了一些控制流混淆,不执行main函数,而是进入heart函数,其中包含混淆的key和一个twine加密,并且每8byte进行一次加密