您的位置:首页 > 其它

攻防世界新手逆向题

2020-05-05 12:23 387 查看

一共九道题:

1.Hello,CTF(输出格式转换)

拿到文件先运行一下。发现不管输入什么都是wrong,同时程序循环输出“please input your serial:”。需要找到一个正确答案。

用ida(32位)打开文件进行分析,大概流程是输入的字符串转换后若与v13相同,则success。其中关键的转换函数sprintf,指的是字符串格式化命令,主要功能是把格式化的v4写入v8中。

点开其参数asc_408044发现其为’%x’,意思是以十六进制的形式输出整数。由此可知输入的正确答案转换成16进制数后为v13。

用在线转换工具将v13转换成字符串,(这也是flag):

2.insanity(关键参数)

文件放到虚拟机中运行一下,没有输入,“wait…”过了几秒后输出第二行

用ida打开文件查看主函数,发现关键在输出的函数中。

该处puts()函数与常用形式不同,查看特殊变量strs,找到flag:

3.Python-trade(pyc文件需要反编译)

尝试运行文件发现乱码:

查看其文件类型,发现后缀是pyc, 是python编译产生的中间文件。

使用在线工具进行反编译:(Python反编译在线工具)。发现correct字符串是由flag转换得到的。其中ord函数是返回参数的ASCAII码值,chr函数是返回该ASCAII码值所对应的字符。

因此写出一个倒推出flag的脚本,运行之后得到flag:

4.simple-unpack(加壳的二进制文件)

(1)直接搜索字符串:

题目已说明这是个加壳的文件,用ida直接打开只有几个函数。

在ida上搜索字符串"flag"并无结果。尝试用WinHex打开文件搜索“flag”:

能找到一串“flag{…}”形式的文字,复制粘贴到记事本出现乱码,把乱码删去的“flag{Upx_1s_n0t_a_d3liv3r_c0mp4ny}”就是flag…

(附上一篇关于WinHex的介绍)

(2)脱壳:
用以下工具打开,发现是加了upx壳的64位文件。

在电脑上搜索“cmd”打开命令提示符,按“ upx路径 -d 目标文件路径 ”输入命令即可对该文件进行脱壳。(upx需要到“upx官网”上下载)

5.logmein(大小端读取的问题)

先查壳,确定是没有加壳的64位文件。

用ida打开查看主函数,发现当输入的s满足关键条件(s[ i ] == (char)(((_BYTE *)&v7 + i % v6) ^ v8[ i ]))的时候就correct。

由此写出一个倒推出s的程序,运行得到 flag :
1.文件中v8定义的长度是8,因为strcpy( v8, “…”) 中赋给v8的字符串长度(18)超出了定义的范围,v8实际存储的是整个字符串,所以strlen(v8)==18。
2.第一次运行的时候v7初始化为“ ebmarah ”,结果出现乱码,猜测该文件采用了小端模式存储变量,即在低地址存放低位数据。所以猜测正确的v7应该是倒着读的“ ebmarah ”。
3.由文件的第一个 if 可知 s 的长度 >= 18,由第二个 if 可知 (s 的长度-1 ) < 18,可推测 s 的长度也为18。所以让循环体循环18次。

6.no-strings-attached(用idapy获取存储内容)

题目描述是“有的程序运行就能拿Flag?”,先放到虚拟机里运行一下。

查壳,并没有加壳,是32位文件。

用32位ida打开文件查看主函数,发现前面的函数用wprintf函数输出了文字,与第一次运行的时的输出的前两行和最后一行文字相符。

查看最后一个函数,只要ws和s2相同就success。

关键在于给s2赋值的decrypt函数:从循环体来看,要知道dest的内容必须知道a2(dword_8048A90)的内容及a2(dword_8048A90)、s的长度。

查看相关变量,长度和内容未知。因此使用快捷键“ * ”查看数组的起始大小:
a2(dword_8048A90)长度为6,s 长度为39。但是a2(dword_8048A90)的内容仍未知。

此时可用 idapy 写一个脚本,让其输出 s 和 a2(dword_8048A90) 的内容:
append函数的作用相当于拷贝

