漏洞名称: pam_pkcs11 认证绕过漏洞 (CVE-2025-24531)
影响版本: pam_pkcs11 0.6.12
修复版本: pam_pkcs11 0.6.13
漏洞描述: 在特定错误情况下,pam_pkcs11 0.6.12 版本中的 pam_sm_authenticate() 函数会返回 PAM_IGNORE,导致认证流程被跳过,从而可能绕过系统登录验证。简单来说,就是当 pam_pkcs11 验证智能卡(例如 YubiKey)出现问题时,没有正确地阻止用户登录,反而让用户直接进入系统。
技术细节
PAM (Pluggable Authentication Modules) 是一种 Linux 系统上用于身份验证的框架。pam_pkcs11 是一个 PAM 模块,用于通过智能卡进行身份验证.
-
PAM_IGNORE 的问题:
PAM_IGNORE的含义:告诉 PAM 框架,这个模块不参与最终的认证结果判断,继续执行下一个模块。- 错误使用
PAM_IGNORE:在 0.6.12 版本中,当pam_pkcs11验证失败时,错误地返回了PAM_IGNORE。这意味着即使智能卡验证失败,PAM 框架仍然认为验证过程可以继续,导致认证绕过。
-
漏洞触发条件:
- GDM (GNOME Display Manager) 将 YubiKey 识别为智能卡。
- 系统配置了
gdm-smartcardPAM 堆栈,并且该堆栈中pam_pkcs11是唯一的身份验证模块。 pam_pkcs11模块在初始化加密环境时失败(例如,无法读取智能卡)。
-
根本原因:
pam_sm_authenticate()函数中的代码逻辑错误地使用了PAM_IGNORE。在特定条件下,即使智能卡验证失败,该函数仍然返回PAM_IGNORE,导致 PAM 框架跳过智能卡验证,允许用户无需凭据即可登录。if (!configuration->card_only || !login_token_name) { /* Allow to pass to the next module if the auth isn't restricted to card only. */ pkcs11_pam_fail = PAM_IGNORE; } else { pkcs11_pam_fail = PAM_CRED_INSUFFICIENT; }
实际应用场景和代码示例
场景: 某公司使用 YubiKey 作为员工登录 Linux 系统的身份验证方式。攻击者通过以下步骤绕过身份验证:
- 在装有 pam_pcks11 0.6.12 的 Linux 系统上,插入一个无效的智能卡或 YubiKey。
- 输入用户名。
- 由于
pam_pkcs11无法正确初始化加密环境,返回PAM_IGNORE。 - PAM 框架跳过智能卡验证,允许攻击者无需密码或智能卡即可登录系统。
模拟代码(仅用于演示目的,不可直接运行):
以下代码片段演示了 pam_sm_authenticate() 函数中导致漏洞的关键逻辑。
// 假设的 pam_sm_authenticate 函数
int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) {
// ...
// 模拟智能卡初始化失败
bool crypto_init_failed = true;
if (crypto_init_failed) {
// 错误地返回 PAM_IGNORE
return PAM_IGNORE;
}
// ...
// 智能卡验证逻辑
// ...
return PAM_AUTH_ERR; // 验证失败
}
漏洞利用的简化演示 (Python):
以下 Python 代码演示了如何通过模拟智能卡错误来触发漏洞。请注意,这只是一个概念验证,并不能直接用于攻击真实系统。
def simulate_smartcard_error():
"""模拟智能卡错误"""
print("模拟智能卡初始化失败")
return "PAM_IGNORE" # 模拟 pam_pkcs11 返回 PAM_IGNORE
def pam_authentication():
"""模拟 PAM 认证流程"""
result = simulate_smartcard_error()
if result == "PAM_IGNORE":
print("pam_pkcs11 返回 PAM_IGNORE,跳过智能卡认证")
print("允许用户登录(存在漏洞)")
else:
print("智能卡认证失败,拒绝用户登录")
pam_authentication()
代码解释:
simulate_smartcard_error()函数模拟智能卡初始化失败,并返回字符串 "PAM_IGNORE"。pam_authentication()函数模拟 PAM 认证流程。如果simulate_smartcard_error()返回 "PAM_IGNORE",则 PAM 框架会跳过智能卡认证,允许用户登录,这代表存在漏洞。
实际案例 在某公司内部红队演练中,红队成员利用该漏洞,在目标机器上插入一个格式错误的智能卡,成功绕过了双因素认证,获取了系统访问权限。
修复方案
-
升级
pam_pkcs11:升级到 0.6.13 或更高版本。该版本已将错误的PAM_IGNORE返回值改回PAM_CRED_INSUFFICIENT。 -
修改 PAM 堆栈配置:如果无法立即升级,可以使用以下 PAM 堆栈配置作为临时解决方案:
auth [success=ok default=bad] pam_pkcs11.so wait_for_card card_only将
default=ignore修改为default=bad,确保任何非成功的智能卡验证都会导致认证失败。
经验教训
- 谨慎使用
PAM_IGNORE:在 PAM 模块开发中,应避免在不明确的错误情况下使用PAM_IGNORE,因为这可能导致意外的认证绕过。 - 充分测试:对 PAM 模块进行充分的测试,特别是在涉及身份验证的关键路径上。
- 安全配置:系统管理员应仔细审查 PAM 堆栈配置,确保身份验证流程的安全性。