首页
社区
课程
招聘
[原创]2022 春季KCTF 第二题 末日邀请 解题过程
发表于: 2022-5-12 22:28 11127

[原创]2022 春季KCTF 第二题 末日邀请 解题过程

2022-5-12 22:28
11127

整体流程

#include <iostream>

int sub_4010B7(unsigned char *str, int len)
{
char c; // dl
char tmp; // al

}

void print_hex(char* str, int len)
{
for (int i = 0; i < len; i++)
{
printf("%.2x ", str[i]);
}

}

/// 原始str
// unsigned char first(unsigned char str, int len)
// {
// unsigned char tmp = 0;
// for (int i = 0; i < len; i++)
// {
// tmp ^= str[i];
// for (int j = 0; j < 8; j++)
// {
// char v9 = 2
tmp;
// tmp = v9 >= 0 ? v9 : (v9 ^ 7);
// }
// }
// return tmp;
// }

// void second(char v, int out[200])
// {
// unsigned char v15 = v;
// for (int i = 1; i < 200; i++)
// {
// if ((v15 & 1) != 0)
// v15 = 3 * v15 + 1;
// else
// v15 >>= 1;
// out[i] = v15;
// printf("%.2x ", v15);

// if ((i + 1) % 0x10 == 0)
// printf("\r\n");
// }

// printf("\r\n");
// }

int calc_pre(unsigned char* ss, int len)
{
unsigned char c = first(ss, len);
printf(">>> c: %x\n", c);
int sz[200] = { 0 };
second(c, sz);
return sz[198] | sz[197] | sz[196];
}

void init_box()
{

}

// int main()
// {
// // char sz[] = "1234567890_ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// // sub_4010B7(sz, sizeof(sz));
// // print_hex(sz, sizeof(sz));

// unsigned char x[] = "???KCTF???";
// int v = calc_pre(x, 4);
// printf("%lx\n", v);
// sub_4010B7(x, sizeof(x));

// if ((x[0] ^ x[1] ^ x[2]) == v)
// {
// printf("pass!\n");
// }
// else {
// printf("failed!\n");
// }
// return 0;
// }

char first(unsigned char str, int len)
{
char tmp = 0;
for (int i = 0; i < len; i++)
{
tmp ^= str[i];
for (int j = 0; j < 8; j++)
{
char v9 = 2
tmp;
tmp = v9 >= 0 ? v9 : (v9 ^ 7);
}
}
return tmp;
}

