侧边栏壁纸
  • 累计撰写 38 篇文章
  • 累计创建 23 个标签
  • 累计收到 10 条评论

目 录CONTENT

文章目录

【Reverse】VNCTF2023 re部分复现

Fup1p1
2023-02-24 / 0 评论 / 0 点赞 / 883 阅读 / 1,815 字 / 正在检测是否收录...

jijijiji

官方WP还没出,看了sln.1550佬的博客,得到了提示,然后复现了此题。

主函数

资源文件的查找

image-1677235282442
其中FindResouceA函数指出了资源文件“shell”的位置
image-1677235182652
我们可以通过工具Resouce hacker查看到资源文件的数据(解密前),或可以在PE文件的末尾找到,当然也可以在动调时在IDA中找到。
image-1677235531658

image-1677235646116

解密函数

动调然后在堆栈中找到lpBuffer的地址,然后通过IDApython将解密后的资源数据dump下来
image-1677235865673

image-1677235879353
看到MZ,就知道是个EXE了。

IDApython脚本

def main():
    begin = 0x17C6A86B940; #需对应修改
    size = 0x16000  # #需对应修改
    list1 = []
    for i in range(size):
        byte_tmp = get_bytes(begin + i,1)
        list1.append(ord(byte_tmp))
        if (i + 1) % 0x1000 == 0:
            print("All count:{}, collect current:{}, has finish {}".format(hex(size), hex(i + 1), float(i + 1) / size))
    print('collect over')
    file = "C:\\Users\\MESSI\\Desktop\\VNCTF2023\\jijiji\\dump.exe" #需对应修改
    #print(bytearray(list1))
    buf = bytearray(list1)
    with open(file, 'wb') as fw:
        fw.write(buf)
    print('write over')

if __name__=='__main__':
    main()

分析dump.exe

对于flag的验证和加密多半是在dump下来的文件里。
果然,查看字符串能找到提示输入的地方

image-1677236102132

image-1677236659443

动态调试失败?

直接调试会发现运行到后面就会卡在这个地方。
image-1677244276574
一路交叉引用向上找,发现两个很怪的库函数,猜测是启动参数。
于是输入了一堆启动参数,多次地址跳转可以发现(* * )v2的地址是参数的数值,而v1是参数的个数。
image-1677244322557
那么启动参数是什么呢?
我们直接跑起jijiji.exe,然后IDA attach上,能发现
Snipaste_2023-02-24_21-06-34
VNctf2023 其实就是我们dump下来的exe,怀疑后面两个就是参数!
事实证明我们的猜想没有问题!

动态调试

设置好参数
image-1677237627394
过掉反调试
image-1677236815988
动调走到flag验证处
image-1677237813346
去掉无用的jmp,发现是个魔改的XTEA
image-1677238386232
编写EXP

#include <stdio.h>
#include <stdlib.h>
 void decrypt(unsigned int* v, unsigned int* key,unsigned int round) {
  unsigned int l = v[0], r = v[1], sum = 0, delta = 0x88408067;
  sum = delta * round;
  for (size_t i = 0; i < round; i++) {
    sum -= delta;
    r -= (((l << 4) ^ (l >> 5)) + l) ^ (sum + key[(sum >> 11) & 3]);
    l -= (((r << 4) ^ (r >> 5)) + r) ^ (sum + key[sum & 3])^sum;
  }
  v[0] = l;
  v[1] = r;
}
int main()
{
    unsigned int v[11] = {  0xADD4F778, 0xA6D7F132, 0x61813290, 0x2D4A40A6, 0x00B05F11, 0xB6D59424, 0x231BBFC6, 0xCD405B31, 
    0x03020100, 0x00C30504};
    unsigned int key[4] = {98,111,109,98};
    for(int i=0;i<4;i++){
        decrypt(v+i*2,key,33);
    
    }
    for(int i=0;i<8;i++)
    {
        printf("%c%c%c%c",*((char*)&v[i]+0),*((char*)&v[i]+1),*((char*)&v[i]+2),*((char*)&v[i]+3));
    }
    return 0;
}
//2d326e43eb8fea8837737fc0f50f83f2
0

评论区