复制成功
请遵守本站 许可

仅用Android手机拯救Linux主机,带你深入了解USB Gadget

2012 字
10 分钟
Chongxi
Chongxi Author
2025-12-16 16:34:26

0. 引#

首先介绍一下本期主角,Chongxi 之前购入过一台玩客云小主机,并给他刷了 Ubuntu armv7,当作一个轻量的服务器来使用,在上面跑跑 AdguardHome 这种小玩意。在爆改的过程中,因为配置文件错误,导致主机的网卡死了,无法进行 ssh 连接,由于所处环境没有实体键盘以及 HDMI 显示器用,主机也没有 reset 按钮,使这台主机成了半残废的状态。

0.1 食材准备#

首先介绍下救砖工具:

  • 一台 root 过的 Android 手机
  • USB 数据线 所需软件:
  • USB Gadget Tool
  • Android HID Keyword

所需文件均已给出其 GitHub 链接,您也可以通过Atlas 快递站一键下载所需文件。

1. 原理讲解#

其实非常简单,就是拿 Android 设备模拟成键盘,输入到主机中。至于无 HDMI 可视化是如何判断命令输出的?答案是,IO 灯
对,你没听错,大多数人可能听说过靠主板 IO 灯来 debug,很少听说过靠 IO 灯来判断输入输出并拯救 ubuntu 主机吧,当你输入操作和主机输出时,IO 灯会闪烁,本文就是靠 IO 灯来诊断的

既然知道了原理,那么接下来救砖就一定很简单了…吧?

1.1 拦路虎#

首先,绝对不是你想的「把数据线一接,然后打开 Gboard 就能输入」这么简单。
USB 协议有严格的主从关系,你插上主机后,大概率是被主机作为要被调试的设备,而不是反过去调试主机。
再者就是 BadUSB 风险,这里简单过一下基本知识

BadUSB

BadUSB是最经典的攻击手段之一,USB 协议有一个信任漏洞,主机会无条件信任设备对自己身份的声明,你说你是键盘他就会相信,没有额外的校验过程。一个简单的 BadUSB 攻击过程如下

  1. 将攻击设备插入主机
  2. 攻击设备向主机声明他是 U 盘,主机信任并加载
  3. 攻击设备主动断开连接,并以 HID 的声明重新连接,主机并不会校验他到底是不是键盘,会直接加载驱动,无任何防备接受一切来自此设备的输入
  4. 攻击设备开始向主机注入命令(如启动 powershell 下载木马),而在主机看来,这可能是一个打字飞快的人类,所以不会有任何阻拦
这和你的 android 手机又有什么关系?

如果你的 android 设备有完整的USB Gadget权限,他就能变成 OURWORLD 里最强大最隐蔽的 BadUSB,谁会怀疑一个毫无威胁的正在充电的手机呢? 你可以使用 Termux 写攻击脚本来对目标设备注入,对方以为你在充电,实则模拟成键盘,甚至 USB 网卡劫持流量来发起中间人攻击,NetHunter就是一个专门为 Android 设备定制的渗透用 rom,可以随意控制手机 USB 接口,伪装成各种设备

OEM 厂商 Google Android 社区都明白,对于这么巨大的安全隐患,做决策就非常简单了,直接砍掉
因为对于普通消费者来说,他们用 USB 传输顶多就是互传照片文件和网络共享,直接干掉 Gadget 无疑是 OEM 厂商的必然选择,风险实在过于严重

那么,我是如何让 Android 设备成功模拟成 HID 对 Ubuntu 进行输入的呢

2. 实现原理#

Talk is cheap, show me the code.

我们直接来看 Linux 内核的官方configfs.txt来解释,为什么用户空间程序能够控制内核级别的硬件行为

2.1 内核提供蓝图 而不是成品#

Where sysfs is a filesystem-based view of kernel objects, configfs is a filesystem-based manager of kernel objects

也就是说,sysfs 是让你看内核已经创建好的东西(比如你的 CPU 温度),而 configfs 是让你要求内核为你创建新的东西。 当 Android 内核被编译时,开启了 CONFIG_USB_GADGETCONFIG_USB_HID 选项后,内核并不会立刻创建一个 USB 键盘设备。它只是在 /config/usb_gadget/ 目录下,准备好了基础工具,等着你来超级拼装

