技术分享 | 绕过Cobalt-Strike在使用.NET程序集时的大小限制

访客4年前黑客文章938

话不多说,我们直奔主题!

Cobalt-Strike的问题

Cobalt Strike是全球众多咨询公司和 *** 犯罪分子都会使用的命令和控制软件,Cobalt Strike能够通过生成一个新进程并将CLR(用于.NET的解释器)引导到该进程上来实现在内存中执行.NET程序集,这种功能行为通常也被称为CLR工具(技术)。这个功能非常棒,使用起来也非常好,但是它存在一个缺点,即Cobalt-Strike只能在程序集是自包含的情况下执行程序集。这意味着,如果您的程序集使用任何依赖项(比如说其他的程序集或DLL),那么就会出现问题了。不过,我们有两种 *** 来绕过这个限制:

使用ILMerge或Fody(或其他一些链接器)将依赖项嵌入进去;

使用反射在执行时加载依赖项(本文的主要内容);

将依赖项嵌入进去的问题就在于,这会导致程序集变得非常大,依赖项越多,体积也就越大。这也就引出了Cobalt-Strike的第二个问题:

如果程序集大于1MB,Cobalt Strike无法内存中执行它了

通常情况下,这并不是什么大问题。但是在某些特殊情况下,你的程序集可能会远远超过1MB,这就导致我们不得不想办法在运行时加载依赖项了。

.NET加载依赖项的方式

为了让我们了解如何创建在运行时加载其依赖项的程序集,首先我们要了解.NET如何加载其引用。完整的技术解析文档实际上是由微软自己编写的,但是从高层的角度来看,可以归结为如下内容:

一般来说,我们需要添加对项目的引用并在程序开始处使用using关键字来导入。一个典型的例子就是使用System.web,它可以让我们的程序集调用System.web.dll(位于GAC中-全局Assembly缓存),GAC位于%WinDir%之中,攻击者一般对它都不感兴趣,因为如果没有实现提权的话,WinDir是不能写入内容的。

如果程序集在GAC中找不到引用,它将在程序集所在的目录中查找引用。如果没有找到它,它也会出错(前提是没有配置文件,但是配置文件超出了本文的范围)。

欢迎来到“反射”的世界

绕过搜索依赖项行为的一种 *** 是使用反射技术,常见的反射技术实施步骤如下:

使用Load *** 调用我们所要使用的程序集;

使用GetType *** 调用获取到正确的Type(=类);

使用GetMethod *** 调用获取到我们索要调用的实际 *** ;

使用CreateInstance *** 调用“激活”Type(=类);

使用Invoke *** 来调用目标 *** ;

在这种 *** 的帮助下,我们甚至还可以在PowerShell中调用C#程序集,这在应用程序锁定的环境中可能非常有用,因为我们仍然可以运行PowerShell。

下面给出的例子中,我们演示了如何在PowerShell中调用C#程序集:

using System;

using System.Reflection;

namespace HelloFromDotNetFramework

{

public class Program

{

?public static void Main(string[] args)

{

?Console.WriteLine("Hi from {0}", Assembly.GetExecutingAssembly());

}

}

}

clear