void second(char v, int out[200])
{
unsigned char v15 = v;
for (int i = 1; i < 200; i++)
{
if ((v15 & 1) != 0)
v15 = 3 * v15 + 1;
else
v15 >>= 1;
out[i] = v15;
printf("%.2x ", v15);

}

unsigned char to_hex(unsigned char a)
{
return (a >= 0x3a) ? (a - 0x37) : (a - 0x30);
}

int sub_4010B7(unsigned char* str, int len)
{
for (int i = 0; i < len; ++i)
{
str[i] = to_hex(str[i]);
}
return 0;
}

int ctf_1(unsigned char ctf, int len)
{
int tmp = 0;
int tk = 1;
for (int i = 0; i < len; i++)
{
int v23 = ctf[i] + tmp
10;
int v24 = v23 - 0x37373737;
if (v23 <= 0x4b435445)
v24 = v23;
tmp = v24;

}

int __cdecl main(int argc, const char argv, const char envp)
{
/// 取字符串
sub_40103A("%s", (char)str);
/// 异或处理
int len = strlen(str);
char a = first(str, len);
/// 初始化sbox, 直接拷贝即可
sub_40106C();
/// 哈希计算
int v = -1;
for (int i = 0; i < len; i++)
{
v = ((unsigned int)sbox)[(unsigned char)(v ^ s[i])] ^ (v >> 8);
}
/// must be 0xf52e0765
v ~= v;
/// 字符转换hex?
sub_4010B7(str, len);
/// 第一关,其值为0x07
char tbox[200] = { 0 };
second(a, tbox);
/// 观察tbox的结果, tbox[198] | tbox[197] | tbpx[196] 为 0x07
/// 注意:有符号的情况下不能通过第一关,可以修改 0x12A7 edi==0x07, 后面会用到
char k = str[0] ^ str[1] ^ str[2];
if (k != 0x07) failed(-1);
/// 第二关 {3-5} -> 'KCTF'
if (str[3] != 0x14 || str[4] != 0xc || str[5] != 0x1d || str[6] != 0x0f)
failed(-1);
/// 第三关 {未解}
/// 0x13E4 -> nop
6
ctf = &str[7];
if (ctf_1(ctf, strlen(ctf)!=0)
failed(-1);
/// 第四关
/// 1 - 排序 从低到高
sort(ctf, strlen(ctf));
/// 2 - 比较字符串
char cmp[] = '1234567890_A...';
sub4010B7(cmp, 10);
/// 3 - 比较ctf
if (strncmp(ctf, cmp, strlen(ctf)))
failed(-1);
/// 第五关
if (v!= 0xF52E0765)
failed(-1);
return ok();
}
分析
分析完代码后,可以通过第二关得到字符串为 ???KCTF?????????? 分析第四关,可以知道后面接的CTF字符串肯定是 1234567890
等,因为会排序,那么可能是以下几种 1, 12, 123, 1234, 12345, 123456, 1234567, 12345678, 123456789, 1234567890_ 通过动态调试可以知道如果是1234[\x0\x0]这种会被第三关干扰从而生成别的字符串,不符合逻辑,那么大胆猜测就是1-9的字符串 通过第一关可以快速遍历得到所有 前三个字符 如下:

unsigned char st = 0x20;
unsigned char se = 0x7f;
for (unsigned char x = st; x <= se; x++)
{
for (unsigned char y = st; y <= se; y++)
{
for (unsigned char z = st; z <= se; z++)
{
if ((to_hex(x) ^ to_hex(y) ^ to_hex(z)) == 0x07)
{
printf("%c%c%c\n", x, y, z);
}
}
}
}
然后我就目测了一下,感觉那个 Hi[ 很像, 然后就走入了误区 合在一起是 Hi[KCTF]1-8, 然后就越走越远了,最后才发现可能是其他的字符+KCTF+1-9

破解测试
写下如下代码,进行尝试性破解

#include <iostream>

#include <algorithm>

unsigned char st = 0x20;
unsigned char se = 0x7f;
unsigned char buf[9] = { 0 };
memcpy(&buf[3], "KCTF", 4);
for (unsigned char x = st; x <= se; x++)
{
for (unsigned char y = st; y <= se; y++)
{
for (unsigned char z = st; z <= se; z++)
{
if ((to_hex(x) ^ to_hex(y) ^ to_hex(z)) == 0x07)
{
buf[0] = x;
buf[1] = y;
buf[2] = z;
int v = get_ctf((char)buf, 7);
check(v, (char
)buf);
}
}
}
}

int get_ctf(char s, int len)
{
int v = -1;
for (int i = 0; i < len; i++)
{
v = ((unsigned int
)sbox)[(unsigned char)(v ^ s[i])] ^ (v >> 8);
}
return v;
}
void check(int v, char s)
{
char arr[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};
char arr2[sizeof(arr)] = { 0 };
for (int i = 1; i < sizeof(arr); i++)
{
arr2[i] = 0;
memcpy(arr2, arr, i);
do {
if (check_ctf2(arr2, i, v)) {
printf("found: \n");
printf("%s\n", s);
print_hex((unsigned char
)arr2, i);
printf("%s\n", arr2);
}
} while (std::next_permutation(arr2, arr2 + i));
}
}
思路就是遍历所有三个字符符合条件的来匹配,因为实在不知道哪三个字符符合条件,包括后面的判断也没有看出来,只能盲猜所有可能,之前误判为Hi[走错了后,改进为所有可能。

进行第五关的校验,就是所有的字符串参与计算,分拆前面7个字符先初始化得到值。 然后就是1-9的排列组合,直接生成所有排列可能,然后参与计算对比得到结果,结果如下:

found:
,0+KCTF
32 37 34 38 35 33 36 31 39
274853619
found:
421KCTF
33 38 31 36 35 34 37 32 39
381654729
found:
6?9KCTF
31 38 35 37 36 34 33 32
18576432
带入到程序中, 421KCTF381654729, 验证通过。

补一个sbox表格

unsigned char sbox[1024] = {
0x00, 0x00, 0x00, 0x00, 0x96, 0x30, 0x07, 0x09, 0x2C, 0x61, 0x0E, 0x12, 0xBA, 0x51, 0x09, 0x1B,
0x19, 0xC4, 0x6D, 0xFF, 0x8F, 0xF4, 0x6A, 0xF6, 0x35, 0xA5, 0x63, 0xED, 0xA3, 0x95, 0x64, 0xE4,
0x32, 0x88, 0xDB, 0xFE, 0xA4, 0xB8, 0xDC, 0xF7, 0x1E, 0xE9, 0xD5, 0xEC, 0x88, 0xD9, 0xD2, 0xE5,
0x2B, 0x4C, 0xB6, 0x01, 0xBD, 0x7C, 0xB1, 0x08, 0x07, 0x2D, 0xB8, 0x13, 0x91, 0x1D, 0xBF, 0x1A,
0x64, 0x10, 0xB7, 0xFD, 0xF2, 0x20, 0xB0, 0xF4, 0x48, 0x71, 0xB9, 0xEF, 0xDE, 0x41, 0xBE, 0xE6,
0x7D, 0xD4, 0xDA, 0x02, 0xEB, 0xE4, 0xDD, 0x0B, 0x51, 0xB5, 0xD4, 0x10, 0xC7, 0x85, 0xD3, 0x19,
0x56, 0x98, 0x6C, 0x03, 0xC0, 0xA8, 0x6B, 0x0A, 0x7A, 0xF9, 0x62, 0x11, 0xEC, 0xC9, 0x65, 0x18,
0x4F, 0x5C, 0x01, 0xFC, 0xD9, 0x6C, 0x06, 0xF5, 0x63, 0x3D, 0x0F, 0xEE, 0xF5, 0x0D, 0x08, 0xE7,
0xC8, 0x20, 0x6E, 0xFB, 0x5E, 0x10, 0x69, 0xF2, 0xE4, 0x41, 0x60, 0xE9, 0x72, 0x71, 0x67, 0xE0,
0xD1, 0xE4, 0x03, 0x04, 0x47, 0xD4, 0x04, 0x0D, 0xFD, 0x85, 0x0D, 0x16, 0x6B, 0xB5, 0x0A, 0x1F,
0xFA, 0xA8, 0xB5, 0x05, 0x6C, 0x98, 0xB2, 0x0C, 0xD6, 0xC9, 0xBB, 0x17, 0x40, 0xF9, 0xBC, 0x1E,
0xE3, 0x6C, 0xD8, 0xFA, 0x75, 0x5C, 0xDF, 0xF3, 0xCF, 0x0D, 0xD6, 0xE8, 0x59, 0x3D, 0xD1, 0xE1,
0xAC, 0x30, 0xD9, 0x06, 0x3A, 0x00, 0xDE, 0x0F, 0x80, 0x51, 0xD7, 0x14, 0x16, 0x61, 0xD0, 0x1D,
0xB5, 0xF4, 0xB4, 0xF9, 0x23, 0xC4, 0xB3, 0xF0, 0x99, 0x95, 0xBA, 0xEB, 0x0F, 0xA5, 0xBD, 0xE2,
0x9E, 0xB8, 0x02, 0xF8, 0x08, 0x88, 0x05, 0xF1, 0xB2, 0xD9, 0x0C, 0xEA, 0x24, 0xE9, 0x0B, 0xE3,
0x87, 0x7C, 0x6F, 0x07, 0x11, 0x4C, 0x68, 0x0E, 0xAB, 0x1D, 0x61, 0x15, 0x3D, 0x2D, 0x66, 0x1C,
0x90, 0x41, 0xDC, 0xF6, 0x06, 0x71, 0xDB, 0xFF, 0xBC, 0x20, 0xD2, 0xE4, 0x2A, 0x10, 0xD5, 0xED,
0x89, 0x85, 0xB1, 0x09, 0x1F, 0xB5, 0xB6, 0x00, 0xA5, 0xE4, 0xBF, 0x1B, 0x33, 0xD4, 0xB8, 0x12,
0xA2, 0xC9, 0x07, 0x08, 0x34, 0xF9, 0x00, 0x01, 0x8E, 0xA8, 0x09, 0x1A, 0x18, 0x98, 0x0E, 0x13,
0xBB, 0x0D, 0x6A, 0xF7, 0x2D, 0x3D, 0x6D, 0xFE, 0x97, 0x6C, 0x64, 0xE5, 0x01, 0x5C, 0x63, 0xEC,
0xF4, 0x51, 0x6B, 0x0B, 0x62, 0x61, 0x6C, 0x02, 0xD8, 0x30, 0x65, 0x19, 0x4E, 0x00, 0x62, 0x10,
0xED, 0x95, 0x06, 0xF4, 0x7B, 0xA5, 0x01, 0xFD, 0xC1, 0xF4, 0x08, 0xE6, 0x57, 0xC4, 0x0F, 0xEF,
0xC6, 0xD9, 0xB0, 0xF5, 0x50, 0xE9, 0xB7, 0xFC, 0xEA, 0xB8, 0xBE, 0xE7, 0x7C, 0x88, 0xB9, 0xEE,
0xDF, 0x1D, 0xDD, 0x0A, 0x49, 0x2D, 0xDA, 0x03, 0xF3, 0x7C, 0xD3, 0x18, 0x65, 0x4C, 0xD4, 0x11,
0x58, 0x61, 0xB2, 0x0D, 0xCE, 0x51, 0xB5, 0x04, 0x74, 0x00, 0xBC, 0x1F, 0xE2, 0x30, 0xBB, 0x16,
0x41, 0xA5, 0xDF, 0xF2, 0xD7, 0x95, 0xD8, 0xFB, 0x6D, 0xC4, 0xD1, 0xE0, 0xFB, 0xF4, 0xD6, 0xE9,
0x6A, 0xE9, 0x69, 0xF3, 0xFC, 0xD9, 0x6E, 0xFA, 0x46, 0x88, 0x67, 0xE1, 0xD0, 0xB8, 0x60, 0xE8,
0x73, 0x2D, 0x04, 0x0C, 0xE5, 0x1D, 0x03, 0x05, 0x5F, 0x4C, 0x0A, 0x1E, 0xC9, 0x7C, 0x0D, 0x17,
0x3C, 0x71, 0x05, 0xF0, 0xAA, 0x41, 0x02, 0xF9, 0x10, 0x10, 0x0B, 0xE2, 0x86, 0x20, 0x0C, 0xEB,
0x25, 0xB5, 0x68, 0x0F, 0xB3, 0x85, 0x6F, 0x06, 0x09, 0xD4, 0x66, 0x1D, 0x9F, 0xE4, 0x61, 0x14,
0x0E, 0xF9, 0xDE, 0x0E, 0x98, 0xC9, 0xD9, 0x07, 0x22, 0x98, 0xD0, 0x1C, 0xB4, 0xA8, 0xD7, 0x15,
0x17, 0x3D, 0xB3, 0xF1, 0x81, 0x0D, 0xB4, 0xF8, 0x3B, 0x5C, 0xBD, 0xE3, 0xAD, 0x6C, 0xBA, 0xEA,
0x20, 0x83, 0xB8, 0xED, 0xB6, 0xB3, 0xBF, 0xE4, 0x0C, 0xE2, 0xB6, 0xFF, 0x9A, 0xD2, 0xB1, 0xF6,
0x39, 0x47, 0xD5, 0x12, 0xAF, 0x77, 0xD2, 0x1B, 0x15, 0x26, 0xDB, 0x00, 0x83, 0x16, 0xDC, 0x09,
0x12, 0x0B, 0x63, 0x13, 0x84, 0x3B, 0x64, 0x1A, 0x3E, 0x6A, 0x6D, 0x01, 0xA8, 0x5A, 0x6A, 0x08,
0x0B, 0xCF, 0x0E, 0xEC, 0x9D, 0xFF, 0x09, 0xE5, 0x27, 0xAE, 0x00, 0xFE, 0xB1, 0x9E, 0x07, 0xF7,
0x44, 0x93, 0x0F, 0x10, 0xD2, 0xA3, 0x08, 0x19, 0x68, 0xF2, 0x01, 0x02, 0xFE, 0xC2, 0x06, 0x0B,
0x5D, 0x57, 0x62, 0xEF, 0xCB, 0x67, 0x65, 0xE6, 0x71, 0x36, 0x6C, 0xFD, 0xE7, 0x06, 0x6B, 0xF4,
0x76, 0x1B, 0xD4, 0xEE, 0xE0, 0x2B, 0xD3, 0xE7, 0x5A, 0x7A, 0xDA, 0xFC, 0xCC, 0x4A, 0xDD, 0xF5,
0x6F, 0xDF, 0xB9, 0x11, 0xF9, 0xEF, 0xBE, 0x18, 0x43, 0xBE, 0xB7, 0x03, 0xD5, 0x8E, 0xB0, 0x0A,
0xE8, 0xA3, 0xD6, 0x16, 0x7E, 0x93, 0xD1, 0x1F, 0xC4, 0xC2, 0xD8, 0x04, 0x52, 0xF2, 0xDF, 0x0D,
0xF1, 0x67, 0xBB, 0xE9, 0x67, 0x57, 0xBC, 0xE0, 0xDD, 0x06, 0xB5, 0xFB, 0x4B, 0x36, 0xB2, 0xF2,
0xDA, 0x2B, 0x0D, 0xE8, 0x4C, 0x1B, 0x0A, 0xE1, 0xF6, 0x4A, 0x03, 0xFA, 0x60, 0x7A, 0x04, 0xF3,
0xC3, 0xEF, 0x60, 0x17, 0x55, 0xDF, 0x67, 0x1E, 0xEF, 0x8E, 0x6E, 0x05, 0x79, 0xBE, 0x69, 0x0C,
0x8C, 0xB3, 0x61, 0xEB, 0x1A, 0x83, 0x66, 0xE2, 0xA0, 0xD2, 0x6F, 0xF9, 0x36, 0xE2, 0x68, 0xF0,
0x95, 0x77, 0x0C, 0x14, 0x03, 0x47, 0x0B, 0x1D, 0xB9, 0x16, 0x02, 0x06, 0x2F, 0x26, 0x05, 0x0F,
0xBE, 0x3B, 0xBA, 0x15, 0x28, 0x0B, 0xBD, 0x1C, 0x92, 0x5A, 0xB4, 0x07, 0x04, 0x6A, 0xB3, 0x0E,
0xA7, 0xFF, 0xD7, 0xEA, 0x31, 0xCF, 0xD0, 0xE3, 0x8B, 0x9E, 0xD9, 0xF8, 0x1D, 0xAE, 0xDE, 0xF1,
0xB0, 0xC2, 0x64, 0x1B, 0x26, 0xF2, 0x63, 0x12, 0x9C, 0xA3, 0x6A, 0x09, 0x0A, 0x93, 0x6D, 0x00,
0xA9, 0x06, 0x09, 0xE4, 0x3F, 0x36, 0x0E, 0xED, 0x85, 0x67, 0x07, 0xF6, 0x13, 0x57, 0x00, 0xFF,
0x82, 0x4A, 0xBF, 0xE5, 0x14, 0x7A, 0xB8, 0xEC, 0xAE, 0x2B, 0xB1, 0xF7, 0x38, 0x1B, 0xB6, 0xFE,
0x9B, 0x8E, 0xD2, 0x1A, 0x0D, 0xBE, 0xD5, 0x13, 0xB7, 0xEF, 0xDC, 0x08, 0x21, 0xDF, 0xDB, 0x01,
0xD4, 0xD2, 0xD3, 0xE6, 0x42, 0xE2, 0xD4, 0xEF, 0xF8, 0xB3, 0xDD, 0xF4, 0x6E, 0x83, 0xDA, 0xFD,
0xCD, 0x16, 0xBE, 0x19, 0x5B, 0x26, 0xB9, 0x10, 0xE1, 0x77, 0xB0, 0x0B, 0x77, 0x47, 0xB7, 0x02,
0xE6, 0x5A, 0x08, 0x18, 0x70, 0x6A, 0x0F, 0x11, 0xCA, 0x3B, 0x06, 0x0A, 0x5C, 0x0B, 0x01, 0x03,
0xFF, 0x9E, 0x65, 0xE7, 0x69, 0xAE, 0x62, 0xEE, 0xD3, 0xFF, 0x6B, 0xF5, 0x45, 0xCF, 0x6C, 0xFC,
0x78, 0xE2, 0x0A, 0xE0, 0xEE, 0xD2, 0x0D, 0xE9, 0x54, 0x83, 0x04, 0xF2, 0xC2, 0xB3, 0x03, 0xFB,
0x61, 0x26, 0x67, 0x1F, 0xF7, 0x16, 0x60, 0x16, 0x4D, 0x47, 0x69, 0x0D, 0xDB, 0x77, 0x6E, 0x04,
0x4A, 0x6A, 0xD1, 0x1E, 0xDC, 0x5A, 0xD6, 0x17, 0x66, 0x0B, 0xDF, 0x0C, 0xF0, 0x3B, 0xD8, 0x05,
0x53, 0xAE, 0xBC, 0xE1, 0xC5, 0x9E, 0xBB, 0xE8, 0x7F, 0xCF, 0xB2, 0xF3, 0xE9, 0xFF, 0xB5, 0xFA,
0x1C, 0xF2, 0xBD, 0x1D, 0x8A, 0xC2, 0xBA, 0x14, 0x30, 0x93, 0xB3, 0x0F, 0xA6, 0xA3, 0xB4, 0x06,
0x05, 0x36, 0xD0, 0xE2, 0x93, 0x06, 0xD7, 0xEB, 0x29, 0x57, 0xDE, 0xF0, 0xBF, 0x67, 0xD9, 0xF9,
0x2E, 0x7A, 0x66, 0xE3, 0xB8, 0x4A, 0x61, 0xEA, 0x02, 0x1B, 0x68, 0xF1, 0x94, 0x2B, 0x6F, 0xF8,
0x37, 0xBE, 0x0B, 0x1C, 0xA1, 0x8E, 0x0C, 0x15, 0x1B, 0xDF, 0x05, 0x0E, 0x8D, 0xEF, 0x02, 0x07
};
总结
第三关不是很明确,观察了一下是奇数偶数这样搭配来么?比如第一个是奇数,第二个是偶数,第三个是奇数。。。。
第二关盲猜Hi[KCTF 导致走入了误区,花费了不少时间,还是不能瞎猜啊。
第二关有符号判断,汇编地址 128B 需要注意,不然就不是0x07了,而是-1,-1肯定是匹配不了的。

 
 
for (int i = 0; i < len; ++i)
{
    c = str[i];
    tmp = 0x30;
    if (c >= 0x3a)
        tmp = 0x37;
    str[i] = c - tmp;
}
return 0;
for (int i = 0; i < len; ++i)
{
    c = str[i];
    tmp = 0x30;
    if (c >= 0x3a)
        tmp = 0x37;
    str[i] = c - tmp;
}

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2022-5-13 18:59 被kanxue编辑 ,原因:
上传的附件:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//