网络靶场实战-恶意程序自启动

简介

当恶意程序入侵目标为个人计算机时,相较于服务器,个人计算机对关机或重启操作更加频繁,关机时计算机所有的进程都会被结束,因此恶意程序需要配置自启动来使自己在每次开机时能够被运行。

本篇介绍一个恶意样本(b8090d7d12d6f0abacd16ecfab252f48ee466a254c1751d928567485208634f9)中使用的自启技术,该样本是一个可执行程序,运行后会释放一些文件,其中两个文件比较重要,一个文件为saxbn.exe,该文件是联想应用商店的一个组件(LeASLane),是一个正常的程序。

图片

另一个文件名为libcrypto-3.dll,在正常情况下,该文件为OpenSSL的加密库,被LeASLane所依赖,攻击者通过劫持该文件,并对其使用了文件膨胀、seh异常、加壳等技术来对抗安全检测,在saxbn.exe运行时,会加载被劫持的libcrypto-3.dll,执行其中的恶意载荷。

图片

上述介绍中,可以知道该攻击利用了白加黑,那么想在每次开机时都执行恶意程序,saxbn.exe需要设置自启,该样本对saxbn.exe自启方式比较隐蔽,如果在没有原始样本的情况下,找到自启配置还是比较困难的,在隔离环境中执行样本,并将原始样本清理,然后试着用常规方式,看能否找到可疑的启动项。

自启动排查

上文中已经说明,想要执行恶意载荷,需要在每次开机时执行saxbn.exe,因此需要找到该程序的信息。

最常见的方式是去注册表中查找RUN启动项,配置项如下:

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Runonce

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServices

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServicesOnce

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\explorer\run

HKCU\Software\Microsoft\Windows\CurrentVersion\Run

HKCU\Software\Microsoft\Windows\CurrentVersion\Runonce

HKCU\Software\Microsoft\Windows\CurrentVersion\RunServices

HKCU\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce

HKCU\Software\Microsoft\Windows\CurrentVersion\policies\explorer\run

对这些项逐个进行排查,没有发现可疑配置。

图片

然后排查启动项目录,需要自启动的程序会将自己的快捷方式保存在该目录下,按下Win + R键打开"运行"对话框,输入"shell:startup"打开启动项目录,勾选显示隐藏的项目,防止文件隐藏,发现该目录下为空,也没有发现可疑信息。

图片

接下来排查计划任务,恶意程序可以利用com接口,通过类似下方的代码,在计划任务中添加自启动

#include <windows.h>
#include <comdef.h>
#include <taskschd.h>
#include <iostream>

#pragma comment(lib, "taskschd.lib")
#pragma comment(lib, "comsupp.lib")