$bytes=[System.IO.File]::ReadAllBytes("C:\Users\jeanm\source\repos\HelloFromDotNetFrame

$a *** =[System.Reflection.Assembly]::Load($bytes)

$params={null}

[HelloFromDotNetFramework.Program]::Main($params)

执行这个PowerShell脚本之后,将会生成如下图所示的输出结果:

不过,我们还可以通过互联网获取bytearray,而不是使用PowerShell中的webclass来从本地磁盘中加载它。

尽管如此,这种 *** 还是存在缺点的。使用此 *** 的主要缺点是必须使用MethodBase.Invoke来调用,这意味着你需要调整代码以支持这种加载方式,但有可能会让你对每一个函数的调用都要进行重构和调整。

此 *** 的另一个缺点是,所有 *** 都必须是公共 *** ,并且一些“复杂”的操作可能会引起中断。

关于应用程序域(AppDomain)

绕过.NET程序集搜索依赖项的“正常”行为的另一种 *** 是使用AppDomain.AssemblyResolve *** 。应用程序域能够提供安全性、可靠性和版本控制等服务,它通常由运行时主机创建,运行时主机负责在应用程序运行前引导公共语言运行时环境。

AssemblyResolve *** 是一个回调函数,当应用程序域找不到引用的程序集时便会触发该函数。使用此 *** 可以像正常情况一样创建程序集,正常调用对依赖项的所有调用。

不过,我在测试过程中遇到了一个小问题。如果将AssemblyResolve *** 放在main *** 中,并且也从主 *** 中的依赖项进行调用,那么AssemblyResolve可能就无法正常工作了。这是因为它作为订阅服务工作,并且因为依赖项也位于main *** 中,所以resolve *** 还没有任何订阅。解决 *** 如下:

创建一个静态类并创建一个构造函数来设置这个程序集解析 *** ,从而在调用Main *** 之前创建它。

将依赖关系逻辑放在一个单独的 *** 中,并从main函数中调用该 *** 。

下面给出的这个PoC将演示我上述介绍的内容,其中NvisoLib是一个小型的测试dll:

using System;

?

namespace NvisoLib

{

public class Test

{

public void Say(String message)

{

Console.WriteLine(message);

}

?

}

}

AppDomainResolveTest是一个用于测试的可执行文件,并且使用了NvisoLib。

我们可以看到,NvisoLib的调用过程就像你通常会利用任何其他依赖性一样,我把逻辑放在seperate函数中,并从main函数中调用它。我用一个非常简单的实现实现了RevolveAssembly函数,并从磁盘上的另一个位置来调用它。

总结

在这篇文章中,我们探讨了如何利用反射技术在运行时加载依赖项,从而避免了将所有的依赖组件都嵌入到一个程序集之中,这样就保证了不超过Cobalt-Strike给出的1MB大小限制。除此之外,我们还介绍了如何通过反射技术在PowerShell中执行C#程序集。

相关文章

如何防范别人入侵手机微信记录_怎样查询别人的微信消费记录

三星安全文件夹(三星Galaxy A8s安全又易用的安全文件夹功能)入手了Galaxy A8s也已经有一段时间了,陆陆续续也分享了一些使用心得,今天想和大家说说手机隐私保护的问题~ 因为现在的手机能做...

餐饮店怎么做推广(小餐馆如何推广自己的餐厅)

  餐馆怎么做推广(小餐饮店怎么推广自身的饭店)小餐饮店做为低成本,收益快的象征性领域,深受很多人的钟爱。可是,绝大多数小餐饮店都存有早期欠缺名气和资产的难题,那麼,小餐饮店该怎么推广自身的饭店,有什...

让你当挡泥板的意思是什么 做我的挡泥板是什么梗

让你当挡泥板的意思是什么 做我的挡泥板是什么梗

抖音短视频变成许多梗的造就地,各种各样梗和搞笑段子五花八门,便是给你当搓挡泥板是近期较为火的,很多人表明不可以了解这代表什么意思。那麼给你当保险杠的是什么意思 做我的保险杠是什么梗。产生有关详细介绍...

综述:多国青兔毛水晶睐中国新冠疫苗

  综述:多国青睐中国新冠疫苗   新华社北京1月14日电 综述:多国青睐中国新冠疫苗   新华社记者   新冠疫情暴发以来,全球对疫苗翘首以盼。在各方携手推动下,中国新冠疫苗研发工作跑出“加速度”...

支付宝蚂蚁庄园6月9日答案是什么?手机防偷窥膜的原理跟什么很像?

支付宝蚂蚁庄园6月9日答案是什么?手机防偷窥膜的原理跟什么很像?

支付宝蚂蚁庄园6月9日答案是什么?支付宝蚂蚁庄园小课堂6月9日有两个问题,用户参与会随机抽取到一题,大家千万不要答错了哦,下面小编就为大家带来蚂蚁庄园小课堂2020年6月9日问题答案,一起来看看吧。...

乙肝大三阳能治愈吗(乙肝大三阳可以彻底治愈吗?)

  乙肝大三阳能治愈吗(乙肝大三阳可以彻底治愈吗?)肝病是重大疾病中的一类,乙肝大三阳以传播速度快,病毒复制程度高而受到医生与家属重视。治疗乙肝大三阳,需要长期的药物治疗并定期复诊。   乙肝大三阳...