.NET 介绍一种隐蔽的命令执行方式,通过 LINQ 投影执行动态加载

原文链接: https://mp.weixin.qq.com/s?__biz=MzUyOTc3NTQ5MA==&mid=2247499989&idx=1&sn=8f5d60702d8764a873e0a41789698fef

.NET 介绍一种隐蔽的命令执行方式,通过 LINQ 投影执行动态加载

原创 专攻.NET安全的 dotNet安全矩阵 2025-07-01 00:31

图片

在红队渗透过程中,传统的命令执行方式,比如直接调用 

cmd.exe

或通过 Webshell 发起命令往往容易被安全产品检测到。为此,红队需要不断探索更隐蔽、更绕过主流安全机制的方法。而本文要介绍的 

.NET LINQ 投影 + 反射加载 DLL 执行

技术,正是一种融合了语言特性与框架机制的创新利用方式。

不仅规避了传统命令行行为的检测,同时以数据查询逻辑的形式隐藏真实意图,使其在安全审计、日志分析与行为检测中具备极强的对抗性。

01. 技术背景介绍

LINQ,全称 Language Integrated Query,语言集成查询,是微软从 .NET 3.5 开始引入的查询语法扩展,它允许开发者直接在 C# 或 VB.NET 中对集合、数组、数据库、XML 等进行类似 SQL 的查询操作。

1.1 匿名类型

LINQ 中常见的一项语法是使用匿名类型进行数据投影。
匿名类型在代码中无须定义类结构,变量类型由 

var

自动推断,非常适合用于 LINQ 查询结果的快速封装,具体参考如下代码

var student =new{ Name ="Mary Jones", Age =19, Major ="History"};
Console.WriteLine("{0}, Age {1}, Major: {2}", student.Name, student.Age, student.Major);

由于匿名类型没有名字,必须使用
var
关键字作为变量类型,
students
变量是一个具有两个
string
属性和一个
int
属性的匿名类型。运行时如图
所示
.NET 介绍一种隐蔽的命令执行方式,通过 LINQ 投影执行动态加载


种机制为我们动态生成数据结构、传递参数、包装载荷提供了名正言顺的语法基础。
而在攻击层面,我们可以进一步利用它将执行逻辑,比如反射创建实例、动态加载 DLL“伪装”成普通的查询操作,从而绕过静态检测。

1.2 LINQ查询

除了对象初始化语句的赋值形式,匿名类型的对象初始化语句还有两种形式:简单标识符和成员访问表达式。这两种形式叫做投影初始化语句,具体代码如下所示。

classOther
{
staticpublicstring Name ="Mary Jones";
}
internalclassProgram
{
staticvoidMain(string[] args)
{
string Major ="History";
var student =new{ Age =19, Other.Name, Major };                                 Console.WriteLine("{0}, Age {1}, Major: {2}", student.Name, student.Age,                student.Major);
}
}

上述代码中
 var student = new { Age = 19, Other.Name, Major };
这个代码片段包含了
Age
赋值形式,
 Other.Name 
成员访问,
Major 
标识符。

.NET 介绍一种隐蔽的命令执行方式,通过 LINQ 投影执行动态加载

查询语法是声明式的,也就是说,查询描述的
LINQ
语句是你想返回的东西,但并没有指明如何执行这个查询,看上去和
SQL
语句很相似,使用查询表达式形式书写。如下代码所示。

int[] numbers ={2,5,28,31,17,16,42};
var numsQuery =from n in numbers    
wheren<20
select n;
foreach(var x in numsQuery)
{
   Console.Write(&#34;{0}, &#34;, x);
}


LINQPad
运行后输出


2,5,17,16

这四个小于
20
的数字,如图
所示。

.NET 介绍一种隐蔽的命令执行方式,通过 LINQ 投影执行动态加载

02. 红队实战应用

net-calc.dll
calc.exe
internalclassE
{
publicE()
{
        Process.Start(&#34;calc&#34;);
}
}

此时,若攻击者能够通过反射加载该 DLL 并执行该构造函数,即可在目标主机上实现远程命令执行,如下图所示。

2.1 实战流程

LINQ 默认采用 延迟执行
,也就是说,查询不会立即执行,直到你真正需要结果的时候,例如使用 

.ToList()

.Count()

.First()

等方法。具体参考代码如下所示。

byte[] assemblyBytes = File.ReadAllBytes(Path.Combine(
    Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),&#34;net-calc.dll&#34;));
List<byte[]> data =newList<byte[]>();
data.Add(assemblyBytes);
var e1 = data.Select(Assembly.Load);
var e2 = e1.SelectMany(map_type);
var e3 = e2.Select(Activator.CreateInstance).ToList();

这意味着,只看到了一连串的 

Select

操作,并不会立
即意识到这些操作是为了构造命令执行链,直到最后一步才执行。

.NET 介绍一种隐蔽的命令执行方式,通过 LINQ 投影执行动态加载

这种方式通过链式的 

Select -> SelectMany -> CreateInstance

操作,隐藏了对 

Process

类的直接引用,大多数规则引擎不会针对这种投影模式建立规则。此外,字符串“calc”可以事先通过混淆、Base64 编码、或从其他位置动态获取,使得 payload 更难分析。

2.2 实战应用

这正是 

Sharp4ByteShell.aspx

诞生的背景 —— 一款不依赖 

cmd.exe

的纯 .NET编写基于 LINQ 投影机制支持命令交互式操作的 高级 WebShell

将 

Sharp4ByteShell.aspx

上传至目标服务器的 IIS Web 根目录或任意子目录中。例如

C:\inetpub\wwwroot\Sharp4ByteShell.aspx

确保目标环境支持 .NET Framework 4.0 或以上,并启用了 .NET 解析模块。接着,
使用浏览器打开 /
Sharp4ByteShell.aspx,如下图所示。

图片

加载后会显示一个输入框和执行按钮,界面简洁,无任何第三方 UI 库依赖。随后,在输入框中输入任意 Windows 命令。

图片

03. 小结

综上,LINQ 是 .NET 中为开发者提供的强大查询语言扩展,但正因为其灵活的链式查询与延迟执行机制,为红队提供了一个极具隐蔽性的攻击媒介。本文介绍的 

LINQ + Assembly.Load + Activator.CreateInstance

组合方式,可以绕过常见的静态检测规则,实现无命令行行为、无文件落地的命令执行,尤其适用于高对抗场景中的命令触发、权限维持或横向利用。

以上相关的知识点已收录于
新书《.NET安全攻防指南》,全书共计25章,总计1010页,分为上下册,横跨.NET Web代码审计与红队渗透两大领域。

上册深入剖析.NET Web安全审计的核心技术,帮助读者掌握漏洞发现与修复的精髓;下册则聚焦于.NET逆向工程与攻防对抗的实战技巧,揭秘最新的对抗策略与技术方法。

自《.NET安全攻防指南》上线以来,许多读者已抢先下单成功购入并收到了书籍,反响热烈,好评如潮!

感谢大家的支持,我们也将持续为大家带来更多优质的.NET安全研究成果!原价258元,现限量优惠,京东自营店全套仅售141元,数量有限!点击京东链接:https://item.jd.com/10140917044329.html 或者打开手机京东APP即可下单购买。