-
-
[原创]看雪.纽盾 KCTF晋级赛2019 Q2 第六题 消失的岛屿
-
发表于: 2019-6-18 14:37 2787
-
用IDA载入文件,提示有DWARF debug information,选择yes,可以看到更多的信息。然后我们找到main函数。
int __cdecl main(int argc, const char **argv, const char **envp) { int v3; // eax uint8_t bindata; // [esp+11h] [ebp-3Fh] const char *v6; // [esp+48h] [ebp-8h] char *v7; // [esp+4Ch] [ebp-4h] __main(); printf("please enter Serial:"); scanf(" %s", &bindata); if ( strlen((const char *)&bindata) > 0x31 ) puts("error"); v7 = (char *)calloc(1u, 0x400u); v3 = strlen((const char *)&bindata); base64_encode(&bindata, v7, v3); v6 = "!NGV%,$h1f4S3%2P(hkQ94=="; if ( !strcmp("!NGV%,$h1f4S3%2P(hkQ94==", v7) ) puts("Success"); else puts("Please Try Again"); free(v7); system("pause"); return 0; }
这几乎是源代码了,而且代码逻辑也很简单,输入的字符串base64编码以后跟"!NGV%,$h1f4S3%2P(hkQ94=="比较,相同则成功。但是这个看起来不是标准base64编码,进入base64_encode函数看看。
int __cdecl base64_encode(const uint8_t *bindata, char *base64, int binlength) { int v3; // eax char *v4; // ebx int v5; // eax int v6; // ST0C_4 char *v7; // ebx int v8; // eax int v9; // eax char *v10; // ebx int v11; // eax int v12; // eax char *v13; // ebx uint8_t current; // [esp+Bh] [ebp-Dh] uint8_t currenta; // [esp+Bh] [ebp-Dh] int j; // [esp+Ch] [ebp-Ch] int ja; // [esp+Ch] [ebp-Ch] int jb; // [esp+Ch] [ebp-Ch] int i; // [esp+10h] [ebp-8h] i = 0; j = 0; while ( i < binlength ) { v3 = j; ja = j + 1; v4 = &base64[v3]; *v4 = charEncrypt((bindata[i] >> 2) & 0x3F); current = 16 * bindata[i] & 0x30; if ( i + 1 >= binlength ) { v5 = ja; v6 = ja + 1; v7 = &base64[v5]; *v7 = charEncrypt(current); base64[v6] = 61; v8 = v6 + 1; j = v6 + 2; base64[v8] = 61; break; } v9 = ja; jb = ja + 1; v10 = &base64[v9]; *v10 = charEncrypt((bindata[i + 1] >> 4) | current); currenta = 4 * bindata[i + 1] & 0x3C; if ( i + 2 >= binlength ) { base64[jb] = charEncrypt(currenta); v11 = jb + 1; j = jb + 2; base64[v11] = '='; break; } base64[jb] = charEncrypt((bindata[i + 2] >> 6) | currenta); v12 = jb + 1; j = jb + 2; v13 = &base64[v12]; *v13 = charEncrypt(bindata[i + 2] & 0x3F); i += 3; } base64[j] = 0; return j; }
charEncrypt函数
char __cdecl charEncrypt(int data) { int dataa; // [esp+18h] [ebp+8h] dataa = aTuvwxtulmnopqr[data]; if ( dataa > '@' && dataa <= 'Z' ) return 0x9B - dataa; if ( dataa > '`' && dataa <= 'z' ) return dataa - 0x40; if ( dataa > '/' && dataa <= '9' ) return dataa + '2'; if ( dataa == '+' ) return 'w'; if ( dataa == '/' ) dataa = 'y'; return dataa; }
我们可以通过
charEncrypt函数得到真实的码表,把代码复制一份,做点小修改
#include <stdio.h> char b64_chr[] = "tuvwxTUlmnopqrs7YZabcdefghij8yz0123456VWXkABCDEFGHIJKLMNOPQRS9+/"; char charEncrypt(int data) { int dataa; // [esp+18h] [ebp+8h] dataa = data; if ( dataa > '@' && dataa <= 'Z' ) return 0x9B - dataa; if ( dataa > '`' && dataa <= 'z' ) return dataa - 0x40; if ( dataa > '/' && dataa <= '9' ) return dataa + '2'; if ( dataa == '+' ) return 'w'; if ( dataa == '/' ) dataa = 'y'; return dataa; } int main(int argc, char const *argv[]) { for (int i = 0; i < sizeof(b64_chr); ++i) { printf("%c",charEncrypt(b64_chr[i])); } return 0; }
运行得到"45678GF,-./0123iBA!\"#$%&'()*j9:bcdefghEDC+ZYXWVUTSRQPONMLKJIHkwy",这个就是真正的码表。
用这个码表解密"
!NGV%,$h1f4S3%2P(hkQ94==",得到key:KanXue2019ctf_st
int __cdecl main(int argc, const char **argv, const char **envp) { int v3; // eax uint8_t bindata; // [esp+11h] [ebp-3Fh] const char *v6; // [esp+48h] [ebp-8h] char *v7; // [esp+4Ch] [ebp-4h] __main(); printf("please enter Serial:"); scanf(" %s", &bindata); if ( strlen((const char *)&bindata) > 0x31 ) puts("error"); v7 = (char *)calloc(1u, 0x400u); v3 = strlen((const char *)&bindata); base64_encode(&bindata, v7, v3); v6 = "!NGV%,$h1f4S3%2P(hkQ94=="; if ( !strcmp("!NGV%,$h1f4S3%2P(hkQ94==", v7) ) puts("Success"); else puts("Please Try Again"); free(v7); system("pause"); return 0; }
这几乎是源代码了,而且代码逻辑也很简单,输入的字符串base64编码以后跟"!NGV%,$h1f4S3%2P(hkQ94=="比较,相同则成功。但是这个看起来不是标准base64编码,进入base64_encode函数看看。
int __cdecl base64_encode(const uint8_t *bindata, char *base64, int binlength) { int v3; // eax char *v4; // ebx int v5; // eax int v6; // ST0C_4 char *v7; // ebx int v8; // eax int v9; // eax char *v10; // ebx int v11; // eax int v12; // eax char *v13; // ebx uint8_t current; // [esp+Bh] [ebp-Dh] uint8_t currenta; // [esp+Bh] [ebp-Dh] int j; // [esp+Ch] [ebp-Ch] int ja; // [esp+Ch] [ebp-Ch] int jb; // [esp+Ch] [ebp-Ch] int i; // [esp+10h] [ebp-8h] i = 0; j = 0; while ( i < binlength ) { v3 = j; ja = j + 1; v4 = &base64[v3]; *v4 = charEncrypt((bindata[i] >> 2) & 0x3F); current = 16 * bindata[i] & 0x30; if ( i + 1 >= binlength ) { v5 = ja; v6 = ja + 1; v7 = &base64[v5]; *v7 = charEncrypt(current); base64[v6] = 61; v8 = v6 + 1; j = v6 + 2; base64[v8] = 61; break; } v9 = ja; jb = ja + 1; v10 = &base64[v9]; *v10 = charEncrypt((bindata[i + 1] >> 4) | current); currenta = 4 * bindata[i + 1] & 0x3C; if ( i + 2 >= binlength ) { base64[jb] = charEncrypt(currenta); v11 = jb + 1; j = jb + 2; base64[v11] = '='; break; } base64[jb] = charEncrypt((bindata[i + 2] >> 6) | currenta); v12 = jb + 1; j = jb + 2; v13 = &base64[v12]; *v13 = charEncrypt(bindata[i + 2] & 0x3F); i += 3; } base64[j] = 0; return j; }
charEncrypt函数
int __cdecl base64_encode(const uint8_t *bindata, char *base64, int binlength) { int v3; // eax char *v4; // ebx int v5; // eax int v6; // ST0C_4 char *v7; // ebx int v8; // eax int v9; // eax char *v10; // ebx int v11; // eax int v12; // eax char *v13; // ebx uint8_t current; // [esp+Bh] [ebp-Dh] uint8_t currenta; // [esp+Bh] [ebp-Dh] int j; // [esp+Ch] [ebp-Ch] int ja; // [esp+Ch] [ebp-Ch] int jb; // [esp+Ch] [ebp-Ch] int i; // [esp+10h] [ebp-8h] i = 0; j = 0; while ( i < binlength ) { v3 = j; ja = j + 1; v4 = &base64[v3]; *v4 = charEncrypt((bindata[i] >> 2) & 0x3F); current = 16 * bindata[i] & 0x30; if ( i + 1 >= binlength ) { v5 = ja; v6 = ja + 1; v7 = &base64[v5]; *v7 = charEncrypt(current); base64[v6] = 61; v8 = v6 + 1; j = v6 + 2; base64[v8] = 61; break; } v9 = ja; jb = ja + 1; v10 = &base64[v9]; *v10 = charEncrypt((bindata[i + 1] >> 4) | current); currenta = 4 * bindata[i + 1] & 0x3C; if ( i + 2 >= binlength ) { base64[jb] = charEncrypt(currenta); v11 = jb + 1; j = jb + 2; base64[v11] = '='; break; } base64[jb] = charEncrypt((bindata[i + 2] >> 6) | currenta); v12 = jb + 1; j = jb + 2; v13 = &base64[v12]; *v13 = charEncrypt(bindata[i + 2] & 0x3F); i += 3; } base64[j] = 0; return j; }
charEncrypt函数
char __cdecl charEncrypt(int data) { int dataa; // [esp+18h] [ebp+8h] dataa = aTuvwxtulmnopqr[data]; if ( dataa > '@' && dataa <= 'Z' ) return 0x9B - dataa; if ( dataa > '`' && dataa <= 'z' ) return dataa - 0x40; if ( dataa > '/' && dataa <= '9' ) return dataa + '2'; if ( dataa == '+' ) return 'w'; if ( dataa == '/' ) dataa = 'y'; return dataa; }
我们可以通过
charEncrypt函数得到真实的码表,把代码复制一份,做点小修改
char __cdecl charEncrypt(int data) { int dataa; // [esp+18h] [ebp+8h] dataa = aTuvwxtulmnopqr[data]; if ( dataa > '@' && dataa <= 'Z' ) return 0x9B - dataa; if ( dataa > '`' && dataa <= 'z' ) return dataa - 0x40; if ( dataa > '/' && dataa <= '9' ) return dataa + '2'; if ( dataa == '+' ) return 'w'; if ( dataa == '/' ) dataa = 'y'; return dataa; }
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
看原图
赞赏
雪币:
留言: