2024 西湖论剑 Reverse BabyCPP

当时打完比赛跟着复现过一遍,好多都是跟着WP做的,变形的RC4也没理清楚,现在重新独立做一遍。

题目附件:https://n0zom1z0.lanzoup.com/iqoFf1mq6n8h

CPP,没有完全去符号,用了一堆C++的特性,还有诸如类、成员函数这些disgusting的逆向元素。。

整体流程:

cipher的赋值点:

先看XTEA:

text_79:

这里的v11对应的XTEA的DELTA:

这里可以得到XTEA的循环轮数为0x100:

然后就是disgusting大合集了:

对比下运算和>>11&3,可以比较容易的知道是XTEA算法:

注意下顺序,先是两个v0,v1的,最后再加DELTA。

然后看RC4:

前面部分都没有魔改:

在swap完后,跟正常的RC4相比,多了一次xor的操作:

这里可以结合动态调试来分析下一些关键的点,然后能写出改动后的核心部分:

即 xor1,add,xor2

那么对应的逆向解回去:

当然,也可以像我当时复现时看WP的,直接dump出这三个数组(xor1,add,xor2),难度都不大。

这样,先解RC4,转DWORD后,解XTEA,换个端序即可得到flag.

rc4:

c 复制代码
#include<bits/stdc++.h>
using namespace std;
signed main(){
	int base64_table[] = {0x33, 0xB2, 0x49, 0x8C, 0x39, 0xDD, 0x60, 0x5F, 0x5F, 0x77,
    0x72, 0xAB, 0x38, 0xD9, 0xED, 0xE7, 0xF3, 0xF0, 0x66, 0x67,
    0x16, 0xC8, 0x53, 0x80, 0x71, 0xB2, 0xFA, 0x5E, 0x7C, 0x2B,
    0xBB, 0x0B, 0xE5, 0x88, 0x82, 0x0B, 0x06, 0x8C, 0x8D, 0xAD,
    0x47, 0xB5, 0x85, 0xBB, 0x06, 0x8D, 0x01, 0x2B };
    
	string key = "gaLf_Ek@f_A_s1_sih7";
	int s[256],k[256];
	int j=0;
	for (int i = 0; i < 256; i++) {
            s[i] = i;
            k[i] = key[i % key.length()];
        }
        for (int i2 = 0; i2 < 256; i2++) {
            j = (s[i2] + j + k[i2]) & 255;
            int temp = s[i2];
            s[i2] = s[j];
            s[j] = temp;
        }
	int j2 = 0;
        int i3 = 0;
        for (int i4 : base64_table) {
//            i3 = (i3 + 1) & 255; // 1
//            j2 = (s[i3] + j2) & 255; // s[1] + 0 = 0xEE
//            int temp2 = s[i3];
//            s[i3] = s[j2];
//            s[j2] = temp2; // swap(s[1],s[0xEE])
//            int rnd = s[(s[i3] + s[j2]) & 255];
//            int v21 = (i4 ^ rnd);
//            int v23 = s[i3];
//            int v24 = s[j2];
//            int v20 = v21 + v23;
//            int v25 = v24 ^ v20;
//            cout << v25 % 0x100;
            
            i3 = (i3 + 1) & 255; // 1
            j2 = (s[i3] + j2) & 255; // s[1] + 0 = 0xEE
            int temp2 = s[i3];
            s[i3] = s[j2];
            s[j2] = temp2; // swap(s[1],s[0xEE])
            int rnd = s[(s[i3] + s[j2]) & 255];
			int v23 = s[i3];
            int v24 = s[j2];
            int v20 = i4 ^ v24;
            int v21 = (v20 - v23) & 0xFF;
            cout <<( v21 ^ rnd )<<",";
        }


}

tea.cpp

c 复制代码
#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=0xDEADBEEF;
    for (i=0; i < num_rounds; i++) {
        v0 += (((v1 << 2) ^ (v1 >> 7)) + v1) ^ (sum + key[sum & 3]);
        v1 += (((v0 << 6) ^ (v0 >> 3)) + v0) ^ (sum + key[(sum>>11) & 3]);
        sum += delta;
    }
    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=0xDEADBEEF, sum=+delta*num_rounds;
    for (i=0; i < num_rounds; i++) {
    	sum -= delta;
        v1 -= (((v0 << 6) ^ (v0 >> 3)) + v0) ^ (sum + key[(sum>>11) & 3]);
        v0 -= (((v1 << 2) ^ (v1 >> 7)) + v1) ^ (sum + key[sum & 3]);
    }
    v[0]=v0; v[1]=v1;
}
 
