前言
把22年寒假的WP转移到blog上,这次是逆向入门专题的,原题链接在最底下。
re
先拖到die打开,发现是无壳elf64文件,用ida64打开,找到main函数
打开这个sub_4007BD函数,发现是做了一些变换,变换后与main函数里的的flag比一下,变换前的应该就是真flag
获得flag的代码如下
#include <stdio.h>
int main()
{
char a1[26];
char a2[26] = "flag{PbkD7j4X|8Wz;~;z_O1}";
for (int i = 0; i < 5; i++)
{
a1[i] = a2[i];
}
for (int i = 0; i <= 7; ++i)
{
a1[i + 5] = a2[i + 5] ^ 7;
}
for (int j = 8; j <= 15; ++j)
{
a1[j + 5] = a2[j + 5] ^ 8;
}
for (int j = 21; j < 26; ++j)
{
a1[j] = a2[j];
}
for (int i = 0; i < 26; i++)
{
printf("%c", a1[i]);
}
return 0;
}
得到flag为flag{WelC0m3_t0_r3v3r_O1}
验证一下,通过
re2
还是拖到die打开,无壳elf64文件,用ida64打开,找到main函数
有很多很长的函数,搜了一下资料,发现一般是某些类的静态调用函数,最后一个函数名可能是调用函数的名字。点开部分sub开头的函数看看,某些函数就是实现了递增、取地址等操作。
整段代码大致意思就是比较输入的字符和引用的字符是否一致,关键部分就在while循环内,点开offsset和dword地址分别看看,应该是索引调用一个字符串的字符即得到flag
点开字符串看看,两行合起来就是完整的字符串
再看看索引数组,看起来不太对劲,数组中间多了一个align指令,查了一下,是个对齐指令,但是后面的数也不是对齐8的,搜了一下,应该是ida把连续的0当成了间隔,需要手动改一下,右键改成undefined
改好后得到正确的索引数组,4个字节为一个数
把这些数据换成数组的形式,然后开始写代码了
代码如下
#include <stdio.h>
int main()
{
char flag[50];
char offset[200] = "L3t_ME_T3ll_Y0u_S0m3th1ng_1mp0rtant_A_{FL4G}_W0nt_b3_3X4ctly_th4t_345y_t0_c4ptur3_H0wev3r_1T_w1ll_b3_C00l_1F_Y0u_g0t_1t";
int dw[50] = {36, 0, 5, 54, 101, 7, 39, 38, 45, 1, 3, 0, 13, 86, 1, 3, 101, 3, 45, 22, 2, 21, 3, 101, 0, 41, 68, 68, 1, 68, 43};
for (int i = 0; i < 31; i++)
{
flag[i] = offset[dw[i]];
}
for (int i = 0; i < 31; i++)
{
printf("%c", flag[i]);
}
return 0;
}
最终得到flag为ALEXCTF{W3_L0v3_C_W1th_CL45535}
验证通过
reverse-sample
先拖到die看看,是无壳elf32,用ida32打开,找到main函数
发现有个check函数很关键,点开看看
是个比较函数,for循环里面有个大数,应该是地址,转换一下是0x804A060,找到这个地址里的内容
写个代码解一下flag,代码如下
#include <stdio.h>
int main()
{
char flag[35];
char a[35] = "bcg|nd4q6>cp1o7i0c|w4h|~6>?weios=";
for (int i = 0; i <= 31; i++)
{
flag[i] = a[i] ^ 6;
}
for (int i = 0; i <= 31; i++)
{
printf("%c", flag[i]);
}
return 0;
}
得到flag为deazhb2w08ev7i1o6ezq2nzx089qcoiu
验证通过
OpenReverse
先拖到die打开,无壳pe64,用ida64打开,找到main函数
main函数就是比较输入与v4,v4经过sub_401000调整过,点开sub_401000看看
可以得到flag了,代码如下
#include <stdio.h>
int main()
{
char v4[28];
int v3; // edx
int v1; // eax
int v5; // esi
int v6; // ecx
unsigned int result; // eax
char v8; // dl
char v9; // [esp+8h] [ebp-34h]
char v10[51] = {'\0'}; // [esp+9h] [ebp-33h] BYREF
v4[0] = -29;
v4[1] = 118;
v4[2] = -5;
v4[3] = 111;
v4[4] = -40;
v4[5] = 40;
v4[6] = -14;
v4[7] = 112;
v4[8] = -24;
v4[9] = 118;
v4[10] = 73;
v4[11] = 0x80;
v4[12] = 75;
v4[13] = -99;
v4[14] = 86;
v4[15] = -114;
v4[16] = 98;
v4[17] = -78;
v4[18] = 38;
v4[19] = -67;
v4[20] = 32;
v4[21] = -124;
v4[22] = 2;
v4[23] = -125;
v4[24] = 26;
v4[25] = -40;
v3 = 2 * 56 + 10;
v9 = 0;
v10[48] = 0;
v1 = 0;
v5 = 10 * v3 - 9;
do
{
v10[v1++] = v5;
v5 += v3;
} while (v1 < 50);
v6 = 0;
for (result = 0; result < 26; ++result)
{
if (v6 == 50)
v6 = 0;
v8 = v10[v6++];
v4[result] ^= v8;
}
for (int i = 0; i < 26; i++)
{
printf("%c", v4[i]);
}
return 0;
}
flag为XCTF{5eacs6y8p1o9gitc9521}
看一下字符串窗口,也发现了flag
验证通过
Test-base64
先拖到die打开,无壳pe32,用ida32打开, 先找到main函数
观察逻辑后,发现有两个函数很关键,先把str经sub_40100F处理后输出str->v6,再把v6经sub_401005处理了输出v6->str
先看看sub_40100F函数,一路跳到sub_401030函数,看特征是对str进行base64编码然后存在v6里
找到base64的表看看,就是普通的表
用在线工具编码得20190318->MjAxOTAzMTg=
先看看sub_401005函数,一路跳到sub_401260函数,这个函数借助sub_4013F0函数对v6进行base64解码然后存在str里
用在线工具解码得MjAxOTAzMTg=->20190318