zsky 发表于 2021-11-29 15:01

2021NCTF RE_WP

本帖最后由 zsky 于 2021-11-29 15:20 编辑

# NCTF2021_RE_WP

## Hello せかい

记事本都能做的题.IDA打开直接看到flag



flag为 `NCTF{We1come_2_Reverse_Engineering}`

## Shadowbringer

base64换了2次表,调试起来找到表,逆回去即可







写脚本解密

```python
import base64

flag = "U>F2UsQXN`5sXMELT=:7M_2<X]^1ThaWF0=KM?9IUhAsTM5:T==_Ns&<Vhb!"
std_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
my_table = '#$%&\x27()*+,-.s0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`ab'
my_table2 = 'ba`_^]h[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210s.-,+*)(\x27&%$#'

flag = flag.translate(str.maketrans(my_table2, std_table))
flag = flag.replace("!", '=').encode() # "6G074JP+s)WV:Z+T<&(Q18`Ks)WV:Y4hs9[h:YCS?&0`"
flag = base64.b64decode(flag).decode()
flag = flag.translate(str.maketrans(my_table, std_table))
print(base64.b64decode(flag))

# NCTF{H0m3_r1d1n9_h0m3_dy1n9_h0p3}
```

flag 为 `NCTF{H0m3_r1d1n9_h0m3_dy1n9_h0p3}`

## 鲨鲨的秘密

这个题跟西湖论剑那个第一个RE题好像



`loc_404E3B`为执行的指令,因为每次就33条汇编,也不长,直接调试把第一轮所有的汇编拿出来分析

```
mov   ds:dword_404E50, 0FFFFFFFFh                                        # dword_404E50 = -1
mov   ecx, ds:I
mov   dl,                                                    # flag
mov   byte ptr ds:dword_404E4C, dl                              
movzx   eax, byte ptr ds:dword_404E4C
xor   eax, ds:dword_404E50                                                dword_404E4C = (flag ^ 404E50 ) & 0xFF
mov   byte ptr ds:dword_404E4C, al
movzx   ecx, byte ptr ds:dword_404E4C
and   ecx, 0FFh                                                                        dword_404E50 >>= 8
mov   byte ptr ds:dword_404E4C, cl
mov   edx, ds:dword_404E50                                                dword_404E50 ^= dword_404A38
shr   edx, 8
mov   ds:dword_404E50, edx
movzx   eax, byte ptr ds:dword_404E4C
mov   ecx, ds:dword_404E50
xor   ecx, ds:dword_404A38
mov   ds:dword_404E50, ecx

mov   edx, ds:I
mov   al,                                                 # flag
mov   byte ptr ds:dword_404E4C, al
movzx   ecx, byte ptr ds:dword_404E4C
xor   ecx, ds:dword_404E50                                        404E4C = flag ^ 404E50
mov   byte ptr ds:dword_404E4C, cl
mov   edx, ds:dword_404E50      
shr   edx, 8                                                                        dword_404E50 >>= 8
mov   ds:dword_404E50, edx
movzx   eax, byte ptr ds:dword_404E4C
mov   ecx, ds:dword_404E50
xor   ecx, ds:dword_404A38                              dword_404E50 ^= dword_404A38
mov   ds:dword_404E50, ecx
mov   edx, ds:dword_404E50
xor   edx, 0FFFFFFFFh
mov   ds:dword_404E50, edx      
```

分析完毕,把程序中加密后的flag提取出来直接爆破

```cpp
#include <stdio.h>
#include <windows.h>

