【CSAPP】探秘AttackLab奥秘:level 5的解密与实战

举报
SarPro 发表于 2024/02/05 16:33:01 2024/02/05
【摘要】 这篇博文深入研究了斯坦福大学《深入理解计算机系统》课程中的实验项目,聚焦于AttackLab的第五级别。作者通过详细的解密和实战分析,揭示了该实验的奥秘。文章囊括了底层系统编程技术、计算机系统的安全学习路径,以及对计算机科学奇迹的深度探索。

1.gif

7dd2b7f171704327b7d8987c49da4628.gif

📋 前言

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

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

欢迎来到我的【CSAPP】攻击实验室!这里是探索计算机系统安全领域的秘境,我的学习笔记博客将引导你进入CSAPP的攻击之门。在这个实验室中,我不仅分享计算机系统的基本原理和高级技术,还涵盖了实用的攻击技术和项目经验的秘密武器。无论你是初学者还是安全大师,这个实验室将为你呈现学术与实践的魔法,助你在CSAPP的攻击领域中展开一场刺激的冒险。准备好了吗?跟随我的引导,让我们一同挑战那些神秘的攻击代码,揭开计算机系统安全的神秘面纱!

🌳1. CSAPP与AttackLab简介

🌼1.1 CSAPP

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


🌼1.2 AttackLab

target1实验通常与CS:APP书中的“Buffer Overflow Attack”相关。这个实验旨在教授计算机系统的安全性,防止攻击者定位攻击和锻炼使用金丝雀防护,特别是关于缓冲区溢出漏洞的理解和利用。在这个实验中,尝试利用缓冲区溢出漏洞来修改程序的执行流程,从而实现未授权的操作,比如执行恶意代码或获取系统权限。要求深入了解程序内存布局、堆栈和函数调用等概念,并学会利用输入缓冲区溢出漏洞来修改程序行为,这有助于理解系统安全中的一些基本原则和漏洞。

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



🌳2. AttackLab

🌼2.1 实验环境

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

🌼2.2 实验过程

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

下载target1压缩包并输入

tar –xvf target1.tar

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

​​​


当前提供材料包含一个攻击实验室实例的材料:

1.ctarget

带有代码注入漏洞的Linux二进制文件。用于作业的第1-3阶段。

2.rtarget

带有面向返回编程漏洞的Linux二进制文件。用于作业的第4-5阶段。

3.cookie.txt

包含此实验室实例所需的4字节签名的文本文件。(通过一些Phase需要用到的字符串)

4.farm.c

rtarget实例中出现的gadget场的源代码。您可以编译(使用标志-Og)并反汇编它来查找gadget。

5.hex2raw

生成字节序列的实用程序。参见实验讲义中的文档。(Lab提供给我们的把16进制数转二进制字符串的程序)

在终端处输入命令

tar -xvf target1.tar

将压缩包解压如下:

​​​


实验过程阶段:

使用

objdump -d ctarget > ctarget.asm

objdump -d rtarget > rtarget.asm

对ctarget以及rtarget进行反汇编,得到ctarget.asm和rtarget.asm。

​​​


在官方文档的目标程序给出,CTARGET和RTARGET都从标准输入读取字符串。它们使用下面定义的函数getbuf来执行此操作:

​​


