上来先看了下壳,没有。直接上IDA,发现原来是MAC系统下的东西,我没有MAC,看来要在IDA下一条路走到黑了。
进了IDA,如图:
函数不多,松了口气。直接进start。
似乎程序总体结构一览无余。先输入KEY,然后由两个sub进行KEY的变换,所得结果与aN进行比较。进KEY变换的两个sub看了下,第二个sub比较复杂。
第二个sub我不上图了,简单说下,主要是多层循环控制结构,主要进行移位、或、与、取反、异或操作,没整明白。但仔细看下,发现对KEY的变换操作特别少,而且没有对aN的操作。aN在程序中初始状态如图。
所以aN不是flag,这也正符合提示:没有输出的内容。接着往下看,下面还有个函数sub_100001530,输入参数是KEY经过第一个字串处理函数变换后的值。
先对输入参数分别与两个字串进行变换,然后进入一个循环,访问网络并对字串进行处理。折腾很久,没有折腾出结果。后来网上找到一篇WP(http://www.secpulse.com/archives/39058.html),一切就清楚了,写这篇WP就是想把网上WP略过的东西说说。毕竟我是小菜,flag不是目的,学习才是目的。
如果把sub_100001530的输入参数记作a,如网上的WP如说,在sub_100001480中用a的前6位与目标字串进行异或生成一个url,url的开头肯定是http://或者https://。这样就可以反推出a的前6位,并再得出url。而且还可以用a算出另一个字串的变换结果。直接上代码,两种可能性都算,一看便知真假。
# -*- coding:utf-8 -*-
# code by poyoten
def main():
t1 = r'http:/'
t2 = r'https:'
#b为unk_1000020E0
b = [0x3c,0x44,0x19,0x11,0x7,0x55,0x7B,0x1F,0x0E,0x15,0x12,0x1B,0x3D,0x5D,\
0x8,0x4F,0x1B,0x1D,0x33,0x1F,0x8,0x17,0x11,0x1,0x20,0x1F]
#c为unk_100002100
c = [0xF1,0x31,0x78,0x98,0xC0,0x62,0x50,0x7A,0xDA,0x62,0x70,0x9D,0xFE,0x2D,\
0x6E,0xC3,0xEE,0x7A,0x51,0xA,0xC8,0x74,0x74,0xE,0xC2,0x31,0x6D,0xBD,0xFB,\
0x6A,0x57,0x94,0xEC,0x6E,0x7C,0x77,0xF1,0x37,0x6F,0x95,0x3,0x56,0x57,0xD8,\
0xE0,0x6A,0x70,0x5D,0xCE,0x33,0x6F,0x61,0xD1,0x64,0x55,0x75,0xC7,0x66,0x74,\
0xC0,0xD5,0x3B,0x6E,0x19,0xE0,0x62,0x5C,0x18,0xDA,0x44,0x75,0x9A]
a1 = ''
a2 = ''
for i in range(6):
a1 += chr(ord(t1[i]) ^ b[i])
a2 += chr(ord(t2[i]) ^ b[i])
print a1,'\t',a2
b1 = ''
b2 = ''
for i in range(len(b)):
b1 += chr((b[i]^ord(a1[i%len(a1)])))
b2 += chr((b[i]^ord(a2[i%len(a2)])))
c1 = []
c2 = []
for i in range(len(c)):
c1.append(c[i]^ord(a1[i%len(a1)]))
c2.append(c[i]^ord(a2[i%len(a2)]))
print b1,'\n',b2,'\n',c1,'\n',c2
if __name__ == '__main__':
main()
print 'done'
pass
得出一个网址和一组数,代入sub_10000133进行运算,最终能得出flag。既然内容没有输出,我也没有MAC,那我们输出内容吧。代码如下,尽量保持了伪代码的原样。
// poppy.cpp : Defines the entry point for the console application.
//code by poyoten
#include "stdafx.h"
#include <string.h>
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>
#include <curl/curl.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
size_t sub_1000011C0(void* a1, size_t a2, size_t a3, void* a4)
{
__int64 v4; // ST18_8@1
v4 = a3;
//memset(data, 0LL, 0x1000000LL);
int size = strlen((char*)a4);
int len = size_t(a3*a2);
if (size == 0)
strcpy_s((char*)a4, len+1, (char*)a1);
else
strcat_s((char*)a4, 0x1000000uLL, (char*)a1);
return size_t(a3*a2);
}
_int64 __fastcall sub_100001210(char* a1, char* a2)
{
CURL *curl; // ST38_8@1
CURLcode res;
//FILE* fp;
//if ((fp = fopen("1.htm", "w")) == NULL)
// return false;
//__memset_chk(a2, 0LL, 0x100000LL, -1LL);
curl_global_init(3LL);
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, a1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30LL);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, sub_1000011C0);
//curl_easy_setopt(curl, CURLOPT_FILE, (FILE*)a2);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, a2);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0LL);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0LL);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_global_cleanup();
return 0LL;
}
__int64 __fastcall sub_100001740(const char *a1, int a2, char *a3, int a4, int a5)
{
signed int v5; // eax@42
signed int v6; // eax@45
signed int v7; // eax@48
signed int v8; // eax@53
signed int v9; // eax@57
signed int v10; // eax@62
signed int v11; // eax@65
bool v13; // [sp+7Bh] [bp-45h]@0
signed int v14; // [sp+7Ch] [bp-44h]@1
char *v15; // [sp+80h] [bp-40h]@0
char *v16; // [sp+88h] [bp-38h]@0
int v17; // [sp+94h] [bp-2Ch]@0
int v18; // [sp+98h] [bp-28h]@1
int v19; // [sp+9Ch] [bp-24h]@1
char *v20; // [sp+A0h] [bp-20h]@1
signed int v21; // [sp+B8h] [bp-8h]@0
int v22; // [sp+BCh] [bp-4h]@1
v20 = a3;
v19 = a4;
v18 = a5;
v22 = a5;
v14 = 687849597;
do
{
while (v14 > -721349906)
{
if (v14 > -251959739)
{
if (v14 > 1643955)
{
if (v14 > 2139374635)
{
if (v14 == 2139374636)
{
v11 = 1996424361;
if (v17 < v18)
v11 = -251959738;
v14 = v11;
}
}
else if (v14 > 111058115)
{
if (v14 > 319798562)
{
if (v14 > 497514003)
{
if (v14 > 687849596)
{
if (v14 > 1056727273)
{
if (v14 > 1629186829)
{
if (v14 > 1841852057)
{
if (v14 > 1996424360)
{
if (v14 == 1996424361)
{
v21 = (DWORD)v15 - (DWORD)v20;
v14 = -2127602345;
}
}
else
{
switch (v14)
{
case 1841852058:
v6 = 111058116;
if (a2 <= 0)
v6 = 319798563;
v14 = v6;
break;
case 1892047314:
v8 = -721349905;
if (v17 < v18)
v8 = 497514004;
v14 = v8;
v13 = 0;
break;
case 1914277125:
v10 = 2139374636;
if (!v15)
v10 = -251959738;
v14 = v10;
break;
}
}
}
else if (v14 == 1629186830)
{
v16 += (signed int)v15 - (signed int)v16 + 1;
v14 = 1643956;
}
}
else if (v14 == 1056727274)
{
v17 = 0;
v16 = v20;
v14 = 1892047314;
}
}
else if (v14 == 687849597)
{
v5 = 1841852058;
if (v22 <= 0)
v5 = 319798563;
v14 = v5;
}
}
else if (v14 == 497514004)
{
v15 = strstr(v16, a1);
v14 = -721349905;
v13 = v15 != 0LL;
}
}
else if (v14 == 319798563)
{
v21 = -1;
v14 = -2127602345;
}
}
else if (v14 == 111058116)
{
v7 = 1056727274;
if (v19 <= 0)
v7 = 319798563;
v14 = v7;
}
}
else if (v14 == 1643956)
{
++v17;
v14 = 1892047314;
}
}
else if (v14 == -251959738)
{
v21 = -1;
v14 = -2127602345;
}
}
else if (v14 == -721349905)
{
v9 = 1914277125;
if (v13)
v9 = 1629186830;
v14 = v9;
}
}
} while (v14 != -2127602345);
return (unsigned int)v21;
}
__int64 __fastcall sub_100001330(char* a1, unsigned int a2, int a3)
{
int v3; // ST70_4@1
char* v4; // ST60_8@1
int v5; // eax@1
int v6; // eax@1
int v7; // ST5C_4@1
const char *v8; // ST10_8@1
int v9; // eax@1
char v10; // ST4B_1@1
v3 = a3;
v4 = (char *)malloc(0x1000000uLL);
memset(v4, 0LL, 0x1000000LL);
//v4 = data;
sub_100001210(a1, v4);
v5 = strlen(v4);
v6 = sub_100001740("<td>", 4, v4, v5, a2);
v7 = v6;
v8 = &v4[v6 + 4];
v9 = strlen(v8);
v10 = v4[(signed int)(v3 + (unsigned __int64)sub_100001740("\">", 2, (char *)v8, v9, 1) + v7 + 4 + 2)];
free(v4);
return (unsigned int)v10;
}
int _tmain(int argc, _TCHAR* argv[])
{
__int64 v1; // rcx@3
char v2; // al@3
__int64 v4; // [sp+0h] [bp-1F0h]@0
char *i; // [sp+70h] [bp-180h]@1
char *v6; // [sp+80h] [bp-170h]@3
char *v7; // [sp+C0h] [bp-130h]@1
char *v8; // [sp+1C0h] [bp-30h]@1
__int64 v9; // [sp+1E8h] [bp-8h]@1
char url[] = "https://ctftime.org/event/";
char index[] = {165, 1, 21, 249, 180, 13, 4, 74, 183, 3, 4, 242, 170, 29, 3, 162, 154, 21, 5, 58, 165, 21, 0, 97, 150, 1, 0,
220, 143, 5, 3, 164, 129, 15, 8, 24, 165, 7, 2, 244, 119, 57, 3, 232, 141, 11, 4, 50, 154, 3, 2, 0, 165, 11, 1, 69, 170,
7, 0, 175, 129, 11, 3, 120, 148, 13, 8, 40, 183, 37, 1, 245,'\0' };
//memset(&v8, 0, 0x20uLL);
//memset(&v7, 0, 0x100uLL);
v7 = index;
v8 = url;
//strcpy(&v8, url);
//strcpy(&v7, index);
for (i = v7; *i; i += 4)
{
//memset(&v6, 0, 0x40uLL);
v6 = (char *) malloc(0x100ULL);
WORD(v4) = (unsigned __int8) *i;
_snprintf(v6, 0x40uLL, "%s%d", v8, v4);
v1 = (unsigned __int8)*i;
v2 = sub_100001330(v6, (unsigned __int8)i[1], (unsigned __int8)i[2]);
printf("%c", v2);
}
return 0;
}
得出没有输出的内容。不过还有个格式,本题未说明白,原题说了。我不知道aN输出的是什么,也不想弄了。程序中是带有ISG字串的。不要问我怎么知道的。
转自实验吧,原文作者实验吧ID poyoten