【问题标题】:Error: Illegal Instruction of shellcode (at&t) for helloworld.错误:helloworld 的 shellcode (at&t) 的非法指令。
【发布时间】:2014-02-05 02:35:01
【问题描述】:

我正在努力学习如何写shellcode。在四处搜索之后,我为你好世界写了自己的shellcode。我认为逻辑是正确的,但是当我用shellcode 编译包装器时,它总是给我“非法指令”。

谁能帮我检查一下这段代码有什么问题:

外壳代码

    .section .data
    .section .text

    .globl _start

        jmp dummy 

     _start:
            # write(1, message, 13)
            mov     $4, %al                # system call 4 is write
            mov     $1, %bl                # file handle 1 is stdout
            popl    %ecx
            mov     $12, %dl               # number of bytes to write
            int     $0x80                   # invoke operating system code

            # exit(0)
            xor     %eax, %eax
            mov     $1, %al                # system call 1 is exit
            xor     %ebx, %ebx              # we want return code 0
            int     $0x80                   # invoke operating system code

    dummy:
        call _start
        .string  "Hello, World"

运行 objdump 后:

    file format elf32-i386


    Disassembly of section .text:

    00000000 <_start-0x2>:
       0:   eb 11                   jmp    13 <dummy>

    00000002 <_start>:
       2:   b0 04                   mov    $0x4,%al
       4:   b3 01                   mov    $0x1,%bl
       6:   59                      pop    %ecx
       7:   b2 0c                   mov    $0xc,%dl
       9:   cd 80                   int    $0x80
       b:   31 c0                   xor    %eax,%eax
       d:   b0 01                   mov    $0x1,%al
       f:   31 db                   xor    %ebx,%ebx
      11:   cd 80                   int    $0x80

    00000013 <dummy>:
      13:   e8 fc ff ff ff          call   14 <dummy+0x1>
      18:   48                      dec    %eax
      19:   65                      gs
      1a:   6c                      insb   (%dx),%es:(%edi)
      1b:   6c                      insb   (%dx),%es:(%edi)
      1c:   6f                      outsl  %ds:(%esi),(%dx)
      1d:   2c 20                   sub    $0x20,%al
      1f:   57                      push   %edi
      20:   6f                      outsl  %ds:(%esi),(%dx)
      21:   72 6c                   jb     8f <dummy+0x7c>
      23:   64                      fs
        ...

我使用的 C Wrapper

    char code[] = "\xeb\x11"
                    "\xb0\x04"
                    "\xb3\x01"
                    "\x59"
                    "\xb2\x0c"
                    "\xcd\x80"
                    "\x31\xc0"
                    "\xb0\x01"
                    "\x31\xdb"
                    "\xcd\x80"
                    "\xe8\xfc\xff\xff\xff"
                    "\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64";



    void main() {
            int (*func)();
            func = (int(*)()) code;
            (int) (*func)();
    }

【问题讨论】:

标签: c shellcode


【解决方案1】:

您的代码有几个问题。

首先,您只是设置所有参数寄存器的低字节(即albldl)。您需要设置完整的 32 位。当你按照现在的方式执行时,剩下的 24 位中的任何内容都会传递给内核。

另外,在您的 C 代码中,call 不正确:

"\xe8\xfc\xff\xff\xff"

本质上是call $+1,它是调用指令的第二个字节,这就是你得到非法指令的原因。

我不确定您是如何获得code 变量中的字节的,但您需要重新组装。


在 Fedora 17 上使用 gcc 4.7.2 测试,gcc -m32(对不起,我只使用 Intel 语法)

char code[] __attribute__((section(".text"))) = 
    "\xeb\x17"                   // jmp $+19 
    "\xB8\x04\x00\x00\x00"       // mov eax, 4   ; (sys_write)
    "\x31\xDB"                   // xor ebx, ebx
    "\x43"                       // inc ebx
    "\x59"                       // pop ecx      ; (addr of string pushed by call below)
    "\x31\xD2"                   // xor edx, edx
    "\xb2\x0c"                   // mov dl, 0Ch  ; (length of string)
    "\xcd\x80"                   // int 80h

    "\x31\xc0"                   // xor eax, eax
    "\xb0\x01"                   // mov al, 1    ; (sys_exit)
    "\x31\xdb"                   // xor ebx, ebx
    "\xcd\x80"                   // int 80h
    "\xe8\xe4\xff\xff\xff"       // call $-23
    "\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x00";  // "Hello, World"

void main() {
    int (*func)();
    func = (int(*)()) code;
    (int) (*func)();
}

请注意,确实有一些方法可以使代码更小,但这当然留给读者作为练习。


如果您打算像这样使用手动调整的程序集,请准备好调试、调试、调试。 Learn how to use GDB现在,否则你将永远无助。在程序集 (b code) 的开头设置断点并单步执行。您很快就会发现出了什么问题。

【讨论】:

    猜你喜欢
    • 2021-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-05
    • 2014-03-31
    • 2018-07-09
    • 1970-01-01
    相关资源
    最近更新 更多