0

I'm trying to learn shellcode development and currently trying to implement the stack method in which you push the "/bin/sh" string onto the stack. Most tutorials that I've read so far are focused on 32b whereas I want to implement it for 64b and am currently stuck with a Segmentation fault error for the following code:

section .text

  global _start

_start:

  ; zero out RAX 
  xor rax, rax

  ; push string in reverse order onto the stack
  ; first the nullbyte, then /bin//sh
  push rax         ; nullbyte for string
  push 0x68732f2f 
  push 0x6e69622f

  ; stack pointer contains address of string now
  mov ebx, esp ; first argument to execve
  mov ecx, eax ; second argument to execve
  mov al, 0xb  ; 11 := syscall number of execve
  int 0x80

Does somebody know what I'm doing wrong here?

I compile, link and run it in the following way

$ nasm -f elf64 -o shell.o shell.asm
$ ld -o shell shell.o
$ ./shell
phoebus
  • 1,280
  • 1
  • 16
  • 36
  • `int 0x80` is not the right way to do 64 bit system calls on Linux. – fuz Oct 01 '18 at 09:53
  • @fuz that's not the error though. It does work with ```int 0x80``` for other assembly code that I've written as well – phoebus Oct 01 '18 at 09:55
  • 2
    It is the error because `int 0x80` is the way to do 32 bit system calls and all the arguments are 32 bit values. The stack however is located at an address greater than 2³², so your `execve` call tries to use the file name of whatever file it finds at a truncated address. This fails and `execve` returns. Since you haven't put any code after your `execve` call, random junk is executed causing a segfault. There is a canonical duplicate for your question, I just have to find it. – fuz Oct 01 '18 at 09:58
  • changing to ```syscall``` does not solve it. It's not the ```int 0x80``` causing the error. – phoebus Oct 01 '18 at 10:01
  • 1
    You don't just change `int 0x80` to `syscall`, you also have to change the system call numbers and registers. The linked duplicate has a link to the relevant documentation. As is, your `mov ebx, esp` already truncates the address of the file name, breaking your code. Another thing that is wrong is that each stack slot is 8 bytes, not 4 bytes in 64 bit mode, so you don't even push the correct file name. Try using `strace` to see what your code does and perhaps add some error handling. – fuz Oct 01 '18 at 10:04
  • Note that those two `push` instructions each zero-extend their immediate to 64 bits. You can't use *just* normal push in 64-bit mode to make a contiguous string, so it's also a duplicate of another question. – Peter Cordes Oct 01 '18 at 11:15
  • When you're testing/debugging this, use `strace ./shell` to see what system calls it makes. (strace is broken for int 0x80 in 64-bit code.) – Peter Cordes Oct 01 '18 at 11:25

0 Answers0