unsigned char byte_404A38[] =
{
0x00, 0x00, 0x00, 0x00, 0x96, 0x30, 0x07, 0x77, 0x2C, 0x61,
0x0E, 0xEE, 0xBA, 0x51, 0x09, 0x99, 0x19, 0xC4, 0x6D, 0x07,
0x8F, 0xF4, 0x6A, 0x70, 0x35, 0xA5, 0x63, 0xE9, 0xA3, 0x95,
0x64, 0x9E, 0x32, 0x88, 0xDB, 0x0E, 0xA4, 0xB8, 0xDC, 0x79,
0x1E, 0xE9, 0xD5, 0xE0, 0x88, 0xD9, 0xD2, 0x97, 0x2B, 0x4C,
0xB6, 0x09, 0xBD, 0x7C, 0xB1, 0x7E, 0x07, 0x2D, 0xB8, 0xE7,
0x91, 0x1D, 0xBF, 0x90, 0x64, 0x10, 0xB7, 0x1D, 0xF2, 0x20,
0xB0, 0x6A, 0x48, 0x71, 0xB9, 0xF3, 0xDE, 0x41, 0xBE, 0x84,
0x7D, 0xD4, 0xDA, 0x1A, 0xEB, 0xE4, 0xDD, 0x6D, 0x51, 0xB5,
0xD4, 0xF4, 0xC7, 0x85, 0xD3, 0x83, 0x56, 0x98, 0x6C, 0x13,
0xC0, 0xA8, 0x6B, 0x64, 0x7A, 0xF9, 0x62, 0xFD, 0xEC, 0xC9,
0x65, 0x8A, 0x4F, 0x5C, 0x01, 0x14, 0xD9, 0x6C, 0x06, 0x63,
0x63, 0x3D, 0x0F, 0xFA, 0xF5, 0x0D, 0x08, 0x8D, 0xC8, 0x20,
0x6E, 0x3B, 0x5E, 0x10, 0x69, 0x4C, 0xE4, 0x41, 0x60, 0xD5,
0x72, 0x71, 0x67, 0xA2, 0xD1, 0xE4, 0x03, 0x3C, 0x47, 0xD4,
0x04, 0x4B, 0xFD, 0x85, 0x0D, 0xD2, 0x6B, 0xB5, 0x0A, 0xA5,
0xFA, 0xA8, 0xB5, 0x35, 0x6C, 0x98, 0xB2, 0x42, 0xD6, 0xC9,
0xBB, 0xDB, 0x40, 0xF9, 0xBC, 0xAC, 0xE3, 0x6C, 0xD8, 0x32,
0x75, 0x5C, 0xDF, 0x45, 0xCF, 0x0D, 0xD6, 0xDC, 0x59, 0x3D,
0xD1, 0xAB, 0xAC, 0x30, 0xD9, 0x26, 0x3A, 0x00, 0xDE, 0x51,
0x80, 0x51, 0xD7, 0xC8, 0x16, 0x61, 0xD0, 0xBF, 0xB5, 0xF4,
0xB4, 0x21, 0x23, 0xC4, 0xB3, 0x56, 0x99, 0x95, 0xBA, 0xCF,
0x0F, 0xA5, 0xBD, 0xB8, 0x9E, 0xB8, 0x02, 0x28, 0x08, 0x88,
0x05, 0x5F, 0xB2, 0xD9, 0x0C, 0xC6, 0x24, 0xE9, 0x0B, 0xB1,
0x87, 0x7C, 0x6F, 0x2F, 0x11, 0x4C, 0x68, 0x58, 0xAB, 0x1D,
0x61, 0xC1, 0x3D, 0x2D, 0x66, 0xB6, 0x90, 0x41, 0xDC, 0x76,
0x06, 0x71, 0xDB, 0x01, 0xBC, 0x20, 0xD2, 0x98, 0x2A, 0x10,
0xD5, 0xEF, 0x89, 0x85, 0xB1, 0x71, 0x1F, 0xB5, 0xB6, 0x06,
0xA5, 0xE4, 0xBF, 0x9F, 0x33, 0xD4, 0xB8, 0xE8, 0xA2, 0xC9,
0x07, 0x78, 0x34, 0xF9, 0x00, 0x0F, 0x8E, 0xA8, 0x09, 0x96,
0x18, 0x98, 0x0E, 0xE1, 0xBB, 0x0D, 0x6A, 0x7F, 0x2D, 0x3D,
0x6D, 0x08, 0x97, 0x6C, 0x64, 0x91, 0x01, 0x5C, 0x63, 0xE6,
0xF4, 0x51, 0x6B, 0x6B, 0x62, 0x61, 0x6C, 0x1C, 0xD8, 0x30,
0x65, 0x85, 0x4E, 0x00, 0x62, 0xF2, 0xED, 0x95, 0x06, 0x6C,
0x7B, 0xA5, 0x01, 0x1B, 0xC1, 0xF4, 0x08, 0x82, 0x57, 0xC4,
0x0F, 0xF5, 0xC6, 0xD9, 0xB0, 0x65, 0x50, 0xE9, 0xB7, 0x12,
0xEA, 0xB8, 0xBE, 0x8B, 0x7C, 0x88, 0xB9, 0xFC, 0xDF, 0x1D,
0xDD, 0x62, 0x49, 0x2D, 0xDA, 0x15, 0xF3, 0x7C, 0xD3, 0x8C,
0x65, 0x4C, 0xD4, 0xFB, 0x58, 0x61, 0xB2, 0x4D, 0xCE, 0x51,
0xB5, 0x3A, 0x74, 0x00, 0xBC, 0xA3, 0xE2, 0x30, 0xBB, 0xD4,
0x41, 0xA5, 0xDF, 0x4A, 0xD7, 0x95, 0xD8, 0x3D, 0x6D, 0xC4,
0xD1, 0xA4, 0xFB, 0xF4, 0xD6, 0xD3, 0x6A, 0xE9, 0x69, 0x43,
0xFC, 0xD9, 0x6E, 0x34, 0x46, 0x88, 0x67, 0xAD, 0xD0, 0xB8,
0x60, 0xDA, 0x73, 0x2D, 0x04, 0x44, 0xE5, 0x1D, 0x03, 0x33,
0x5F, 0x4C, 0x0A, 0xAA, 0xC9, 0x7C, 0x0D, 0xDD, 0x3C, 0x71,
0x05, 0x50, 0xAA, 0x41, 0x02, 0x27, 0x10, 0x10, 0x0B, 0xBE,
0x86, 0x20, 0x0C, 0xC9, 0x25, 0xB5, 0x68, 0x57, 0xB3, 0x85,
0x6F, 0x20, 0x09, 0xD4, 0x66, 0xB9, 0x9F, 0xE4, 0x61, 0xCE,
0x0E, 0xF9, 0xDE, 0x5E, 0x98, 0xC9, 0xD9, 0x29, 0x22, 0x98,
0xD0, 0xB0, 0xB4, 0xA8, 0xD7, 0xC7, 0x17, 0x3D, 0xB3, 0x59,
0x81, 0x0D, 0xB4, 0x2E, 0x3B, 0x5C, 0xBD, 0xB7, 0xAD, 0x6C,
0xBA, 0xC0, 0x20, 0x83, 0xB8, 0xED, 0xB6, 0xB3, 0xBF, 0x9A,
0x0C, 0xE2, 0xB6, 0x03, 0x9A, 0xD2, 0xB1, 0x74, 0x39, 0x47,
0xD5, 0xEA, 0xAF, 0x77, 0xD2, 0x9D, 0x15, 0x26, 0xDB, 0x04,
0x83, 0x16, 0xDC, 0x73, 0x12, 0x0B, 0x63, 0xE3, 0x84, 0x3B,
0x64, 0x94, 0x3E, 0x6A, 0x6D, 0x0D, 0xA8, 0x5A, 0x6A, 0x7A,
0x0B, 0xCF, 0x0E, 0xE4, 0x9D, 0xFF, 0x09, 0x93, 0x27, 0xAE,
0x00, 0x0A, 0xB1, 0x9E, 0x07, 0x7D, 0x44, 0x93, 0x0F, 0xF0,
0xD2, 0xA3, 0x08, 0x87, 0x68, 0xF2, 0x01, 0x1E, 0xFE, 0xC2,
0x06, 0x69, 0x5D, 0x57, 0x62, 0xF7, 0xCB, 0x67, 0x65, 0x80,
0x71, 0x36, 0x6C, 0x19, 0xE7, 0x06, 0x6B, 0x6E, 0x76, 0x1B,
0xD4, 0xFE, 0xE0, 0x2B, 0xD3, 0x89, 0x5A, 0x7A, 0xDA, 0x10,
0xCC, 0x4A, 0xDD, 0x67, 0x6F, 0xDF, 0xB9, 0xF9, 0xF9, 0xEF,
0xBE, 0x8E, 0x43, 0xBE, 0xB7, 0x17, 0xD5, 0x8E, 0xB0, 0x60,
0xE8, 0xA3, 0xD6, 0xD6, 0x7E, 0x93, 0xD1, 0xA1, 0xC4, 0xC2,
0xD8, 0x38, 0x52, 0xF2, 0xDF, 0x4F, 0xF1, 0x67, 0xBB, 0xD1,
0x67, 0x57, 0xBC, 0xA6, 0xDD, 0x06, 0xB5, 0x3F, 0x4B, 0x36,
0xB2, 0x48, 0xDA, 0x2B, 0x0D, 0xD8, 0x4C, 0x1B, 0x0A, 0xAF,
0xF6, 0x4A, 0x03, 0x36, 0x60, 0x7A, 0x04, 0x41, 0xC3, 0xEF,
0x60, 0xDF, 0x55, 0xDF, 0x67, 0xA8, 0xEF, 0x8E, 0x6E, 0x31,
0x79, 0xBE, 0x69, 0x46, 0x8C, 0xB3, 0x61, 0xCB, 0x1A, 0x83,
0x66, 0xBC, 0xA0, 0xD2, 0x6F, 0x25, 0x36, 0xE2, 0x68, 0x52,
0x95, 0x77, 0x0C, 0xCC, 0x03, 0x47, 0x0B, 0xBB, 0xB9, 0x16,
0x02, 0x22, 0x2F, 0x26, 0x05, 0x55, 0xBE, 0x3B, 0xBA, 0xC5,
0x28, 0x0B, 0xBD, 0xB2, 0x92, 0x5A, 0xB4, 0x2B, 0x04, 0x6A,
0xB3, 0x5C, 0xA7, 0xFF, 0xD7, 0xC2, 0x31, 0xCF, 0xD0, 0xB5,
0x8B, 0x9E, 0xD9, 0x2C, 0x1D, 0xAE, 0xDE, 0x5B, 0xB0, 0xC2,
0x64, 0x9B, 0x26, 0xF2, 0x63, 0xEC, 0x9C, 0xA3, 0x6A, 0x75,
0x0A, 0x93, 0x6D, 0x02, 0xA9, 0x06, 0x09, 0x9C, 0x3F, 0x36,
0x0E, 0xEB, 0x85, 0x67, 0x07, 0x72, 0x13, 0x57, 0x00, 0x05,
0x82, 0x4A, 0xBF, 0x95, 0x14, 0x7A, 0xB8, 0xE2, 0xAE, 0x2B,
0xB1, 0x7B, 0x38, 0x1B, 0xB6, 0x0C, 0x9B, 0x8E, 0xD2, 0x92,
0x0D, 0xBE, 0xD5, 0xE5, 0xB7, 0xEF, 0xDC, 0x7C, 0x21, 0xDF,
0xDB, 0x0B, 0xD4, 0xD2, 0xD3, 0x86, 0x42, 0xE2, 0xD4, 0xF1,
0xF8, 0xB3, 0xDD, 0x68, 0x6E, 0x83, 0xDA, 0x1F, 0xCD, 0x16,
0xBE, 0x81, 0x5B, 0x26, 0xB9, 0xF6, 0xE1, 0x77, 0xB0, 0x6F,
0x77, 0x47, 0xB7, 0x18, 0xE6, 0x5A, 0x08, 0x88, 0x70, 0x6A,
0x0F, 0xFF, 0xCA, 0x3B, 0x06, 0x66, 0x5C, 0x0B, 0x01, 0x11,
0xFF, 0x9E, 0x65, 0x8F, 0x69, 0xAE, 0x62, 0xF8, 0xD3, 0xFF,
0x6B, 0x61, 0x45, 0xCF, 0x6C, 0x16, 0x78, 0xE2, 0x0A, 0xA0,
0xEE, 0xD2, 0x0D, 0xD7, 0x54, 0x83, 0x04, 0x4E, 0xC2, 0xB3,
0x03, 0x39, 0x61, 0x26, 0x67, 0xA7, 0xF7, 0x16, 0x60, 0xD0,
0x4D, 0x47, 0x69, 0x49, 0xDB, 0x77, 0x6E, 0x3E, 0x4A, 0x6A,
0xD1, 0xAE, 0xDC, 0x5A, 0xD6, 0xD9, 0x66, 0x0B, 0xDF, 0x40,
0xF0, 0x3B, 0xD8, 0x37, 0x53, 0xAE, 0xBC, 0xA9, 0xC5, 0x9E,
0xBB, 0xDE, 0x7F, 0xCF, 0xB2, 0x47, 0xE9, 0xFF, 0xB5, 0x30,
0x1C, 0xF2, 0xBD, 0xBD, 0x8A, 0xC2, 0xBA, 0xCA, 0x30, 0x93,
0xB3, 0x53, 0xA6, 0xA3, 0xB4, 0x24, 0x05, 0x36, 0xD0, 0xBA,
0x93, 0x06, 0xD7, 0xCD, 0x29, 0x57, 0xDE, 0x54, 0xBF, 0x67,
0xD9, 0x23, 0x2E, 0x7A, 0x66, 0xB3, 0xB8, 0x4A, 0x61, 0xC4,
0x02, 0x1B, 0x68, 0x5D, 0x94, 0x2B, 0x6F, 0x2A, 0x37, 0xBE,
0x0B, 0xB4, 0xA1, 0x8E, 0x0C, 0xC3, 0x1B, 0xDF, 0x05, 0x5A,
0x8D, 0xEF, 0x02, 0x2D
};