2.2 mkdir#

A configfs config_item is created via an explicit userspace operation: mkdir(2).

你在 configfs 里每创建一个目录,就等于在调用一个内核函数

比如

Terminal window
mkdir /config/usb_gadget/g1
  • 这个命令执行时,configfs会通知 USB Gadget:用户想创建一个新的 Gadget 实例 g1
  • 内核模块后在内存里分配了一块空间,用来描述这个即将被创建的 USB 设备

2.3 目录与文件#

The item's attributes will also appear at this time.

mkdir 成功后,内核会立刻在这个新目录里,为你生成一堆配置文件,这些文件就是这个新对象的可配置属性

比如我们 mkdir g1 之后,ls /config/usb_gadget/g1 可能会看到类似这样的东西:

idVendor # 厂商 ID
idProduct # 产品 ID
strings/ # 各种字符串描述,比如厂商名
functions/ # 定义了这个 Gadget 能扮演什么设备
configs/ # 具体的 USB 配置绑定
UDC # 把配置好的 Gadget 绑定到物理 USB 控制器上

2.4 写入配置#

write(2) can store new values.

也就是你用 echo 往这些属性文件里写东西,就等于在设置内核里那个对象的参数

比如让它模拟成键盘

Terminal window
mkdir /config/usb_gadget/g1/functions/hid.usb0
# 配置参数
echo "..." > /config/usb_gadget/g1/functions/hid.usb0/report_desc
# 创建一个 USB 配置,绑定键盘功能
mkdir /config/usb_gadget/g1/configs/c.1
ln -s /config/usb_gadget/g1/functions/hid.usb0 /config/usb_gadget/g1/configs/c.1

2.5 激活#

[configfs handles] the filesystem representation... allowing the subsystem to ignore all but the basic show/store interaction.

内核模块本身不关心你是怎么创建和配置的,它只在最后一步,等待激活

Terminal window
# 找到你手机的 USB 控制器名称 ( 比如 a12345.dwc3),然后把它写入 UDC 文件
echo "a12345.dwc3" > /config/usb_gadget/g1/UDC

当 UDC 文件被写入时,内核的 USB Gadget 模块会收到一个 Commit 信号
它会读取你刚才在 g1 目录下做的所有配置,把它们组装成一个完整的 USB 设备描述符
然后,它会命令物理 USB 控制器断开当前的连接,并以键盘身份重新连接到主机

这样,就完成了 Android 设备模拟成键盘输入设备的操作。

3. 我是如何救砖的#

  1. 确保你的 android 手机已 root,安装前文的两个开源工具,在 Gadget Tool 中授予 su 权限,并勾选启用 HID Keyboard,便完成了 Android 设备模拟成键盘的操作

  2. 使用数据线将 Android 设备接入 ubuntu 主机,此时手机会被识别成输入设备,当你按下 HID Keyboard 提供的软键盘时,是能够看到 IO 灯闪烁的,接下来的诊断完全是靠 IO 灯判断的

  3. 尝试输入密码并等待十秒,建议直接使用 root 账号,可以省去 sudo 的麻烦,这种情况在乎用户组安全没啥必要,随后执行ls观察 IO 灯是否剧烈闪烁,如果剧烈闪烁则说明 ls 成功提供了输出,为了稳妥起见,这里决定reboot一下,主机重启,说明我们登录操作没问题

  4. Chongxi 这里是提前准备过一个恢复脚本,防止这种铸币情况,主要功能是恢复原来的网卡备份的内容。再次通过 io 灯判断输入,直接执行恢复命令,主机重启,打开 openwrt,发现 ubuntu 对应的 LAN 口开始有正常流量通信,ssh 可以正常连接,救砖成功

4. 结#

本文确实已经超出了普通 Linux 桌面版使用的范畴,可以说是纯粹的炫技,需要你的设备内核支持且已 root,可以说是天时地利人和都很考验的一种解决方案

对于 Linux 玩家来说,没有绝对的死局,只有你还未发现的后门,这就是卓越的开放性

仅用Android手机拯救Linux主机,带你深入了解USB Gadget

作者: Chongxi
发布于: 2025-12-16
许可协议: CC BY-NC-SA 4.0
分享博文信息 (Copy All)
Contents