首页
社区
课程
招聘
[原创]第七届强网拟态RE WP
发表于: 2024-10-21 00:01 8772

[原创]第七届强网拟态RE WP

2024-10-21 00:01
8772

发现有多种花指令,对angr不太熟,感觉通过ida_python没法直接解出,故开始了苦逼的硬逆之旅

通过在strlen下断点,可以定位到输入的位置

image-20241019215021520

下硬件断点,发现是8个字节一组的分组加密,猜测是tea算法中的某一个,接下来就是验证了

接着trace与调试,看到了一些特征

image-20241019215031399

还有一个 shr 11没截下来,故猜测是xtea,接着调试可以得到是66轮

然后密钥呢

image-20241019215044804

观察算法,实际上我们只要让v0,v1都等于0,让sum分别等于0,1,2,3就可以分别得到v0,v1,v2,v3

然后输入数据调试验证发现出题人没有魔改,还是很善良的ww。

接着尝试获取密文,总之还是没看到逻辑,但是看到了cmp

image-20241019215055395

动调试了下发现确实是这里,故下个条件断点主动更改寄存器并将所有值打出来

然后解发现不对,试了下attach,啊发现有反调试我滴妈,一度陷入绝望

上网搜了下发现https://github.com/x64dbg/ScyllaHide/

尝试使用了下还真绕过了似乎

接着按照以上步骤再来一次 即可写出解密脚本

至于开始的单字节加密,把全部塞进去跑了下得到了个映射表,解密后映射回来即可

flag{u_ar3_re@11y_g00d_@t_011vm_de0bf_and_anti_debugger}

和学长一起做的题,熬夜脑子真是浆糊,这题把我俩套到两点多

首先是一个AES没加密,接着是一个对输入的“二进制化”,最后是一个校验,用z3解就行

这题早上起床看了一会,以前没做过游戏题,中间找到win的逻辑尝试patch赢了游戏,但是没啥发现,接着看到game.data,猜测肯定会有对data的加载过程,尝试去找,只找到了对game.record的加载过程,最终没定位到(),赛后尝试复现。

首先比赛时发现用frida调用直接寄,猜测做了反调试

不太了解windows的反调试机制,这里用插件AntiDebugSeeker成功定位到了反调试的位置

image-20241020224712919

将jnz patch 为jmp绕过

image-20241020235728446

接着这里如果马后炮的话直接去康康对应的函数就行,但是今天面对这种题目确实一直找不到切入点,故考虑能否通过frida hook的方式通过对读写文件的api的监控来达到寻找切入点的目的,思考了下可能以下的步骤会有帮助:

首先查看程序加载后加载了哪些dll,查看下各个加载的dll,将其中的open,read,write等函数都hook上,最好再将exit函数hook上,可以一定程度上防止反调试,当然如果其反调试是对逻辑的改变则一点没用。

得到以下hook脚本

可以看到,hook到了对应的ps脚本

image-20241020235706574

并且可以打印出堆栈帮忙定位

image-20241020234843657

这里用attch,因为spawn的话好像不太方便注入

接着dump下来ps脚本解混淆即可解

flag是73412036-7d8c-437b-9026-0c2ca1b7f79d

脚本参考DJB Team师傅发的wp

import ida_dbg
 
# 获取 R8D 寄存器的值
r8d_value = ida_dbg.get_reg_val("R8D")
print(f"R8D value: 0x{r8d_value:X}")
 
# 使用 SetRegVal 设置 EDX 为 R8D 的值
ida_dbg.set_reg_val("EDX", r8d_value)
 
# 验证 EDX 是否已更改
edx_value = ida_dbg.get_reg_val("EDX")
print(f"New EDX value: 0x{edx_value:X}")
import ida_dbg
 
# 获取 R8D 寄存器的值
r8d_value = ida_dbg.get_reg_val("R8D")
print(f"R8D value: 0x{r8d_value:X}")
 
# 使用 SetRegVal 设置 EDX 为 R8D 的值
ida_dbg.set_reg_val("EDX", r8d_value)
 
