文件描述符(FD)是 Linux/Unix 系统中用于访问文件、管道、套接字等 I/O 资源的整数标识符。每个进程默认打开 3 个标准文件描述符:
FD | 名称 | 默认绑定设备 | 用途 |
---|---|---|---|
0 | stdin | 键盘 | 标准输入(读取数据) |
1 | stdout | 终端屏幕 | 标准输出(打印数据) |
2 | stderr | 终端屏幕 | 标准错误(打印错误) |
一、文件描述符如何工作?
Linux 内核为每个进程维护一个 文件描述符表(File Descriptor Table),通过 FD 索引访问对应的文件或设备:
进程A
├── FD 0 → stdin(键盘)
├── FD 1 → stdout(终端)
├── FD 2 → stderr(终端)
├── FD 3 → /etc/passwd(打开的文件)
└── FD 4 → socket(网络连接)
二、如何查看进程的文件描述符?
方法 1:ls -l /proc/<PID>/fd
ls -l /proc/$$/fd # 查看当前 shell 的 FD
输出示例:
lrwx------ 1 user user 64 Jan 1 00:00 0 → /dev/pts/0 (stdin)
lrwx------ 1 user user 64 Jan 1 00:00 1 → /dev/pts/0 (stdout)
lrwx------ 1 user user 64 Jan 1 00:00 2 → /dev/pts/0 (stderr)
方法 2:lsof -p <PID>
lsof -p $$ # 查看当前进程的所有 FD
三、文件描述符的利用方法
文件描述符在 系统安全、漏洞利用(PWN)、权限提升 中有重要作用。
1. 文件描述符劫持(FD Hijacking)
场景:某些程序以高权限运行时,可能意外泄漏敏感 FD(如打开 /etc/shadow
)。
利用方法:
# 假设某个 SUID 程序意外泄漏了 FD 3 指向 /etc/shadow
cat /proc/<PID>/fd/3 # 尝试读取
2. 重定向敏感数据(Bash 重定向)
场景:通过 exec
修改进程的 FD,实现持久化重定向。
示例:
exec 3>/tmp/stolen_data.txt # 打开 FD 3 并绑定到文件
echo "Sensitive Data" >&3 # 写入 FD 3
exec 3>&- # 关闭 FD 3
3. 绕过过滤(如 PWN 题目中的 1>&2
)
场景:程序可能过滤 stdout
,但 stderr
仍然可用。
利用方法:
# 在漏洞利用中,让数据从 stderr 泄露
p.sendline(b"exec 1>&2") # 让 stdout 走 stderr
p.sendline(b"cat flag") # 结果从 stderr 输出
4. 文件描述符注入(FD Injection)
场景:通过 ptrace
或 /proc/<PID>/fd
向进程注入 FD。
示例:
# 假设目标进程 PID=1234,我们想让它的 FD 3 指向 /etc/passwd
ln -s /etc/passwd /proc/1234/fd/3 # 符号链接攻击(需权限)
5. 特权文件访问(通过泄漏的 FD)
场景:某些 SUID 程序可能意外继承高权限 FD。
示例:
# 如果某个 SUID-root 程序打开了 /etc/shadow 并泄漏 FD
cat /proc/<PID>/fd/3 # 可能读到 shadow 文件
四、防御措施
- 最小权限原则:程序运行时关闭不必要的 FD。
close()
未使用的 FD:防止泄漏。O_CLOEXEC
标志:exec
时自动关闭 FD。- 限制
/proc/<PID>/fd
访问:防止低权限用户窥探。
五、总结
技术 | 用途 | 示例 |
---|---|---|
FD 劫持 | 读取进程泄漏的敏感 FD | cat /proc/1234/fd/3 |
重定向绕过 | 让数据从 stderr 泄露 | exec 1>&2; cat flag |
FD 注入 | 通过 /proc 修改目标进程的 FD | ln -s /etc/passwd /proc/1234/fd/3 |
特权 FD 利用 | 通过 SUID 程序泄漏的 FD 读敏感文件 | cat /proc/<SUID-PID>/fd/x |
文件描述符是 Linux 系统安全的关键部分,理解其机制可以用于 漏洞利用、权限提升、数据泄露,同时也是 防御敏感数据泄漏 的重要知识点。