0

I have been trying to create a simple chunk of shell code that allows me to modify a string by doing something simple like changing a letter, then print it out.

_start:
        jmp short ender
starter:
        xor ecx, ecx            ;clear out registers
        xor eax, eax
        xor ebx, ebx
        xor edx, edx
        pop esi                 ;pop address of string into esi register

        mov byte [esi+1], 41    ;try and put an ASCII 'A' into the second letter of the string
                                ;at the address ESI+1

        mov ecx, esi            ;move our string into the ecx register for the write syscall
        mov al, 4               ;write syscall number
        mov bl, 1               ;write to STDOUT
        mov dl, 11              ;string length
        int 0x80                ;interrupt call
ender:
        call starter
        db 'hello world'

It's supposed to print out "hallo world". The problem occurs (segfault) when I try and modify a byte of memory with a mov command like so.

mov byte [esi+1], 41

I ran the program though GDB and the pop esi command works correctly, esi is loaded with the address of the string and everything is valid. I can't understand why I cant modify a byte value at the valid address though. I am testing this "shellcode" by just running the executable generated by NASM and ld, I am not putting it in a C program or anything yet so the bug exists in the assembly.

Extra information

I am using x64 Linux with the following build commands:

nasm -f elf64 shellcode.asm -o shellcode.o
ld -o shellcode shellcode.o
./shellcode

I have pasted the full code here.

1
  • You are possibly running into W^X. Commented Nov 4, 2012 at 20:32

1 Answer 1

1

If I had to guess, I'd say dbhello world` is being compiled in as code, rather than data, and as such has read and execute permissions, but not write ones. So you're actually falling foul of page protection.

To change this, you need to place the string in a section .data section and use nasm's variable syntax to find it. In order to modify the data as is, you're going to need to make a mprotect call to modify the permissions on your pages, and write to them. Note: these won't persist back to the executable file - mmap()'s MAP_PRIVATE ensures that's the case.

Sign up to request clarification or add additional context in comments.

3 Comments

I tried placing section .data on the line above db 'hello world' but it still segfaulted :( As for changing the string to a variable, that won't work for shellcoding. The address has null bytes in it and I remember reading that you can't use static addresses in shellcode.
@user99545 section .data will place the variable in a totally different place in memory to being at the return address of your function, which is what you're currently relying on. In shellcode of a buffer-overflow variety, you'd be on the stack - so you'd be writeable (but not executable!) - unfortunately because you're effectively building a program rather than executable data, that's where the problem lies. You're absolutely right on the null bytes count - usually shellcode is written to avoid these, including if necessary decoding strings when running, because 0 terminates a string...
which means you can't overflow a buffer with say strcpy.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.