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 问一下楼主解那道ollvm混淆的题目,动态调试用的是deflate去除olivm混淆后的文件,还是原版文件动态调试硬杠ollvm??
另外,怎么不考虑用ida trace来跑出程序运行流程?? chenjingyes 发表于 2021-12-8 22:40
问一下楼主解那道ollvm混淆的题目,动态调试用的是deflate去除olivm混淆后的文件,还是原版文件动态调试硬 ...
醒刚的ollvm 好详细,感谢大佬分享 感谢大佬分享 解密过程吗,不是很明白 感谢大佬分享,太谢谢你了 看看怎么样 感谢大佬分享,太谢谢你了
感谢大佬分享,太谢谢你了 感谢,试试看哦 做题的时候对程序逻辑还是太不敏感了,Base64换表那个一时间没看出来{:1_909:}