int main()
{
    HRESULT hr;

    // 创建与计划任务相关的 COM 对象
    CoInitializeEx(NULL, COINIT_MULTITHREADED);

    ITaskService* pService = NULL;
    hr = CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskService, (void**)&pService);
    if (FAILED(hr))
    {
        std::cout << "Failed to create an instance of ITaskService!" << std::endl;
        return -1;
    }

    // 连接到任务计划程序
    hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
    if (FAILED(hr))
    {
        std::cout << "Failed to connect to the Task Scheduler service!" << std::endl;
        pService->Release();
        return -1;
    }

    ITaskFolder* pRootFolder = NULL;
    hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
    if (FAILED(hr))
    {
        std::cout << "Failed to get the root folder!" << std::endl;
        pService->Release();
        return -1;
    }

    ITaskDefinition* pTaskDefinition = NULL;
    hr = pService->NewTask(0, &pTaskDefinition);
    if (FAILED(hr))
    {
        std::cout << "Failed to create a new task definition!" << std::endl;
        pRootFolder->Release();
        pService->Release();
        return -1;
    }

    ITriggerCollection* pTriggerCollection = NULL;
    hr = pTaskDefinition->get_Triggers(&pTriggerCollection);
    if (FAILED(hr))
    {
        std::cout << "Failed to get the trigger collection!" << std::endl;
        pTaskDefinition->Release();
        pRootFolder->Release();
        pService->Release();
        return -1;
    }

    ITrigger* pTrigger = NULL;
    hr = pTriggerCollection->Create(TASK_TRIGGER_BOOT, &pTrigger);
    if (FAILED(hr))
    {
        std::cout << "Failed to create a new trigger!" << std::endl;
        pTriggerCollection->Release();
        pTaskDefinition->Release();
        pRootFolder->Release();
        pService->Release();
        return -1;
    }

    IActionCollection* pActionCollection = NULL;
    hr = pTaskDefinition->get_Actions(&pActionCollection);
    if (FAILED(hr))
    {
        std::cout << "Failed to get the action collection!" << std::endl;
        pTrigger->Release();
        pTriggerCollection->Release();
        pTaskDefinition->Release();
        pRootFolder->Release();
        pService->Release();
        return -1;
    }

    IAction* pAction = NULL;
    hr = pActionCollection->Create(TASK_ACTION_EXEC, &pAction);
    if (FAILED(hr))
    {
        std::cout << "Failed to create a new action!" << std::endl;
        pActionCollection->Release();
        pTrigger->Release();
        pTriggerCollection->Release();
        pTaskDefinition->Release();
        pRootFolder->Release();
        pService->Release();
        return -1;
    }

    IExecAction* pExecAction = NULL;
    hr = pAction->QueryInterface(IID_IExecAction, (void**)&pExecAction);
    if (FAILED(hr))
    {
        std::cout << "Failed to query IExecAction interface!" << std::endl;
        pAction->Release();
        pActionCollection->Release();
        pTrigger->Release();
        pTriggerCollection->Release();
        pTaskDefinition->Release();
        pRootFolder->Release();
        pService->Release();
        return -1;
    }

    // 设置要执行的程序
    hr = pExecAction->put_Path(_bstr_t("C:\\Path\\To\\Your\\Program.exe"));
    if (FAILED(hr))
    {
        std::cout << "Failed to set the path of the program to execute!" << std::endl;
        pExecAction->Release();
        pAction->Release();
        pActionCollection->Release();
        pTrigger->Release();
        pTriggerCollection->Release();
        pTaskDefinition->Release();
        pRootFolder->Release();
        pService->Release();
        return -1;
    }

    IRegisteredTask* pRegisteredTask = NULL;
    hr = pRootFolder->RegisterTaskDefinition(_bstr_t(L"YourTaskName"),
        pTaskDefinition,
        TASK_CREATE_OR_UPDATE,
        _variant_t(),
        _variant_t(),
        TASK_LOGON_INTERACTIVE_TOKEN,
        _variant_t(L""),
        &pRegisteredTask);
    if (FAILED(hr))
    {
        std::cout << "Failed to register the task definition!" << std::endl;
        pExecAction->Release();
        pAction->Release();
        pActionCollection->Release();
        pTrigger->Release();
        pTriggerCollection->Release();
        pTaskDefinition->Release();
        pRootFolder->Release();
        pService->Release();
        return -1;
    }

    std::cout << "The program has been added to startup successfully!" << std::endl;

    // 释放 COM 对象及其接口
    pRegisteredTask->Release();
    pExecAction->Release();
    pAction->Release();
    pActionCollection->Release();
    pTrigger->Release();
    pTriggerCollection->Release();
    pTaskDefinition->Release();
    pRootFolder->Release();
    pService->Release();
    CoUninitialize();

    return 0;
}

打开计划任务,发现也没有相关配置信息。

图片

由于自启的方式还有很多,接下来我们使用Autoruns 工具来查看是否有saxbn.exe启动项的一些信息。

Autoruns 是一款由 Sysinternals 开发的免费工具,用于管理Windows操作系统中自动启动的程序和服务。它提供了一个全面的系统启动项和登录项清单,包括注册表中的所有自动启动位置,从而帮助用户找到并禁用或删除不需要的自动启动项。Autoruns 还提供了强大的搜索功能,以帮助用户准确定位到特定的启动项。此外,该工具还可以显示每个启动项的详细信息,包括路径、描述、发布者和数字签名等,从而帮助用户判断是否需要保留或禁用该启动项。Autoruns 可以帮助用户提高计算机的启动速度,减少系统资源的占用,并且增加系统的安全性,因为某些恶意软件和病毒可能会利用自动启动功能在计算机启动时自动运行。使用Autoruns,用户可以轻松地管理系统的启动项,确保只有必要的程序和服务在系统启动时自动运行。

