L3HCTF 部分RE WP
本帖最后由 zsky 于 2021-11-17 18:34 编辑# L3HCTF 部分RE WP
## double-joy
IDA打开程序,找到main函数进行分析
最关键的是`enc_flag` 函数, 经过调试,发现传入的参数有2套,都是固定的结构体
```cpp
typedef struct _struc_1
{
BYTE* pKey; //指向OPCODE
_DWORD* pFlag; //指向FLAG,主要这个FLAG前40个字节是用户输入的,后面一大部分要留给程序用
int i; //指向OPCODE的索引
int stack; //指向了一些 “操作数”,在OPCODE 中存着,比如OPCODE是 \XE的话,后面4个字节就是一个“操作数”
}struc_1;
```
进入 `enc_flag`函数,F5,发现很乱,然后patch掉一些用于对齐的代码后,F5, 发现是个VM
调试,发现一共执行了0XCA次 `enc_flag`, 并且传入的参数是交替的
还原程序代码
```cpp
#include <windows.h>
#include <basetsd.h>
#include <stdio.h>
typedef unsigned int uint32;
#define _DWORD uint32
typedef struct _struc_1
{
BYTE* pKey; //指向OPCODE
_DWORD* pFlag; //指向FLAG,主要这个FLAG前40个字节是用户输入的,后面一大部分要留给程序用
int i; //指向OPCODE的索引
int stack; //指向了一些 “操作数”,在OPCODE 中存着,比如OPCODE是 \XE的话,后面4个字节就是一个“操作数”
}struc_1;
BYTE key1[] =
{
0x11, 0x15, 0x00, 0x00, 0x00, 0x0E, 0x0A, 0x00, 0x00, 0x00,
0x0E, 0x15, 0xCD, 0x5B, 0x07, 0x08, 0x0E, 0x0B, 0x00, 0x00,
0x00, 0x0E, 0xB1, 0x68, 0xDE, 0x3A, 0x08, 0x0E, 0x12, 0x00,
0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0E, 0x13,
0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0E,
0x13, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x0A, 0x00, 0x00, 0x00,
0x0C, 0x01, 0x0B, 0x0A, 0x10, 0x44, 0x00, 0x00, 0x00, 0x0E,
0x13, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0E, 0x13, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x09, 0x0E, 0x13, 0x00, 0x00, 0x00, 0x09,
0x0E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x01, 0x01, 0x01,
0x01, 0x02, 0x07, 0x08, 0x0E, 0x13, 0x00, 0x00, 0x00, 0x0E,
0x13, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x01, 0x00, 0x00, 0x00,
0x00, 0x08, 0x0F, 0xA8, 0xFF, 0xFF, 0xFF, 0x0E, 0x00, 0x00,
0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x4C,
0x49, 0x00, 0x00, 0x08, 0x0E, 0x01, 0x00, 0x00, 0x00, 0x0E,
0x0E, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x76, 0x6F, 0x00, 0x00,
0x08, 0x0E, 0x02, 0x00, 0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00,
0x00, 0x00, 0x0E, 0x20, 0x65, 0x00, 0x00, 0x08, 0x0E, 0x03,
0x00, 0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x0E,
0x55, 0x43, 0x00, 0x00, 0x08, 0x0E, 0x13, 0x00, 0x00, 0x00,
0x0E, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0E, 0x13, 0x00, 0x00,
0x00, 0x09, 0x0E, 0x0A, 0x00, 0x00, 0x00, 0x0C, 0x01, 0x0B,
0x0A, 0x10, 0x56, 0x01, 0x00, 0x00, 0x0E, 0x14, 0x00, 0x00,
0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0E, 0x14, 0x00,
0x00, 0x00, 0x09, 0x0E, 0x14, 0x00, 0x00, 0x00, 0x0C, 0x01,
0x0B, 0x0A, 0x10, 0x20, 0x01, 0x00, 0x00, 0x0E, 0x0C, 0x00,
0x00, 0x00, 0x0E, 0x13, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x00,
0x00, 0x00, 0x00, 0x00, 0x09, 0x08, 0x0E, 0x0D, 0x00, 0x00,
0x00, 0x0E, 0x13, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x01, 0x00,
0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
0x08, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x0E, 0x0C, 0x00, 0x00,
0x00, 0x09, 0x0E, 0x0D, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x10,
0x00, 0x00, 0x00, 0x02, 0x0E, 0x0D, 0x00, 0x00, 0x00, 0x09,
0x0E, 0x20, 0x00, 0x00, 0x00, 0x0C, 0x03, 0x07, 0x0E, 0x0D,
0x00, 0x00, 0x00, 0x09, 0x00, 0x0E, 0x0B, 0x00, 0x00, 0x00,
0x09, 0x0E, 0x0B, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x03, 0x00,
0x00, 0x00, 0x05, 0x0E, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x09,
0x00, 0x07, 0x00, 0x08, 0x0E, 0x0B, 0x00, 0x00, 0x00, 0x0E,
0x0B, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x0A, 0x00, 0x00, 0x00,
0x09, 0x00, 0x08, 0x0E, 0x0D, 0x00, 0x00, 0x00, 0x0E, 0x0D,
0x00, 0x00, 0x00, 0x09, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x09,
0x0E, 0x10, 0x00, 0x00, 0x00, 0x02, 0x0E, 0x0C, 0x00, 0x00,
0x00, 0x09, 0x0E, 0x20, 0x00, 0x00, 0x00, 0x0C, 0x03, 0x07,
0x0E, 0x0C, 0x00, 0x00, 0x00, 0x09, 0x00, 0x0E, 0x0B, 0x00,
0x00, 0x00, 0x09, 0x0E, 0x0B, 0x00, 0x00, 0x00, 0x09, 0x0E,
0x00, 0x08, 0x00, 0x00, 0x0C, 0x03, 0x0E, 0x03, 0x00, 0x00,
0x00, 0x05, 0x0E, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
0x07, 0x00, 0x08, 0x0E, 0x13, 0x00, 0x00, 0x00, 0x09, 0x0E,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0C, 0x00, 0x00, 0x00,
0x09, 0x08, 0x0E, 0x13, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x01,
0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0E, 0x0D, 0x00, 0x00, 0x00, 0x09, 0x08, 0x12, 0x01, 0x00,
0x00, 0x00, 0x0E, 0x14, 0x00, 0x00, 0x00, 0x0E, 0x14, 0x00,
0x00, 0x00, 0x09, 0x0E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
0x0F, 0xCC, 0xFE, 0xFF, 0xFF, 0x0E, 0x13, 0x00, 0x00, 0x00,
0x0E, 0x13, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x02, 0x00, 0x00,
0x00, 0x00, 0x08, 0x0F, 0x96, 0xFE, 0xFF, 0xFF, 0x12, 0x00,
0x00, 0x00, 0x00, 0x00
};
BYTE key2[] =
{
0x11, 0x15, 0x00, 0x00, 0x00, 0x0E, 0x0A, 0x00, 0x00, 0x00,
0x0E, 0xF7, 0xCB, 0x54, 0x01, 0x08, 0x0E, 0x0B, 0x00, 0x00,
0x00, 0x0E, 0xAD, 0xDE, 0xED, 0x5E, 0x08, 0x0E, 0x12, 0x00,
0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0E, 0x13,
0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0E,
0x13, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x0A, 0x00, 0x00, 0x00,
0x0C, 0x01, 0x0B, 0x0A, 0x10, 0x44, 0x00, 0x00, 0x00, 0x0E,
0x13, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0E, 0x13, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x09, 0x0E, 0x13, 0x00, 0x00, 0x00, 0x09,
0x0E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x01, 0x01, 0x01,
0x01, 0x02, 0x07, 0x08, 0x0E, 0x13, 0x00, 0x00, 0x00, 0x0E,
0x13, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x01, 0x00, 0x00, 0x00,
0x00, 0x08, 0x0F, 0xA8, 0xFF, 0xFF, 0xFF, 0x0E, 0x00, 0x00,
0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x54,
0x53, 0x00, 0x00, 0x08, 0x0E, 0x01, 0x00, 0x00, 0x00, 0x0E,
0x0E, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x4D, 0x4F, 0x00, 0x00,
0x08, 0x0E, 0x02, 0x00, 0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00,
0x00, 0x00, 0x0E, 0x74, 0x20, 0x00, 0x00, 0x08, 0x0E, 0x03,
0x00, 0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x0E,
0x61, 0x65, 0x00, 0x00, 0x08, 0x0E, 0x13, 0x00, 0x00, 0x00,
0x0E, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0E, 0x13, 0x00, 0x00,
0x00, 0x09, 0x0E, 0x0A, 0x00, 0x00, 0x00, 0x0C, 0x01, 0x0B,
0x0A, 0x10, 0x5B, 0x01, 0x00, 0x00, 0x0E, 0x14, 0x00, 0x00,
0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0E, 0x14, 0x00,
0x00, 0x00, 0x09, 0x0E, 0x14, 0x00, 0x00, 0x00, 0x0C, 0x01,
0x0B, 0x0A, 0x10, 0x25, 0x01, 0x00, 0x00, 0x0E, 0x0C, 0x00,
0x00, 0x00, 0x0E, 0x13, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x00,
0x00, 0x00, 0x00, 0x00, 0x09, 0x08, 0x0E, 0x0D, 0x00, 0x00,
0x00, 0x0E, 0x13, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x01, 0x00,
0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
0x08, 0x0E, 0x0B, 0x00, 0x00, 0x00, 0x0E, 0x0B, 0x00, 0x00,
0x00, 0x09, 0x0E, 0x0A, 0x00, 0x00, 0x00, 0x09, 0x00, 0x08,
0x0E, 0x0C, 0x00, 0x00, 0x00, 0x0E, 0x0C, 0x00, 0x00, 0x00,
0x09, 0x0E, 0x0D, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x10, 0x00,
0x00, 0x00, 0x02, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0E,
0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x0E, 0x0D, 0x00, 0x00,
0x00, 0x09, 0x0E, 0x0B, 0x00, 0x00, 0x00, 0x09, 0x00, 0x0E,
0x0D, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x20, 0x00, 0x00, 0x00,
0x0C, 0x03, 0x0E, 0x01, 0x00, 0x00, 0x00, 0x0E, 0x0E, 0x00,
0x00, 0x00, 0x00, 0x09, 0x00, 0x07, 0x07, 0x00, 0x08, 0x0E,
0x0D, 0x00, 0x00, 0x00, 0x0E, 0x0D, 0x00, 0x00, 0x00, 0x09,
0x0E, 0x0C, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x10, 0x00, 0x00,
0x00, 0x02, 0x0E, 0x02, 0x00, 0x00, 0x00, 0x0E, 0x0E, 0x00,
0x00, 0x00, 0x00, 0x09, 0x00, 0x0E, 0x0C, 0x00, 0x00, 0x00,
0x09, 0x0E, 0x0B, 0x00, 0x00, 0x00, 0x09, 0x00, 0x0E, 0x0C,
0x00, 0x00, 0x00, 0x09, 0x0E, 0x20, 0x00, 0x00, 0x00, 0x0C,
0x03, 0x0E, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00,
0x00, 0x00, 0x09, 0x00, 0x07, 0x07, 0x00, 0x08, 0x0E, 0x13,
0x00, 0x00, 0x00, 0x09, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0E, 0x0C, 0x00, 0x00, 0x00, 0x09, 0x08, 0x0E, 0x13, 0x00,
0x00, 0x00, 0x09, 0x0E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0E,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0D, 0x00, 0x00, 0x00,
0x09, 0x08, 0x12, 0x01, 0x00, 0x00, 0x00, 0x0E, 0x14, 0x00,
0x00, 0x00, 0x0E, 0x14, 0x00, 0x00, 0x00, 0x09, 0x0E, 0x01,
0x00, 0x00, 0x00, 0x00, 0x08, 0x0F, 0xC7, 0xFE, 0xFF, 0xFF,
0x0E, 0x13, 0x00, 0x00, 0x00, 0x0E, 0x13, 0x00, 0x00, 0x00,
0x09, 0x0E, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0F, 0x91,
0xFE, 0xFF, 0xFF, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
void enc_flag(struc_1* st)
{
BYTE* pKey = st->pKey;
BYTE opcode = 0;
_DWORD* pFlag = st->pFlag;
int data1, data2, tmp, index;
while (true)
{
opcode = pKey; //取出对应的opcode
st->i++; //每取出一个opcode, 索引就+1
printf("------>OPCODE :%d\n", opcode);
switch (opcode)
{
case 0:
st->stack--;
data1 = pFlag;
data2 = pFlag;
pFlag = data1 + data2;
printf("pFlag[%d] = pFlag[%d]:%#x + pFlag[%d]:%#x;\n", st->stack - 1, st->stack, data1, st->stack - 1, data2);
continue;
case 1:
st->stack--;
data1 = pFlag;
data2 = pFlag;
pFlag = data1 - data2;
printf("pFlag[%d] = pFlag[%d]:%#x - pFlag[%d]:%#x;\n", st->stack - 1, st->stack, data1, st->stack - 1, data2);
continue;
case 2:
st->stack--;
data1 = pFlag;
data2 = pFlag;
pFlag = data1 * data2;
printf("pFlag[%d] = pFlag[%d]:%#x * pFlag[%d]:%#x;\n", st->stack - 1, st->stack, data1, st->stack - 1, data2);
continue;
case 3:
st->stack--;
data1 = pFlag;
data2 = pFlag;
pFlag = data1 / data2;
printf("pFlag[%d] = pFlag[%d]:%#x / pFlag[%d]:%#x;\n", st->stack - 1, st->stack, data1, st->stack - 1, data2);
continue;
case 4:
st->stack--;
data1 = pFlag;
data2 = pFlag;
pFlag = data1 % data2;
printf("pFlag[%d] = pFlag[%d]:%#x %% pFlag[%d]:%#x;\n", st->stack - 1, st->stack, data1, st->stack - 1, data2);
continue;
case 5:
st->stack--;
data1 = pFlag;
data2 = pFlag;
pFlag = data1 & data2;
printf("pFlag[%d] = pFlag[%d]:%#x & pFlag[%d]:%#x;\n", st->stack - 1, st->stack, data1, st->stack - 1, data2);
continue;
case 6:
st->stack--;
data1 = pFlag;
data2 = pFlag;
pFlag = data1 | data2;
printf("pFlag[%d] = pFlag[%d]:%#x | pFlag[%d]:%#x;\n", st->stack - 1, st->stack, data1, st->stack - 1, data2);
continue;
case 7:
st->stack--;
data1 = pFlag;
data2 = pFlag;
pFlag = data1 ^ data2;
printf("pFlag[%d] = pFlag[%d]:%#x ^ pFlag[%d]:%#x;\n", st->stack - 1, st->stack, data1, st->stack - 1, data2);
continue;
case 8:
st->stack--;
tmp = pFlag;
index = pFlag;
pFlag = tmp;
printf("pFlag[%d] = %#x;\n", index, tmp);
st->stack--;
continue;
case 9:
index = pFlag;
data1 = pFlag;
pFlag = data1;
printf("pFlag[%d] = %#x;\n", st->stack -1, data1);
continue;
case 10:
tmp = pFlag;
if (tmp == 0)
{
pFlag = 1;
printf("pFlag[%d] = 1;\n", st->stack - 1);
}
else {
pFlag = 0;
printf("pFlag[%d] = 0;\n", st->stack - 1);
}
continue;
case 11:
tmp = pFlag;
if ((int)tmp < 0)
{
pFlag = 1;
printf("pFlag[%d] = 1;\n", st->stack - 1);
}
else {
pFlag = 0;
printf("pFlag[%d] = 0;\n", st->stack - 1);
}
continue;
case 12:
data1 = pFlag;
data2 = pFlag;
pFlag = data2;
pFlag = data1;
printf("exchange pFlag[%d]:%#x, pFlag[%d]:%#x\n", st->stack - 1, data2, st->stack - 2, data1);
continue;
case 13:
st->stack--;
continue;
case 14:
tmp = *(_DWORD*)&pKey;
st->i += 4;
pFlag = tmp;
printf("pFlag[%d] = %#x\n", st->stack-1, tmp);
continue;
case 15:
tmp = *(_DWORD*)&pKey;
index = st->i + 4 + tmp;
st->i = index;
continue;
case 16:
tmp = st->i + 4;
st->stack--;
if (pFlag)
tmp += *(_DWORD*)&pKey;
st->i = tmp;
continue;
case 17:
tmp = *(_DWORD*)&pKey;
st->stack += tmp;
st->i += 4;
continue;
case 18:
st->i += 4;
return;
default:
st->i++;
}
}
}
char flag1 = { 0 }; //前40个字节使用户输入的flag,40往后是为了加密flag用到的数据
char flag2 = { 0 }; //前40个字节使用户输入的flag,40往后是为了加密flag用到的数据
char compare_date = {
0xE8, 0xFA, 0xE0, 0xAE, 0x01, 0x41, 0x3E, 0xFC, 0x92, 0xAD,
0x7C, 0x16, 0xBE, 0x6C, 0xEA, 0x51, 0x00, 0x01, 0x2A, 0x24,
0x1B, 0x1A, 0x51, 0x01, 0x94, 0x66, 0x4D, 0x51, 0xEB, 0xBF,
0x5F, 0x2F, 0x98, 0x63, 0xD3, 0x46, 0xF0, 0xE3, 0xEE, 0x79,
0
};
int main()
{
struc_1 v12 = { 0 };
struc_1 v13 = { 0 };
memcpy(flag1, "111111111111222211111111111111111111111\0", 40);
memcpy(flag2, "111111111111222211111111111111111111111\0", 40);
v12.pFlag = (_DWORD *)flag1;
v12.pKey = key1;
v12.i = 0;
v12.stack = 0;
v13.pFlag = (_DWORD*)flag2;
v13.pKey = key2;
v13.i = 0;
v13.stack = 0;
for (int i = 0; i < 0XCA; i+=2)
{
enc_flag(&v12);
memcpy(flag2, flag1, 40);
enc_flag(&v13);
memcpy(flag1, flag2, 40);
printf("----------------------------------------------------------------------------");
}
return 0;
}
```
调试发现,flag是分组进行加密的,每8个字符一组,共5组
第一组 `L3HCTF{*`, 只差1个字符, 暴力破解
```cpp
char compare_date[] = {
0xE8, 0xFA, 0xE0, 0xAE, 0x01, 0x41, 0x3E, 0xFC, 0x92, 0xAD,
0x7C, 0x16, 0xBE, 0x6C, 0xEA, 0x51, 0x00, 0x01, 0x2A, 0x24,
0x1B, 0x1A, 0x51, 0x01, 0x94, 0x66, 0x4D, 0x51, 0xEB, 0xBF,
0x5F, 0x2F, 0x98, 0x63, 0xD3, 0x46, 0xF0, 0xE3, 0xEE, 0x79
};
int main()
{
struc_1 v12 = { 0 };
struc_1 v13 = { 0 };
memcpy(flag1, "111111111111111111111111111111111111111\0", 40);
memcpy(flag2, "111111111111111111111111111111111111111\0", 40);
v12.pFlag = (_DWORD*)flag1;
v12.pKey = key1;
v12.i = 0;
v12.kk = 0;
v13.pFlag = (_DWORD*)flag2;
v13.pKey = key2;
v13.i = 0;
v13.kk = 0;
memcpy(flag1, "L3HCTF{1", 8);
memcpy(flag2, "L3HCTF{1", 8);
for (int j = 32; j < 127; j++)
{
v12.pFlag = (_DWORD*)flag1;
v12.pKey = key1;
v12.i = 0;
v12.kk = 0;
v13.pFlag = (_DWORD*)flag2;
v13.pKey = key2;
v13.i = 0;
v13.kk = 0;
memcpy(flag1, "L3HCTF{", 8);
memcpy(flag2, "L3HCTF{", 8);
flag1 = j;
flag2 = j;
for (int i = 0; i < 0XCA; i += 2)
{
enc_flag(&v12);
memcpy(flag2, flag1, 40);
enc_flag(&v13);
memcpy(flag1, flag2, 40);
}
if (memcmp(flag1, compare_date, 8) == 0)
{
printf("%c\n", j);
getchar();
}
}
return 0;
}
//D
```
发现第一组是`L3HCTF{D`
然后下面开始还原VM,只需还原出加密每一组的第一个循环就OK
输入flag 为 `L3HCTF{D1111222211111111111111111111111}`
```
第二组为
Input:31 31 31 31 32 32 32 32
enc后
Output: ec 9d 57 67 94 6a 7e a5
```
通过打印的日志,追踪Input,来分析如何得到的Output
**加密flag的第二组的第一个循环的日志**
```
输入:31 31 31 31 32 32 32 32
输出:ec 9d 57 67 94 6a 7e a5
======以下是打印的日志
OPCODE :14
pFlag = 0x14
------>OPCODE :14
pFlag = 0x14
------>OPCODE :9
pFlag = 0x13;
------>OPCODE :14
pFlag = 0x1
------>OPCODE :0
pFlag = pFlag:0x1 + pFlag:0x13;
------>OPCODE :8
pFlag = 0x14;
------>OPCODE :15
------>OPCODE :14
pFlag = 0x14
------>OPCODE :9
pFlag = 0x14;
------>OPCODE :14
pFlag = 0x14
------>OPCODE :12
exchange pFlag:0x14, pFlag:0x14
------>OPCODE :1
pFlag = pFlag:0x14 - pFlag:0x14;
------>OPCODE :11
pFlag = 0;
------>OPCODE :10
pFlag = 1;
------>OPCODE :16
------>OPCODE :14
pFlag = 0x13
------>OPCODE :14
pFlag = 0x13
------>OPCODE :9
pFlag = 0;
------>OPCODE :14
pFlag = 0x2
------>OPCODE :0
pFlag = pFlag:0x2 + pFlag:0;
------>OPCODE :8
pFlag = 0x2;
------>OPCODE :15
------>OPCODE :14
pFlag = 0x13
------>OPCODE :9
pFlag = 0x2;
------>OPCODE :14
pFlag = 0xa
------>OPCODE :12
exchange pFlag:0x2, pFlag:0xa
------>OPCODE :1
pFlag = pFlag:0x2 - pFlag:0xa;
------>OPCODE :11
pFlag = 1;
------>OPCODE :10
pFlag = 0;
------>OPCODE :16
------>OPCODE :14
pFlag = 0x14
------>OPCODE :14
pFlag = 0
------>OPCODE :8
pFlag = 0;
------>OPCODE :14
pFlag = 0x14
------>OPCODE :9
pFlag = 0;
------>OPCODE :14
pFlag = 0x14
------>OPCODE :12
exchange pFlag:0, pFlag:0x14
------>OPCODE :1
pFlag = pFlag:0 - pFlag:0x14;
------>OPCODE :11
pFlag = 1;
------>OPCODE :10
pFlag = 0;
------>OPCODE :16
------>OPCODE :14
pFlag = 0xc
------>OPCODE :14
pFlag = 0x13
------>OPCODE :9
pFlag = 0x2;
------>OPCODE :14
pFlag = 0
------>OPCODE :0
pFlag = pFlag:0 + pFlag:0x2;
------>OPCODE :9
pFlag = 0x31313131;
------>OPCODE :8
pFlag = 0x31313131;
------>OPCODE :14
pFlag = 0xd
------>OPCODE :14
pFlag = 0x13
------>OPCODE :9
pFlag = 0x2;
------>OPCODE :14
pFlag = 0x1
------>OPCODE :0
pFlag = pFlag:0x1 + pFlag:0x2;
------>OPCODE :14
pFlag = 0
------>OPCODE :0
pFlag = pFlag:0 + pFlag:0x3;
------>OPCODE :9
pFlag = 0x32323232;
------>OPCODE :8
pFlag = 0x32323232;
------>OPCODE :14
pFlag = 0xc
------>OPCODE :14
pFlag = 0xc
------>OPCODE :9
pFlag = 0x31313131;
------>OPCODE :14
pFlag = 0xd
------>OPCODE :9
pFlag = 0x32323232;
------>OPCODE :14
pFlag = 0x10
------>OPCODE :2
pFlag = pFlag:0x10 * pFlag:0x32323232; ====
------>OPCODE :14
pFlag = 0xd
------>OPCODE :9
pFlag = 0x32323232;
------>OPCODE :14
pFlag = 0x20
------>OPCODE :12
exchange pFlag:0x32323232, pFlag:0x20
------>OPCODE :3
pFlag = pFlag:0x32323232 / pFlag:0x20; ====
------>OPCODE :7
pFlag = pFlag:0x1919191 ^ pFlag:0x23232320;
------>OPCODE :14
pFlag = 0xd
------>OPCODE :9
pFlag = 0x32323232; ====
------>OPCODE :0
pFlag = pFlag:0x32323232 + pFlag:0x22b2b2b1; ====
------>OPCODE :14
pFlag = 0xb
------>OPCODE :9
pFlag = 0xce0a6e55;
------>OPCODE :14
pFlag = 0xb
------>OPCODE :9
pFlag = 0xce0a6e55;
------>OPCODE :14
pFlag = 0x3
------>OPCODE :5
pFlag = pFlag:0x3 & pFlag:0xce0a6e55;
------>OPCODE :14
pFlag = 0xe
------>OPCODE :0
pFlag = pFlag:0xe + pFlag:0x1;
------>OPCODE :9
pFlag = 0x6f76;
------>OPCODE :0
pFlag = pFlag:0x6f76 + pFlag:0xce0a6e55;
------>OPCODE :7
pFlag = pFlag:0xce0addcb ^ pFlag:0x54e4e4e3;
------>OPCODE :0
pFlag = pFlag:0x9aee3928 + pFlag:0x31313131;===
------>OPCODE :8
pFlag = 0xcc1f6a59;
------>OPCODE :14
pFlag = 0xb
------>OPCODE :14
pFlag = 0xb
------>OPCODE :9
pFlag = 0xce0a6e55; === 上一轮循环剩下的
------>OPCODE :14
pFlag = 0xa
------>OPCODE :9
pFlag = 0x75bcd15;
------>OPCODE :0
pFlag = pFlag:0x75bcd15 + pFlag:0xce0a6e55;
------>OPCODE :8
pFlag = 0xd5663b6a;====
------>OPCODE :14
pFlag = 0xd
------>OPCODE :14
pFlag = 0xd
------>OPCODE :9
pFlag = 0x32323232;
------>OPCODE :14
pFlag = 0xc
------>OPCODE :9
pFlag = 0xcc1f6a59;
------>OPCODE :14
pFlag = 0x10
------>OPCODE :2
pFlag = pFlag:0x10 * pFlag:0xcc1f6a59; ===
------>OPCODE :14
pFlag = 0xc
------>OPCODE :9
pFlag = 0xcc1f6a59;
------>OPCODE :14
pFlag = 0x20
------>OPCODE :12
exchange pFlag:0xcc1f6a59, pFlag:0x20
------>OPCODE :3
pFlag = pFlag:0xcc1f6a59 / pFlag:0x20;
------>OPCODE :7
pFlag = pFlag:0xfe60fb53 ^ pFlag:0xc1f6a590;
------>OPCODE :14
pFlag = 0xc
------>OPCODE :9
pFlag = 0xcc1f6a59;
------>OPCODE :0
pFlag = pFlag:0xcc1f6a59 + pFlag:0x3f965ec3;
------>OPCODE :14
pFlag = 0xb
------>OPCODE :9
pFlag = 0xd5663b6a;
------>OPCODE :14
pFlag = 0xb
------>OPCODE :9
pFlag = 0xd5663b6a;
------>OPCODE :14
pFlag = 0x800
------>OPCODE :12
exchange pFlag:0xd5663b6a, pFlag:0x800
------>OPCODE :3
pFlag = pFlag:0xd5663b6a / pFlag:0x800;
------>OPCODE :14
pFlag = 0x3
------>OPCODE :5
pFlag = pFlag:0x3 & pFlag:0xfffaacc8; ====
------>OPCODE :14
pFlag = 0xe
------>OPCODE :0
pFlag = pFlag:0xe + pFlag:0;
------>OPCODE :9
pFlag = 0x494c;
------>OPCODE :0
pFlag = pFlag:0x494c + pFlag:0xd5663b6a;===
------>OPCODE :7
pFlag = pFlag:0xd56684b6 ^ pFlag:0xbb5c91c; ===
------>OPCODE :0
pFlag = pFlag:0xded34daa + pFlag:0x32323232;
------>OPCODE :8
pFlag = 0x11057fdc; ===
------>OPCODE :14
pFlag = 0x13
------>OPCODE :9
pFlag = 0x2;
------>OPCODE :14
pFlag = 0
------>OPCODE :0
pFlag = pFlag:0 + pFlag:0x2;
------>OPCODE :14
pFlag = 0xc
------>OPCODE :9
pFlag = 0xcc1f6a59;
------>OPCODE :8
pFlag = 0xcc1f6a59;
------>OPCODE :14
pFlag = 0x13
------>OPCODE :9
pFlag = 0x2;
------>OPCODE :14
pFlag = 0x1
------>OPCODE :0
pFlag = pFlag:0x1 + pFlag:0x2;
------>OPCODE :14
pFlag = 0
------>OPCODE :0
pFlag = pFlag:0 + pFlag:0x3;
------>OPCODE :14
pFlag = 0xd
------>OPCODE :9
pFlag = 0x11057fdc;
------>OPCODE :8
pFlag = 0x11057fdc;
------>OPCODE :18=============================================v13准备开始
------>OPCODE :14
pFlag = 0x14
------>OPCODE :14
pFlag = 0x14
------>OPCODE :9
pFlag = 0x13;
------>OPCODE :14
pFlag = 0x1
------>OPCODE :0
pFlag = pFlag:0x1 + pFlag:0x13;
------>OPCODE :8
pFlag = 0x14;
------>OPCODE :15
------>OPCODE :14
pFlag = 0x14
------>OPCODE :9
pFlag = 0x14;
------>OPCODE :14
pFlag = 0x14
------>OPCODE :12
exchange pFlag:0x14, pFlag:0x14
------>OPCODE :1
pFlag = pFlag:0x14 - pFlag:0x14;
------>OPCODE :11
pFlag = 0;
------>OPCODE :10
pFlag = 1;
------>OPCODE :16
------>OPCODE :14
pFlag = 0x13
------>OPCODE :14
pFlag = 0x13
------>OPCODE :9
pFlag = 0;
------>OPCODE :14
pFlag = 0x2
------>OPCODE :0
pFlag = pFlag:0x2 + pFlag:0;
------>OPCODE :8
pFlag = 0x2;
------>OPCODE :15
------>OPCODE :14
pFlag = 0x13
------>OPCODE :9
pFlag = 0x2;
------>OPCODE :14
pFlag = 0xa
------>OPCODE :12
exchange pFlag:0x2, pFlag:0xa
------>OPCODE :1
pFlag = pFlag:0x2 - pFlag:0xa;
------>OPCODE :11
pFlag = 1;
------>OPCODE :10
pFlag = 0;
------>OPCODE :16
------>OPCODE :14
pFlag = 0x14
------>OPCODE :14
pFlag = 0
------>OPCODE :8
pFlag = 0;
------>OPCODE :14
pFlag = 0x14
------>OPCODE :9
pFlag = 0;
------>OPCODE :14
pFlag = 0x14
------>OPCODE :12
exchange pFlag:0, pFlag:0x14
------>OPCODE :1
pFlag = pFlag:0 - pFlag:0x14;
------>OPCODE :11
pFlag = 1;
------>OPCODE :10
pFlag = 0;
------>OPCODE :16
------>OPCODE :14
pFlag = 0xc
------>OPCODE :14
pFlag = 0x13
------>OPCODE :9
pFlag = 0x2;
------>OPCODE :14
pFlag = 0
------>OPCODE :0
pFlag = pFlag:0 + pFlag:0x2;
------>OPCODE :9
pFlag = 0xcc1f6a59;
------>OPCODE :8
pFlag = 0xcc1f6a59;
------>OPCODE :14
pFlag = 0xd
------>OPCODE :14
pFlag = 0x13
------>OPCODE :9
pFlag = 0x2;
------>OPCODE :14
pFlag = 0x1
------>OPCODE :0
pFlag = pFlag:0x1 + pFlag:0x2;
------>OPCODE :14
pFlag = 0
------>OPCODE :0
pFlag = pFlag:0 + pFlag:0x3;
------>OPCODE :9
pFlag = 0x11057fdc;
------>OPCODE :8
pFlag = 0x11057fdc;
------>OPCODE :14
pFlag = 0xb
------>OPCODE :14
pFlag = 0xb
------>OPCODE :9
pFlag = 0x798dcdf9;
------>OPCODE :14
pFlag = 0xa
------>OPCODE :9
pFlag = 0x154cbf7; = =====系统中的立即数
------>OPCODE :0
pFlag = pFlag:0x154cbf7 + pFlag:0x798dcdf9; == 这2个数是固定的
------>OPCODE :8
pFlag = 0x7ae299f0; =========
------>OPCODE :14
pFlag = 0xc
------>OPCODE :14
pFlag = 0xc
------>OPCODE :9
pFlag = 0xcc1f6a59;
------>OPCODE :14
pFlag = 0xd
------>OPCODE :9
pFlag = 0x11057fdc;
------>OPCODE :14
pFlag = 0x10
------>OPCODE :2
pFlag = pFlag:0x10 * pFlag:0x11057fdc;========
------>OPCODE :14
pFlag = 0
------>OPCODE :14
pFlag = 0xe
------>OPCODE :0
pFlag = pFlag:0xe + pFlag:0;
------>OPCODE :9
pFlag = 0x5354;
------>OPCODE :0
pFlag = pFlag:0x5354 + pFlag:0x1057fdc0; =======
------>OPCODE :14
pFlag = 0xd
------>OPCODE :9
pFlag = 0x11057fdc;
------>OPCODE :14
pFlag = 0xb
------>OPCODE :9
pFlag = 0x7ae299f0;
------>OPCODE :0
pFlag = pFlag:0x7ae299f0 + pFlag:0x11057fdc;
------>OPCODE :14
pFlag = 0xd
------>OPCODE :9
pFlag = 0x11057fdc;
------>OPCODE :14
pFlag = 0x20
------>OPCODE :12
exchange pFlag:0x11057fdc, pFlag:0x20
------>OPCODE :3
pFlag = pFlag:0x11057fdc / pFlag:0x20; ### 0x882bfe
------>OPCODE :14
pFlag = 0x1
------>OPCODE :14
pFlag = 0xe
------>OPCODE :0
pFlag = pFlag:0xe + pFlag:0x1;
------>OPCODE :9
pFlag = 0x4f4d;
------>OPCODE :0
pFlag = pFlag:0x4f4d + pFlag:0x882bfe;
------>OPCODE :7
pFlag = pFlag:0x887b4b ^ pFlag:0x8be819cc; =====
------>OPCODE :7
pFlag = pFlag:0x8b606287 ^ pFlag:0x10585114;==
------>OPCODE :0
pFlag = pFlag:0x9b383393 + pFlag:0xcc1f6a59;=====
------>OPCODE :8
pFlag = 0x67579dec; ######
------>OPCODE :14
pFlag = 0xd
------>OPCODE :14
pFlag = 0xd
------>OPCODE :9
pFlag = 0x11057fdc;
------>OPCODE :14
pFlag = 0xc
------>OPCODE :9
pFlag = 0x67579dec;
------>OPCODE :14
pFlag = 0x10
------>OPCODE :2
pFlag = pFlag:0x10 * pFlag:0x67579dec;
------>OPCODE :14
pFlag = 0x2
------>OPCODE :14
pFlag = 0xe
------>OPCODE :0
pFlag = pFlag:0xe + pFlag:0x2;
------>OPCODE :9
pFlag = 0x2074;
------>OPCODE :0
pFlag = pFlag:0x2074 + pFlag:0x7579dec0; === 49
------>OPCODE :14
pFlag = 0xc
------>OPCODE :9
pFlag = 0x67579dec;
------>OPCODE :14
pFlag = 0xb
------>OPCODE :9
pFlag = 0x7ae299f0;
------>OPCODE :0
pFlag = pFlag:0x7ae299f0 + pFlag:0x67579dec; =====
------>OPCODE :14
pFlag = 0xc
------>OPCODE :9
pFlag = 0x67579dec;
------>OPCODE :14
pFlag = 0x20
------>OPCODE :12
exchange pFlag:0x67579dec, pFlag:0x20
------>OPCODE :3
pFlag = pFlag:0x67579dec / pFlag:0x20;==='0x33abcef'
------>OPCODE :14
pFlag = 0x3
------>OPCODE :14
pFlag = 0xe
------>OPCODE :0
pFlag = pFlag:0xe + pFlag:0x3;
------>OPCODE :9
pFlag = 0x6561;
------>OPCODE :0
pFlag = pFlag:0x6561 + pFlag:0x33abcef;
------>OPCODE :7
pFlag = pFlag:0x33b2250 ^ pFlag:0xe23a37dc;
------>OPCODE :7
pFlag = pFlag:0xe101158c ^ pFlag:0x7579ff34;
------>OPCODE :0
pFlag = pFlag:0x9478eab8 + pFlag:0x11057fdc; # '0xa57e6a94'
------>OPCODE :8
pFlag = 0xa57e6a94;
------>OPCODE :14
pFlag = 0x13
------>OPCODE :9
pFlag = 0x2;
------>OPCODE :14
pFlag = 0
------>OPCODE :0
pFlag = pFlag:0 + pFlag:0x2;
------>OPCODE :14
pFlag = 0xc
------>OPCODE :9
pFlag = 0x67579dec;
------>OPCODE :8
pFlag = 0x67579dec;
------>OPCODE :14
pFlag = 0x13
------>OPCODE :9
pFlag = 0x2;
------>OPCODE :14
pFlag = 0x1
------>OPCODE :0
pFlag = pFlag:0x1 + pFlag:0x2;
------>OPCODE :14
pFlag = 0
------>OPCODE :0
pFlag = pFlag:0 + pFlag:0x3;
------>OPCODE :14
pFlag = 0xd
------>OPCODE :9
pFlag = 0xa57e6a94;
------>OPCODE :8
pFlag = 0xa57e6a94;
------>OPCODE :18
----------------------------------------------------------------------------
```
**分析算法**
```
A = FLAG
B = FLAG
pFlag = B * 0x10
pFlag = B / 0X20
pFlag = pFlag ^ pFlag
pFlag = B + pFlag
pFlag = (0xCE0A6E55 + 0X6F76) ^ pFlag
pFlag = pFlag + A
TMP1 = pFlag# 173行0xcc1f6a59 ***V12导出 # v0
pFlag = 0xCE0A6E55 # (过会回来补坑,这个是上一轮循环剩下的) 这个与FLAG无关,是固定的
pFlag = 0x75bcd15(立即数) + 0xce0a6e55
TMP2 = pFlag# 187行0xd5663b6a #TMP2 = sum1
pFlag = TMP1
pFlag = TMP1 * 0X10# 201
pFlag = TMP1 / 0x20# 213
pFlag = pFlag ^ pFlag
pFlag = TMP1 + pFlag
pFlag = TMP2
pFlag = pFlag / 0x800#233行
pFlag = TMP2 + 0x494c ###245
pFlag = pFlag ^ pFlag
pFlag = pFlag + B
TMP3 = pFlag ### 251行 0x11057fdc***V12导出 #v1
pFlag = 0x154cbf7(立即数) + 0x798dcdf9; #这2个数是固定的 #在第一轮的时候是这个,其他的还没测试
TMP4 = pFlag ###407行0x7ae299f0
pFlag = TMP3 * 0X10
pFlag = pFlag + 0X5354 # 421
pFlag = TMP4 + TMP3#441
pFlag = TMP3 / 0x20 #451### 0x882bfe
pFlag = 0x4f4d + pFlag
pFlag = pFlag ^ pFlag
pFlag = pFlag ^ pFlag#465 ## 0x9b383393
pFlag = pFlag + TMP1
TMP5 = pFlag #### 4690x67579dec
pFlag = TMP5 * 0X10
pFlag = pFlag + 0x2074## 0x7579ff34
pFlag = TMP4 + TMP5####503行
pFlag = TMP5 / 0x20
pFlag = pFlag + 0x6561
pFlag = pFlag ^ pFlag
pFlag = pFlag ^ pFlag
pFlag = pFlag + TMP3# 529行 0xa57e6a94
TMP6 = pFlag# 0xa57e6a94
```
通过 `* 0x10 、/0x20、 /0x800、 &3`等特征,猜测是xtea, tea算法
一边猜一边还原算法,用C语言写出1轮的循环加密算法
```
int tea_key = { 0X5354, 0x4f4d, 0x2074, 0x6561 };
int xtea_key = { 0x494c, 0X6F76 , 0x6520, 0x4355 };
void encrypt(int* v, int& sum_xtea, int& sum_tea)
{
int v0 = v, v1 = v;
v0 += (((v1 << 4) ^ (v1 / 0x20)) + v1) ^ (sum_xtea + xtea_key);
sum_xtea += 0x75bcd15;
v1 += (((v0 << 4) ^ (v0 / 0x20)) + v0) ^ (sum_xtea + xtea_key[(sum_xtea / 0x800) & 3]);
sum_tea += 0x154cbf7;
v0 += ((v1 << 4) + tea_key) ^ (v1 + sum_tea) ^ ((v1 / 0x20) + tea_key);
v1 += ((v0 << 4) + tea_key) ^ (v0 + sum_tea) ^ ((v0 / 0x20) + tea_key);
v = v0;
v = v1;
}
```
sum_tea 和 sum_xtea,对于每一组来说,初始值是不同的,比如第二组这里是0x798dcdf9 和 0xce0a6e55
最后通过打印三,四,五组第一个循环的日志,来与第二组的日志做对比,找到了所有组的初始的sum_tea 和 sum_xtea
```
int sum = {
0xCE0A6E55, 0x798dcdf9,
0x613673f9, 0x942dbd45,
0xf462799d, 0xaecdac91,
0x878e7f41, 0xc96d9bdd
};
```
最终写脚本解密
```
#include <windows.h>
#include <stdio.h>
int sum = {
0xCE0A6E55, 0x798dcdf9,
0x613673f9, 0x942dbd45,
0xf462799d, 0xaecdac91,
0x878e7f41, 0xc96d9bdd
};
int tea_key = { 0X5354, 0x4f4d, 0x2074, 0x6561 };
int xtea_key = { 0x494c, 0X6F76 , 0x6520, 0x4355 };
void encrypt(int* v, int& sum_xtea, int& sum_tea)
{
int v0 = v, v1 = v;
v0 += (((v1 << 4) ^ (v1 / 0x20)) + v1) ^ (sum_xtea + xtea_key);
sum_xtea += 0x75bcd15;
v1 += (((v0 << 4) ^ (v0 / 0x20)) + v0) ^ (sum_xtea + xtea_key[(sum_xtea / 0x800) & 3]);
sum_tea += 0x154cbf7;
v0 += ((v1 << 4) + tea_key) ^ (v1 + sum_tea) ^ ((v1 / 0x20) + tea_key);
v1 += ((v0 << 4) + tea_key) ^ (v0 + sum_tea) ^ ((v0 / 0x20) + tea_key);
v = v0;
v = v1;
}
void decrypt(int* v, int& sum_xtea, int& sum_tea)
{
int v0 = v, v1 = v;
v1 -= ((v0 << 4) + tea_key) ^ (v0 + sum_tea) ^ ((v0 / 0x20) + tea_key);
v0 -= ((v1 << 4) + tea_key) ^ (v1 + sum_tea) ^ ((v1 / 0x20) + tea_key);
sum_tea -= 0x154cbf7;;
v1 -= (((v0 << 4) ^ (v0 / 0x20)) + v0) ^ (sum_xtea + xtea_key[(sum_xtea / 0x800) & 3]);
sum_xtea -= 0x75bcd15;
v0 -= (((v1 << 4) ^ (v1 / 0x20)) + v1) ^ (sum_xtea + xtea_key);
v = v0;
v = v1;
}
char compare_date =//这里是从程序中提取的加密后的flag的值
{
0xE8, 0xFA, 0xE0, 0xAE, 0x01, 0x41, 0x3E, 0xFC, 0x92, 0xAD,
0x7C, 0x16, 0xBE, 0x6C, 0xEA, 0x51, 0x00, 0x01, 0x2A, 0x24,
0x1B, 0x1A, 0x51, 0x01, 0x94, 0x66, 0x4D, 0x51, 0xEB, 0xBF,
0x5F, 0x2F, 0x98, 0x63, 0xD3, 0x46, 0xF0, 0xE3, 0xEE, 0x79
};
int main()
{
int v = { 0 };
int* encFlag = (int*)compare_date;
//flag的前8个字符爆破得到的L3HCTF{D
for (int j = 0; j < 4; j++) //后32个字符,分4组
{
for (int i = 0; i < 20; i++)
encrypt(v, sum, sum);//提升sum_xtea 和 sum_tea
for (int i = 0; i < 20; i++)
decrypt(&encFlag, sum, sum);
}
char* flag = (char*)&encFlag;
printf("flag is L3HCTF{D%s\n", flag);
return 0;
}
// L3HCTF{D0uBle_vM_W1th_dOubIe_TEA}
```
## Load
IDA打开程序分析
进入LOAD_PE函数,就是创建了个傀儡进程
在ResumeThread这里下断点,dump,然后foremost分离
注意在foremost分离的时候要把dump下来的程序的MZ头抹去,这样才能分离解密后的PE文件来
IDA打开分析
获取flag后,对flag中的字符在 0x30-0x39或 a-f 范围做了个小处理
```
0x30 - 0x39---> 0x00 - 0x09
a - f ---> 0xA ---0xF
# 然后
假设输入的是123f-->0x12, 0x3f 存在了0x434380的位置
```
注意这里全是对应的十六进制,猜测输入的flag的范围就是
最终434380处的数据是13个。下面又分为9 + 4 个,正好是3和2的平方,并且下面验证的时候也是分为9 + 4进行验证的
猜测是3 *3 + 2 * 2的某个矩阵运算, 在上述图89行位置下断点,修改src处的数据为100010001,
```
1 0 0
0 1 0
0 0 1
正好是单位矩阵
```
然后运行,加密后发现Src处的数据没变,但是v29处的数据全乱了,猜测是逆矩阵
提取出加密后Src 和 v29处的数据
```
Src:
1 0-9
0 -1-6
-1-2-4
v29:
7 3
3013
```
写脚本求逆矩阵,并转换为flag
```python
import numpy
if __name__ == "__main__":
a = numpy.array([, , [-1, -2, -4]])
b = numpy.array([, ])
a_inv = numpy.linalg.inv(a)
b_inv = numpy.linalg.inv(b)
a_list =
b_list =
flag_list = a_list + a_list + a_list + b_list + b_list
flag_list =
flag = bytes(flag_list).hex()
print(flag)
#f812f706f306ff02ff0dfde207
```
拼接后进行验证,Load.exe在 ResumeThread那里下断点,输入flag,程序断下,在运行dump提取出来的exe,验证成功
最终flag为 : `flag{f812f706f306ff02ff0dfde207}` 有几张图片挂了,师傅能补一下吗? 搜索曾经的回忆 发表于 2021-11-17 14:50
有几张图片挂了,师傅能补一下吗?
我看了看没有啊{:1_907:} 搜索曾经的回忆 发表于 2021-11-17 15:28
好吧,抱歉,过会上完课回去重新传 搜索曾经的回忆 发表于 2021-11-17 15:28
图片已重新上传 感谢楼主分享
感谢楼主分享,wp很详细
感谢楼主分享 楼主好人啊
页:
[1]
2