unsigned char compare[] = {
          0x5E, 0x60, 0xF6, 0xC0, 0x0A, 0x6E, 0xB1, 0x00, 0xD2, 0xA2,
          0x19, 0x33, 0xB7, 0xB7, 0xCA, 0x57, 0x9C, 0x6D, 0x64, 0x9A,
          0x26, 0x27, 0xD8, 0xBD, 0x91, 0xFB, 0x38, 0xD8, 0xB3, 0x0B,
          0xE1, 0x8D, 0xAD, 0x0D, 0x6B, 0x17, 0xEF, 0xDE, 0x5F, 0x68,
          0xB1, 0xF7, 0x1F, 0x2C, 0x96, 0x42, 0x44, 0x6C, 0x90, 0xFE,
          0x5C, 0xA1, 0x21, 0x87, 0xCD, 0x20, 0xE8, 0x7C, 0x96, 0x62,
          0xFD, 0x41, 0x16, 0x2C, 0x9A, 0x0F, 0x2D, 0x57, 0x2C, 0xDC,
          0x52, 0xAE, 0xCF, 0x7D, 0x49, 0x50, 0x4A, 0xBF, 0x6A, 0xFF
};

int main() {

      DWORD* dword_404A38 = (DWORD*)byte_404A38;
      DWORD* dwcompare = (DWORD*)compare;
      char flag = {0};

      for (int k = 0; k < 40; k+=2) {
                for (int i = 32; i < 128; i++)
                {
                        for (int j = 32; j < 128; j++)
                        {
                              flag = i;
                              flag = j;

                              DWORD dword_404E50 = 0xFFFFFFFF;
                              DWORD dword_404E4C = (flag ^ dword_404E50) & 0xFF;
                              dword_404E50 >>= 8;
                              dword_404E50 ^= dword_404A38;

                              dword_404E4C = (flag ^ dword_404E50) & 0Xff;
                              dword_404E50 >>= 8;
                              dword_404E50 ^= dword_404A38;
                              dword_404E50 = 0xFFFFFFFF - dword_404E50;


                              if (dword_404E50 == dwcompare)
                              {
                                        printf("%c%c", i, j);
                              }
                        }
                }
      }

      return 0;
}
```

flag为 `NCTF{rLdE57TG0iHA39qUnFZp6LeJyYEBcxMNL7}`

## 狗狗的秘密



前面是47进制,直接用C语言实现上面那个框中的算法,调试,输几个数试试就能试出来了

先写脚本从下往上把47进制后的flag弄出来,发现有很多种情况

```python
byte_405018 = [
    0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0x65, 0xA2, 0x9B,
    0xF4, 0xDF, 0xAC, 0x7C, 0xA1, 0xC6, 0x16, 0xD0, 0x0F, 0xDD,
    0xDC, 0x73, 0xC5, 0x6B, 0xD1, 0x96, 0x47, 0xC2, 0x26, 0x67,
    0x4E, 0x41, 0x82, 0x20, 0x56, 0x9A, 0x6E, 0x33, 0x92, 0x88,
    0x29, 0xB5, 0xB4, 0x71, 0xA9, 0xCE, 0xC3, 0x34, 0x50, 0x59,
    0xBF, 0x2D, 0x57, 0x22, 0xA6, 0x30, 0x04, 0xB2, 0xCD, 0x36,
    0xD5, 0x68, 0x4D, 0x5B, 0x45, 0x9E, 0x85, 0xCF, 0x9D, 0xCC,
    0x61, 0x78, 0x32, 0x76, 0x31, 0xE3, 0x80, 0xAD, 0x39, 0x4F,
    0xFA, 0x72, 0x83, 0x4C, 0x86, 0x60, 0xB7, 0xD7, 0x63, 0x0C,
    0x44, 0x35, 0xB3, 0x7B, 0x19, 0xD4, 0x69, 0x08, 0x0B, 0x1F,
    0x3D, 0x11, 0x79, 0xD3, 0xEE, 0x93, 0x42, 0xDE, 0x23, 0x3B,
    0x5D, 0x8D, 0xA5, 0x77, 0x5F, 0x58, 0xDB, 0x97, 0xF6, 0x7A,
    0x18, 0x52, 0x15, 0x74, 0x25, 0x62, 0x2C, 0x05, 0xE8, 0x0D,
    0x98, 0x2A, 0x43, 0xE2, 0xEF, 0x48, 0x87, 0x49, 0x1C, 0xCA,
    0x2B, 0xA7, 0x8A, 0x09, 0x81, 0xE7, 0x53, 0xAA, 0xFF, 0x6F,
    0x8E, 0x91, 0xF1, 0xF0, 0xA4, 0x46, 0x3A, 0x7D, 0x54, 0xEB,
    0x2F, 0xC1, 0xC0, 0x0E, 0xBD, 0xE1, 0x6C, 0x64, 0xBE, 0xE4,
    0x02, 0x3C, 0x5A, 0xA8, 0x9F, 0x37, 0xAF, 0xA0, 0x13, 0xED,
    0x1B, 0xEC, 0x8B, 0x3E, 0x7E, 0x27, 0x99, 0x75, 0xAB, 0xFE,
    0xD9, 0x3F, 0xF3, 0xEA, 0x70, 0xF7, 0x95, 0xBA, 0x1D, 0x40,
    0xB0, 0xF9, 0xE5, 0xF8, 0x06, 0xBC, 0xB6, 0x03, 0xC9, 0x10,
    0x9C, 0x2E, 0x89, 0x5C, 0x7F, 0xB1, 0x1A, 0xD6, 0x90, 0xAE,
    0xDA, 0xE6, 0x5E, 0xB9, 0x84, 0xE9, 0x55, 0xBB, 0xC7, 0x0A,
    0xE0, 0x66, 0xF2, 0xD8, 0xCB, 0x00, 0x12, 0xB8, 0x17, 0x94,
    0x6A, 0x4A, 0x01, 0x24, 0x14, 0x51, 0x07, 0x65, 0x21, 0xC8,
    0x38, 0xFD, 0x8F, 0xC4, 0xF5, 0xFC
]
byte_405118 = [
    0xA7, 0x1C, 0x7E, 0xAF, 0xD9, 0xC2, 0xC0, 0xBE, 0x1F, 0x45,
    0x9A, 0x85, 0x26, 0xE3, 0x87, 0xC3, 0x21, 0xE0, 0x95, 0x10,
    0x71, 0x70, 0x02, 0x75, 0x35, 0xA5, 0x1D, 0x0D, 0x2F, 0xEE,
    0x25, 0x7B, 0xB5, 0x82, 0x66, 0x8D, 0xDB, 0x53, 0x3A, 0x29,
    0xD4, 0x43, 0x99, 0x97, 0x9D, 0xE8, 0x49, 0x00]