# 验证 EDX 是否已更改
edx_value = ida_dbg.get_reg_val("EDX")
print(f"New EDX value: 0x{edx_value:X}")
#include <stdio.h>
#include <stdint.h>
  
/* take 64 bits of data in v[0] and v[1] and 128 bits of key[0] - key[3] */
  
void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
    unsigned int i;
    uint32_t v0 = v[0], v1 = v[1], sum = 0, delta = 0x9E3779B9;
    for (i = 0; i < num_rounds; i++) {
        v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
        sum += delta;
        v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
        printf("Round %d: v0 = %08X, v1 = %08X, sum = %08X\n", i + 1, v0, v1, sum);
    }
    v[0] = v0;
    v[1] = v1;
}
  
void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
    unsigned int i;
    uint32_t v0 = v[0], v1 = v[1], delta = 0x9E3779B9, sum = delta * num_rounds;
    for (i = 0; i < num_rounds; i++) {
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
        sum -= delta;
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
        // printf("Round %d: v0 = %08X, v1 = %08X, sum = %08X\n", num_rounds - i, v0, v1, sum);
    }
    v[0] = v0;
    v[1] = v1;
}
 
int main() {
    uint32_t v[7][2] = {
        {0x9851e3a1, 0x49765686},
        {0x812b6b6f, 0x9612cecf},
        {0x3c3570a2, 0xf15c6231},
        {0xaa6b77fa, 0xbe056d9e},
        {0xf8a424e8, 0x0b3a23db},
        {0x03cc2016, 0xa92bb5ad},
        {0x1d789f34, 0x9ef9b92e}
    };
    uint32_t v1[2] = {0x1e1e1e1e,0x1e1e1e1e};
    uint32_t const k[4] = {0xef6fd9db, 0xd2c273d3, 0x6f97e412, 0x72bfd624};
    unsigned int r = 0x66; // num_rounds建议取值为32
 
    // printf("\n开始加密...\n");
    // encipher(r, v1, k);
    // printf("加密后的数据:%08X %08X\n", v1[0], v1[1]);
     
    printf("\n开始解密...\n");
    for(int i = 0;i<7;i++){
        decipher(r, v[i], k);
        printf("解密后的数据:%08X %08X\n", v[i][0], v[i][1]);
    }
 
 
    return 0;
}
#include <stdio.h>
#include <stdint.h>
  
/* take 64 bits of data in v[0] and v[1] and 128 bits of key[0] - key[3] */
  
void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
    unsigned int i;
    uint32_t v0 = v[0], v1 = v[1], sum = 0, delta = 0x9E3779B9;
    for (i = 0; i < num_rounds; i++) {
        v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
        sum += delta;
        v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
        printf("Round %d: v0 = %08X, v1 = %08X, sum = %08X\n", i + 1, v0, v1, sum);
    }
    v[0] = v0;
    v[1] = v1;
}
  
void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
    unsigned int i;
    uint32_t v0 = v[0], v1 = v[1], delta = 0x9E3779B9, sum = delta * num_rounds;
    for (i = 0; i < num_rounds; i++) {
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
        sum -= delta;
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
        // printf("Round %d: v0 = %08X, v1 = %08X, sum = %08X\n", num_rounds - i, v0, v1, sum);
    }
    v[0] = v0;
    v[1] = v1;
}
 
