跨境派

跨境派

跨境派,专注跨境行业新闻资讯、跨境电商知识分享!

当前位置:首页 > 卖家故事 > HIT 计统实验2 二进制炸弹(gdb破解版) 拆弹过程

HIT 计统实验2 二进制炸弹(gdb破解版) 拆弹过程

时间:2024-04-11 20:25:27 来源:网络cs 作者:峨乐 栏目:卖家故事 阅读:

标签: 过程  实验  二进制  炸弹 
阅读本书更多章节>>>>

CSAPP 实验2是一个很好玩的实验,网上有很多参考资源写的都很好,本文增加了一些具体细节。

想要我的炸弹可以私信我。  炸弹6 7 有时间再拆

明明内容都是自己写的 但是为什么CSDN说版权问题不通过,很难理解。 

gdb调试笔记(持续更新)_gdb step out_Zerg Wang的博客-CSDN博客

补充 gdb单步运行的方法: 找到函数断点 然后si单步进行

222425c7e3194fc28b626a087419f761.png

第1章 实验基本信息

1.1 实验目的

熟练掌握计算机系统的ISA指令系统与寻址方式熟练掌握Linux下调试器的反汇编调试跟踪分析机器语言的方法增强对程序机器级表示、汇编语言、调试器和逆向工程等的理解

1.2 实验环境与工具

1.2.1 硬件环境

Intel 10850H x86_64

1.2.2 软件环境

Ubuntu 20.04

1.2.3 开发工具

Vim、gdb、visual studio

1.3 实验预习

认真学习gdb的用法与汇编语言相关知识

了解一些cmd指令,比如看计算器 cmd+calc

cmd命令以及用法大全_cmd命令操作_qq_38196334的博客-CSDN博客

第2章 实验环境建立

2.1 Ubuntu下CodeBlocks反汇编(10分)

CodeBlocks运行hello.c。反汇编查看printf函数的实现。

要求:C、ASM、内存(显示hello等内容)、堆栈(call printf前)、寄存器同时在一个窗口。

注意:如果想调试的话必须建立工程,血的教训!!!!

测试代码:

#include<stdio.h>int m = 0;int r = 3;int sum(int x1,int x2,int x3,int x4, int x5,int x6,int x7,int x8){    return x1+x2+x3+x4+x5+x6+x7+x8;}int main(){    m = m/r;    m = sum(1,2,3,4,5,6,7,8);    printf("%d\n",m);    const char* a= "Hello-2021112114-lyx";    printf("Hello-202111-xiaoyu");}

进行调试:

74803f67723c42e5bc14964c99f4bd5c.png

 查看变量m的值:

6c730f81fc2349a88a8c25b0527b5edb.png

bd4118ab3e0844dca38acaef4d1f016f.png

如图所示(橙色荧光标注),由于数据在计算机中采用小端存储,所以是0000000..24(十六进制)转换成十进制就是36

查看字符串2021112114-lyx:

方法1:字符串在字符串表里,你这个是字符串常量,它的值是个const char*,你如果想看可以用一个const char*指向它然后查一下这个地址

c53302ddaea846ab885621cf55a338d7.png 方法2:通过rip查找,也就是查看PC的值,然后去访问那个地址,把字节开到最大就能找到字符串。

82115e0df70c4ce2a3b616e6f601b3c0.png

将rip的地址输入,把字节调到最大就能找到,这里显示的是printf中的参数,不是const char *的参数,一个是字符库一个是位于数据区和代码区 

ef65674689f344bbb19ad474b19210b5.png

本来想拿edb看虚拟地址,但是有保护机制,每次运行的虚拟地址不一样。

2.2 Ubuntu下EDB运行环境建立(10分)

用EDB调试hello.c的执行文件,截图,要求同2.1

gcc hello.cedb --run a.out

59adeb191581493a973b90b33d9d8582.jpeg

 点完run 以后一直step into 不要问为什么QWQ

第3章 各阶段炸弹破解与分析

前几阶段的密码:防止笔误

I was trying to give Tina Fey more material.0 1 1 2 3 53 g 20714 75 115

每阶段30分,密码10分,分析20分,总分不超过80分

汇编器将汇编代码翻译成二进制指令

