-
-
[原创]看雪CTF2019晋级赛Q2第六题《消失的岛屿》解题wp
-
2019-6-14 12:28 2371
-
程序的流程:
IDA伪代码:
int __cdecl main() { int v0; // eax@3 _BYTE v2[3]; // [sp+11h] [bp-3Fh]@1 const char *v3; // [sp+48h] [bp-8h]@3 char *v4; // [sp+4Ch] [bp-4h]@3 __main(); printf("please enter Serial:"); scanf(" %s", v2); if ( strlen(v2) > 0x31 ) puts("error"); v4 = (char *)calloc(1u, 0x400u); v0 = strlen(v2); base64_encode(v2, v4, v0); v3 = "!NGV%,$h1f4S3%2P(hkQ94=="; if ( !strcmp("!NGV%,$h1f4S3%2P(hkQ94==", v4) ) puts("Success"); else puts("Please Try Again"); free(v4); system("pause"); return 0; }
这里是程序的算法:
跟进去看看
IDA伪代码:
int __cdecl base64_encode(const uint8_t *bindata, char *base64, int binlength) { int v3; // eax@2 char *v4; // ebx@2 int v5; // eax@3 int v6; // ST0C_4@3 char *v7; // ebx@3 int v8; // eax@3 int v9; // eax@4 char *v10; // ebx@4 int v11; // eax@5 int v12; // eax@6 char *v13; // ebx@6 uint8_t current; // [sp+Bh] [bp-Dh]@2 uint8_t currenta; // [sp+Bh] [bp-Dh]@4 int j; // [sp+Ch] [bp-Ch]@1 int ja; // [sp+Ch] [bp-Ch]@2 int jb; // [sp+Ch] [bp-Ch]@4 int i; // [sp+10h] [bp-8h]@1 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] = '='; v8 = v6 + 1; j = v6 + 2; base64[v8] = '='; 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; }
这里看到base64必备的编码变换函数:
跟进去看看,找到字符表
OD定位,查看里面的存储数据,这里也能用IDA直接看,但是我还是习惯用OD来定位。
到这里,就可以参考网上的base64,来写出对应的解密算法
int __cdecl base64_decode(char *base64, char *bindata, int binlength) { int t = 0, x = 0, y = 0, i = 0; unsigned char c = 0; int g = 3; while (base64[x] != 0) { // 需要解码的数据对应的ASCII值对应base64_suffix_map的值 c = charUnEncrypt(base64[x]); x++; if (c == 255) return -1;// 对应的值不在转码表中 if (c == 253) continue;// 对应的值是换行或者回车 if (c == 254) { c = 0; g--; }// 对应的值是'=' t = (t << 6) | c; // 将其依次放入一个int型中占3字节 if (++y == 4) { bindata[i++] = (unsigned char)((t >> 16) & 0xff); if (g > 1) bindata[i++] = (unsigned char)((t >> 8) & 0xff); if (g > 2) bindata[i++] = (unsigned char)(t & 0xff); y = t = 0; } } return i; }
得出flag
程序解密完整源码如下:
#include "pch.h" #include <iostream> #include <locale> #include <cstdlib> #include <stdio.h> #include <stdlib.h> #include <locale.h> #include <string> #include <windows.h> char aTuvwxtulmnopqr[65] = "tuvwxTUlmnopqrs7YZabcdefghij8yz0123456VWXkABCDEFGHIJKLMNOPQRS9+/"; char __cdecl charEncrypt(int data) { int dataa; // [esp+18h] [ebp+8h] dataa = aTuvwxtulmnopqr[data]; if (dataa > 64 && dataa <= 90) return 155 - dataa; if (dataa > 96 && dataa <= 122) return dataa - 64; if (dataa > 47 && dataa <= 57) return dataa + 50; if (dataa == 43) return 119; if (dataa == 47) dataa = 121; return dataa; } char __cdecl charUnEncrypt(int data) { int i; if (data == 121) { data = 47; } else if (data == 119) { data = 43; } else if (data > 47 + 50 && data <= 57 + 50) { data = data - 50; } else if (data > 96 - 64 && data <= 122 - 64) { data = data + 64; } else if (data >= 155 - 90 && data < 155 - 64) { data = 155 - data; } for (i = 0; i < 64; i++) { if (data == aTuvwxtulmnopqr[i]) return i; } return 254; } int __cdecl base64_decode(char *base64, char *bindata, int binlength) { int t = 0, x = 0, y = 0, i = 0; unsigned char c = 0; int g = 3; while (base64[x] != 0) { // 需要解码的数据对应的ASCII值对应base64_suffix_map的值 c = charUnEncrypt(base64[x]); x++; if (c == 255) return -1;// 对应的值不在转码表中 if (c == 253) continue;// 对应的值是换行或者回车 if (c == 254) { c = 0; g--; }// 对应的值是'=' t = (t << 6) | c; // 将其依次放入一个int型中占3字节 if (++y == 4) { bindata[i++] = (unsigned char)((t >> 16) & 0xff); if (g > 1) bindata[i++] = (unsigned char)((t >> 8) & 0xff); if (g > 2) bindata[i++] = (unsigned char)(t & 0xff); y = t = 0; } } return i; } int __cdecl base64_encode(char *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 = (bindata[i] << 4) & 0x30; if (i + 1 >= binlength) { v5 = ja; v6 = ja + 1; v7 = &base64[v5]; *v7 = charEncrypt(current); base64[v6] = '='; v8 = v6 + 1; j = v6 + 2; base64[v8] = '='; 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] = 61; 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; } char * wchar2char(const wchar_t* wchar)//wchar转换为char { char * m_char; int len = WideCharToMultiByte(CP_ACP, 0, wchar, wcslen(wchar), NULL, 0, NULL, NULL); m_char = new char[len + 1]; WideCharToMultiByte(CP_ACP, 0, wchar, wcslen(wchar), m_char, len, NULL, NULL); m_char[len] = '\0'; return m_char; } int main() { //goto lbtest; int i = 0; char buf[256] = { 0 }; char buf1[256] = { 0 }; const wchar_t* code = L"!NGV%,$h1f4S3%2P(hkQ94=="; char* as = wchar2char(code); //base64_encode(as, buf, 1); base64_decode(as, buf1, 16); printf(buf1); }
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
谁下载
无
看原图