int main() {
    uint32_t v[7][2] = {
        {0x9851e3a1, 0x49765686},
        {0x812b6b6f, 0x9612cecf},
        {0x3c3570a2, 0xf15c6231},
        {0xaa6b77fa, 0xbe056d9e},
        {0xf8a424e8, 0x0b3a23db},
        {0x03cc2016, 0xa92bb5ad},
        {0x1d789f34, 0x9ef9b92e}
    };
    uint32_t v1[2] = {0x1e1e1e1e,0x1e1e1e1e};
    uint32_t const k[4] = {0xef6fd9db, 0xd2c273d3, 0x6f97e412, 0x72bfd624};
    unsigned int r = 0x66; // num_rounds建议取值为32
 
    // printf("\n开始加密...\n");
    // encipher(r, v1, k);
    // printf("加密后的数据:%08X %08X\n", v1[0], v1[1]);
     
    printf("\n开始解密...\n");
    for(int i = 0;i<7;i++){
        decipher(r, v[i], k);
        printf("解密后的数据:%08X %08X\n", v[i][0], v[i][1]);
    }
 
 
    return 0;
}
enc = 0xD9, 0xD3, 0xDE, 0xD8, 0xC4, 0xCA, 0xE0, 0xDE,0xCD,0X0C,0XE0,0Xcd,0Xda,0Xff,0X0e,0x0e,
         0xc6, 0xe0, 0xd8, 0x0f, 0x0f, 0xdb,0xe0, 0xff, 0xcb,0xe0,0x0f,0x0e,0x0e,0xc9,0xd2,0xe0,
         0xdb ,0xda ,0x0f, 0xdd , 0xd9, 0xe0 ,0xde, 0xd1,0xdb,0xe0,0xde,0xd1,0xcb,0xd6,0xe0,0xdb,
         0xda,0xdd,0xca,0xd8,0xd8,0xda,0xcd,0xc2]
 
print(len(enc))
my_dict  = {
    0x0f: '0', 0x0e: '1', 0x0d: '2', 0x0c: '3', 0x0b: '4', 0x0a: '5', 0x09: '6', 0x08: '7',
    0x07: '8', 0x06: '9', 0xde: 'a', 0xdd: 'b', 0xdc: 'c', 0xdb: 'd', 0xda: 'e', 0xd9: 'f',
    0xd8: 'g', 0xd7: 'h', 0xd6: 'i', 0xd5: 'j', 0xd4: 'k', 0xd3: 'l', 0xd2: 'm', 0xd1: 'n',
    0xd0: 'o', 0xcf: 'p', 0xce: 'q', 0xcd: 'r', 0xcc: 's', 0xcb: 't', 0xca: 'u', 0xc9: 'v',
    0xc8: 'w', 0xc7: 'x', 0xc6: 'y', 0xc5: 'z', 0xfe: 'A', 0xfd: 'B', 0xfc: 'C', 0xfb: 'D',
    0xfa: 'E', 0xf9: 'F', 0xf8: 'G', 0xf7: 'H', 0xf6: 'I', 0xf5: 'J', 0xf4: 'K', 0xf3: 'L',
    0xf2: 'M', 0xf1: 'N', 0xf0: 'O', 0xef: 'P', 0xee: 'Q', 0xed: 'R', 0xec: 'S', 0xeb: 'T',
    0x1E: '!', 0x1D: '"', 0x1C: '#', 0x1B: '$', 0x1A: '%', 0x19: '&', 0x18: "'", 0x17: '(',
    0x16: ')', 0x15: '*', 0x14: '+', 0x13: ',', 0x12: '-', 0x11: '.', 0x10: '/', 0x05: ':',
    0x04: ';', 0x03: '<', 0x02: '=', 0x01: '>', 0x00: '?', 0xFF: '@', 0xE4: '[', 0xE3: '\\',
    0xE2: ']', 0xE1: '^', 0xE0: '_', 0xDF: '`', 0xC4: '{', 0xC3: '|', 0xC2: '}', 0xC1: '~',
    0xEA: 'U', 0xE9: 'V', 0xE8: 'W', 0xE7: 'X', 0xE6: 'Y', 0xE5: 'Z', 0xFC: 'C', 0xFB: 'D',
    0xFA: 'E', 0xF9: 'F', 0xF8: 'G', 0xF7: 'H', 0xF6: 'I', 0xF5: 'J', 0xF4: 'K', 0xF3: 'L'
}
flag = ''
for i in range(len(enc)):
    print(hex(enc[i]))
    try:
        flag += my_dict[enc[i]%256]
    except:
        continue
    print(flag)