Autoruns 对自启动的检测是比较全面的,然而遗憾的是,我们在Autoruns中依然没有找到saxbn.exe自启动的信息,但是Autoruns帮我们排除了很多saxbn.exe可能配置的方法。

图片

样本中使用的自启动

那么恶意样本是如何配置自启动的呢?

恶意程序在释放saxbn.exe时,修改了注册表\HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders下Startup项,将其改为C:\Users\Public\Documents\miso。

图片

Windows开机时会根据Startup配置的值,去该目录下获取自启项,查看miso目录,发现有一个快捷方式,指向了加载恶意dll的白程序saxbn.exe。

图片

Windows默认情况下,Startup的初始值为C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup,这与我们之前通过命令执行shell:startup打开的目录相同。但是恶意程序已经修改了Startup值,也就是说,即使修改了Startup项的值,执行shell:startup依旧会打开默认配置,但实际情况该目录已被替换,这会误导我们启动项目录好像没有问题,甚至Autoruns工具也没有检测出来。

总结

使用样本中自启方式,是比较隐蔽,但是该方式仍有缺点,当受害者通过shell:startup添加一些自启项时,会因默认目录被修改,如果没有将默认目录下的文件持续同步到新配置的目录,自启动项不会生效,这时受害者会警惕自己的计算机可能已经被入侵。

图片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/553730.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OCR识别图片的字体与正常的字不同怎么调回来呢?

一般来说&#xff0c;OCR的任务是将图片文字转化成计算机可编辑的文字&#xff0c;一般不识别字体&#xff0c;当然&#xff0c;也不排除某些OCR软件可以识别字体的&#xff0c;具体来说&#xff0c;造成这种现象的可能原因如下&#xff1a; 1. **字体匹配问题**&#xff1a;OC…

【SpringBoot+VUE+ELEMENT 】前后端分离的管理系统的实现——基础功能(记录向)

一个前后端分离的实现。后端使用SpringBoot&#xff0c;前端使用Vue&#xff0c;后端标准的四层结构&#xff0c;前端是用的Element。 一、环境准备 1.安装node.js Node.js 是一个开源的、跨平台的 JavaScript 运行时环境。 成功后cmd中运行 node -v npm -v 出现 对应的版本…

【python】flask中ORM工具SQLAIchemy,各种数据查询操作详细解析

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

使用Spring进行文件的上传和下载

概览 使用Spring进行文件的上传和下载Spring上传文件接口设计dubbo接口设计上传文件流的RPC的接口设计 Spring文件下载接口设计dubbo接口设计下载文件流的RPC的接口设计 spring上传文件大小控制 使用Spring进行文件的上传和下载 本文主要介绍在Spring框架下面调用微服务的dubb…

学习笔记(4月17日)vector底层原理

1.vector<vector>底层原理 vector是表示可变大小数组的序列容器&#xff0c;相当于一个动态的数组&#xff0c;比数组优越的在于它具有可动态改变的大小&#xff0c;同时&#xff0c;它写成了类模板&#xff0c;说明可以适用于其他类型&#xff0c;包括vector本身&#…

AI赋能自动化测试:智能接口自动化测试数据生成平台设计思路

目录 1.背景 2.名词解释 3.设计目标 4.设计思路及折衷 4.1阶段性任务 4.2方案选型 4.2.1 设计方案选型 4.2.1.1 原始数据获取模块 4.2.1.2 数据构造模块 4.2.1.3 预执行模块 4.2.1.4 覆盖率反馈调整模块 4.2.1.5 预测模型 4.2.2 技术选型 5.系统设计 5.1 项目架…

LeetCode669:修剪二叉搜索树

题目描述 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即&#xff0c;如果没有被移除&#xff0c;原有的父代子代关系都应…

vivo怎么录屏?玩转手机新体验!(2024最新)

“最近新入手了一款vivo手机&#xff0c;感觉用起来真的很顺手&#xff0c;各种功能都很强大。昨天和朋友一起打游戏&#xff0c;突然想到要记录下精彩瞬间&#xff0c;但是找遍了手机&#xff0c;都没有找到录屏功能。我想请教一下各位vivo手机用户&#xff0c;你们通常在哪里…

解决动态规划问题