byte_v17 = [0x52, 0xC3, 0x1A, 0xE0, 0x16, 0x5D, 0x5E, 0xE2, 0x67, 0x1F,
            0x1F, 0x06, 0x06, 0x1F, 0x17, 0x06, 0x0F, 0xF9, 0x06, 0x67,
            0x58, 0xB2, 0xE2, 0x8C, 0x0F, 0x2A, 0x06, 0x89, 0xCF, 0x2A,
            0x06, 0x1F, 0x98, 0x1A, 0x3E, 0x17, 0x67, 0x1F, 0xF7, 0x3A,
            0x44, 0xC3, 0x16, 0x33, 0x69, 0x1A, 0x75, 0x16, 0x3E, 0x17,
            0xD5, 0x69, 0x7A, 0x1B, 0x44, 0x44, 0x3E, 0x67, 0xF7, 0x89,
            0x67]
v11 = []


for v17 in byte_v17:
    for i in range(256):
      c = byte_405018 ^ i
      if c == v17:
            # print(hex(i))
            if i in byte_405118:
                print(byte_405118.index(i), end=" ")
    print("")
```

索引为

```
2   
0   
33 45
44   
30   
40   
8   
23
22 11 7
37 34
37 34
19 20 43
19 20 43
37 34
24
19 20 43
31 4
29
19 20 43
22 11 7
13
5
23
41
31 4
35
19 20 43
9
14
35
19 20 43
37 34
3
33 45
10
24
22 11 7
37 34
38
1
25
0
30
6
42
33 45
36
30
10
24
21
42
26
28
25
25
10
22 11 7
38
9
22 11 7
```

然后写脚本,从一头开始试,因为如果一头稍微一改,打印的字符串前面变化很大的话,说明改对了,因为数据高位一改,整个数字变化才大,然后`long_to_bytes`后对应的字符也变换很大了,如果从低位改,数据变化不大,`long_to_bytes`后头部的字符变化也不大了, 就这样一点点改,flag就一点点的显示出来了

可能描述的有点抽象,举个例子就很容易懂了



对应的解密脚本

```python
from Crypto.Util.number import *
compare = [2,
         0,
         45,
         44,
         30,
         40,
         8,
         23,
         11,
         37,
         34,
         43,
         43,
         37,
         24,
         19,
         4,
         29,
         19,          # 19 20 43
         22,            # 22 11 7
         13,
         5,
         23,
         41,
         4,         # 314
         35,
         20,          # 19 20 43
         9,
         14,
         35,
         43,          # 19 20 43
         37,          # 37 34
         3,
         33,          # 33 45
         10,
         24,
         22,         # 22 11 7
         37,      # 37 34
         38,
         1,
         25,
         0,
         30,
         6,
         42,
         45,          # 33 45
         36,
         30,
         10,
         24,
         21,
         42,
         26,
         28,
         25,
         25,
         10,
         7,
         38,
         9,
         11]

