getcap本身不支持递归扫描,必须配合find使用;可靠命令为find / -xdev -type f -exec getcap {} \; 2>/dev/null | grep -v ' = cap\_',其中-xdev避免跨文件系统,-type f确保只查普通文件。

getcap 怎么递归扫描整个文件系统
getcap 本身不支持直接递归扫描,必须配合 find 使用。常见错误是只跑 getcap /usr/bin/*,漏掉 /opt、/snap、/home 下的二进制,甚至忽略符号链接目标。
实际可用命令是:
find / -type f -perm /6000 -exec getcap {} \; 2>/dev/null
但这个写法有明显问题:它依赖 setuid/setgid 位(-perm /6000)来粗筛,而 Capability 可以独立存在、无需 setuid —— 所以会漏掉大量真实带 cap 的文件(比如 ping 在多数发行版里已移除 setuid,仅靠 cap_net_raw+ep 运行)。
更可靠的做法是遍历所有普通文件,再用 getcap 检查(代价是慢一点,但结果完整):
find / -xdev -type f -exec getcap {} \; 2>/dev/null | grep -v ' = cap_'
其中 -xdev 防止跨挂载点(跳过 /proc、/sys、/dev 等虚拟文件系统),grep -v ' = cap_' 过滤掉无 cap 的行(getcap 对无 cap 文件输出形如 /bin/ls =)。
为什么 getcap 输出里有些路径显示 “no value”
这不是错误,而是 getcap 对两类情况的统一反馈:
- 文件确实没绑定任何 capability(输出
/path/to/binary =) - 文件存在,但当前用户无读权限(输出同样为
/path/to/binary =,不报错也不提示权限问题)
容易误判为“没 cap”,实则是权限不足导致看不到。验证方式很简单:
sudo getcap /some/binary
如果 sudo 后输出类似 /some/binary = cap_net_bind_service+ep,说明之前只是权限不够。
另外注意:某些路径(如 /snap/<em>/current/</em>)下二进制可能被 squashfs 封装或硬链接到只读位置,getcap 能读元数据,但若文件被 mount 为 noexec 或 nodev,不影响 capability 检查本身。
扫描结果里 cap_net_raw 和 cap_sys_admin 哪个更危险
不是所有 capability 危险程度相同,得看实际能力边界:
-
cap_net_raw+ep允许原始套接字操作 → 可发任意 IP 包(如伪造 ICMP、构造 TCP 握手),常用于ping、traceroute、抓包工具。攻击者可借此做网络探测、DoS 或中间人前提准备。 -
cap_sys_admin+ep是最高危之一,等价于 root 级别系统管理权:能挂载文件系统、修改内核参数(sysctl)、绕过 DAC 检查、调用reboot等。一旦被非特权进程持有,基本等于提权成功。
其他高风险 capability 还包括:
-
cap_setuid+ep:可任意切换 UID/GID -
cap_dac_override+ep:无视文件读写执行权限 -
cap_sys_module+ep:可加载/卸载内核模块(直接控制内核)
检查时建议优先关注含 +ep(effective + permitted)的条目,这类 capability 在执行时自动启用,无需额外 seteuid 等操作。
如何快速定位某个 capability 被哪些二进制使用
不用手动翻扫描结果,用 grep 直接过滤:
getcap -r / 2>/dev/null | grep cap_net_bind_service
但更实用的是反向查——已知一个可疑二进制,想确认它到底绑了什么:
getcap -v /usr/bin/python3
-v 参数会显示详细字段含义(如 effective、permitted、inheritable),避免把 cap_net_bind_service+ip(仅 inheritable)误当成可直接使用的权限。
另外注意:部分二进制(如 Docker 容器内运行的)可能通过 --cap-add 在运行时注入 capability,这种不会出现在宿主机文件系统扫描结果里——getcap 只查文件的 file-based capability,不反映 runtime 添加的。
真正要覆盖全场景,得结合 ps auxZ(SELinux)、cat /proc/PID/status | grep Cap 和容器运行时配置一起看。单靠 getcap -r 只能解决静态文件层面的问题。











