pwneglyph logo
web php ld-preload mail shared-object rce putenv

Spawn an external binary via mail() with attacker-controlled LD_PRELOAD to load a malicious shared object even when PHP functions are restricted.

LD_PRELOAD + mail() + symlink to a .so

Even if PHP's dangerous functions are mostly restricted, spawning an external binary through mail() can still inherit attacker-controlled environment variables. LD_PRELOAD then loads an attacker .so before the target binary starts. The write primitive only needs to land a shared object somewhere readable by the process; a symlink can make path placement easier.

Why It Works

  • mail() invokes sendmail, which inherits the PHP process environment — including a putenv-set LD_PRELOAD.

Vulnerable Pattern

  • PHP with putenv, symlink, and mail() still available, plus a writable path where a .so can be uploaded or smuggled.

Exploit Flow

  1. Confirm mail() truly reaches a system binary such as sendmail.
  2. Place the shared object in a stable path, or symlink from a predictable runtime directory to the upload location.
  3. Set LD_PRELOAD, trigger mail(), and make the library perform a simple side effect (write a file).

Variations

  • If mail() is unavailable, test other binary-launching functions or extension-loading paths.

Common Blockers

  • Hardened runtimes stripping environment variables, PIE / loader mismatches, or no writable place for the .so.

PoC Sketch

symlink('/var/www/html/public/shared_notes/hook.so','/run/apache2/socks/hook.so');
putenv('LD_PRELOAD=/run/apache2/socks/hook.so');
mail('a@b.c','x','y');

Good Situations To Use It

  • putenv, symlink, and mail() are still enabled.
  • You can write a .so to a readable path.
  • Classic PHP RCE functions are disabled.

Sources

  • fcsc2026/web/secure_mood_notes_2