NCTF2021_RE_WP
Hello せかい
记事本都能做的题.IDA打开直接看到flag
flag为 NCTF{We1come_2_Reverse_Engineering}
Shadowbringer
base64换了2次表,调试起来找到表,逆回去即可
写脚本解密
import base64
flag = "U>F2UsQXN`5sXMELT=:7M_2<X]^1ThaWF0=KM?9IUhAsTM5:T==_Ns&<Vhb!"
std_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
my_table = '#$%&\x27()*+,-.s0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[h]^_`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, [ecx+4049F8h] # flag[0]
mov byte ptr ds:dword_404E4C, dl
movzx eax, byte ptr ds:dword_404E4C
xor eax, ds:dword_404E50 dword_404E4C = (flag[0] ^ 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[dword_404E4C * 4]
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[eax*4]
mov ds:dword_404E50, ecx
mov edx, ds:I
mov al, [edx+4049F9h] # flag[1]
mov byte ptr ds:dword_404E4C, al
movzx ecx, byte ptr ds:dword_404E4C
xor ecx, ds:dword_404E50 404E4C = flag[1] ^ 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[eax*4] dword_404E50 ^= dword_404A38[dword_404E4C * 4]
mov ds:dword_404E50, ecx
mov edx, ds:dword_404E50
xor edx, 0FFFFFFFFh
mov ds:dword_404E50, edx
分析完毕,把程序中加密后的flag提取出来直接爆破
#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[40] = {0};
for (int k = 0; k < 40; k+=2) {
for (int i = 32; i < 128; i++)
{
for (int j = 32; j < 128; j++)
{
flag[0] = i;
flag[1] = j;
DWORD dword_404E50 = 0xFFFFFFFF;
DWORD dword_404E4C = (flag[0] ^ dword_404E50) & 0xFF;
dword_404E50 >>= 8;
dword_404E50 ^= dword_404A38[dword_404E4C];
dword_404E4C = (flag[1] ^ dword_404E50) & 0Xff;
dword_404E50 >>= 8;
dword_404E50 ^= dword_404A38[dword_404E4C];
dword_404E50 = 0xFFFFFFFF - dword_404E50;
if (dword_404E50 == dwcompare[k/2])
{
printf("%c%c", i, j);
}
}
}
}
return 0;
}
flag为 NCTF{rLdE57TG0iHA39qUnFZp6LeJyYEBcxMNL7}
狗狗的秘密
前面是47进制,直接用C语言实现上面那个框中的算法,调试,输几个数试试就能试出来了
先写脚本从下往上把47进制后的flag弄出来,发现有很多种情况
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] ^ 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就一点点的显示出来了
可能描述的有点抽象,举个例子就很容易懂了
对应的解密脚本
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, # 31 4
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[i] * 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', ':'] = [1687, 1824, 1912, 2002]
['9', '0', '1', '2'] * ['0', '1', '2', '3'] + ['P', 'R', 'S', 'T'] = [2816, 2434, 2533, 2634]
['5', '6', '7', '8'] * [' ', '"', '#', '$'] + ['7', '8', '9', ':'] = [1751, 1892, 1982, 2074]
['1', '2', '3', '4'] * [' ', '"', '#', '$'] + ['7', '8', '9', ':'] = [1623, 1756, 1842, 1930]
写脚本解密得到flag的前16个字符
a = [3287, 1688, 3452, 1786,
3255, 1994, 1947, 2002,
2384, 2777, 2783, 5286,
3319, 1824, 1842, 2038]
mul1 = [ord(i) for i in "0123"]
mul2 = [ord(i) for i in ' "#$']
add1 = [ord(i) for i in "PRST"]
add2 = [ord(i) for i in "789:"]
flag = []
flag1 = [(a[:4][i]-add2[i])/mul2[i] for i in range(4)]
flag2 = [(a[4:8][i]-add2[i])/mul2[i] for i in range(4)]
flag3 = [(a[8:12][i]-add1[i])/mul1[i] for i in range(4)]
flag4 = [(a[12:][i]-add2[i])/mul2[i] for i in range(4)]
print(flag1)
print(flag2)
print(flag3)
print(flag4)
flag = flag1 + flag2 + flag3 + flag4
flag = [chr(int(i)) for i in flag]
print("".join(flag))
# [101.0, 48.0, 97.0, 48.0]
# [100.0, 57.0, 54.0, 54.0]
# [48.0, 55.0, 54.0, 102.0]
# [102.0, 52.0, 51.0, 55.0]
# e0a0d966076ff437
然后flag输入e0a0d966076ff437ABCD1234
重新调试,果然程序断在了TEA算法的位置
发现果然是对flag的后8个字符进行TEA加密,直接运行到加密完成
然后进入汇编界面单步调试,注意CMP指令
可以发现V0加密后应改为0XC65AEDA
, 这里修改X13的值为0XC65AEDA
,使其验证通过,然后再单步
运行到这个位置,发现V1加密后的数据为 0xADBF8DB1
直接写脚本解密
#include <stdio.h>
#include <stdint.h>
//加密函数
void encrypt(uint32_t* v, uint32_t* k) {
uint32_t v0 = v[0], v1 = v[1], sum = 0, i;
uint32_t delta = 0x12345678;
uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
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[0] = v0; v[1] = v1;
}
//解密函数
void decrypt(uint32_t* v, uint32_t* k) {
uint32_t delta = 0x12345678;
uint32_t v0 = v[0], v1 = v[1], sum = delta * 32, i;
uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
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[0] = v0; v[1] = 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[2] = { 0x000000000C65AEDA , 0x00000000ADBF8DB1 };
uint32_t* k = (uint32_t*)byte_key;
decrypt(v, k);
printf("解密后的数据:%u %u\n", v[0], v[1]);
return 0;
}
后8位是 58af2715
拼凑得到 flag e0a0d966076ff43758af2715
验证成功
纪念AK RE, 拿了3一血,美滋滋
继续加油~~
题目附件
链接:https://pan.baidu.com/s/1FaBD6_FDjKLziKpVqvGe-Q
提取码:ptjq