sum = 0
re_compare = compare[::-1]
for i in range(len(compare)):
    tmp = re_compare * pow(47, i)
    sum += tmp

print(long_to_bytes(sum))
# NCTF{ADF0E239-D911-3781-7E40-A575A19E5835}
```

flag为 `NCTF{ADF0E239-D911-3781-7E40-A575A19E5835}`

## easy_mobile

JEB打开分析



发现check_flag 的算法在对应的so文件里



IDA打开找到` Java_com_example_rectf_MainActivity_checkflag` 函数



哇塞,看这优美的图形,是OLLVM,从网上找来各种脚本平坦化,要么是失败,要么是去了还不如不去容易看

>我一共试了这2个脚本
>
>https://github.com/cq674350529/deflat (成功去除,基址设置为0X400000,比如check_flag是0X7900,然后 就运行
>
>`python deflat.py -f libnative-lib.so --addr 0x407900`,但是去了后我感觉更难看了)
>
>https://github.com/pcy190/deobfuscator (这个我去除失败,可能是qiling版本的问题)

好吧,直接硬刚OLLVM,真机调试

>如何搭建真机调试环境可以参考我写的这篇文章
>
>https://zzzzsky.com/2021/11/29/IDA%E7%9C%9F%E6%9C%BA%E8%B0%83%E8%AF%95%E5%AE%89%E5%8D%93so%E6%96%87%E4%BB%B6/



在下面每个框中第一条指令下断点,尤其是这种大的块肯定是有用的,先审视一下这种大的块





发现在这个位置调用了strlen,然后与0X18对比 猜测是验证flag的长度,继续审视其他块



在这个位置发现了一些类似密钥的字符串,还调用了一个函数,进入这个` sub_7D30F1E260` 函数



根据`<< 4` ` >>5` `0X12345678`等特征,发现这是一种个TEA算法,delta改为了`0X12345678`

继续审视,在这个位置发现了一些明文


F5,发现这里还有一些加减乘除的一些操作



开始调试,直接在上面对应的位置下断点,flag先输入12345试试,一点点来到strlen的位置,发现果然是验证flag的长度



继续F9,发现即没有到达加减乘除那个块,也没有到达TEA算法那里就显示NO了,我么输入flag为 123456789012345678901234



好,程序断在了加减乘除那个块那里,直接一点点单步调试



在mul之前停下,观察寄存器,发现X1指向的是最后8个字符,然后来到X16寄存器指向的内存位置,稍微整理整理



发现系统初始化了16个字符`PRST0123789: "#$` ,然后下面紧跟着flag 的前16位,猜测flag是分开验证的16 + 8