cd 到所在文件夹gdb bombb phase_1 #设置断点runni 单步运行一句 ni 2单步运行两句layout asm 调试查看方便一些
objdump -d ./bomb > bomb.s翻译成汇编代码

3.1 阶段1的破解与分析

密码如下:I was trying to give Tina Fey more material.(注意标点).

破解过程:

f6745b483b72410080f8fb74cdc15e7f.png

 调用了string not equal函数,如果不相等,就跳转到炸弹爆炸函数,推测比较的字符串在寄存器里,此外可以看到两个push将参数入栈,是为strings_not_equal()准备的。根据函数名,可以知道这个函数是在比较两个字符串是否相等,所以push的很有可能就是一个答案字符串所在地址(如果是程序自带的变量包括字符串等都会在.rodata部分,所以压栈时会直接压入对应地址,另一个来自标准输入的字符串地址。所以利用gdb查看输入和比较的字符串。

e2327fb766c240e3a48f32276ce8afac.png

3.2 阶段2的破解与分析

密码如下:0 1 1 2 3 5 

破解过程:光看汇编代码就能破解。

 根据汇编代码推测,第一个参数的位置在$rbp-0x30(位置) 第二个参数在$rbp-0x2c(44)的位置根据规律依次减少四,存入参数地址。首先判断第一个和第二个数是不是0和1,ebx相当于计数器i记录循环的标志,-0x30(%rbp,%rax,4)相当于数组是输入的参数以偏移量的形式展示。$rdx和$ebx是相等的,ecx比eax少1,显示不同顺序的参数,由add    -0x30(%rbp,%rcx,4),%eax相当于一个斐波那契数列,递归的起点是0 1,递推式是fib(n) = fib(n-1)+fib(n-2)

0000000000401414 <phase_2>:  401414:55                   push   %rbp  401415:48 89 e5             mov    %rsp,%rbp  401418:53                   push   %rbx  401419:48 83 ec 28          sub    $0x28,%rsp  40141d:48 8d 75 d0          lea    -0x30(%rbp),%rsi  401421:e8 c8 05 00 00       call   4019ee <read_six_numbers>  401426:83 7d d0 00          cmpl   $0x0,-0x30(%rbp)        //第一个数是不是0  40142a:75 06                jne    401432 <phase_2+0x1e>    //不相等或者不为0  40142c:83 7d d4 01          cmpl   $0x1,-0x2c(%rbp)//同理  401430:74 05                je     401437 <phase_2+0x23>//如果第二个参数不是1引爆炸弹  401432:e8 95 05 00 00       call   4019cc <explode_bomb>  401437:bb 02 00 00 00       mov    $0x2,%ebx// i = 2  40143c:eb 08                jmp    401446 <phase_2+0x32>  40143e:e8 89 05 00 00       call   4019cc <explode_bomb>  401443:83 c3 01             add    $0x1,%ebx//i = i+1=3  i=4 i = 5  401446:83 fb 05             cmp    $0x5,%ebxif(i!=5)  401449:7f 1e                jg     401469 <phase_2+0x55>//我们的目标是安全循环出来  40144b:48 63 d3             movslq %ebx,%rdx//rdx = 2 rdx = 3  40144e:8d 4b fe             lea    -0x2(%rbx),%ecx//ecx = 0 ecx = 1 ecx = 2 ecx = 3  401451:48 63 c9             movslq %ecx,%rcx  401454:8d 43 ff             lea    -0x1(%rbx),%eax//eax = 1eax = 2 eax = 3 ecx = 4  401457:48 98                cltq     401459:8b 44 85 d0          mov    -0x30(%rbp,%rax,4),%eax//传入第二个参数 传入第三个参数  40145d:03 44 8d d0          add    -0x30(%rbp,%rcx,4),%eax//a2'=a1+a2=1a3'=a2+a3=1+a3  a4'=a3+a4 a5=a4+a5  401461:39 44 95 d0          cmp    %eax,-0x30(%rbp,%rdx,4)//a3=a2'=1?a4=a3'=a3+1?  a5 = a4'? a6=a5'=a4'+a5=2(a3+1)+a5?  401465:74 dc                je     401443 <phase_2+0x2f>  401467:eb d5                jmp    40143e <phase_2+0x2a>  401469:48 83 c4 28          add    $0x28,%rsp  40146d:5b                   pop    %rbx  40146e:5d                   pop    %rbp  40146f:c3                   ret    

3.3 阶段3的破解与分析

密码如下:3 g 207(答案不唯一)

破解过程:

gdb bombb phase_run sol.txt
 首先当然还是先观察phase_3的汇编代码,看是不是调用了有关输入的参数的函数:在sscanf函数调用后检查$eax,因为sscanf在参数匹配成功后会将匹配成功的参数的个数放入eax中返回,所以检查eax是否大于2,即至少应匹配三个参数才能过第一个爆炸点.

367fea93a7cd4bb19de5833d32d83033.png

确定输入字符串的格式: %d %c %d 

4f737705410b486aa3923e79876e2535.png

 08fe27a63cff48bf917911e5665bd2ff.png

                        推断出$ rbp - 0x4存的是第一参数,并且必须小于7,这里就以3为例

06fe474cebf94a3cbf8e7eae9fe6d3cb.png

x/x 地址 #查看地址存的数据第一个x代表查看内存内容 第二个x代表以十六进制的形式显示

461ac0ea3e424f1aa637fe8e36d42ca7.png

                                         猜测:判断第三个参数和0xcf也就是207是否相等

3d7c0458750343d19463e110e5c9119e.png

e93eba6a2ace48cbbf0479450f884be3.png

3d45799abfed4cb58011dd424932ba4e.png

                  猜测rbp-0x9位置存放的是字符,再根据acii码对比可知103--g,第二个是比较ACII码

76a9d9bed2c04d6a833747088bcb3bae.png

 3.4 阶段4的破解与分析

密码如下:14 7

破解过程:

gdb bomb b phase_4r sol.txt #推荐把前几关的密码写入文件中nilayout asmx/s 地址  #查看字符串形式的输入格式

破解过程相信大家已经轻车熟路了,首先查看输入的形式,输入两个数字,如果输入的数字个数不是2,就会引爆炸弹。

22101c00e5c24ab69c0bc01c638b1465.png

 根据寄存器的使用规则,arg1作为函数的第三个输入参数,他的存放地址由寄存器rdx来确定,对于第四个参数他的寄存地址由rcx确定,接下来我们要根据代码确定arg1和arg2的具体数值。3fccc35c07424c0fa3ccecbeaabc9ced.png

604c6e4065c24605b6b7e8cad46d0dae.png

1.测试数据 99 88; 通过测试发现$rbp-0x4储存的是第一参数,下方的test是判断是不是等于0的操作。

773e19cd386e420ba414543608e77465.png

2.接着单步运行发现不仅要大于0,而且还不能大于0xe也就是15 

3.紧接着,执行了三条赋值语句,可以推测三条mov指令是为fun4准备参数 

d82e00e0971c47dba58383fd97972c93.png

eccbaf8ae8d14614bc868f2d7a4c2673.png

4.关于fun4如何执行我们之后再看,我们先看fun4执行完之后的代码

6d0ea7f6eeec4bdd8d01cce048a12cd3.png

根据寄存器的使用规则,函数返回值必须放在rax中,所以返回值必须为7,否则会引爆炸弹。

第二个cmpl函数cmpl -x08(rbp),用来比较agr2和7的大小,所以可以确定第二个输入参数为7,我们进一步缩小范围,第一个数小于等于14第二个数是7

5.下面我们来分析一下函数fun4的代码:

627c7a65489847ddaa91bb0911fafacf.png

                                                                 测试数据

49ad18137ac74dd9b509cace7c4ab117.png

50a364577b5c488ab82e41229c140630.png

(gdb) i r

         在调用函数之前查看寄存器 rax 存放第一个值 rdx =14 rsi = 0 rdi存放函数的第一个参数,如果相等那么mov    $0x0,%eax返回值是0不是7,就不符合要求,所以一定是在函数中跳转结束的。

看代码:

00000000004015be <func4>:            (edx=14 ecx =7 esi=0)  4015be:55                   push   %rbp  4015bf:48 89 e5             mov    %rsp,%rbp  4015c2:89 d1                mov    %edx,%ecx    #此时ecx = edx=14  4015c4:29 f1                sub    %esi,%ecx    #ecx = ecx = 14  4015c6:89 c8                mov    %ecx,%eax    #eax = ecx = 14  4015c8:c1 e8 1f             shr    $0x1f,%eax   #逻辑右移eax >> 0x1f(31)逻辑移位 相当于左移一位 此时eax应该是0 因为不能保证精度  4015cb:01 c8                add    %ecx,%eax   #eax = eax+ecx =14  4015cd:d1 f8                sar    %eax   #移位的位数等于1时,可以省略 对eax进行算数算数右移一位的操作,可以看成这个数除以2 eax = 7  4015cf:01 f0                add    %esi,%eax   #eax = 0+eax = 7  4015d1:39 f8                cmp    %edi,%eax   #7和第一个参数对比  4015d3:7f 09                jg     4015de <func4+0x20>#如果比第二个参数大话,edi[7,14]  4015d5:7c 13                jl     4015ea <func4+0x2c>#如果小的话  4015d7:b8 00 00 00 00       mov    $0x0,%eax  4015dc:5d                   pop    %rbp  4015dd:c3                   ret      4015de:8d 50 ff             lea    -0x1(%rax),%edx  4015e1:e8 d8 ff ff ff       call   4015be <func4>  4015e6:01 c0                add    %eax,%eax  4015e8:eb f2                jmp    4015dc <func4+0x1e>  4015ea:8d 70 01             lea    0x1(%rax),%esi  4015ed:e8 cc ff ff ff       call   4015be <func4>  4015f2:8d 44 00 01          lea    0x1(%rax,%rax,1),%eax  4015f6:eb e4                jmp    4015dc <func4+0x1e>

第一轮调用:如果是jg eax = 7 ecx = 14 edx = 14  让rax+1

 4015ea:8d 70 01             lea    0x1(%rax),%esi  4015ed:e8 cc ff ff ff       call   4015be <func4>

5c9faface65345f6bf84275b2e01b978.png

 只有函数返回值为1的时候递归才结束,此时返回值一定是eax = 2*0+1 = 1

要想让eax= 7只有调用7次,也就是eax增加七次所以7+7 = 14或者7-7=0;又因为前面的限制条件所以第一个参数不能为0,所以密码只能是14 7;

ecx = edx = 6 eax = edx = 6 eax = 0 eax = 6  eax = 3 eax = 3

faa91eb8e0f045a4b564076d3ceac0e2.png

3.5 阶段5的破解与分析

密码如下:5 115

破解过程:

老规矩我们先分析一下汇编代码

7883e66c9cd041c5961e9fbd5f38d777.png

 确定参数地址和输入形式

0d27cb4d0d6143baa8f918ff63d98263.png

 and一个都是1的数字,没有啥作用,作用主要是生成标志位判断是不是0。指令and    $0xf, %eax取得第一个参数的后四位,且要求第一个参数不能是15,edx为计数器,ecx为累加,根据当次循环eax的值去寻址mov    0x403200(,%rax,4),%eax取到数组中的下一个不连续的元素,结束循环的条件是eax取到15时edx计数到15次,第二个参数与ecx相等。查看地址    0x4031e0(,%rax,4)的元素,观察数组有唯一确定的跳转表将这些值累加得115 其实直接最后看看ecx就行

     3-12-7-11-4-13-6-9-4-8-0-10-1-2-14-6-15

cffe7682f4944072b78c753d91113167.png

94d3e54138f446fd9062902e0f0d7cb5.png

0db7781e0b2b4b6f83ab3292ca5b263f.png

daa4e296c26a48fa99be2d2de0f85267.png

                                         3-12-7-11-4-13-6-9-4-8-0-10-1-2-14-6-15

7cf18a7314cb4d88a0ec55cfc2143d44.png

                                        最后和ecx比较是不是相等 

 参考:

CSAPP第二次实验 bomb二进制炸弹的破解_FatFat-Whale的博客-CSDN博客

汇编学习记录-两种架构汇编指令简单总结_此号已废20的博客-CSDN博客

B站九曲阑干 

哈工大各位大佬

阅读本书更多章节>>>>

本文链接:https://www.kjpai.cn/gushi/2024-04-11/157282.html,文章来源:网络cs,作者:峨乐,版权归作者所有,如需转载请注明来源和作者,否则将追究法律责任!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。

文章评论