文章目录 动态规划的定义动态规划的核心思想青蛙跳阶问题解法一&#xff1a;暴力递归解法二&#xff1a;带备忘录的递归解法&#xff08;自顶向下&#xff09;解法三&#xff1a;动态规划&#xff08;自底向上&#xff09; 动态规划的解题套路什么样的问题考虑使用动态规划&…

转录组上游分析,Count计算

本期教程原文链接&#xff1a;转录组定量&#xff0c;最简单的操作&#xff0c;你会吗&#xff1f; 本期教程 第六章 转录本定量分析 定量软件有RSEM,eXpress,salmoe,kallisto&#xff0c;featureCounts。在网络中吗&#xff0c;都有比较详细的教程&#xff0c;大家可以自己去…

最新UI发卡盗U,支持多语言,更新UI界面,支持多个主流钱包,附带系统搭建教程

环境&#xff1a;Linux系统 进入宝塔安装环境&#xff1a;Nginx 1.22.1 MySQL 8.0 php7.4 phpMyAdmin 5.2 按照说明去安装环境&#xff0c;如果没有找到MySQL8.0版本去"软件商店"搜索Mysql切换至8.0 1.上传开源源码 2.上传数据库文件 3.上传猴导入数据库文件 4.修…

SpringBoot+FreeMaker

目录 1.FreeMarker说明2.SpringBootFreeMarker快速搭建Pom文件application.properties文件Controller文件目录结构 3.FreeMarker数据类型3.1.布尔类型3.2.数值类型3.3.字符串类型3.4.日期类型3.5.空值类型3.6.sequence类型3.7.hash类型 4.FreeMarker指令assign自定义变量指令if…

HTML学习笔记:(一)基础方法

Html格式 里面文件使用平台为&#xff1a;w3school 1、基础功能&#xff1a; <html><head> <title>这是我的第一个html页面,会显示在浏览器的标题栏中</title> </head> <!--修改背景颜色 --> <body bgcolor"yellow"> …

QtQuick 学习笔记(二)按钮组件

1. QPushButton 功能 按压按钮&#xff0c;用于接受用户点击事件&#xff0c;可显示设定的字符串提示信息&#xff0c;但需要父组件作为容器&#xff0c;多用以执行命令或触发事件 常用函数 QPushButton&#xff1a;&#xff1a;QPushButton&#xff08;const QString &…

RHCE1

unit1.定时任务和延迟任务项目 1.在系统中设定延迟任务要求如下: 在系统中建立easylee用户&#xff0c;设定其密码为easylee 延迟任务由root用户建立 要求在5小时后备份系统中的用户信息文件到/backup中确保延迟任务是使用非交互模式建立 再使用chmod修改权限&#xff1a; 确保…

HarmonyOS真机调试页面运行卡顿/黑屏解决方法,亲测有效

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 用mate40等发行时间相对较早但系统是HarmonyOS4.0的真机调试 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; 程序点击容易卡顿或黑屏 原因分析&#xff1a; CPU兼容问题导致屏幕…

Text2sql的一些技巧

最近看到了一篇关于text2sql的文章&#xff0c;以及一些论文。对使用模型做text2sql给了一些不错的建议。 参考文章&#xff1a;24年大模型潜力方向&#xff1a;大浪淘沙后的Text-to-SQL和Agent - 知乎 论文&#xff1a;https://arxiv.org/pdf/2403.09732.pdf 关于模型的建议 …

STM32H7定时器TIM1-TIM17中断、PWM实现

STM32H7定时器TIM1-TIM17中断、PWM实现 高级定时器硬件框图定时器模式时基输出PWM定时器输入捕获 TIM1-TIM17的中断配置TIM1-TIM17的PWM输出 STM32H7 支持的定时器有点多&#xff0c;要简单的区分下。STM32H7 支持 TIM1-TIM8&#xff0c;TIM12-TIM17 共14 个定时器&#xff0c;…

使用API有效率地管理Dynadot域名,锁定账户中的域名

关于Dynadot Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮…

Zynq7000系列中的时钟管理

PS&#xff08;处理系统&#xff09;时钟子系统生成的所有时钟都源自三个可编程PLL&#xff08;锁相环&#xff09;中的一个&#xff1a;CPU、DDR和I/O。时钟子系统的主要组件如图25-1所示。 在正常工作期间&#xff0c;PLL被启用&#xff0c;并由PS_CLK时钟引脚驱动。在启用P…