int main()
{
    uint32_t v[12]={3320791996, 1852925827, 2794088750, 3032168981, 2247472955, 2257807924, 1534038864, 3924795740, 2794088750, 3032168981, 2247472955, 2257807924};
    uint32_t const k[4]={0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476};
    unsigned int r=0x100;
    decipher(r, v, k);
    decipher(r,(uint32_t*)(v+2),k);
    decipher(r,(uint32_t*)(v+4),k);
    decipher(r,(uint32_t*)(v+6),k);
    decipher(r,(uint32_t*)(v+8),k);
    decipher(r,(uint32_t*)(v+10),k);
    for(int i=0;i<12;i++)
    	printf("%d,",v[i]);
    return 0;
}

exp.py:

py 复制代码
cipher = [
    0x33, 0xB2, 0x49, 0x8C, 0x39, 0xDD, 0x60, 0x5F, 0x5F, 0x77,
    0x72, 0xAB, 0x38, 0xD9, 0xED, 0xE7, 0xF3, 0xF0, 0x66, 0x67,
    0x16, 0xC8, 0x53, 0x80, 0x71, 0xB2, 0xFA, 0x5E, 0x7C, 0x2B,
    0xBB, 0x0B, 0xE5, 0x88, 0x82, 0x0B, 0x06, 0x8C, 0x8D, 0xAD,
    0x47, 0xB5, 0x85, 0xBB, 0x06, 0x8D, 0x01, 0x2B    
]


aaa_cipher = [
    0x8A, 0x18, 0x65, 0x89, 0xCA, 0xB6, 0x63, 0xF2, 0x8A, 0x18, 0x65, 0x89, 0xCA, 0xB6, 0x63, 0xF2, 0x8A, 0x18, 0x65, 0x89, 0xCA, 0xB6, 0x63, 0xF2, 0x8A, 0x18, 0x65, 0x89, 0xCA, 0xB6, 0x63, 0xF2, 0x8A, 0x18, 0x65, 0x89, 0xCA, 0xB6, 0x63, 0xF2, 0x8A, 0x18, 0x65, 0x89, 0xCA, 0xB6, 0x63, 0xF2
]

rc4_table = [
    0x31, 0xEE, 0x17, 0x80, 0xE3, 0x2D, 0x0A, 0xE5, 0x53, 0x33, 0x9E, 0x2E, 0x1D, 0x05, 0x6F, 0xB4, 
    0x51, 0x9A, 0x36, 0x5C, 0xBD, 0x08, 0xA2, 0x34, 0xA3, 0x65, 0x59, 0x62, 0xAE, 0xEF, 0x0D, 0xD0, 
    0xBC, 0x30, 0x81, 0xEB, 0x8C, 0xE8, 0x22, 0xFD, 0x7E, 0x4A, 0x1E, 0x10, 0x27, 0xDD, 0x5A, 0xA4, 
    0x0B, 0x29, 0xD5, 0x61, 0x9C, 0x48, 0x6E, 0x7D, 0xF1, 0xBE, 0x90, 0xB3, 0x55, 0x1B, 0x74, 0x89, 
    0x60, 0x6C, 0xC1, 0x76, 0x3B, 0x8F, 0xD4, 0x6B, 0x44, 0xE7, 0x49, 0x1F, 0xFB, 0x7C, 0x5B, 0x0F, 
    0x86, 0xA8, 0xB0, 0xA7, 0xCF, 0x5E, 0xC9, 0xCC, 0x13, 0xB6, 0x03, 0x4D, 0xD1, 0xE4, 0x6D, 0xBB, 
    0xF4, 0xA1, 0x37, 0xF9, 0x00, 0x38, 0xFE, 0x14, 0x42, 0x3C, 0x4C, 0x7A, 0x0C, 0x6A, 0x26, 0x01, 
    0xA6, 0x70, 0x02, 0x87, 0xE2, 0x04, 0x45, 0x50, 0x3E, 0x58, 0xA9, 0x52, 0x23, 0x82, 0x20, 0x7F, 
    0x39, 0x75, 0xC6, 0xB7, 0x9B, 0xF8, 0x21, 0xA0, 0x8E, 0xC2, 0xBA, 0xD2, 0x35, 0x5F, 0xBF, 0x06, 
    0x16, 0xC3, 0x32, 0xAB, 0xB2, 0x68, 0x2C, 0xF7, 0xAD, 0x96, 0x09, 0x8A, 0x2A, 0xF5, 0x8B, 0x7B, 
    0x19, 0x8D, 0x4E, 0x93, 0xFF, 0x78, 0xEC, 0xD7, 0x25, 0x9D, 0xD3, 0x64, 0xCA, 0xAA, 0xCB, 0xD8, 
    0xE0, 0x24, 0x46, 0xB5, 0xD6, 0xD9, 0xC7, 0x0E, 0x98, 0xAF, 0x85, 0xFC, 0x41, 0x94, 0x91, 0xC8, 
    0xC4, 0x63, 0x84, 0xF6, 0xC0, 0x07, 0x69, 0x88, 0x1C, 0x11, 0x18, 0x3A, 0x72, 0x47, 0x4B, 0xF0, 
    0xDE, 0x73, 0x66, 0xDA, 0xEA, 0x54, 0xF2, 0xA5, 0x3D, 0x79, 0x71, 0x1A, 0x15, 0x3F, 0x40, 0x92, 
    0xCD, 0xC5, 0xB9, 0x57, 0xDF, 0xAC, 0xFA, 0x99, 0x95, 0x5D, 0xE1, 0x77, 0x9F, 0xDC, 0x56, 0xB8, 
    0x43, 0xE9, 0x12, 0x2F, 0x83, 0x2B, 0x28, 0x4F, 0xE6, 0xF3, 0xDB, 0xCE, 0xB1, 0x97, 0xED, 0x67
]
add = [0x56,0x2d,0xf8,0x42,0x7f,0xc2,0x26,0x63,0x83,0x32,0xc4,0x3f,0xb9,0xa8,0x7f,0xc9,0x43,0x22,0xc6,0x89,0x6b,0x5d,0xef,0x2e,0xe8,0x20,0xcd,0xbf,0x84,0xf0,0x7b,0x4d,0xd2,0x3f,0x4f,0xb7,0x95,0xf0,0xcd,0x96,0x57,0x56,0x43,0xf1,0x6b,0x1,0xc6,0x36]
xor1 = [0x3b,0x3b,0x3e,0xe8,0x2c,0x72,0x2e,0xc7,0xc7,0xde,0x12,0xd1,0x91,0x34,0x61,0x59,0x1d,0x13,0x81,0xd4,0x87,0x67,0xeb,0x73,0x7c,0x58,0xa4,0x6a,0x98,0x97,0x1f,0x83,0x2d,0xa3,0x90,0x76,0xdb,0xf0,0x18,0x89,0x8d,0xe2,0xa7,0x2e,0x44,0xbc,0x4c,0x6c]
xor2 = [0xee,0x17,0x80,0xe3,0x17,0xa,0xe5,0x53,0x33,0x9e,0x2e,0x1d,0x5,0x6f,0xb4,0x51,0x9a,0x36,0x5c,0xbd,0x8,0xa2,0x34,0xa3,0x65,0x59,0x62,0xae,0x34,0xd,0xd0,0xbc,0x30,0x81,0xeb,0x8c,0x65,0x36,0xfd,0x7e,0x4a,0x1e,0x10,0x27,0xdd,0x5a,0xa4,0xb]

