看我怎样一步步将基于堆的 AMSI 绕过做到靠近圆满 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

看我怎样一步步将基于堆的 AMSI 绕过做到靠近圆满

申博_新闻事件 申博 45次浏览 已收录 0个评论

CVE-2019-16941: NSA Ghidra工具RCE漏洞

Ghidra是由美国国家安全局(NSA)研究部门开发的软件逆向工程(SRE)套件,用于支持网络安全任务。Ghidra是一个软件逆向工程(SRE)框架,包括一套功能齐全的高端软件分析工具,使用户能够在各种平台上分析编译后的代码,包括Windows、Mac OS和Linux。功能包括反汇编,汇编,反编译,绘图和脚本,以及数百个其他功能。Ghidra支持各种处理器指令集和可执行格式,可以在用户交互模式和自动模式下运行。用户还可以使用公开的API开发自己的Ghidra插件

这篇博文形貌了如安在 Excel 中完成运用 VBA (Visual Basic for Applications) 绕过微软的AMSI (Antimalware Scan Interface)。 与其他的绕过思绪差别的是,这类要领不运用硬编码的偏移量或操纵码,而是辨认堆上的症结数据并对其举行修正。 其他研讨人员之前也提到过基于堆的绕过,但在撰写本文时,还没有可用的大众 PoC。 这篇博文将为读者供应关于 AMSI 完成的一些看法,以及一种绕过它的通用要领。

弁言

自从微软推出 AMSI 完成以来,已宣布了许多关于绕过其完成机制的文章。 白色代码(Code White)平安团队实行红队的运用场景,个中收集垂纶扮演了主要角色。 收集垂纶一般与微软 Office 有关,具体来讲是与用 VBA 编写的歹意剧本有关。 依据微软的 AMSI,还包括放入 MS Office 文档中的 VBA 代码。 这一现实促使我在本年早些时候做了一些研讨。 已对 AMSI 是不是以及如安在 MS Office Excel 环境中被击败举行了评价。

在过去几年已有人宣布了几种差别的要领来绕过 AMSI。 以下链接是曾被我用作启示或参考的材料:

·https://modexp.wordpress.com/2019/06/03/disable-amsi-wldp-dotnet 列出了许多其他的 writeups 并完成了一个很好的基于数据的要领

·https://outflank.nl/blog/2019/04/17/bypassing-amsi-for-vba/ 用于 VBA 的 AMSI 绕过手艺

上面的列表中的第一篇文章也提到了基于堆的要领。 独立于这些纪录,Code White 的要领恰好运用了这个主意。 在撰写本文时期,还没有完成这一主意的公然代码。 这是写这篇博文的另一个效果。 将这类绕过手艺移植到 MS Excel /VBA 中显现了一些有待处理的困难。 以下各章按时候递次展现了 Code White 完成的演化历程:

·用 C 言语完成我们自身的 AMSI 客户端,以便具有一个调试平台

·邃晓 AMSI API 是怎样事变的

·在我们自身的客户端中绕过 AMSI

·将这类要领移植到 VBA 中

·革新绕过思绪

·革新绕过思绪-使其能在临盆环境中停当

完成我们自身的 AMSI 客户端

为了简化调试,我们将用 C 言语完成我们自身的一个小的 AMSI 客户端,它会触发对歹意字符串 amsiutils 的扫描。 这个字符串被标记为 evil,因为马特 · 格雷伯的 AMSI 绕过体式格局用到了这个字符串。扫描这个简朴的字符串指导了一个简朴的要领来搜检 AMSI 是不是事变,并考证我们的绕过思绪是不是可行。 sinn3r 的 github 上可以找到一个立即运用的 AMSI 客户端。这段代码为我们供应了一个很好的出发点,同时也包括了一些主要的提醒,比方当地组战略中的前置条件。

我们将运用 Microsoft Visual Studio Community 2017 完成我们自身的测试客户端。在第一步中,我们取得两个函数,amsiInit()和amsiScan(),不要与amsi.dll 的导出函数殽杂在一同。稍后,我们将增加另一个函数amsiByPass(),该函数会实行如其称号所暗示的功用。请在这个 gist 中检察终究的代码和绕过体式格局。

运转该顺序会天生以下输出:

这意味着我们的amsiutils 被以为是歹意的字符串。 如今我们可以最先举行绕过研讨了。

邃晓 AMSI 的构造

