![为什么 ping 可以在没有能力和 setuid 的情况下工作](https://linux22.com/image/182857/%E4%B8%BA%E4%BB%80%E4%B9%88%20ping%20%E5%8F%AF%E4%BB%A5%E5%9C%A8%E6%B2%A1%E6%9C%89%E8%83%BD%E5%8A%9B%E5%92%8C%20setuid%20%E7%9A%84%E6%83%85%E5%86%B5%E4%B8%8B%E5%B7%A5%E4%BD%9C%20.png)
我从中学到了这里有两种方法可以控制特权活动:setuid
和capability
。
但是当我在我的机器上玩时ping
,它似乎可以绕过这两种机制。
首先,确认我的机器/usr/bin/ping
有cap_net_raw
能力并且它使用SOCK_RAW
:
$ ll /usr/bin/ping
-rwxr-xr-x 1 root root 72K Jan 31 2020 /usr/bin/ping
$ getcap /usr/bin/ping
/usr/bin/ping = cap_net_raw+ep
$ strace -e socket ping <some-ip>
socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE) = 5
复制二进制文件会删除该功能,但它仍然有效:
$ cp /usr/bin/ping ~
$ ll ~/ping
-rwxr-xr-x 1 user user 72K Nov 4 16:54 /home/user/ping
$ getcap ~/ping
[empty result]
$ ~/ping <some-ip>
[it works]
我正在使用Ubuntu 20.04
和5.4.0-52-generic
。
答案1
在最近的 Linux 系统上,ping 的最基本操作不需要任何权限,即发送ICMP回显请求消息并接收响应的回显应答消息。
Ubuntu 20.04 有两种 ping 实现。默认的,来自iputils-ping,已安装 setcap CAP_NET_RAW
,但适用于 ICMP echo,无需特权。那个来自inetutils-ping已安装 setuid root,但也适用于没有特权的 ICMP echo。两者都使用 ICMP 套接字,无需特权即可使用:
socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP) = 3
我无法在这些实现中重现使用 netlink 套接字进行基本 ping,无论有或没有特权。