跳过乘法,再看内存



最终调试到memcpy的位置



`dword_7CD3B3E14C` 处的数据为



而刚才`0007FD020C630`处的数据已经变为了



于是猜测是flag的前16位根据`PRST0123789: "#$` 加减乘除后 与`dword_7CD3B3E14C`进行对比,然后flag 的后8位是那个tea算法

这里一点点调试,发现

```
['3', '4', '5', '6'] * [' ', '"', '#', '$'] + ['7', '8', '9', ':'] =
['9', '0', '1', '2'] * ['0', '1', '2', '3'] + ['P', 'R', 'S', 'T'] =
['5', '6', '7', '8'] * [' ', '"', '#', '$'] + ['7', '8', '9', ':'] =
['1', '2', '3', '4'] * [' ', '"', '#', '$'] + ['7', '8', '9', ':'] =
```

写脚本解密得到flag的前16个字符

```python
a = [3287, 1688, 3452, 1786,   
   3255, 1994, 1947, 2002,   
   2384, 2777, 2783, 5286,   
   3319, 1824, 1842, 2038]   


mul1 =

mul2 =

add1 =

add2 =

flag = []

flag1 = [(a[:4]-add2)/mul2 for i in range(4)]
flag2 = [(a-add2)/mul2 for i in range(4)]
flag3 = [(a-add1)/mul1 for i in range(4)]
flag4 = [(a-add2)/mul2 for i in range(4)]

print(flag1)
print(flag2)
print(flag3)
print(flag4)

flag = flag1 + flag2 + flag3 + flag4
flag =
print("".join(flag))
#
#
#
#
# e0a0d966076ff437
```