正如我们所许诺的那样,我们愿望完成一个基于堆的绕过。 但为何是基于堆的呢?

起首,我们必须邃晓,运用 AMSI API 须要初始化一个所谓的 AMSI 高低文(HAMSICONTEXT)。 必须运用函数 AMSIInitialize ()初始化此高低文。 每当我们想要扫描某些内容时,比方经由过程挪用 AMSIScanBuffer() ,我们必须将高低文作为第一个参数举行通报。 假云云高低文背地的数据无效,相干的 AMSI 函数将挪用失利。 这就是我们所寻求的,但我们会在稍后再谈到这一点。

看一下 HAMSICONTEXT,我们将看到这个范例被预处理器剖析为以下内容:

所以我们在这里取得的是一个指向一个叫做 HAMSICONTEXT 的构造体的指针。 让我们经由过程在客户端中打印“ amsiContext”的内存地点来检察这个指针指向的位置。 这将使我们可以运用 windbg 搜检其内容:

看我怎样一步步将基于堆的 AMSI 绕过做到靠近圆满

变量自身的地点是0x16a144(注重我们这里是个32位的顺序) ,它的内容是0x16c8b10,这就是它指向的位置。 在地点0x16c8b10处,我们看到一些内存,以标识有用 AMSI 高低文的 ASCII 字符‘AMSI’作为开首。 内存字段下面的输出是经由过程’!address’打印当前历程的内存规划。

在这里,我们可以看到地点0x16c8b10被分派到一个地区,从0x16c0000到0x16df0000,这个地区被标识为“堆”。 OK,这意味着AmsiInitialize() 为我们供应了一个指向堆上的构造体的指针。运用 IDA 对 AMSIInitialize() 举行更深切的研讨后,供应了一些这个方面的证据:

函数运用特定的COM API——CoTaskMemAlloc ()分派16个字节(10h)。 后者是堆的笼统层。 可以点击这里及这里相识概况。 在分派缓冲区以后,魔法词 0x49534D41被写到块的开首,这就是我们用 ASCII 示意的‘ AMSI’。

值得注重的是,应用顺序不能轻易地转变这类行动。 AMSI 高低文的内容将一直存储在堆中,除非进击操纵已完成,比方将高低文复制到其他地方或完成自身的内存供应顺序。 这就诠释了为何微软在其 API 文档中指明,应用顺序担任在运用 AMSI 时挪用 amsiunitialiize ()。 这是因为客户端不能(也不应当)开释内存,而清算历程是由 AMSI 库实行的。

如今我们邃晓了这一点:

·AMSI 高低文是一种主要的数据构造

·它老是被放在堆上

·它老是以 ASCII 字符‘ AMSI’ 作为开首

In case our AMSI context is corrupt, functions like 假如我们的 AMSI 高低文是损坏的,像 AmsiScanBuffer() 如许的函数将实行失利,返回值不即是零。 但损坏意味着什么,AMSIScanBuffer() 怎样检测高低文是不是有用? 让我们在 IDA 中搜检一下:

该函数实行我们在最先时就已指定的操纵: 将 AMSI 高低文的前四个字节与值‘0x49534D41’举行比较。 假如比较失利,函数返回0x80070057,这不即是0,并关照我们运转出错了。

在我们自身的 AMSI 客户端中绕过 AMSI

我们的基于堆的要领假定了几件事变来终究形貌一个所谓的绕过:

·我们已在 AMSI 客户端高低文中实行了代码,比方经由过程实行一个 VBA 剧本

· AMSI 客户端(比方 Excel)只对 AMSI 高低文初始化一次,并对每一个 AMSI 操纵重用该高低文

·假如 AMSIScanBuffer()函数运转失利,AMSI 客户端将搜检有用载荷评级为“非歹意”

第一点不适用于我们用于测试的客户端,但也不是必须的,因为它只形貌了一个测试历程,我们可以依据须要举行修正。

特别是末了一点异常主要,因为我们将尝试损坏目标历程中唯一可用的 AMSI 高低文。 假如 AMSIScanBuffer() 的失利致使负面的副作用,在最坏的状况下,顺序能够崩溃,绕过将不能一般事变。

因而,我们的使命是遍历 AMSI 客户端历程的堆,寻觅以‘ AMSI’开首的块,并将这个块弄乱,使一切进一步的 AMSI 操纵失利。

微软供应了一个很好的代码例子 ,运用了来自kernel32.dll的两个函数遍历堆。

因为一切须要的信息都存在于用户空间中,所以人们可以经由过程剖析内存中的数据构造来完成这项使命。 如许做会使外部函数的运用过期,但能够会损坏我们的代码,因而我们决议运用上面示例中的函数。

在将示例削减到我们须要的最小功用以后,我们终究取得了一个函数amsiByPass()。

看我怎样一步步将基于堆的 AMSI 绕过做到靠近圆满

因而,这段代码会检索当前历程的堆,遍历它并检察标记为“劳碌”的每一个块。 在这些忙碌的块中,我们搜检前面的字节是不是与我们的把戏情势“AMSI”相婚配,假如婚配,则用一些垃圾覆盖掉它。

如今的希冀是我们的有用载荷不再被标记为歹意的,然则 AMSIScanBuffer() 函数应当返回一个毛病。 让我们再搜检一下:

看我怎样一步步将基于堆的 AMSI 绕过做到靠近圆满

好吧,这正是我们所期待的。你不禁会问说完了吗? 不,还没有,因为我们在文章开首申明的是在 Excel应用 VBA 实行 AMSI 绕过,所以让我们继承吧。

Excel VBA 绕过 AMSI

如今我们将进入 VBA 的新鲜天下。 我们将运用微软的 Office 365 MSO (16.0.11727.20222) 中的 32 位 Excel 举行测试。

xHunt:针对科威特航运构造的进击行为

概要 2019年5月至6月,unit42安全团队在一起针对科威特航运业的攻击事件中,检测到了一个新后门工具——Hisoka,它的作用是下载几个的定制工具进行后漏洞利用,所有工具似乎都由同一个开发人员创建,最早的一个工具其版本可以追溯到2018年7月。 工具的名称都借用了动漫《全职猎人》中的人物名字,这也是此次行动“xHunt”名称的来源,如后门工具Sakabota、Hisoka、Netero和Killua,它们通过HTTP、DNS隧道和电子邮件与C2通信。除了上述的后门工具外,还有名为Gon和EYE的工具,

在用 C 编写了一个基础 POC 以后,我们必须将这个 POC 移植到 VBA。 VBA 支撑从 dll 中导入恣意外部函数,因而运用我们的堆 API 应当不成题目。 就我们对 VBA 的邃晓而言,它不许可指针算法或直接内存接见。 这个题目可以经由过程导入一个许可将数据从恣意内存位置复制到 VBA 变量的函数来处理。 实行此使命的一个异常稀有的函数是RtlMoveMemory()。

在一些代码修正以后,我们取得了以下效果代码。

正如正如你所看到的,我们在主轮回旁边安排了一些时候丈量的代码。 轮回的轮询次数能够到达几十万次,再加上 VBA 机能不是很好,我们估计实行完轮回会消费大批的时候。 在实在的进击场景中,时候是至关主要的。 假如我们的收集垂纶受害者翻开一个歹意的 Excel 表格,嵌入的剧本会阻挠实行凌驾一到两秒,这是不可接收的。 至少在应用顺序落空相应才能5秒以后,人们就会变得不耐烦,就会做出一些事变,比方试图封闭 Excel,这不是我们想要的。

让我们看看实行绕过须要多长时候。 说实话,我们没有想到会发作如许的事变。 效果很难重现,但丈量的运转时候从15分钟到无穷无尽不等。 在一些稀有的状况下,Excel 在几分钟后封闭,没有任何进一步的关照。 这能够是因为它在太长时候内没有回响反映了。 但是,这并非我们真正可以在实在场景中运用的东西。

好吧,这里出了什么题目? VBA 真的那末慢吗? 没错,它比我们的 C 代码慢了有几秒的数量级,但这并不能诠释我们所阅历的。 微软供应了一些内部的细节: 如安在 Excel 中完成 AMSI。 现实证明,Excel 运用了另一种战略,比方 PowerShell。 后者或多或少地将全部剧本发送到 AMSIScanBuffer()。 完成了一个基于所谓触发器的更智慧的要领。 微软以为纯 VBA 代码在导入之前是无害的。 这正是我们要做的——从外部 dll 中导入函数。 个中一些导入函数被视为具有潜伏危险性的函数,它们的挪用(包括一切参数)被放入一个环形缓冲区,该缓冲区被发送到 AMSI。 这使得像微软的 defender 如许的反病毒处理方案有时机搜检地点背地的数据,这固然是有意义的。 让我们看看在我们的例子中,经由过程运用 windbg 破解 AMSIScanBuffer,哪些数据被发送到了 AMSI API:

我们可以看到,环形缓冲区包括我们导入的一切函数,包括它们的参数值。 我们的 Windows 10体系已装置并激活了微软的Defender。 所以每次挪用 AMSIScanBuffer() 都邑触发 Defender。 AMSI 起首完成为历程内 COM。 然则为了终究与其他反病毒处理方案举行通讯,它必须将数据传输出历程并实行高低文切换。 这可以鄙人一个微软供应的架构概述中看到:

泉源:https://docs.microsoft.com/en-us/windows/win32/amsi/how-amsi-helps

图底部的绿色小块显现我们的历程(Excel)经由过程 rpc 与 Defender 间接通讯。 嗯… … 好吧,这个事变做完要有个10万次吧,这消费的现实太多了,不过也诠释了为何须要云云长的运转时。 为了供应一些更多的证据,我们封闭了 Defender 然后反复执绕过,这应当会明显加速实行我们的绕过代码。 除此之外,我们还看管对 AMSIScanBuffer() 的挪用量,如许我们就可以取得挪用 AMSIScanBuffer() 的频次。

一样的轮回在禁用了 Defender 的状况下须要一到两分钟:

看我怎样一步步将基于堆的 AMSI 绕过做到靠近圆满

在另一次运转中,我们运用 windbg 来搜检对 AMSIScanBuffer() 的挪用量:

AMSIscanbuffer()被挪用了124624次(0x10000000-0xffe1930) ,大抵相当于我们的轮回所做的迭代次数。 此次数已许多了,并强调了我们的假定,AMSI 确切被异常频仍的挪用。 因而,我们邃晓正在发作什么,但现在彷佛没有可用的变通要领来处理我们的运转时题目

如今就摒弃吗?-固然不..

Excel 中革新 AMSI 绕过思绪

正如上面一章所形貌的,我们现在的要领运转速率太慢,没法在现实场景中运用。 那末,我们能做些什么来改良这类状况呢?

我们导入的函数之一是 RtlMoveMemory() ,正如前面提到的,许多歹意软件都运用这个函数。 看管这个函数会有很大的意义,它能够被以为是触发器。 让我们经由过程删除对 CopyMem (RtlMoveMemory 的别号)的挪用来考证这一点,然后看看会发作什么。 这阻挠了我们绕过事变,但它能够给我们一些看法。

运转时候如今是0.8秒。 哇,好吧,这真的转变了许多。 须要注重的是,在这类设置中,我们以至遍历了全部堆。 因为缺乏对 RtlMoveMemory() 函数的挪用,我们将没法找到我们的情势。

在我们肯定了瓶颈以后,我们能做什么? 我们必须找到一种替代要领来接见没有被 Excel 视为触发器的原始内存。 一些随机的谷歌搜刮显现了可以运用函数——CryptBinaryToStringA() : 该函数旨在将字符串从一种花样转换为另一种花样,但它也可以仅用于从我们指定的恣意内存位置复制字节。 太酷了,这正是我们要找的! 为了到达我们的目标,我们可以挪用这个函数就像从 Process Heap Entry 构造中读取 lpData 字段:

输入参数从左到右诠释以下:

·Lpdata 是我们要复制数据的源,

·ByVal 4 是我们要复制的字节长度(在我们的32位 Excel 中,lpData 是32位的)

·Byval 2 是我们要复制的原始二进制文件(CRYPT_STRING_BINARY 隐蔽字符串二进制)

·ByVal VarPtr (magicWord)是我们想要将内存复制到的目标(我们的 VBA 变量 magicWord)

·末了一个参数(ByVal VarPtr (bytesWritten))关照我们现实复制了若干字节

替代一切的 RtlMoveMemory() ,并再次搜检我们的绕过须要多长时候。 你可以 在这里找到源代码的更新版本.

我们的轮回如今须要约莫四秒钟完成,时候依然很长,但绕过胜利完成了,这关照我们,我们找到了我们正在寻觅的情势。 让我们看看 Excel 如今运用的这个版本中挪用 AMSIScanBuffer() 的次数:

哦,天哪… Excel 基础没有挪用 AMSIScanBuffer()。 因而,这意味着只需我们的代码中没有触发器,就不会向 AMSI 发送任何内容。 或许反过来: 只需我们运用一个触发器函数,Excel 就会将一切挪用发送到 AMSI。 很愉快我们晓得到了这一点..

