Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

linux - Segfault when writing to string allocated by db [assembly]

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.

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.

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. 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
    

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"

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] ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

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


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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...