x86-64
, 通常可以通过从指令字节序指令的其他部分提取出我们想要的指令 。
文章插图
下面举个例子来详细说明
ROP
与之前的Buffer overflow
有什么区别 , 我们不关心栈地址在哪 , 只需要看有没有可以利用的指令我们可以在程序的汇编代码中找到这样的代码:
0000000000400f15 <setval_210>:400f15: c7 07 d4 48 89 c7 movl $0xc78948d4,(%rdi)400f1b: c3 retq
这段代码的本意是void setval_210(unsigned *p){*p = 3347663060U;}
这样一个函数 , 但是通过观察我们可以发现 , 汇编代码的最后部分:48 89 c7 c3
又可以代表movq %rax, %rdiret
这两条指令(指令的编码可以见讲义中的附录) 。第1行的
movq
指令可以作为攻击代码的一部分来使用 , 那么我们怎么去执行这个代码呢?我们知道这个函数的入口地址是0x400f15
, 这个地址也是这条指令的地址 。我们可以通过计算得出48 89 c7 c3
这条指令的首地址是0x400f18
, 我们只要把这个地址存放在栈中 , 在执行ret
指令的时候就会跳转到这个地址 , 执行48 89 c7 c3
编码的指令 。同时 , 我们可以注意到这个指令的最后是c3
编码的是ret
指令 , 利用这一点 , 我们就可以把多个这样的指令地址依次放在栈中 , 每次ret
之后就会去执行栈中存放的下一个地址指向的指令 , 只要合理地放置这些地址 , 我们就可以执行我们想要执行的命令从而达到攻击的目的 。下面是一些常见指令的指令码
- movq : The codes for these are shown in Figure
3A
. - popq : The codes for these are shown in Figure
3B
. - ret : This instruction is encoded by the single byte
0xc3
. - nop : This instruction (pronounced “no op,” which is short for “no operation”) is encoded by the single byte
0x90
. Its only effect is to cause the program counter to be incremented by 1
movq
、popq
、movl
、nop(2 Bytes)
、可以参考CSAPPAttackLab文章插图
文章插图
文章插图
文章插图
寻找 gadget理论上 , ROP是图灵完备的 。在漏洞利用过程中 , 比较常用的gadget有以下类型:
- 保存栈数据到寄存器 , 如
pop rax; ret;
- 系统调用 , 如
syscall; ret;int 0x80; ret;
- 会影响栈帧的gadget , 如
leave; ret;pop rbp; ret
,leave
指令相当于move rsp(目的), rbp;(即rsp = rbp)pop rbp
- 如果是一个很小的程序 , 首先应该查找有没有
syscall
这类的gadget , 没有的话就要想办法获取一些动态链接库(如libc)的加载地址 , 再用libc
中的gadget构造可以实现任意代码执行的ROP 。程序中常常有putsgets
等libc
提供的库函数 , 这些函数在内存中的地址会写在程序的GOT表中 , 当程序调用库函数时 , 会在GOT表中读出对应函数在内存中的地址 , 然后跳转到该地址执行 , 所以先利用经验总结扩展阅读
- 四十一 增删查改分页 Java开发学习----MyBatisPlus标准数据层开发
- 中 学习ASP.NET Core Blazor编程系列十——路由
- CC1,3,6回顾
- 图学习【参考资料2】-知识补充与node2vec代码注解
- 二十四 设计模式学习:Spring 中使用到的设计模式
- Java安全之CC3
- TensorFlow深度学习!构建神经网络预测股票价格!?
- JUC学习笔记——共享模型之管程
- Seata Server 1.5.2 源码学习
- 2022极端高温!机器学习如何预测森林火灾?? 万物AI