ezmore
动调的题,跟进去在4019d6下断点看比较情况得到neft输入后得到flag组成提示
有手就行
一上来就猜入口是_main然后解到一个fake
s2 = [99,23,113,2,106,5,114,9,109,2,93,36,75,62,97,13,100,15,106,53,83,50,89,60,3,60,65]
s1 = [0]*len(s2)
s1[0] = 99
#~(*(v1 - 2) & v2) & (*(v1 - 2) ^ v2)
#~(s1[i-1] & s1[i]) & (s1[i-1] ^ s1[i])
for i in range(1,27):
for j in range(0x20,0x7f):
if (0xff - (s2[i-1]&j) )&(s2[i-1]^j) == s2[i]:
s1[i] = j
break
print(bytes(s1))
#ctfshow{do_you_like_fake??}
再回来看main,入口在Game start前边
int __cdecl main(int argc, const char **argv, const char **envp)
{
_DWORD v4[6]; // [esp+15h] [ebp-1Bh] BYREF
__int16 v5; // [esp+2Dh] [ebp-3h]
char v6; // [esp+2Fh] [ebp-1h]
sub_401BF0(); // 真正入口
puts("Game start");
scanf("%s", &dword_406060);
v4[0] = dword_406060; // 26
v4[1] = dword_406064;
v4[2] = dword_406068;
v4[3] = dword_40606C;
v4[4] = dword_406070;
v4[5] = dword_406074;
v5 = word_406078;
v6 = byte_40607A;
if ( !sub_4013F0(v4) )
exit(0);
return 0;
}
一直跳下去到401f20,主要逻辑就是互换,异或和移位,这里专门给函数改了个名字
_onexit_t sub_401F20()
{
Buf2 = &dword_406060; // 输入内容 Buf2
buf2_ex();
sub_4012D0(sub_401600); // 比较
sub_4012D0(buf2_xor_result);
return sub_4012D0(buf2_add_7);
}
然后写出逆向程序
s2 = [0xDC,0x47,0x7F,0x6E,0x9A,0xD8,0x60,0x77,0xF4,0xB0,0x8C,0x54,0xB0,0xAA,0x26,0x23,0x02,0x42,0x8E,0xBA,0x90,0x8C,0xAB,0x86,0x24,0x6E,0xF8]
d_406480 = [256-i for i in range(256)]
d_406080 = (b'keykeykey'*100)[:256]
#交换码表
v1 = 0
r = 0
for i in range(256):
v3 = d_406480[v1]
r = (d_406080[v1]+v3 + r)%256
d_406480[v1],d_406480[r] = d_406480[r],v3
v1+=1
#异或,+7
v0 = 0
tab = [0]*256
for i in range(27):
v0 = (d_406480[i+1] + v0)%256
d_406480[i+1],d_406480[v0] = d_406480[v0],d_406480[i+1]
tab[i] = d_406480[(d_406480[v0] + d_406480[i+1])%256]
print(chr((tab[i] ^ s2[i])-7), end='')
#ctfshow{y0u_g0t_t4e_5ecret}
EzAutoRe
没有直接给附件而是给了远程环境。登上后直接得到base64编码的程序。
下下来发现有壳,用upx脱后,跟36D杯BBBigEqSet极为相似都是用numpy.linalg.solve()求解行列式的128个解,唯一区别就是每次写到的变量不是接顺序的,这个需要读写入变量位置
将原来的程序稍加改动。另外直接搜索下的upx3.96脱壳工具大多是国内包装过有window界面的,需要到github上下命令行执行的原生版本。
from pwn import *
from base64 import b64decode
p = remote('pwn.challenge.ctf.show', 28138)
context.log_level = 'debug'
p.recvuntil(b'-------------------------------------------------\n')
data = p.recvuntil(b'-------------------------------------------------\n', drop=True)
open('EzAutoRe', 'wb').write(b64decode(data))
os.system('c:\\tools\\upx-3.96-win64\\upx.exe -d EzAutoRe')
data = open('EzAutoRe','rb').read()
ta = []
tb = []
tmp = [0]*128
ptr = 0x1218
while ptr<len(data):
idx = 0
if data[ptr:ptr+3] == b'\x0f\xb6\x85': #movzx eax, [rbp+var_C2] 存到哪个变量里
idx = data[ptr+3]
ptr+=10
if data[ptr:ptr+2] == b'\x69\xd0': #imul edx, eax, 0ABA4h 开始读数据第1个
tmp[idx] = u32(data[ptr+2: ptr+6])
ptr+=6
if data[ptr:ptr+2] == b'\x69\xc0': #imul eax, 0A755h 后续 多 add edx, eax
tmp[idx] = u32(data[ptr+2: ptr+6])
ptr+=8
if data[ptr] == 0x3d: #cmp eax, 1A59D41Eh; jnz loc_496B4
tb.append(u32(data[ptr+1:ptr+5]))
ta.append(tmp)
tmp = [0]*128
ptr+=11
if data[ptr:ptr+5] == b'\x48\x8d\x3d\x85\x09': #结束
break
import numpy as np
an = np.array(ta)
bn = np.array(tb)
x = np.linalg.solve(an,bn)
print(x)
flag = bytes([round(i) for i in x])
print(flag)
p.sendline(flag)
p.recv()
p.interactive()
#ctfshow{0105ed6e-4395-49a9-a0e3-59742d504cd4}