【CSAPP】探究BombLab奥秘:Phase_4的解密与实战

举报
SarPro 发表于 2024/02/04 23:41:43 2024/02/04
【摘要】 《【CSAPP】探究BombLab奥秘:Phase_4的解密与实战》深入解析了CSAPP(Computer Systems: A Programmer's Perspective)课程中的BombLab实验,特别关注了第四阶段(Phase_4)的解密与实战过程。文章详细介绍了学习者如何应对该阶段的挑战,透过逆向工程、汇编语言分析等手段揭示程序背后的奥秘。通过深刻的实践,读者将更好地理解计算机系统底


1.gif

2c3b549f930dc81c1bb64cca20bce92e.gif

7dd2b7f171704327b7d8987c49da4628.gif


📋 前言

🌈个人主页:SarPro
🔥 系列专栏:《CSAPP | 奇遇记》
⏰诗赋清音:笔墨奔雷动,心随翠浪飞。山川蕴壮志澎湃,梦驭风云意悠远。

 🎉欢迎大家关注🔍点赞👍收藏⭐️留言📝
 🔔作者留言:

欢迎来到我的【CSAPP】炸弹实验室!这里是探索计算机系统世界的秘境,我的学习笔记博客为你打开CSAPP的炸弹之门。在这里,我不仅分享计算机系统的基础知识和高级技巧,还有着涉猎实用技术和项目经验的爆炸药水。无论你是初学者还是计算机大师,这个实验室会为你施展出神秘的学习魔法,帮助你在CSAPP的炸弹领域中踏上一场惊险之旅。准备好了吗?跟着我,让我们一起解除那些迷人的炸弹代码,揭示计算机系统的神奇面纱!


🌺1. CSAPP与Bomb简介

🍀1.1 CSAPP

《CSAPP》是指计算机系统基础课程的经典教材《Computer Systems: A Programmer's Perspective》,由Randal E. Bryant和David R. O'Hallaron编写。该书的主要目标是帮助深入理解计算机系统的工作原理,包括硬件和软件的相互关系,其涵盖了计算机体系结构、汇编语言、操作系统、计算机网络等主题,旨在培养学生系统级编程和分析的能力。

🍀1.2 Bomb

"Bomb实验" 是与CSAPP教材相关的一项编程实验。它是一种反汇编和逆向工程任务,旨在教授如何分析和解决复杂的程序问题。Bomb实验的目标是解开一系列的"炸弹",每个炸弹都有不同的解锁方法,需要分析程序的汇编代码,理解其工作原理,并找到正确的输入来解除炸弹。这个实验教授了计算机系统的底层知识,包括汇编语言和程序执行的原理。

资源获取:关注公众号 科创视野 回复  CSAPP Bomb实验


🌺2. bomb

🍀2.1 实验环境

  • VMware Workstation虚拟机环境下的Ubuntu 64位。

🍀2.2 实验过程

实验准备阶段:首先需要使用ubuntu联网环境跳转到链接下载实验所需的bomblab:Bomblab源文件

下载bomblab压缩包并输入

tar –xvf bomb.tar

进行解压缩,进入该目录所有文件如下所示:


在终端输入

sudo apt-get install gdb

安装调试器。基本用法参考下图:



实验过程阶段:

“Binary bombs”是一个可在Linux系统上运行的C程序,它由6个不同的阶段(phase1~phase6)组成。在每个阶段,程序会要求输入一个特定的字符串。如果输入的字符串符合程序的预期输入,那么这个阶段的炸弹就会被“解除”,否则炸弹就会“爆炸”,并输出“BOOM!!!”的提示信息。实验的目的是尽可能多地解除这些炸弹的阶段。

每个炸弹阶段考察了机器级语言程序的一个不同方面,难度逐级递增:

* 阶段1:字符串比较

* 阶段2:循环

* 阶段3:条件/分支

* 阶段4:递归调用和栈

* 阶段5:指针

* 阶段6:链表/指针/结构

在炸弹拆除任务中,还存在一个隐藏阶段。然而,只有在第四个阶段解决后添加特定的字符串后,该隐藏阶段才会出现。为了完成任务,需要使用gdb调试器和objdump反汇编炸弹的可执行文件,然后单步跟踪每个阶段的机器代码,理解每个汇编语言的行为或作用。这将帮助“推断”出拆除炸弹所需的目标字符串。为了调试,可以在每个阶段的开始代码前和引爆炸弹的函数前设置断点。

在终端输入

objdump -d bomb > bomb.asm

得到bomb的反汇编文件bomb.asm如下所示。



🍀2.3 Phase_4

Phase_4是Bomblab中的一道难度较大的炸弹题目,需要破解一个使用了跳转表的程序,以解除炸弹。在这个过程中需要运用一些调试技巧和汇编知识,逐步分析程序的运行逻辑,找到正确的输入值,解除炸弹。


通过逐行分析代码,发现phase_4函数的代码逻辑与phase_3函数的代码逻辑有很多相似之处。在代码的第12行,可以看到调用了scanf函数,该函数会读取用户输入的内容,并按照指定的格式进行解析。从这个函数的参数可以看出,它需要读取两个数字,并将它们分别存储在0x8(%rsp)、0xc(%rsp)中,因此可以暂时确定需要输入至少两个数字。但是,这并不意味着只有两个数字是正确答案,还需要进一步的分析才能确定正确的密钥。

在代码的40102c,可以看到调用了第一个explode_bomb函数. 这说明在输入错误的密钥时,程序会触发炸弹并终止运行。为了跳过这个炸弹,我们需要输入正确的密钥。根据代码的第401033行,我们可以发现需要满足输入的第一个数字不为2,才能跳过这个炸弹,因此,我们需要在输入时避免将第一个数字设置为2。

401058explode_bomb函数,这说明在输入错误的密钥时,程序会触发另一个炸弹并终止运行。为了跳过这个炸弹输入正确的密钥,根据代码的第40105f行,需要满足输入的第一个数字为0xe(14),才能跳过这个炸弹。


当成功输入6个参数并且满足特定的条件后,程序会进行一系列操作并将三个寄存器(%edx、%esi、%edi)赋值,接着将这些参数传入func函数中进行处理。首先,我们需要注意的是在输入6个参数后,程序会对第一个参数进行一系列的位运算操作,最终得到一个索引值并跳转到对应的地址处。这个地址指向了一个跳转表,其中每个元素都是一个8字节的地址。程序以输入的第一个参数作为索引,查找跳转表中对应的地址,并跳转到该地址处执行下一步操作。 接着,程序会将输入的6个参数按顺序存储到栈中,然后将第一个参数作为索引,从跳转表中查找对应的地址,并跳转到该地址处执行代码。这个地址指向了一个函数,这个函数的作用是将输入的参数分别存储到%edx、%esi、%edi寄存器中,并调用func函数进行处理。 在func函数中,程序依次对%edx、%esi、%edi寄存器中的值进行一系列位运算操作,并将结果存储到%eax寄存器中。最终,当func函数执行完毕后,程序会将%eax寄存器中的值与一个特定的值进行比较,如果相等则输出“Phase_4 defused”,表示成功解除炸弹;否则输出“BOOM!!!”,表示炸弹爆炸了。 在这个过程中,需要仔细分析程序的运行逻辑和寄存器的作用,理解程序的实现原理。通过逐步分析和调试,

程序执行fun4函数后,返回值存放在%eax寄存器中。为了避免调用explode_bomb函数,我们需要将%eax的返回值设置为0,并保证输入的第二个数为0(从地址0x(%rsp)获取)。

对于func4函数而言,它整体较为复杂,为了便于之后的分析,我们将其转换为对应的C代码:

//x: %edi y:%esi z:%edx k: %ecx t:%eax
int func4(int x,int y,int z)
{//x in %rdi,y in %rsi,z in %rdx,t in %rax,k in %ecx
 //y的初始值为0,z的初始值为14
  int t=z-y;
  int k=t>>31;
  t=(t+k)>>1;
  k=t+y;
  if(k>x)
  {
    z=k-1;
    func4(x,y,z);
    t=2t;
    return t;
  }
  else
   {
     t=0;
     if(k<x)
     {
        y=k+1;
        func4(x,y,z);
        t=2*t+1;
        return t;
     }
     else
     {
         return t;   
     }
   }
}

根据之前传入func4函数的两个参数,我们得知func4函数会将7存储到%eax和%ecx寄存器中,并将%edi里存储的输入的第一个数与%ecx寄存器中的值进行比较。

在代码分析中,可以发现在400ff2的代码中,当%edi的值大于等于7时,会将%eax置为0。因此可以尝试将第一个输入的数字设置为7,以此来获取想要的返回值。


如果%edi的值小于7,程序会进入400fe9处并再次调用func4函数,形成递归调用。虽然看起来很复杂,但我们可以通过代入寄存器中的值并记录它们的变化来推导出最终的结果。据此,我们可以得知第一个输入的数字为0、1、3、7,而第二个输入的数字为0。

在终端输入

./bomb

填入密钥0 0结果显示phase_4通关。

综上所述,Phase_4程序使用了一个跳转表来实现多个分支语句。具体来说,程序先将输入的第一个值存储到%eax寄存器中,然后执行一个间接跳转,跳转的目标地址存储在内存地址0x402470(,%rax,8)处。这里的%rax寄存器就是我们输入的第一个值。通过将输入的值作为索引,程序可以从跳转表中查找对应的目标地址,然后进行跳转。跳转表通常使用数组或者指针来实现,每个元素对应一个分支语句的目标地址。在Phase_4中,跳转表使用的是数组实现方式,每个元素占据8个字节,因此需要将输入值乘以8来计算数组元素的偏移量。 在Phase_4中,程序使用了一些位运算操作,需要仔细分析代码,理解其运行逻辑。具体来说,程序使用了“and”、“shr”和“cmp”等指令来对输入值进行位运算操作,并判断其是否符合特定的条件。

Phase_4中每句代码的作用解释如下所示。

000000000040100c <phase_4>:
  40100c:  48 83 ec 18              sub    $0x18,%rsp        //申请空间
  401010:  48 8d 4c 24 0c           lea    0xc(%rsp),%rcx    //传参,加载有效地址,将0xc(%rsp)设为num2
  401015:  48 8d 54 24 08           lea    0x8(%rsp),%rdx    //传参,加载有效地址,将0x8(%rsp)设为num1
  40101a:  be cf 25 40 00           mov    $0x4025cf,%esi    //scanf函数输入格式, %d %d
  40101f:  b8 00 00 00 00           mov    $0x0,%eax
  401024:  e8 c7 fb ff ff           callq  400bf0 <__isoc99_sscanf@plt>   //调用scanf函数
  401029:  83 f8 02                 cmp    $0x2,%eax         
  40102c:  75 07                    jne    401035 <phase_4+0x29>      //当scanf输入数据个数不等于2时,跳转至爆炸
  40102e:  83 7c 24 08 0e           cmpl   $0xe,0x8(%rsp)
  401033:  76 05                    jbe    40103a <phase_4+0x2e>      //jdb:无符号小于等于跳转,当num1小于等于14时,跳转至40103a,否则爆炸,所以num1的限制条件为[0,14]
  401035:  e8 00 04 00 00           callq  40143a <explode_bomb>
  40103a:  ba 0e 00 00 00           mov    $0xe,%edx            //%edx=14
  40103f:  be 00 00 00 00           mov    $0x0,%esi            //%esi=0
  401044:  8b 7c 24 08              mov    0x8(%rsp),%edi       //%edi=num1
  401048:  e8 81 ff ff ff           callq  400fce <func4>         //调用函数fun4,三个参数%edx,%esi,%edi
  40104d:  85 c0                    test   %eax,%eax
  40104f:  75 07                    jne    401058 <phase_4+0x4c>      //如果fun4返回值%eax不等于0,则跳转至爆炸,所以需要知道当num1为何值时,%eax为0
  401051:  83 7c 24 0c 00           cmpl   $0x0,0xc(%rsp)
  401056:  74 05                    je     40105d <phase_4+0x51>      //如果num2=0,则跳转至结束,否则爆炸,所以输入的第二个数据只能为0
  401058:  e8 dd 03 00 00           callq  40143a <explode_bomb>
  40105d:  48 83 c4 18              add    $0x18,%rsp     //释放空间
  401061:  c3                       retq  

🍀2.4 实验结果

以上代码均存储在bomb_idea.txt文件中,每行代表对应的关卡,各阶段密钥如下所示:

在终端输入

./bomb result.txt

显示全部通关。


🍀2.5 实验体会

  1. 逆向分析挑战: 探索CSAPP中的BombLab Phase_4实验,着眼于逆向分析,挑战了解密阶段的复杂算法。通过深度解析程序逻辑,成功解开了Phase_4的神秘面纱。

  2. 实战经验分享: 在实验过程中,学到了许多实战技巧,包括调试器的巧妙运用和汇编代码的精准理解。这些经验不仅提升了解题效率,也增强了对计算机系统底层运作的理解。

  3. 深度学习与收获: 通过参与Phase_4的解密过程,深刻理解了程序的运行原理和安全设计,为深度学习计算机系统打下了坚实基础。这次实验不仅是知识的获取,更是对计算机科学深度思考的契机。


📝 总结 

计算机系统的世界,如同一座未被揭示奥秘的古老迷宫,引领你勇敢踏入计算机科学的神秘领域。CSAPP的Bomblab实验便是这场独特的学习冒险,从基本概念到底层实现,逐步揭示更深层次的计算机系统内核、汇编语言和数据结构的奥秘。

渴望挑战计算机系统中的安全学习路径和掌握底层系统编程的技术?不妨点击下方链接,一同探讨更多计算机科学的奇迹吧。我们推出引领趋势的💻 计算机科学专栏:《斯坦福大学之CSAPP》,旨在深度探索计算机系统中安全编程技术的实际应用和创新。🌐🔍

7dd2b7f171704327b7d8987c49da4628.gif

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。