前言
把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