【问题标题】:Segfault when writing to string allocated by db [assembly]写入由 db [程序集] 分配的字符串时出现段错误
【发布时间】:2014-08-04 17:48:37
【问题描述】:

我正在关注一个基本的 shell 生成漏洞利用示例。以下正是我的书告诉我要写的内容,但我仍然遇到段错误。

在 gdb 中运行它时,我在“mov byte [esi + 7], al”处得到一个段错误。这一行是必要的,这样我就可以在字符串“/bin/sh”的末尾放置一个空字节。 当我将它翻转到“mov byte al,[esi + 7]”时,这并没有导致段错误。我假设我对存储字符串的内存位置没有写权限。看来我只有读取权限。

我正在使用运行 32 位 centos 的虚拟机,该虚拟机由 64 位 centos 机器托管。

我已经采取的预防措施:

  1. 使用 sysctl -w kernel.randomize_va_space=0 在我的虚拟机中禁用 ASLR
  2. 使用 sysctl -w kernel.exec-shield=0 在我的 vm 中禁用 dep
  3. 通过 BIOS 设置禁用了我的主机中的 XD 标志

    Section         .text
       global _start
    
    _start:
    
    jmp short    GotoCall
    
    shellcode:
    
    pop          esi                     ; stores address of string in esi 
    xor          eax, eax                ; fill eax with null bytes
    mov byte     [esi + 7], al           ; replace 'J' with null byte - SEGFAULT!
    lea          ebx, [esi]              ; stores address of string in ebx
    mov long     [esi + 8], ebx          ; stores address of string in AAAA
    mov long     [esi + 12], eax         ; stores null bytes in KKKK
    mov byte     al, 0x0b                ; stores 11 (execve code) in al
    mov          ebx, esi                ; stores address of string in ebx
    lea          ecx, [esi + 8]          ; stores pointer to string in ecx
    lea          edx, [esi + 12]         ; stores pointer to null in edx
    int          0x80                    ; system call
    
    GotoCall:
    
    call         shellcode               ; pushes address of string on stack
    db           '/bin/shJAAAAKKKK'      ; creates space for string
    

我已经确认 ESI 包含指向 gdb 中字符串的正确地址。

    /x $esi = 0x8048081
    (gdb) x/s 0x8048081
    0x8048081 <GotoCall+5>:  "/bin/shJAAAAKKKK"

我也尝试用 0x1 而不是 al 写入 [esi] 而不是 [esi + 7]。看来我只是无法写入 db 指令分配的内存。为什么我不能向 [esi + 7] 写入空字节?

【问题讨论】:

标签: linux assembly x86 exploit shellcode


【解决方案1】:

您已经发现了问题——您在内存中的字符串不可写。那是因为它在.text 部分,默认为只读。

您可以通过链接-N 选项使其可写(用于测试shellcode)


On older kernels,与gcc -zexecstack 链接使.data 可执行,因此您可以将修改自身的shellcode 放在那里作为使.text 可写ld -N 的替代方法。在当前的 Linux 上,-z execstack 只会影响堆栈本身,而不是使用 Linux 的 READ_IMPLIES_EXEC 功能。

【讨论】:

  • @PeterCordes 您编辑的内容肯定会搅浑水。这是一个shellcode 问题。因此,如果您要转换指令和数据,您希望它们都在同一部分中。没有 BSS 部分。 .text 部分中的所有内容最终都将在堆栈上运行。但是如果你想独立运行它,你可以这样做,如果你让.text段可写。如果将其放在单独的部分中,生成的字节将用零填充。
  • @MichaelPetch:好点,我忽略了这一点,同时也使它成为普通程序的有用规范(通过给出原始答案所暗示的部分名称)。重新编辑以进一步区分这些内容。
  • 对不起,甚至不属于这里的彼得。你只是让这个答案远离这个问题。事实上,当 Chris 说“或将其移至另一部分”时,我不同意 Chris。任何编写独立运行的 shell 代码或作为堆栈上的漏洞利用的人都会将数据和代码放在 .text(或全部放在 .data节)节。不止一节将介绍填充,这将引入零(并且数据将落在有效负载之外)。然后将其转换为有效负载变得更加困难。
  • 虽然您可以将其全部放在代码中或全部放在数据部分中,但我建议不要使用.data 部分。如果有人试图在 GDB 中独立运行它 - GDB 将无法在标签 _start 上设置断点,然后您必须告知他们如何在不使用标签的情况下停止第一条指令。对于 shell 漏洞利用,坚持 .text 部分中的所有内容通常要容易得多。
猜你喜欢
  • 2013-08-31
  • 1970-01-01
  • 1970-01-01
  • 2017-08-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多