由于最近在学习binary,来拿几道练练手,感受比国赛简单多了(但愿今年也这样…)。大多都是工具的基础使用。
写了re部分的wp,若有错误和更简单的解法欢迎大师傅们指点。linux
打开附件,先拖进Exeninfo看看是什么类型。是一个32bit的ELF。c++
因此拖进ida32,找到main函数,F5一下得到反汇编后的结果。数组
分析一下,程序用memset开辟了几个连续的内存空间(能够认为是数组)v3,v4,v5.而后开始赋值。
一开始很懵。后来发现,问题在于赋的值真的只是数字吗?咱们知道即便是字符串,在内存空间中存储也是以数(ascii)的形式表示的。
因此咱们点一下v3第一块空间的值,按R(转为字符)看看有什么结果。
果不其然,GALF。看来程序实现的是一个反转字符串的功能。直接把剩下的变量全转为字符。得到flag。安全
FLAG-4092849uio2jfklsj4kl
(这是逆向题?)网络
无语的题目。
拿到附件,首先发现他不是一个可执行文件。扔进ida显示是一个二进制文件。也没法反汇编。从题目得知应该是一个内存取证的题目(用linux挂载啥的,还没太接触过)。
而后无语的地方出现了,用ida按下shift+F12(查看字符串)。其中发现了:
行吧。(看来挂载以后,也是去找mnt/test/Flag.txt就能够得到flag了)函数
flag{yc4pl0fvjs2k1t7T}
严格意义上的第一道逆向题。首先先分析:
一个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没啥难度,基本字符串操做,直接上代码:ui
#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题……