然后flag输入`e0a0d966076ff437ABCD1234`重新调试,果然程序断在了TEA算法的位置





发现果然是对flag的后8个字符进行TEA加密,直接运行到加密完成



然后进入汇编界面单步调试,注意CMP指令



可以发现V0加密后应改为`0XC65AEDA`,这里修改X13的值为`0XC65AEDA`,使其验证通过,然后再单步



运行到这个位置,发现V1加密后的数据为 `0xADBF8DB1`

直接写脚本解密

```cpp
#include <stdio.h>
#include <stdint.h>

//加密函数
void encrypt(uint32_t* v, uint32_t* k) {
      uint32_t v0 = v, v1 = v, sum = 0, i;         
      uint32_t delta = 0x12345678;                  
      uint32_t k0 = k, k1 = k, k2 = k, k3 = k;
      for (i = 0; i < 32; i++) {                     
                sum += delta;
                v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
                v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
      }                                             
      v = v0; v = v1;
}
//解密函数
void decrypt(uint32_t* v, uint32_t* k) {
      uint32_t delta = 0x12345678;
      uint32_t v0 = v, v1 = v, sum = delta * 32, i;
      uint32_t k0 = k, k1 = k, k2 = k, k3 = k;
      for (i = 0; i < 32; i++) {                        
                v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
                v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
                sum -= delta;
      }                                          
      v = v0; v = v1;
}


unsigned char byte_key[] =
{
0x71, 0x69, 0x68, 0x61, 0x68, 0x61, 0x69, 0x6E, 0x69, 0x6E,
0x61, 0x6E, 0x61, 0x6E, 0x61, 0x6D
};

//char enc[] = { 'A', 'B', 'C', 'D', '1', '2', '3', '4' };
int main()
{
      //uint32_t* v = (uint32_t*)enc;
      uint32_t v = { 0x000000000C65AEDA , 0x00000000ADBF8DB1 };
      uint32_t* k = (uint32_t*)byte_key;
      decrypt(v, k);
      printf("解密后的数据:%u %u\n", v, v);
      return 0;
}
```



