AliCTF2014题目解析之<reverse-300>

reverse-300


工具:IDA pro、WinDbg、UPX、Resource Hacker



先运行程序看效果

点击按钮直接崩溃,同时由于程序放到32位的xp虚拟机中不能运行,应该是64位程序。
根据提示程序本身就是有问题的,所以直接上IDA pro,发现貌似是用UPX加了壳的:



使用UPX脱壳看看

成功!运行Ch3_d.exe看看效果

这效果。。。直接不能运行了,脱壳之前还可以弹出窗口来着!再从新脱一次壳,还这样,好吧,it‘s a trap!



用windbg分析一下崩溃的原因:把windbg注册为及时调试器,再运行Ch3_d.exe

崩溃的地址为
00000001`3fc81dcd 85c0 test eax,eax
IDA pro中视图导航到该地址,发现载入的基址不对(往下看就知道原因了),在windbg中用LM命令看一下模块情况

基址为13fc80000,在IDA pro中rebase后,查看崩溃点

嗯,和windbg中看到的情况一致,调用_initterm_e函数后就崩溃了,崩溃指令位于_initterm_e:
call rcx ;rcx=0x140001f2c
到这里我困惑好久(唉,菜啊),分析过程如下:
搜索一下 initterm函数,功能大体是执行给定的函数,call rcx出错,估计rcx的值应该就是Ch3_d.exe传递给initterm的参数了,是个函数地址,因此在IDA中搜索2c 1f 00,确实找到了0x140001f2c,0x140000000是64程序的默认加载地址,看来Ch3_d.exe还以为自己被加载到默认地址了呢。
分析到这里(还要分析才明白,一个字,菜!),就很明白了,是vista之后引入的随机基址的问题,依稀记得《0day安全》那本书上讲了相关内容(13章,ASLR),看了一眼,改下注册表就行了(这里就不写具体操作了,需要的可以自己去查,另:改PE头也可以避免这个问题)。



改完注册表,重启,运行程序,成功!激动地去点【Find The Key】,崩~~,windbg弹出来了,又崩溃了!什么情况?没办法,继续分析,看一下崩溃点附近的情况

加载DecryptDll.dll,导入RASDecrypt函数,DecryptDll.dll在哪?还能在哪,估计就在Ch3_d.exe的"肚子里了",用resource hacker看一眼

果然有个DLL,导出来重命名一下,再运行,我看你还崩!?



额,好吧,果断的。。。windbg又弹出来了,不费话了,看看什么情况,

崩在DecryptDll的RSADecrypt函数里了,用IDA加载DecryptDll看一眼(注意基址),

是崩在memcpy函数了,根据64位程序的调用约定,memcpy的三个参数依次为rcx(dst),rdx(src),r8(len),使用windbg跟踪到call memcpy

寄存器情况如图,rcx=0,rdx=21dc56,r8=15,可见是目的地址rcx的问题,在IDA中跟踪rcx,最跟踪到
DecryptDll!RSADecrypt的r8参数,r8应该是个有效的地址。
看一眼Ch3_d.exe调用DecryptDll!RSADecrypt时的参数情况

好吧r8=0,怪不得呢,看源码是故意用xor给清空了
那么只要在调用DecryptDll!RSADecrypt之前把r8改成一个可写的地址就行了,在该地址得到如下字符串

但是弹出的对话框中没有任何内容,但是看大神说这就是flag,就不继续分析了。


  1. k*&>(da30_q-([email protected],

最后总结一下“考点”吧(菜鸟观点):

  • UPX脱壳
  • 64位程序的调试
  • ASLR机制
  • 资源提取

来自为知笔记(Wiz)

时间: 2024-10-07 13:00:47

AliCTF2014题目解析之<reverse-300>的相关文章

AliCTF2014题目解析之&lt;reverse-200&gt;

reverse-200 工具:procmon.immunity dbg.idapro 首先通过procmon观察ch2.exe发现ch2.exe需要读取flag.txt,可以分析出ch2.exe是要读取flag.txt内容,加密后写到flag.crpyt目录下创建一个flag.txt,写入aaaaaaaaaaaa,再次使用procmon观察根据ch2.exe的api调用过程,开始动态调试首先 bp ReadFile直接断在读取flag.txt的过程,继续执行到用户代码用IDA pro打开ch2.

There&#39;s Treasure Everywhere! poj1473题目解析

题目: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 总时间限制:  1000ms 内存限制:  65536kB 描述 Finding buried treasures is simple: all you need is a map! The pirates in the Caribbean were famous for their enormous buried treasures and their elaborate maps

增量备份,11g052题目解析

增量备份分为差异备份(differential incremental backup)和累积备份(cumulative incremental backup),这是两种执行增量备份操作的不同方法. 80. You perform differential incremental level 1 backups of your database on each working day and level 0 backup on Sundays, to tape. Which two stateme

部分单调队列优化 DP 题目解析

这里专门放一些单调队列优化 DP 的题目,并加上简要解析. Luogu P1725 琪露诺 易得转移方程为 $$f_i=\max_{j\,=\,\max(i-R,\;0)}^{i-L}f{_ j}+a_i\;(L \le i \le n)$$ 那么,其中 $\max$ 部分可以看成一段区间的最大值,用单调队列维护. 然后答案是 $$\max_{i\,=\,n-r+1}^{n} f_i$$ 时间复杂度 $O(n)$. 部分单调队列优化 DP 题目解析 原文地址:https://www.cnblog

第七届蓝桥杯C/C++B组省赛题目解析

题目1:煤球数目 有一堆煤球,堆成三角棱锥形.具体:第一层放1个,第二层3个(排列成三角形),第三层6个(排列成三角形),第四层10个(排列成三角形),....如果一共有100层,共有多少个煤球?请填表示煤球总数目的数字.注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字. 解析: 第一层:1个. 第二层:2*3-3=3个. 第三层:3*3-3=6个. 第四层:4*3-3=10个. 代码如下: int s=0,a=0; for(int i=1;i<=100;i++){ a=a+i;

英雄会题目解析- 第五届在线编程大赛月赛第三题:石子游戏

题目: 甲乙两人面对若干堆石子,其中每一堆石子的数目可以任意确定.两人轮流按下列规则取走一些石子,游戏的规则如下:1.每一步应取走至少一枚石子:2.每一步只能从某一堆中取走部分或全部石子:3.如果谁无法按规则取子,谁就是输家.如果甲乙两人都采取最优的策略,甲先拿,请问,是甲必胜还是乙必胜.输入格式:多组数据,每组数据两行,第一行是一个整数N, 2<=N<=10000下一行是N个正整数,代表每堆的石子数,石子数在32位整数内.输出格式:每组测试数据输出一行,如果甲存在必胜策略,输出"W

Sun考试认证题目解析(强力推荐,巩固基础)

转载请注明出处:http://www.ming-yue.cn/java-basic/. 1,给定以下代码,求j的值. public class Test { public static void main(String[] args) throws Exception { int i = 0xFFFFFFF1; int j = ~i; } } A. 0 B. 1 C. 14 D. –15 E. An error at line 3 causes compilation to fail. F. A

JS经典题目解析

此次列举出一些觉得有意思的JS题目(来源于出了名的44题),相信有非常多关于这些题目的博客,写这篇博客的目的在于巩固一些知识点,希望能和读者共同进步. 1. map函数执行过程 ["1", "2", "3"].map(parseInt) 答案: [1, NaN, NaN] 解析: map(function callback(current, index, array)), map 回掉提供三个参数,current value, index of

re 模块, 正则表达式 \w+\d+ 的重复问题引发的题目解析

题目 计算以下代码的结果 s = "?!.18)dajslj$12.15613sdadw.123sdasda35615.168sndsda$15.6sdasd.sdfsdgw123.156s" p1 = re.compile("\w+\.\w+\d+\.+\d+") print(p1.findall(s)) p1 = re.compile("(\w+)\.(\w+)((\d+)\.+\d+)") print(p1.findall(s)) 答案 #