写入db [assembly]分配的字符串时出现段错误 [英] Segfault when writing to string allocated by db [assembly]

查看:79
本文介绍了写入db [assembly]分配的字符串时出现段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm following a basic shell-spawning exploit example. Below is exactly what my book tells me to write, yet I still get a segfault.

在gdb中运行此命令时,在"mov byte [esi + 7] al"处出现段错误.此行是必需的,以便我可以在字符串"/bin/sh"的末尾放置一个空字节.当我将其翻转到"mov byte al,[esi + 7]"时,这不会引起段错误.我假设我没有存储我的字符串存储在内存中的位置的写权限.看来我只有读取权限.

When running this in gdb, I get a segfault at "mov byte [esi + 7], al". This line is necessary so that I can put a null byte at the end of my string "/bin/sh". When I flipped it around to "mov byte al, [esi + 7]", this did not cause a segfault. I'm assuming that I do not have write permissions to the place in memory where my string is stored. It seems I only have read permissions.

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

I am using a virtual machine that is running a 32-bit centos, which is hosted by a 64-bit centos machine.

我已经采取的预防措施:

Precautions I have already taken:

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

  1. Disabled ASLR in my vm with sysctl -w kernel.randomize_va_space=0
  2. Disabled dep in my vm with sysctl -w kernel.exec-shield=0
  3. Disabled the XD flag in my host machine through the BIOS setup

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中字符串的正确地址.

I have already confirmed that ESI contains the correct address which points to the string in gdb.

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

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

I have also tried writing to [esi] instead of [esi + 7] with 0x1 instead of al. It seems that I just cannot write to memory allocated by the db directive. Why can't I write a null byte to [esi + 7] ?

推荐答案

您已经确定了问题-内存中的字符串不可写.那是因为它在 .text 部分中,该部分默认为只读.

You've identified the problem -- your string in memory is not writable. That's because it is in the .text section, which is read-only by default.

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

You can make it writable by linking with the -N option (useful for testing shellcode)

在较早的内核上,与 gcc -zexecstack 链接后使 .data 可执行,因此您可以在其中放置修改自身的shellcode,而不是制作 .text.可与 ld -N 一起写入.在当前的Linux上, -z execstack 仅影响堆栈本身,而不使用Linux的READ_IMPLIES_EXEC功能.

On older kernels, linking with gcc -zexecstack made .data executable, so you can put shellcode that modifies itself there as an alternative to making .text writable with ld -N. On current Linux, -z execstack does only affect the stack itself, instead of using Linux's READ_IMPLIES_EXEC feature.

这篇关于写入db [assembly]分配的字符串时出现段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