[ctf.show.reverse] 吃鸡杯 ezmore,有手就行,EzAutoRe

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}       

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值