两个参数的长度和内容确定后,可根据原decrypt函数写出一个相似的脚本,直接输出dest的内容:
(两个参数最后一项都是0L,即字符’\0’,可将其删去,同时长度-1)

(该方法参考了原网站的witte up,还可以在虚拟机上用gdb动态调试:在decrypt函数处下断点,运行程序后找到关键地址,返回ida查看该地址附近的汇编指令,发现生成的字符串存储到寄存器eax中后,查看当前eax中存储的内容,通过字符串的转换得到flag)

7.getit(算法)

先查壳,是64位未加壳的文件。用ida打开查看主函数:
1.查看变量s的内容,用快捷键“ * ”查看其长度:33。因v5从0开始+1,所以循环总共进行33次。
2.查看 t 的内容,是一个char字符,地址+10刚好到下一个变量 harifctf{…} 括号的内容。用地址间的差值可算得括号里的内容共33个字符,推测该循环体是对 s 进行加密后存储到 harifctf 中。

3.之后的函数利用了地址的偏移把字符一个个写到stream指向的位置上。写进去的字符的地址偏移与当前指针的偏移是相同的,所以此处并没有进行加密,相当于把 t 地址之后的内容赋值到flag文件中:

最后再写一个推算出括号内容的程序:

最后把它放到括号中,flag还要加上字符t存储的字符‘S’,因为在写进去的时候是从t开始写的:
SharifCTF{b70c59275fcfa8aebf2d5911223c6589}

8.csaw2013reversing2(OD动态调试)

先查壳,没有壳。题目说运行会有乱码那就先运行一下,弹出一个窗口:

用ida打开查看主函数。在 if 语句中,sub_40102A函数的返回值可直接查看,是0;而另一个函数点开之后只有地址,没有函数内容。因为两个函数的返回值参与了或运算,所以要知道第二个函数的内容到底是什么。

用 tab 键切换到汇编指令查看第二个函数的具体操作:发现在 int 3 处有“ Trap to Debugger ”。

此处 call 的sub_401000 函数在 if 语句中,执行完该函数之后就exitprocess(0xFFFFFFFF)非正常退出。查看该函数内容,对数字进行一系列运算后返回,猜测是产生乱码的过程。推测 call 前面的 int 3断点处储存的flag尚未变成乱码。

用od打开文件,不断按F8直到停在这一步,并弹出了之前运行时看见的乱码对话框:在这里下个断点。

按ctrl+f2 重新载入函数,按 F9运行到断点处,再按F7单步步入,在新的界面中能找到之前的IsDebuggerPresent函数,下面的汇编命令也一一对应。

此刻返回ida对应着看函数的关系:
1.call isdebuggerpresent函数后进入 loc_401096函数,期间有个INT3断点要去掉,改为NOP。
2.JE命令表示执行完当前函数后转到 loc_4010B9函数,该函数即输出对话框的函数。可以利用它输出未乱码的 flag。

因此作出以下三处改动:
1.TEST后面的JE改成NOP,让其顺序进行。
2.INT3处改成NOP。
3.利用紧接着的 JMP 指令,把地址改成00F910B9,直接跳到对话框的函数输出。

返回上几步取消断点,回到开头之后按F8一步步运行,最终得到flag:

9.maze(迷宫题)

先查壳,是64位无壳ELF文件,所以先拿到虚拟机里面运行一下:

用ida打开查看主函数并分析:按顺序,迷宫的左右上下坐标分别为 ‘O’, ‘o’, ‘.’, ‘0’。


查看关键的asc_601060,遇到 ‘#’ 后输出“Wrong Flag”,猜测这是迷宫地图,而且结束的位置在’#'字符处:

用 shift+E 获取内容,转换成ida生成的伪C代码并导出:

导出后仍是一行字符串,需要将其排成一个方阵。变量的长度是65(含‘\0’),可排成8*8的方阵,之后找到走出迷宫的路线:nctf{o0oo00O000oooo…OO}。(迷宫的左右上下坐标分别为 ‘O’, ‘o’, ‘.’, ‘0’)

(附上迷宫问题的链接)

Wong Chiying ; ) 原创文章 5获赞 0访问量 188 关注 私信
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: