题目链接:http://www.shiyanbar.com/ctf/738
本站提供该二进制程序下载:challenge
sha1sum: 69c762ec8e80cac7766b783d2d3a652e7cedeb5b
md5sum: bc899372bdfe85b7272ea9b8fe5b5643
我做本题的基本思路就是先根据 sub_8048519 函数制作一张可打印字符的对照表,然后根据后面.text:080488BA 地址的汇编代码推断,加密后的第一个字符为0x62,也就是‘b’,再根据.text:08048880 反推出加密后的密文为 bargjbgursyntlb ,在利用对照表即可还原明文。
获取密文的代码:
#include <stdio.h>
int main()
{
int dword_8048980[] = {0xFFFFFFFF, 0x11, 0xFFFFFFF5, 3, 0xFFFFFFF8, 5, 0xE,
0xFFFFFFFD, 1, 6, 0xFFFFFFF5, 6, 0xFFFFFFF8, 0xFFFFFFF6,
0};
char temp = 'b';
printf("key: %c", temp);
for (int i = 0; i < 14; i++)
{
temp = temp + dword_8048980[i];
printf("%c", temp);
}
puts("");
}
获取明文的代码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int dword_8049CA4;
char sub_80484FB(char a1)
{
++dword_8049CA4;
++dword_8049CA4;
return a1;
}
int sub_8048519(char a1)
{
unsigned char v1; // al
signed int v2; // edi
int v3; // ebx
signed int v4; // edi
int v5; // ebx
signed int v6; // edi
int v7; // ebx
signed int v8; // edi
char v9; // cl
int v10; // edx
signed int v11; // edi
int v12; // edx
int v13; // edx
signed int v14; // edi
signed int v15; // ecx
int v16; // edx
signed int v17; // ecx
int v18; // edx
signed int v19; // ecx
int v20; // edx
signed int v21; // ebx
int v22; // edx
signed int v23; // ebx
int v24; // edx
signed int v25; // ebx
int v26; // edx
signed int v27; // ebx
int v28; // edx
signed int v29; // ecx
int v30; // edx
signed int v31; // ecx
int v32; // edx
signed int v33; // ecx
signed int v34; // esi
int v35; // edx
char v36; // cl
int v37; // edx
signed int v38; // esi
int v39; // edx
int v40; // edx
signed int v41; // edi
int v42; // edx
signed int v43; // edi
int v44; // edx
signed int v45; // ecx
signed int v46; // esi
int v47; // edx
int v48; // esi
int v49; // zf
signed int v50; // eax
char v52; // [esp+4h] [ebp-10h]
v1 = sub_80484FB(a1);
v2 = 19;
if ((v1 & 0x3F) != 38)
v2 = 0;
v3 = v2 | (v1 << 8) | 9 * ((v1 & 0x5F) == 86);
v4 = 71;
if ((v1 & 0x77) != 116)
v4 = 0;
v5 = v4 | v3;
v6 = 84;
if ((v1 & 0x3F) != 39)
v6 = 0;
v7 = v6 | v5;
v8 = 48;
if ((v1 & 0x4F) != 4)
v8 = 0;
v9 = v1 & 0x1F;
v10 = 3 * ((v1 & 0x57) == 80) | 8 * (v9 == 1) | v7 | v8 | 2 * (v9 == 15) | 2 * ((v1 & 0x5B) == 83);
v11 = 114;
v52 = ~v1;
v12 = 8 * (v9 == 2) | 8 * (v9 == 11) | v10 | 2 * ((v1 & 0x57) == 66) | 8 * ((v1 & 0x2E) == 44);
if ((v1 & 0x37) != 37)
v11 = 0;
v13 = v11 | v12;
v14 = 16;
v15 = 0;
if ((v1 & 0x1C) == 8)
v15 = 16;
v16 = ((~v1 & 0x78u) < 1 ? 0x48 : 0) | v15 | v13;
v17 = 64;
if ((v1 & 0x1D) != 16)
v17 = 0;
v18 = v17 | v16;
v19 = 0;
if ((v1 & 0xF) == 11)
v19 = 16;
v20 = 4 * ((v1 & 0x55) == 64) | v19 | v18;
v21 = 72;
if ((v1 & 0x4B) != 1)
v21 = 0;
v22 = v21 | v20;
v23 = 24;
if ((v1 & 0x47) != 1)
v23 = 0;
v24 = v23 | v22;
v25 = 96;
if ((v1 & 0x2B) != 34)
v25 = 0;
v26 = ((v52 & 0x55u) < 1 ? 0x48 : 0) | v25 | v24;
v27 = 0;
if ((v1 & 0x31) == 16)
v27 = 16;
v28 = v27 | v26;
v29 = 0;
if ((v1 & 0x55) == 81)
v29 = 68;
v30 = v29 | v28;
v31 = 0;
if ((v1 & 0xE) == 8)
v31 = 32;
v32 = v31 | v30;
v33 = 97;
if ((v1 & 0x59) != 72)
v33 = 0;
v34 = 81;
v35 = v33 | v32;
v36 = v1 & 0x17;
if ((v1 & 0x17) != 4)
v34 = 0;
v37 = v34 | v35;
v38 = 37;
if ((v1 & 0x47) != 66)
v38 = 0;
v39 = v37 | v38 | 8 * ((v1 & 0x43) == 2);
if ((v1 & 0x46) != 2)
v14 = 0;
v40 = v14 | v39;
v41 = 80;
if (v36 != 3)
v41 = 0;
v42 = v41 | v40;
v43 = 70;
if (v36 != 1)
v43 = 0;
v44 = v43 | v42;
v45 = 40;
if ((v1 & 0x70) != 64)
v45 = 0;
v46 = 0;
v47 = 4 * ((v1 & 0x41) == 1) | ((v52 & 0xBu) < 1 ? 0x60 : 0) | v45 | v44;
if ((v1 & 0x48) == 64)
v46 = 32;
v48 = v47 | v46;
v49 = (v1 & 0x21) == 1;
v50 = 0;
if (v49)
v50 = 68;
return v48 | v50;
}
// 找到 字符 find 在字符串数组 s 中的位置
int find_position(char *s, int s_length, char find)
{
for (int i = 0; i < s_length; i++)
{
if (s[i] == find)
{
return i;
}
}
printf("Error\n");
return -1;
}
int main()
{
char printable[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c";
char table[1000] = {0}; // 对照表
int length = strlen(printable);
for (int i = 0; i < length; i++)
{
char temp = sub_8048519(printable[i]);
printf("%c -> %c -> 0x%02X\n", printable[i], temp, (unsigned char)temp);
table[i] = temp;
}
puts("");
printf("flag{");
// 由上面破解得出来的。
char *key = "bargjbgursyntlb";
for (int i = 0; i < 15; i++)
{
int po = find_position(table, length, key[i]);
printf("%c", printable[po]);
}
puts("}");
return 0;
}