函数Gets类似于标准库函数gets—它从标准输入中(从缓冲区)读取字符串 (以’ \n '或文件结束符结束) 并将其(连同空结束符)存储在指定的目的地。即空格/Tab/回车可以写入数组文本文件,不算作字符元素, 不占字节,直到文件结束, 如果是命令行输入的话,直到回车结束(区别getchar ():是在输入缓冲区顺序读入一个字符 (包括空格、回车和 Tab)结束,scanf:空格/Tab/回车都当作结束。函数Gets()无法确定它们的目标缓冲区是否足够大,以存储它们读取的字符串。它们只是复制字节序列,可能会超出在目的地分配的存储边界(缓冲区溢出)对应汇编代码:

​​

因为Ctarget就是让我们通过缓冲区溢出来达到实验目的,所以可以推断sub $0x28,%rsp的40个字节数就等于输入字符串的最大空间,如果大于40个字节,则发生缓冲区溢出(超过40个字节的部分作为函数返回地址,如果不是确切对应指令的地址,则会误入未知区域,报错:

Type string:Ouch!: You caused a segmentation fault!段错误,可能访问了未知额内存)

🌼2.3 第二部分

解决完level1-level3后,进入到第二部分:面向返回的编程。对程序RTARGET执行代码注入攻击比CTARGET要困难得多,因为它使用两种技术来阻止这种攻击:

•使用随机化,以便堆栈位置在不同的运行中不同。这使得无法确定注入的代码将位于何处。

•将保存堆栈的内存部分标记为不可执行,因此即使将程序计数器设置为注入代码的开头,程序也会因分段错误而失败。

通过执行现有代码,而不是注入新代码,在程序中完成有用的事情。这种最通用的形式被称为面向返回编程(ROP)[1,2]。ROP的策略是识别现有程序中的字节序列,该序列由一条或多条指令组成,后面跟着指令ret.这样的段被称为gadget. 即Part II和PartI I的区别是:这里用栈随机性和禁止栈中使用命令:栈随机性导致栈的位置不再固定,也导致我们不能像Part I一样,运行命令直接用栈中的确切位置就返回;禁止栈中使用命令为如果我们的命令是在栈中的,即%rip(程序计数器)指向栈,则会报错(段错误)。

​​​

该图表示需要设置要执行的gadget序列,字节值0xc3对ret指令进行编码。说明了如何设置堆栈以执行一系列n个gadget。图中,堆栈包含一系列gadget地址。每个gadget都由一系列指令字节组成,最后一个字节是0xc3,用于编码ret指令。当程序从该配置开始执行ret指令时,它将启动一系列gadget执行,每个gadget末尾的ret指令会导致程序跳到下一个gadget的开头。gadget可以使用与编译器生成的汇编语言语句相对应的代码,尤其是函数末尾的代码。在实践中,可能有一些这种形式的有用gadget,但不足以实现许多重要的操作。例如,编译后的函数不太可能在返回之前将popq%rdi作为其最后一条指令。幸运的是,对于面向字节的指令集,如x86-64,通常可以通过从指令字节序列的其他部分提取模式来找到gadget。

例如,rtarget的一个版本包含为以下C函数生成的代码:

​​

这个功能对攻击系统有用的可能性似乎很小。但是,这个函数的反汇编机器代码显示了一个有趣的字节序列:

​​​


字节序列48 89 c7对指令movq%rax,%rdi进行编码。此序列后面是字节值c3,它对ret指令进行编码。函数从地址0x400f15开始,序列从函数的第四个字节开始。因此,此代码包含一个gadget,其起始地址为0x400f18,它将把寄存器%rax中的64位值复制到寄存器%rdi。

RTARGET代码包含许多类似于上面显示的setval_210函数的函数,这些函数位于称为gadget farm的区域中(注意: 重要提示:gadget farm由rtarget副本中的函数start_farm和end_farm划分,不要试图从程序代码的其他部分构造gadget)。工作将是在gadget farm中识别有用的gadget,并使用这些gadget执行类似于第2阶段和第3阶段的攻击。


🌼2.4 level 3(第二部分)

 阶段5要求对RTARGET进行ROP攻击,以使用指向cookie的字符串表示的指针调用函数touch3。


🌻2.4.1 解决思路

在第二阶段和第三阶段,已经解决了让一个程序执行自行设计的机器代码。如果CTARGET是一个网络服务器,则可以将自己的代码注入到远处的机器中。第四阶段绕过了现代系统用来阻止缓冲区溢出攻击的两个主要设备。虽然没有注入自己的代码,但可以注入一种通过将现有代码序列拼接在一起来操作的程序类型。这一阶段要求对 RTARGET 进行 ROP 攻击,以使用指向 cookie 字符串表示的指针调用函数 touch3。

要解决阶段5,可以在rtarget中由函数start_farm和end_farm划分的代码区域中使用小工具。除了在阶段4中使用的小工具,这个扩展的场还包括不同的movl指令的编码。这部分场中的字节序列也包含2字节指令,它们作为nops函数,也就是说,它们不改变任何寄存器或内存值。包括指令如andb %al,%al,它们对一些寄存器的低阶字节进行操作,但不改变它们的值。

因为有了栈随机性,我们不能指定指针确切位置了,但是可以通过 相对位置 + 栈顶的位置,先获取到栈顶的位置,然后加上我们放置距离栈顶的相对位置,得到cookie字符串起始地址放置的位置,推导如下:

1.需要 获取栈顶的位置,查看Source = %rsp的mov指令机器码,查找与之相关联的寄存器。

2.发现movq %rsp,%rax可用,则先找movq %rax,%rdi,因为最终需要%rdi 来存放 字符串的指针开始地址,因为lea命令可以起到add和mov的作用,lea (%rdi,%rsi,1),%rax 中%rsi可以作 相对位置偏移的量,这个偏移量由最终栈顶离字符串的相对偏移位置来确定,%rdi里面存%rsp刚开始的栈顶位置,由上一步movq %rsp,%rax movq %rax,%rdi得到,最后的偏移位置在%rax中,最后只需要movq %rax,%rdi即可达到目的。

3.需要把偏移量放到%rsi中,因为没有pop %rsi,只能逆向思维,找与mov %rsi相关的指令。

4.在farm部分只找到movl %ecx,$esi ,需要把%eax与%ecx联系起来,因为只有%rax可以pop(可以指定值),所以逆向寻找movl %ecx,得到逆向顺序:%eax -> %edx -> %ecx -> %esi。

新建anwer4.s文件,内容如下所示:

​​​

movq %rsp,%rax    (location:0x401a06)
movq %rax,%rdi    (location: 0x4019c5)
popq %rax       (location:0x4019cc)
movq %eax,%edx    (location:0x4019dd)
movq %edx,%ecx     (location: 0x401a69)
movq %ecx,%esi    (location:0x401a13)
lea %rdi + %rsi* 1, %rax     (location:0x4019d6)
movq %rax,%rdi     (location:0x4019c5)
retq    (jmp location: touch3 4018fa)

其中movq %rsp,%rax (location:0x401a06)是为了将%rsp元素存放到%rax中,接着使用movq %rax,%rdi (location:0x4019c5)将%rax数据存放到%rdi中,利用popq %rax  (location:0x4019cc) 将栈元素存放到%rax中,接着连着使用movq 是为了将%eax数据依此存放到%edx、%ecx和%esi。

关于lea指令在intel开发手册上的官方解释见下。

​​​


官方解释Load Effective Address,即装入有效地址的意思,它的操作数就是地址;因此lea %rdi + %rsi* 1, %rax (location:0x4019d6)含义是将%rdi与%rsi存储的数据相加,并将结果存放到%rax中。而movq %rax,%rdi (location:0x4019c5)指令是为了将%rax值存放到%rdi,最后的retq (jmp location: touch3 4018fa)指令是为了将栈中值弹出,然后跳转到地址touch3 4018fa。

新建level5.txt建立内容如下:

​​​


🌻2.4.2 问题验证

输入命令进行验证:

./hex2raw < level5.txt | ./rtarget -q

显示结果为PASS(需要注意的是,这里的指向文件应该为rtarget而非ctarget,否则显示仍然为Fail):

​​​


🌼2.5 实验结果

由于实验通关过程中是分阶段的,故展示通关过程中所需的创建文件如下:

​​​


🌼2.6 实验体会

  1. 深度理解系统原理: AttackLab实验让我深刻理解了计算机系统的底层原理和安全机制。通过解密与实战,我不仅熟练掌握了系统编程技术,还对汇编语言和数据结构有了更深层次的认识。这种深度理解使我在编程和系统设计方面取得了显著的进步。

  2. 逆向工程的挑战: AttackLab的逆向工程要求我们通过分析二进制代码解决炸弹挑战。这种实践锻炼了我的逻辑思维和问题解决能力。每一级别的解密都是一次挑战,需要细致入微的分析和耐心的调试。在这个过程中,我学到了很多解决复杂问题的方法,对逆向工程有了更深入的了解。

  3. 团队协作与学术社交: 在实验过程中,我积极与同学进行讨论和合作,分享解决问题的方法和思路。这不仅增加了我对AttackLab的理解,还促进了团队协作和学术社交。与同好共同攻克实验难关,分享心得,使整个学习过程更加充实和有趣。这种团队协作精神在解决复杂计算机科学问题中尤为重要。


📝 总结 

在计算机系统的广袤领域,仿佛是一片未被揭示的复杂网络,隐藏着深奥的密码,而CSAPP的AttackLab实验正是那一场引人入胜的冒险之旅。这实验不仅深入挖掘计算机系统的基本概念,更将目光投向底层的系统实现,逐步揭开计算机系统内核、汇编语言和数据结构这些层次的神秘面纱。

对于那些渴望挑战计算机系统安全学习路径,以及希望掌握底层系统编程技术的冒险者们,AttackLab提供了一个独特的机会。点击下方链接,你将能够深入研究计算机科学的奇迹,探讨安全编程技术的实际应用和创新。我们引领趋势的🌱计算机科学专栏《斯坦福大学之CSAPP》将为你展开一场精彩的学术冒险,带你穿越计算机系统的迷雾,解锁其中的奥秘。🌐🔍

7dd2b7f171704327b7d8987c49da4628.gif

end.gif

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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