def enc_rc4():
    """
    xor1
    add
    xor2
    """
    pass

def dec_rc4(ct):
    pt= []
    for i in range(len(ct)):
        x = ((ct[i]^xor2[i])-add[i])^xor1[i]
        x &= 0xff
        pt.append(x)
    return pt

pt = dec_rc4(cipher)
assert(len(pt)==48)
pt = [188,67,239,197,131,103,113,110,46,105,138,166,21,58,187,180,59,183,245,133,52,106,147,134,80,147,111,91,92,161,239,233,46,105,138,166,21,58,187,180,59,183,245,133,52,106,147,134]
DWORD_pt = []
for i in range(12):
    x = pt[i*4:i*4+4]
    DWORD_pt.append((x[3]<<24)+(x[2]<<16)+(x[1]<<8)+x[0])

print(DWORD_pt)
# [3320791996, 1852925827, 2794088750, 3032168981, 2247472955, 2257807924, 1534038864, 3924795740, 2794088750, 3032168981, 2247472955, 2257807924]

flag = [1681417828,945971512,842162999,909718369,1714500656,1701077561,808739126,943273059,842162999,909718369,1714500656,1701077561]
from libnum import *
for c in flag:
    print(n2s(c)[::-1].decode(),end='')

DASCTF{df8d8ab87c22a396041f9bde6a40c4987c22a396041f9bde}

总结:静下心来,花1h+逆向就好了。

相关推荐
染指11102 小时前
45.第二阶段x86游戏实战2-hook监控实时抓取游戏lua
汇编·c++·windows·反游戏外挂·游戏逆向
我是苏苏16 小时前
Web开发:ABP框架6——appsetting.json的读取以及实例的注入
前端·windows·json
TPCloud16 小时前
windows 11编译安装ffmpeg(包含ffplay)
windows·ffmpeg·源码安装·mysys
password大鸭梨17 小时前
一个简单ASP.NET购物车设计
windows·microsoft·asp.net
Aniay_ivy19 小时前
Java中的不可变集合:性能与安全并重的最佳实践
java·windows·安全
积跬步至千里-积滴水成江海19 小时前
如何查看电脑关机时间
windows·系统安全
喜欢打篮球的普通人19 小时前
Rust面向对象特性
开发语言·windows·rust
晨曦_子画19 小时前
C#中:Any() 与 Count,选择哪一个??
开发语言·windows·c#
醇氧20 小时前
【Windows】CMD命令学习——系统命令
windows
人生の三重奏21 小时前
windows虚拟环境搭建
windows·python·虚拟环境