这是我们第一次有才能真正考证绕过是不是有用。 因而,让我们从 VBA 中寻觅一些触发 AMSI 的代码 Iliya Dafchev 之前提出了一个较旧的运用 VBA 绕过  AMSI 的要领,这个要领起首经由过程 AMSI 自身取得标志。 圆满,我们将把这个代码放到一个函数中,这个函数叫做triggerAMSI() 然后用它做测试:

在运转 Excel 以后,会像预期的那样涌现一个正告,然后会封闭当前的 Excel 实例:

Excel 中的 AMSI 弹框

把我们的绕过和测试放在一同,我们取得了以下函数:

愿望很大,会弹出包括“we survived”的音讯框,因为我们在触发它之前已干掉了AMSI。

 

看我怎样一步步将基于堆的 AMSI 绕过做到靠近圆满

太好了,我们的绕过彷佛起作用了。 所以让我们把这个放到我们真正的收集垂纶运动中。 嗯。 等等,全部历程花了多长时候? 四秒钟? 反复实行绕过以至会显现运转时候大于10秒。 哦,不,时候照样太长了。

如今就摒弃吗?-固然不..

Excel 中革新 AMSI 绕过运转时候

在末了一章,我们革新了我们的 AMSI 绕过,将运转时候从无穷无尽下降到十秒或以下。 这关于一场真正的比赛(我们的看法)来讲彷佛照样太多了。 那末,我们能做些什么来加速全部运转历程呢?

轮回须要约莫10万次的迭代,这在 C 言语中是可以很快完成的。 防守队完整出局了。 因而,我们当前的运转时候彷佛是不好的 VBA 机能致使的地道效果。 公高山说,我们现在正在尝试做的这些事变并非一个典范的 VBA 使命,所以让我们诘问诘责我们自身而不是 Excel 做了一些猖獗的事变。

不管怎样,我们如今能做什么呢? 在 VBA 中编写 C 言语代码不是一种挑选,然则挪用一些 shellcode 怎样呢? 只需我们能导入恣意函数,shellcode 的实行应当不成题目。 这个代码片断给出了如安在 VBA 中完成这一点的示例。 下一步是将 VBA 代码(或许更多的初始 C 代码)转换成汇编言语,也就是说,转换成 shellcode。

每一个曾编写过一些 shellcode 并愿望从 dll 挪用函数的人都晓得,在组装 shellcode时期,这些函数的相对地点是未知的。 这意味着我们必须完成如许的机制,经由过程 GetProcAddress() 在运转时查找所需函数的地点。 如安在没有任何库支撑的状况下做到这一点呢?这个中涉及到的手艺细节已取得了充足的邃晓而且已有相当多的文档细致申清楚明了完成要领,因而我们不会在这里细致议论。 完成这部份的 shellcode 留给读者作为演习。

固然,有许多可以直接运用的代码片断可以完成这项事变,然则我们决议自身完成这些 shellcode。 为何? 因为它很风趣,而且是自身编写的代码,所以不太能够被反病毒处理方案查杀。

我们运用汇编言语改成了 AMSI 绕过代码的主轮回,汇编代码有用载荷可以在这里找到。

ShellCodeEnvironment 构造体包括了一些主要信息,比方 HeapWalk()和 GetProcessHeaps() 函数的查找地点。 轮回的其余部份是可以直接复用的..

因而,把一切东西放在一同,我们天生 shellcode,并把它放到 VBA 代码中,然后以新线程的情势启动它。 固然,我们须要再次盘算运转时候:

此次只要0.02秒

我们以为这个效果是可以接收的。 运转时能够会依据处理器负载或堆的总大小而有所差别,但它应当远远低于我们最初的目标——一秒。

总结

我们愿望你能喜好这篇博文。 我们展现了在 VBA 中基于堆的 AMSI 绕过思绪的可行性。 一样的要领,带有细微的适配,也适用于 PowerShell 和 .Net 4.8。 后者也与 AMSI 的支撑集成在其通用言语运转库。 正如微软的 AMSI 不是一个平安边境,所以我们并不期待这么多的回响反映,然则我们依然很猎奇微软是不是会为这个主意开辟一些检测机制。

本文翻译自https://codewhitesec.blogspot.com/2019/07/heap-based-amsi-bypass-in-vba.html


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明看我怎样一步步将基于堆的 AMSI 绕过做到靠近圆满
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址