.NET内网实战:通过动态编译混淆代码执行Shellcode

01阅读须知

此文所节选自小报童《.NET 内网实战攻防》专栏,主要内容有.NET在各个内网渗透阶段与Windows系统交互的方式和技巧,对内网和后渗透感兴趣的朋友们可以订阅该电子报刊,解锁更多的报刊内容。

02基本介绍

本文内容部分节选自小报童《.NET 通过隐藏任务计划实现权限持久化》,现在限时只需59元,永久买断!目前已有240+位朋友抢先预定,我们会长期更新!

03原理分析

在红队行动中,常常需要规避各种防御机制以成功启动木马进程。今天,我们将深入探讨一种相对冷门但非常有趣的技术:通过 .NET 动态编译结合代码混淆,实现对 shellcode 的隐秘执行。

3.1 VirtualAlloc函数

VirtualAlloc 是 Windows API 中用于内存分配的函数,常用于分配和保护进程的虚拟内存空间。在.NET中可以通过 P/Invoke 调用的非托管函数,具体代码如下所示。

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
private static extern UInt32 VirtualAlloc(
    UInt32 lpStartAddr,        // 内存的起始地址
    UInt32 size,               // 要分配的内存大小(以字节为单位)
    UInt32 flAllocationType,   // 分配类型(如 MEM_COMMIT 或 MEM_RESERVE)
    UInt32 flProtect           // 内存保护属性(如 PAGE_EXECUTE_READWRITE)
);

因此,在.NET里通过[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] 特性声明 Windows API。DllImport 提供了SetLastError 、ExactSpelling 两个选项,当 SetLastError 设置为 true时, 表示是否返回 GetLastError 的错误代码。

3.2 CreateThread函数

CreateThread 也是 Windows API 提供的函数,用于在目标进程中创建一个新的线程。通常在.NET里调用的方式如下所示。

[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr CreateThread(
    UInt32 lpThreadAttributes,  // 线程的安全属性
    UInt32 dwStackSize,         // 线程的初始堆栈大小
    UInt32 lpStartAddress,      // 线程的起始地址(函数指针)
    IntPtr param,               // 传递给线程的参数
    UInt32 dwCreationFlags,     // 创建标志
    ref UInt32 lpThreadId       // 接收线程 ID
);

通常与动态内存分配和 shellcode 执行结合使用,尤其是在渗透测试或恶意代码中,用于将 shellcode 注入到目标进程并执行。

3.3 动态编译技术

安全对抗阶段,有时我们需要在运行时动态编译代码并执行,.NET平台提供的CSharpCodeProvider 是一个编译服务的类,用于与底层的编译器交互,可以动态创建、编辑和编译代码。

public static object function1(string code, string namespacename, string classname, string functionname, bool isstatic, params object[] args)
{
    object returnval = null;
    Assembly asm = BuildAssembly(code);
    object instance = null;
    Type type = null;
    if (isstatic)
    {
        type = asm.GetType(namespacename + "." + classname);
    }
    else
    {
        instance = asm.CreateInstance(namespacename + "." + classname);
        type = instance.GetType();
    }
    MethodInfo method = type.GetMethod(functionname);
    returnval = method.Invoke(instance, args);
    return returnval;
}

上述代码中,通过 Type.GetMethod() 获取指定的方法信息,然后使用 MethodInfo.Invoke() 调用方法,不过做了一次判断,对于静态方法,调用时不需要实例,对于实例方法,需传入已创建的对象实例。

通过调用function1(code, "Namespace", "Program", "run", false, null); 实现动态编译执行,此处的 "run" 便是需要调用的方法名称,"Program" 是类的名称。运行后成功启动本地计算器进程,如下图所示

图片

综上所述,通过动态编译.NET代码实现线程注入的思路,其主要功能是接收经过 Base64 编码的 shellcode 字符串,并将其注入到本地线程中,从而执行恶意代码。想要了解完整或者更多的内网安全方向的文章,可以移步订阅小报童《.NET 内网实战攻防》电子报刊。

 04.NET 电子报刊

电子报刊《.NET 内网安全攻防》专栏,内容主要有.NET在各个内网渗透阶段与Windows系统交互的方式和技巧,可细分为以下8个方向。

1) .NET 安全防御绕过
2) .NET 本地权限提升
3) .NET 内网信息收集
4) .NET 内网代理通道
5) .NET 内网横向移动
6) .NET 目标权限维持
7) .NET 数据传输外发
8) .NET 目标痕迹清理

我们会长期更新,初步计划保持每周更新1-2篇新内容!

图片

想要了解完整或者更多的内网安全方向的文章,可以移步订阅小报童《.NET 内网实战攻防》电子报刊,报刊地址:https://xiaobot.net/p/dotNetAttack

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dot.Net安全矩阵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值