enc = 0xD9, 0xD3, 0xDE, 0xD8, 0xC4, 0xCA, 0xE0, 0xDE,0xCD,0X0C,0XE0,0Xcd,0Xda,0Xff,0X0e,0x0e,
         0xc6, 0xe0, 0xd8, 0x0f, 0x0f, 0xdb,0xe0, 0xff, 0xcb,0xe0,0x0f,0x0e,0x0e,0xc9,0xd2,0xe0,
         0xdb ,0xda ,0x0f, 0xdd , 0xd9, 0xe0 ,0xde, 0xd1,0xdb,0xe0,0xde,0xd1,0xcb,0xd6,0xe0,0xdb,
         0xda,0xdd,0xca,0xd8,0xd8,0xda,0xcd,0xc2]
 
print(len(enc))
my_dict  = {
    0x0f: '0', 0x0e: '1', 0x0d: '2', 0x0c: '3', 0x0b: '4', 0x0a: '5', 0x09: '6', 0x08: '7',
    0x07: '8', 0x06: '9', 0xde: 'a', 0xdd: 'b', 0xdc: 'c', 0xdb: 'd', 0xda: 'e', 0xd9: 'f',
    0xd8: 'g', 0xd7: 'h', 0xd6: 'i', 0xd5: 'j', 0xd4: 'k', 0xd3: 'l', 0xd2: 'm', 0xd1: 'n',
    0xd0: 'o', 0xcf: 'p', 0xce: 'q', 0xcd: 'r', 0xcc: 's', 0xcb: 't', 0xca: 'u', 0xc9: 'v',
    0xc8: 'w', 0xc7: 'x', 0xc6: 'y', 0xc5: 'z', 0xfe: 'A', 0xfd: 'B', 0xfc: 'C', 0xfb: 'D',
    0xfa: 'E', 0xf9: 'F', 0xf8: 'G', 0xf7: 'H', 0xf6: 'I', 0xf5: 'J', 0xf4: 'K', 0xf3: 'L',
    0xf2: 'M', 0xf1: 'N', 0xf0: 'O', 0xef: 'P', 0xee: 'Q', 0xed: 'R', 0xec: 'S', 0xeb: 'T',
    0x1E: '!', 0x1D: '"', 0x1C: '#', 0x1B: '$', 0x1A: '%', 0x19: '&', 0x18: "'", 0x17: '(',
    0x16: ')', 0x15: '*', 0x14: '+', 0x13: ',', 0x12: '-', 0x11: '.', 0x10: '/', 0x05: ':',
    0x04: ';', 0x03: '<', 0x02: '=', 0x01: '>', 0x00: '?', 0xFF: '@', 0xE4: '[', 0xE3: '\\',
    0xE2: ']', 0xE1: '^', 0xE0: '_', 0xDF: '`', 0xC4: '{', 0xC3: '|', 0xC2: '}', 0xC1: '~',
    0xEA: 'U', 0xE9: 'V', 0xE8: 'W', 0xE7: 'X', 0xE6: 'Y', 0xE5: 'Z', 0xFC: 'C', 0xFB: 'D',
    0xFA: 'E', 0xF9: 'F', 0xF8: 'G', 0xF7: 'H', 0xF6: 'I', 0xF5: 'J', 0xF4: 'K', 0xF3: 'L'
}
flag = ''
for i in range(len(enc)):
    print(hex(enc[i]))
    try:
        flag += my_dict[enc[i]%256]
    except:
        continue

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2024-10-21 23:20 被z2zccc编辑 ,原因:
上传的附件:
收藏
免费 5
支持
分享
最新回复 (2)
雪    币: 29182
活跃值: (63621)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
2
实例以附件形式提供一下
2024-10-21 18:39
0
雪    币: 406
活跃值: (296)
能力值: ( LV3,RANK:33 )
在线值:
发帖
回帖
粉丝
3
Editor 实例以附件形式提供一下
已添加附件
2024-10-21 23:20
0
游客
登录 | 注册 方可回帖
返回
//