0x01 我遇到过的混淆加壳对抗

在一次公司内部项目的渗透测试中,我负责模拟外部攻击者试图突破我们的防御系统。为了达到我的目标,我决定使用混淆加壳工具来隐藏我的恶意代码。在这个过程中,我意识到防御者面临的挑战不仅仅是检测恶意代码,还需要识别经过混淆和加壳处理的载荷。今天,我们就从防御角度反推这种攻击方法的实战应用。

如何让载荷更狡猾

在攻击中,我需要让我的载荷能够躲避杀软和EDR的检查。攻击者常常使用混淆加壳技术来实现这一目标。这些技术的核心思想就是通过改变代码的结构、加密代码内容,使得防御系统无法正确识别其恶意行为。

混淆技术:它通过重命名变量、函数,使用复杂的逻辑结构和引入无关代码块等方式,使代码难以理解。

加壳技术:它通过对代码进行压缩或加密,将其封装在一个壳程序中,这样外部分析工具或杀毒软件在扫描时,只能看到无害的壳,而无法看到内部的恶意代码。

我选择了一款名为"Obfuscator-X"的混淆工具和一款名为"ShellPro"的加壳工具。在实战中,这两种工具为我的渗透行动提供了极大的帮助。

黑客示意图

绕过那些防御的花招

黑客示意图

让EDR看不到我

有一次,我的载荷被公司的EDR系统捕获并阻止。我意识到仅仅进行简单的混淆是不够的,必须要在代码的执行方式上进行一定的改变。于是,我开始使用内存加载技术

黑客示意图

内存加载技术是一种将代码在运行过程中加载到内存中执行的方法,这种方法让代码始终处于内存中并从未以文件形式存在。在Go语言中,我使用了以下代码来实现内存加载:

<pre><code class="language-go">package main

import ( &quot;os&quot; &quot;os/exec&quot; &quot;syscall&quot; )

func main() { payload := []byte{ / 恶意代码字节 / } memFd, err := syscall.MemfdCreate(&quot;payload&quot;, syscall.MFD_CLOEXEC) if err != nil { panic(err) } syscall.Write(memFd, payload) _, err = exec.Command(&quot;/proc/self/fd/&quot;+string(memFd)).Output() if err != nil { panic(err) } }</code></pre>

这段代码利用了Linux的memfd来创建一个文件描述符,然后通过exec.Command来执行这个内存中的文件。这样,杀软扫描将无法检测到这个在内存中执行的代码。

绕过流量分析

有一次,我的C2流量被检测出来,因为使用了常见的协议。为了确保我的通信不被发现,我采用了流量伪装技术,将恶意流量伪装成常见的网络协议,比如HTTPS。

我使用Go语言编写了一个简单的HTTPS流量伪装程序:

<pre><code class="language-go">package main

import ( &quot;crypto/tls&quot; &quot;net/http&quot; )

func main() { httpClient := &amp;http.Client{ Transport: &amp;http.Transport{ TLSClientConfig: &amp;tls.Config{InsecureSkipVerify: true}, }, } _, err := httpClient.Get(&quot;https://example.com&quot;) if err != nil { panic(err) } }</code></pre>

这段代码通过创建一个HTTP客户端并访问HTTPS网站,伪装成正常的网络行为。这种伪装可以绕过许多流量分析系统,确保我的C2流量不被检测。

0x02 让它变得更好玩的实战环境

为了进行全面的测试,我在一个虚拟环境中模拟了公司内部的网络结构。这里,我搭建了一个包含多个服务器和客户端的网络,以便测试我的攻击链是否有效。

搭建环境的思路

  1. 服务器配置:我使用了两台虚拟服务器,一个用于模拟公司的web服务器,另一个用于模拟公司内部数据库服务器。两者均安装了最新的安全补丁和防御软件。
  1. 客户端模拟:为了模拟内部员工的操作环境,我配置了三台虚拟客户端,分别安装了不同版本的操作系统和应用程序,并确保每台设备上都有EDR软件运行。
  1. 网络设置:我设置了与公司内部网络相似的路由规则和防火墙策略,以便更真实地测试攻击效果。

在这个环境中,我可以自由地测试不同的混淆加壳方法,并观察它们在真实网络中的表现。这种环境不仅帮助我更好地了解攻击链的每一个环节,还让我能够在安全无害的情况下直观地验证每一种技术的有效性。

0x03 Payload构造的艺术

构造有效载荷不仅仅是简单地编写恶意代码,还需要综合考虑多种因素。为了确保载荷能够成功执行,我需要在设计阶段进行详细的规划。

设计有效载荷的技巧

选择合适的语言:在实战中,我发现使用Go语言编写payload有很多优势。Go语言不仅有强大的并发处理能力,还可以很好地适应不同的操作系统。通过在Go语言中构建恶意载荷,我可以确保其在各种环境下都能顺利执行。

代码混淆与加壳:为了确保载荷不被轻易识别,我使用工具对代码进行了混淆和加壳处理。以下是我在Go语言中实现代码混淆的一个简单示例:

<pre><code class="language-go">package main

func main() { a := 1 b := 2 c := a + b _ = c }</code></pre>

在这段代码中,我故意引入了多个无用变量和操作,增加代码的复杂性,使防御系统更难识别其真实意图。

动态加载与执行:为了进一步增强载荷的隐蔽性,我使用Go语言实现了动态代码加载与执行。通过在程序运行时从外部源加载代码,我可以确保载荷始终保持最新,并可以快速响应防御系统的变化。

0x04 经验分享:那些年我学到的

在多年渗透测试的实战经验中,我总结了几点关于混淆加壳的经验心得,希望能为同行提供一些启发。

小心那些陷阱

保持更新:混淆加壳技术在不断发展,作为渗透测试工程师,我们必须时刻关注最新的工具和技术,以便在实战中灵活运用。

多层防御:虽然混淆加壳可以帮助我们绕过许多防御,但面对复杂的防御体系,仅依赖一种技术可能并不够。我们需要结合多种技术,形成多层次的攻击链,以提高渗透成功率。

黑客示意图

合法合规:始终牢记,在进行任何渗透测试时,我们的行动必须是合法的,并获得授权。本文仅限授权安全测试,供安全研究人员学习。在实际工作中,一定要遵循相关法律法规,确保测试过程和结果不会对目标系统造成任何危害。

通过这些经验,我更加坚定了对渗透测试的热情,也不断在实践中探索新的攻击思路。希望这篇分享能够帮助你更好地理解混淆加壳技术,并在实战中灵活运用。