后8位是 `58af2715`

拼凑得到 flag `e0a0d966076ff43758af2715`



验证成功

----

纪念AK RE, 拿了3一血,美滋滋



继续加油~~

# 题目附件

链接:https://pan.baidu.com/s/1FaBD6_FDjKLziKpVqvGe-Q
提取码:ptjq

chenjingyes 发表于 2021-12-8 22:40

问一下楼主解那道ollvm混淆的题目,动态调试用的是deflate去除olivm混淆后的文件,还是原版文件动态调试硬杠ollvm??   


另外,怎么不考虑用ida trace来跑出程序运行流程??

zsky 发表于 2021-12-9 09:08

chenjingyes 发表于 2021-12-8 22:40
问一下楼主解那道ollvm混淆的题目,动态调试用的是deflate去除olivm混淆后的文件,还是原版文件动态调试硬 ...

醒刚的ollvm

vethenc 发表于 2021-11-29 15:43

好详细,感谢大佬分享

2733369 发表于 2021-11-29 17:34

感谢大佬分享

hjw01 发表于 2021-11-29 21:42

解密过程吗,不是很明白

zhouyaxv 发表于 2021-11-29 23:20

感谢大佬分享,太谢谢你了

xytwlh 发表于 2021-11-30 00:20

看看怎么样

douluodalu 发表于 2021-11-30 04:55

感谢大佬分享,太谢谢你了

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


感谢大佬分享,太谢谢你了

lxptyc 发表于 2021-11-30 08:07

感谢,试试看哦

wh4am1 发表于 2021-11-30 08:27

做题的时候对程序逻辑还是太不敏感了,Base64换表那个一时间没看出来{:1_909:}
页: [1] 2 3 4
查看完整版本: 2021NCTF RE_WP