|
@TOC 1.WriteUp 2.知识点
声明一点以下可能说的不是很友好,所以如有敏感词汇请评论我,作者会改
WriteUp
下载压缩包,解压得到babyXor.exe文件,习惯步骤:exe文件用PEiD查壳

在这里插入图片描述
UPolyX v0.5 * 作为菜鸡说实话第一见这种壳,以前都是upx壳,所以先用万能脱壳工具FFI进行脱壳

在这里插入图片描述
原谅我这个新手看不懂,所以貌似是无法识别这个壳,那就只能手动脱壳 使用esp脱壳大法,这是今天的一个收获之一 将exe拖到od

在这里插入图片描述
直接调试到jmp那里

在这里插入图片描述
使用od脱壳插件

在这里插入图片描述
脱壳后形成脱壳后的exe文件 由于菜所以只能用ida进行伪代码查看,大神就直接通过od进行分析代码结构,无疑让人羡慕
int __cdecl main_0()
{
int v0; // ST5C_4
int v1; // ST6C_4
char *v2; // ST68_4
void *v3; // ST64_4
size_t v4; // eax
int v5; // ST60_4
sub_4010B4((int)&unk_4395F0, "世界上最简单的Xor");
sub_40107D(sub_40102D);
if ( --stru_436270._cnt < 0 )
{
_filbuf(&stru_436270);
}
else
{
v0 = (unsigned __int8)*stru_436270._ptr;
++stru_436270._ptr;
}
v1 = sub_40108C(&unk_435DC0, 56);
v2 = (char *)sub_401041((int)&unk_435DC0, (int)&dword_435DF8, 0x38u);
v3 = malloc(0x64u);
v4 = strlen(v2);
memcpy(v3, v2, v4);
v5 = sub_4010C3(&unk_435DC0, v2, &dword_435E30, 56);
sub_40101E(v1, v2, v5);
return 0;
}根据某个大神的解题思路得到启发,看这些简单一点的代码就应该有flag答案的地方从下往上看函数,看了半天也没有发现flag的踪迹,那就先分析重要函数吧
sub_4010C3(&unk_435DC0, v2, &dword_435E30, 56);
(char *)sub_401041((int)&unk_435DC0, (int)&dword_435DF8, 0x38u);
sub_40108C(&unk_435DC0, 56);
sub_40107D(sub_40102D);
sub_4010B4((int)&unk_4395F0, &#34;世界上最简单的Xor&#34;);找到这些重要的函数先不着急,先看传参,并找出其关联
sub_40108C(&unk_435DC0, 56);访问&unk_435DC0

在这里插入图片描述
显然是一个数组,不过在此之间,和我一样的菜鸡注意了,怎么找值 1.找类型,此处类型为db,及占4个字节,及是以四个字节为媒介进行分开 2.看地址,上图是一个地址一个地址进行分开 3.看端序,及所谓小端序(高到低)和大端序(低到高) 又上面3个要点可以得到 435DC0=[0x66,0x6d,0x63,0x64,0x7f,0x37,0x35,0x30,0x30,0x6b,0x3a,0x3c,0x3b,0x20]
(char *)sub_401041((int)&unk_435DC0, (int)&dword_435DF8, 56u);访问&dword_435DF8

在这里插入图片描述
435DF8=[0x37,0x6f,0x38,0x62,0x36,0x7c,0x37,0x33,0x34,0x76,0x33,0x62,0x64,0x7a]
sub_4010C3(&unk_435DC0, v2, &dword_435E30, 56);访问dword_435E30 得到 435E30=[0x1a,0,0,0x51,0x5,0x11,0x54,0x56,0x55,0x59,0x1d,0x9,0x5d,0x12,0,0] 关联:
v2 = (char *)sub_401041((int)&unk_435DC0, (int)&dword_435DF8, 56u);
sub_4010C3(&unk_435DC0, v2, &dword_435E30, 56);可以得到v2的值对sub_4010C3有影响,但是sub_40108C(&unk_435DC0, 56);没有与其有任何关联,所以软柿子肯定要捏一捏,在这之前先可以判断
sub_40107D(sub_40102D);
sub_4010B4((int)&unk_4395F0, &#34;世界上最简单的Xor&#34;);这二个函数应该是打印窗口所以暂时可以不要管
//sub_40108C(&unk_435DC0, 56);
char *__cdecl sub_401190(int a1, unsigned int a2)
{
char *v3; // [esp+4Ch] [ebp-Ch]
signed int i; // [esp+54h] [ebp-4h]
v3 = (char *)malloc(a2 >> 2);
for ( i = 0; i < (signed int)(a2 >> 2); ++i )
sprintf(&v3, &#34;%c&#34;, i ^ *(_DWORD *)(a1 + 4 * i));//435DC0的值与i进行异或得到的结果赋值给v3这个字符串数组
return v3;
}我们先脚本输出结果一下

在这里插入图片描述
???????flag出现了,而且是断片的,这时就瞬间明白了三个函数可能是进行拼凑flag
//sub_401041((int)&unk_435DC0, (int)&dword_435DF8, 0x38u);
char *__cdecl sub_401240(int a1, int a2, size_t a3)
{
signed int i; // [esp+4Ch] [ebp-Ch]
char *v5; // [esp+50h] [ebp-8h]
v5 = (char *)malloc(a3);//初始化字符串v5
sprintf(v5, &#34;%c&#34;, *(_DWORD *)a2);//将435DF8[0]=v5[0]
for ( i = 1; i < (signed int)(a3 >> 2); ++i )
sprintf(&v5, &#34;%c&#34;, *(_DWORD *)(a1 + 4 * i) ^ *(_DWORD *)(a2 + 4 * i) ^ *(_DWORD *)(a1 + 4 * i - 4));//v5=435DC0^435DF8^435DC0[i-1]
return v5;
}得到v5=[55, 100, 54, 101, 45, 52, 53, 54, 52, 45, 98, 100, 99, 97]
//sub_4010C3(&unk_435DC0, v2, &dword_435E30, 56);
char *__cdecl sub_401320(int a1, int a2, int a3, unsigned int a4)
{
int i; // [esp+4Ch] [ebp-10h]
char *v6; // [esp+50h] [ebp-Ch]
char *v7; // [esp+54h] [ebp-8h]
v7 = (char *)malloc(a4 - 1);
v6 = (char *)malloc(4 * a4 - 1);
for ( i = 0; i < (signed int)((a4 >> 2) - 1); ++i )
{
sprintf(&v6, &#34;%c&#34;, *(_DWORD *)(a3 + 4 * i + 4) ^ *(char *)(i + a2));//这里的a2等于上面的v5,所以v6=435E30[i+1]^v5
sprintf(&v7, &#34;%c&#34;, i ^ v6);
}
sprintf(&byte_439558, &#34;%c&#34;, dword_435E30 ^ dword_435DF8);
strcat(&byte_439558, v7);
return &byte_439558;
}Python-writeup:
a1=[0x66,0x6d,0x63,0x64,0x7f,0x37,0x35,0x30,0x30,0x6b,0x3a,0x3c,0x3b,0x20]
a2=[0x37,0x6f,0x38,0x62,0x36,0x7c,0x37,0x33,0x34,0x76,0x33,0x62,0x64,0x7a]
a3=[0x1a,0,0,0x51,0x5,0x11,0x54,0x56,0x55,0x59,0x1d,0x9,0x5d,0x12,0,0]
s=&#39;&#39;
s2=[]
for x in range(0,14):
s+=chr(x ^ a1[x])
print(s)
s+=chr(a2[0])
s2.append(a2[0])
for x in range(1,14):
s+=chr(a1[x]^a2[x]^a1[x-1])
s2.append(a1[x]^a2[x]^a1[x-1])
print(s2)
s+=chr(a3[0]^a2[0])
for x in range(0,13):
s+=chr(x^(a3[x+1]^s2[x]))
print(s)最终得到flag{2378b077-7d6e-4564-bdca-7eec8eede9a2}
知识点
esp脱壳大法
条件:当按f8后esp变红即可用esp脱壳大法

在这里插入图片描述
使用教程 1.先用先用dd命令转到堆栈刚才esp中的内容指的位置,即dd 0019ff64。随即在该处下硬件断点,如图:

在这里插入图片描述
2.按F9运行,然后我们F8单步走,到了有大跳转时不要再按F8了(这是向上跳转的),我们必须跳过去,因为接下来就有可能是程序的OEP领空

在这里插入图片描述

在这里插入图片描述 |
|