zsky 发表于 2021-11-17 12:55

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

有几张图片挂了,师傅能补一下吗?

zsky 发表于 2021-11-17 15:26

搜索曾经的回忆 发表于 2021-11-17 14:50
有几张图片挂了,师傅能补一下吗?

我看了看没有啊{:1_907:}

搜索曾经的回忆 发表于 2021-11-17 15:28

zsky 发表于 2021-11-17 15:37

搜索曾经的回忆 发表于 2021-11-17 15:28


好吧,抱歉,过会上完课回去重新传

zsky 发表于 2021-11-17 19:01

搜索曾经的回忆 发表于 2021-11-17 15:28


图片已重新上传

明次 发表于 2021-11-19 17:16

感谢楼主分享

Atomhua 发表于 2021-11-20 16:27


感谢楼主分享,wp很详细

douluodalu 发表于 2021-11-30 05:06


感谢楼主分享

jnsf077 发表于 2022-3-17 11:15

楼主好人啊
页: [1] 2
查看完整版本: L3HCTF 部分RE WP