【问题标题】:Assembly execve /bin/bash (x64)汇编 execve /bin/bash (x64)
【发布时间】:2017-12-20 00:08:44
【问题描述】:

我是 asm 的新手,我正在尝试对 /bin/bash 执行系统调用。但是我目前遇到以下问题:

我的代码适用于第一个参数长度小于 8 个字节的任何 execve 调用,即“/bin/sh”或“/bin/ls”:

.section .data

    name: .string "/bin/sh"

.section .text

.globl _start

_start:
    #third argument of execve, set to NULL
    xor %rdx, %rdx 

    #push nullbyte to the stack
    pushq %rdx 

    #push /bin/sh to the stack
    pushq name 

    #copy stack to rdi, 1st arg of execve
    mov %rsp, %rdi 

    #copy 59 to rax, defining syscall number for execve  
    movq $59, %rax 

    #3rd arg of execve set to NULL
    movq $0, %rsi 

    syscall

令我困惑的是我无法使用它

name: .string "/bin/bash"

我试图将字符串分成几部分,将“/bash”然后“/bin”推送到堆栈,似乎没有什么能让我让它工作,而且我每次都会收到“非法指令”错误。我究竟做错了什么?

非工作代码:

.section .data

    name: .string "/bin/bash"

.section .text

.globl _start

_start:
    #third argument of execve, set to NULL
    xor %rdx, %rdx 

    #push nullbyte to the stack
    pushq %rdx 

    #push /bin/sh to the stack
    pushq name 

    #copy stack to rdi, 1st arg of execve
    mov %rsp, %rdi 

    #copy 59 to rax, defining syscall number for execve  
    movq $59, %rax 

    #3rd arg of execve set to NULL
    movq $0, %rsi 

    syscall

其他非工作代码:

.section .data

.section .text

.globl _start

_start:
    #third argument of execve, set to NULL
    xor %rdx, %rdx 

    #push nullbyte to the stack
    pushq %rdx 

    #push /bin/bash to the stack
    pushq $0x68
    pushq $0x7361622f
    pushq $0x6e69622f

    #copy stack to rdi, 1st arg of execve
    mov %rsp, %rdi 

    #copy 59 to rax, defining syscall number for execve  
    movq $59, %rax 

    #3rd arg of execve set to NULL
    movq $0, %rsi 

    syscall

【问题讨论】:

  • 您忘记显示 non-working 代码。你也忘了使用调试器。您可能忘记了堆栈是反向工作的。您可能忘记了 push always 写入 8 个字节。所以你应该把你的字符串分成 8 个字节的部分,除了最后一部分(你先推送)。
  • 显然,如果你在.data 中有一个字符串,则无需将其复制到堆栈中。您可以直接使用它的地址并完成它。
  • 您查看过 X86_64 ABI 函数调用约定吗?这可能会帮助您找出问题所在。
  • @Jester 谢谢你的帮助。实际上,我确实考虑到堆栈向后工作并相应地对推送进行排序这一事实,错误保持不变。
  • @MichaelPetch 感谢您的建议。正如我的问题中提到的,这适用于 /bin/sh。即使我拆分了字符串(cf 编辑),我也无法调用 /bin/bash。 "/bin/bash" 将是 0x687361622f6e69622f,不能放入 64 位寄存器。

标签: assembly 64-bit system-calls execve


【解决方案1】:

您似乎完全糊涂了,无法列出所有错误。然而,这是一个不完整的列表:

  1. 你将esi设置为零意味着argvNULL
  2. push nullbyte to the stack 实际上是一个 NULL 指针,用于终止 argv 数组(它不是终止字符串的零字节)。
  3. 你需要把文件名的地址写成argv[0]。您不需要将字符串复制到堆栈中。

这是一个固定版本:

.section .data

    name: .string "/bin/bash"

.section .text

.globl _start

_start:
    # third argument of execve is envp, set to NULL
    xor %rdx, %rdx 

    # push NULL to the stack, argv terminator
    pushq %rdx 

    # first argument to execve is the file name
    leaq name, %rdi

    # also argv[0]
    push %rdi

    # second argument to execve is argv
    mov %rsp, %rsi

    #copy 59 to rax, defining syscall number for execve  
    movq $59, %rax 
    syscall

还有一个从代码在堆栈上创建字符串的版本,没有零字节:

.section .text

.globl _start

_start:
    # third argument of execve is envp, set to NULL
    xor %rdx, %rdx 

    # zero terminator
    push %rdx

    # space for string
    sub $16, %rsp

    # end is aligned to the zero terminator
    movb $0x2f, 7(%rsp)        # /
    movl $0x2f6e6962, 8(%rsp)  # bin/
    movl $0x68736162, 12(%rsp) # bash

    # first argument to execve is the file name
    leaq 7(%rsp), %rdi

    # push NULL to the stack, argv terminator
    pushq %rdx 

    # also argv[0]
    push %rdi

    # second argument to execve is argv
    mov %rsp, %rsi

    # copy 59 to rax, defining syscall number for execve
    # avoid zero byte
    xor %eax, %eax
    movb $59, %al 
    syscall

【讨论】:

  • 你说得对,我很困惑,正如我的问题中所说,我对 ASM 完全陌生 :)。无论如何,非常感谢您的帮助和纠正我的错误,它现在正在工作。还有一个问题,如果我想避免 .data 部分,我应该如何进行?
  • @Goujon :您需要将字符串推入堆栈
  • 是的,但请记住,一次 8 个字节!不幸的是,push 不需要 8 字节的立即数,所以通过一个寄存器。
  • 不,一次不是 32 位值。 32 位值被放置在堆栈零扩展这导致额外的零被放置在堆栈上,这就是它无法这样做的原因。
  • 这就是为什么我推荐使用 movabsq 到寄存器并推送完整的 64 位寄存器的原因。碰巧我作为评论发布的内容是错误的字符串。如果您正在编写 shell 代码,您将不得不避免在流中包含任何 0x00 字节,因此在堆栈上构建字符串对最后一个字节和 NUL 的参与度更高。我很确定您正在做的是最终将其编码为 shell 漏洞利用,因此人们试图从编码的指令中避免字节流中的 0x00。
猜你喜欢
  • 2021-02-01
  • 1970-01-01
  • 2014-03-25
  • 1970-01-01
  • 1970-01-01
  • 2011-12-28
  • 2013-10-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多