下面是一些常见指令的指令码
- 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表中读出对应函数在内存中的地址,然后跳转到该地址执行 , 所以先利用puts
函数打印库函数的地址,减掉该库函数与libc
加载基地址的偏移,就可以计算libc
的基地址 。然后可以利用libc
中的gadget构造可以执行 " /bin/sh" 的ROP ,
使用ROPgadget检查程序中是否存在/bin/sh字符串或某条指令:ROPgadget --binary 文件名 --string="/bin/sh"ROPgadget --binary 文件名 --sting '/bin/sh'命令: ROPgadget --binary 文件名 --sting 'sh'命令: ROPgadget --binary 文件名 --sting 'cat flag'命令: ROPgadget --binary 文件名 --sting 'cat flag.txt'ROPgadget --binary 文件名 --only="pop|ret"用ROPgadget找一下程序里有没有可以用的改变rdi寄存器的值的gadgetsROPgadget --binary 文件名 --only "pop|ret" | grep rdi
栈溢出栈溢出指的是程序向栈中某个变量中写入的字节数超过了这个变量本身所申请的字节数,因而导致与其相邻的栈中的变量的值被改变 。这种问题是一种特定的缓冲区溢出漏洞,类似的还有堆溢出,bss 段溢出等溢出方式 。栈溢出漏洞轻则可以使程序崩溃,重则可以使攻击者控制程序执行流程 。此外,我们也不难发现,发生栈溢出的基本前提是- 程序必须向栈上写入数据 。
- 写入的数据大小没有被良好地控制 。
#include <stdio.h>#include <string.h>void success() { puts("You Hava already controlled it."); }void vulnerable() {char s[12];gets(s);puts(s);return;}int main(int argc, char **argv) {vulnerable();return 0;}
这个程序的主要目的读取一个字符串,并将其输出 。我们希望可以控制程序执行 success 函数 。输入
gcc -m32 -fno-stack-protector stack1.c -o stack1 -no-pie -z execstack
进行编译,可以看见报错了(但仍会生成可执行文件),可以看出 gets 本身是一个危险函数 。它从不检查输入字符串的长度,而是以回车来判断输入是否结束,所以很容易可以导致栈 溢出 , 
文章插图
gcc 编译指令中,
-m32
指的是生成 32 位程序; -fno-stack-protector
指的是不开启堆栈溢出保护,即不生成 canary 。-z execstack
表示开启栈的可执行权限,在gcc4.1中默认禁用,此外 , 为了更加方便地介绍栈溢出的基本利用方式 , 这里还需要关闭 PIE(Position Independent Executable),避免加载基址被打乱 。不同 gcc 版本对于 PIE 的默认配置不同 , 我们可以使用命令gcc -v
查看 gcc 默认的开关情况 。如果含有
推荐阅读
- 四十一 增删查改分页 Java开发学习----MyBatisPlus标准数据层开发
- 中 学习ASP.NET Core Blazor编程系列十——路由
- CC1,3,6回顾
- 图学习【参考资料2】-知识补充与node2vec代码注解
- 二十四 设计模式学习:Spring 中使用到的设计模式
- Java安全之CC3
- TensorFlow深度学习!构建神经网络预测股票价格!?
- JUC学习笔记——共享模型之管程
- Seata Server 1.5.2 源码学习
- 2022极端高温!机器学习如何预测森林火灾?? 万物AI