online
projects

ldpreload Malware Overview

malware ld_preload

POC Malware LD_PRELOAD – Project Overview

Disclaimer: This project was built purely for educational purposes as part of a school assignment. It was also my very first real project written in C. Everything described here was tested in an isolated, controlled environment (Docker containers). Do not use any of this outside of a lab setup.


What is this project?

This is a proof of concept (POC) malware written in C that abuses the Linux LD_PRELOAD mechanism to intercept SSH credentials on a compromised machine and exfiltrate them to a remote Command & Control (C2) server over SSL.

The project is split into four main components:

  • The malware (malware.so) – a shared library injected via LD_PRELOAD
  • The loader – a fake “V-Bucks generator” used to deploy the malware
  • The C2 server – receives stolen credentials over an encrypted SSL connection
  • The database – stores the exfiltrated data locally on the C2 server (more on this below)

The LD_PRELOAD Technique

LD_PRELOAD is a Linux environment variable that tells the dynamic linker to load a specific shared library before all others when a program starts. This means any function defined in that library will take precedence over the real one from libc or any other system library.

This is a well-known technique used legitimately for things like debugging or mocking. Here, it’s used offensively to hook system calls at the userland level — no kernel exploit required.

The malware hooks several key libc functions:

Hooked FunctionPurpose
readIntercepts data being read from file descriptors (captures SSH password input)
writeMonitors outgoing data
openIntercepts file open calls
readdirHides the malware’s presence from directory listings

The most impactful hook is on read: when an SSH client reads the password typed by the user, the hook captures it before it’s processed, giving us plaintext credentials.

Hiding itself

A notable stealth trick: the malware hooks readdir and open to hide the /etc/ld.so.preload file from standard tools like ls or cat. This makes it significantly harder for a user to notice the infection just by browsing the filesystem.


The Loader – A Fake V-Bucks Generator

The initial infection vector is a binary disguised as a Fortnite V-Bucks generator. When executed (typically tricked into running with sudo), it silently:

  1. Connects to the C2 server and downloads malware.so
  2. Writes the path to malware.so into /etc/ld.so.preload

/etc/ld.so.preload is a system-wide file that lists shared libraries to preload for every process on the system. Writing to it requires root — hence why social engineering the victim into running the loader with sudo is part of the attack chain.

Once this file is written, every new process spawned on the system will load malware.so automatically. Persistence is achieved.


The C2 Server

The C2 server is written in C and uses OpenSSL to secure communications. It listens for incoming connections from infected machines and receives stolen credentials.

Key characteristics:

  • SSL/TLS encrypted channel – credentials are not sent in plaintext over the network
  • Uses POSIX threads (pthread) to handle multiple clients concurrently
  • On reception of credentials, forwards them to the local database process via a socket

The server runs on port 6000 and acts as the backbone of the whole operation.


The Database – B-Tree in C

The database component was a school exercise in data structures. It implements a B-Tree from scratch in C to store and query the received credentials.

It communicates with the C2 server locally via a socket on port 7777. In practice, its role is straightforward: persist the stolen data so it can be retrieved and queried later.


Architecture Overview

+------------------+       +---------------------+       +-------------------+
|                  |       |                     |       |                   |
|   sshvictims     | <──── |   victimsdebian     | ────> |    serverc2       |
|  (SSH Server)    |       |  (Malware active)   |       | (SSL + DB + .so)  |
|                  |       |                     |       |                   |
+------------------+       +---------------------+       +-------------------+

The full demo environment is dockerized with three containers on a private subnet (172.21.0.0/16):

ContainerIPRole
victimedebian172.21.0.10Infected victim machine
victimessh172.21.0.11SSH server the victim connects to
serverc2172.21.0.12C2 server + database + malware binary

Attack Flow – Step by Step

1. Infection

The victim runs the loader (sudo ./loader). It downloads malware.so from the C2 server and writes its path into /etc/ld.so.preload. From this point, every process on the machine will load the malicious library.

2. Credential Capture

The victim connects via SSH to sshvictims:

When they type their password, the hooked read() function captures it in memory.

3. Exfiltration Trigger

The credentials are buffered and sent to the C2 server. In the demo, a curl request acts as the trigger that flushes the buffer and initiates the send:

curl https://example.com/

This technique avoids suspiciously timed outbound connections right after an SSH session.

4. Storage

The C2 server receives the credentials over SSL and forwards them to the B-Tree database. The stolen data is now persisted and queryable.


Building the Project

The project compiles cleanly with a single make at the root:

make

This produces:

  • server/server – the C2 server binary
  • server/malware.so – the LD_PRELOAD shared library
  • ldpreload_malware/loader/loader – the fake V-Bucks loader
  • db/projectdb – the B-Tree database binary

Dependencies: gcc, make, libssl-dev, Linux.

To spin up the full demo environment:

docker compose up --build -d

What I Learned

This was my first serious C project, and it covered a lot of ground:

  • Low-level shared library mechanics and the ELF dynamic linker
  • Function interposition with LD_PRELOAD and dlsym(RTLD_NEXT, ...)
  • Network programming in C (BSD sockets, SSL with OpenSSL)
  • Multi-threaded servers with pthreads
  • Implementing a B-Tree data structure from scratch
  • Docker networking and multi-container setups

The project is far from production-grade code and has plenty of rough edges — but as a learning exercise in systems programming and offensive security fundamentals, it covered more ground than any textbook exercise could.


● NORMAL 0xBlog
JetBrains Mono UTF-8 Hugo