2018河北省赛部分writeupre

35次阅读

共计 1952 个字符,预计需要花费 5 分钟才能阅读完成。

前言

因为最近在学习 binary,来拿几道练练手,感觉比国赛简单多了(希望今年也这样…)。大多都是工具的基础使用。
写了 re 部分的 wp,如有错误和更简单的解法欢迎大师傅们指点。

0x01 有点简单的逆向(12)

打开附件,先拖进 Exeninfo 看看是什么类型。是一个 32bit 的 ELF。

所以拖进 ida32,找到 main 函数,F5 一下获得反汇编后的结果。

分析一下,程序用 memset 开辟了几个连续的内存空间(可以认为是数组)v3,v4,v5. 然后开始赋值。
一开始很懵。后来发现,问题在于赋的值真的只是数字吗?我们知道即使是字符串,在内存空间中存储也是以数(ascii)的形式表示的。
所以我们点一下 v3 第一块空间的值,按 R(转为字符)看看有什么结果。

果不其然,GALF。看来程序实现的是一个反转字符串的功能。直接把剩下的变量全转为字符。获得 flag。

FLAG-4092849uio2jfklsj4kl

(这是逆向题?)

0x02 磁盘取证(13)

无语的题目。
拿到附件,首先发现他不是一个可执行文件。扔进 ida 显示是一个二进制文件。也无法反汇编。从题目得知应该是一个内存取证的题目(用 linux 挂载啥的,还没太接触过)。
然后无语的地方出现了,用 ida 按下 shift+F12(查看字符串)。其中发现了:

行吧。(看来挂载之后,也是去找 mnt/test/Flag.txt 就可以获得 flag 了)

flag{yc4pl0fvjs2k1t7T}

0x03 crackme(17)

严格意义上的第一道逆向题。首先先分析:

一个 win32 程序。运行一下看看:

看来是要找出正确的输入内容是什么了,先用 ida 看下:

517 个函数,附带一个鬼畜的 main 函数反汇编结果:

字符串查找也没有结果。静态调试怕是要看死了,考虑用 od 动态调试。
先扔进 od 中,查看参考文本字符串,发现了输入提示语:

双击,找到了在程序中对应的位置。按下 F2 下断点:

运行程序到断点处。这里随便输入数据(111111),继续执行程序:

按 F8 步进,注意观察寄存器中内容的变化。终于发现步进到某个函数时,我们刚才输入的数据被放进了 ecx 寄存器中:

继续 F8,可以看到不远处,有一条指令将 main 函数放入了 eax 寄存器中:

依旧 F8,就可以发现些眉目了。
首先,程序取出了 main 的首字母 m,与输入数据的头位 1,分别放到 cl 与 al 中:


之后将两者进行异或运算,保存在 al 中:

可以看到结果是 ””:

接着步进,可以看到程序往 eax 寄存中放入了一串疑似 base64 编码的字符串:

同时我们可以看到,刚才输入的 11111 已经变成了 ”11111″:

继续步进,程序 jb 到了前面的内存地址,看来是一个循环:

所以我们一路 F8,看看这回 cl 与 al 中都放入了什么,可以看到 cl 中放入了 a,al 中放入了:


两者异或,和刚才的操作类似,这回得到了 ’=’:


继续 F8 下去,可以发现程序的逻辑是:将输入数据的每位与 main 的每位分别异或
例如我们输入了 11111,那么第一位 1 会先与 m 异或得到符号, 符号在与 a 异或得到 = 符号……直到最后一次异或运算得到了:符号,
接下来程序从刚才输入数据的第二位 1 开始,继续上述操作,最后结果也得到了:符号。
如果跑完整个流程,我们输入的 111111 应该变成了 :::::
见图,第二位运算完成后的结果如下:

最终结果如下:

这之后程序跳出了循环,继续 F8,可以发现程序又在 eax 中放入了一串疑似 base64 的字符串:

再往后就回到了 try again 了:

这串 base64 可以在参考文本字符串中看到:

解码后结果为:mgjlpO8F?Ts:R?T|?Ex^Bv

所以程序的逻辑大概可以猜测出来了:输入一串字符,将其每位与 main 每位分别异或,最后与串 mgjlpO8F?Ts:R?T|?Ex^Bv 对比,若不同则 Try again
那么我们可以自己写一个 exp:把 mgjlpO8F?Ts:R?T|?Ex^Bv 每位与 niam 每位分别异或,就可以得到我们一开始应该输入的串

exp 没啥难度,基本字符串操作,直接上代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{char s1[100]="mgjlpO8F?Ts:R?T|?Ex^Bv";
    char s2[100]="niam";
    int i,j;
    for(i=0;i<strlen(s1);i++)
        for(j=0;j<strlen(s2);j++)
        {s1[i] = s1[i] ^ s2[j];
        }
    puts(s1);
    return 0;
}

得到结果,看上去是个 flag 格式。

输入原程序中看看结果:

success,得解:

flag{D3M4_x1Y4_w4NsUI}

省赛的逆向题目貌似就这些了,还是比较基础的。希望能帮到大家。
顺便吐槽一下网络安全大赛居然没有 Web 题……

正文完
 0