基础设施概述
下面是一个高级图表,展示了我为这个实验室构建的基础设施——它可以并且通常会构建得更加完善,但原理保持不变——重定向器被放置在每台服务器的前面,以使基础设施更能适应发现,使操作员能够快速用新的服务器替换烧毁的服务器:
-
总共有 6 台服务器
-
3 个服务器(网络钓鱼、有效载荷和 c2)被视为长期服务器 - 我们不希望我们的友好蓝队发现这些服务器
-
3 个重定向器(smtp 中继、有效负载重定向器和 c2 重定向器) - 这些服务器位于我们的长期服务器前面,充当代理。假设这些服务器将在交战期间被检测和烧毁。这就是 Terraform 的自动化部分发挥作用的地方 - 由于我们的环境状态是在 Terraform 配置文件中定义的,因此我们几乎可以在短时间内重建那些烧毁的服务器,并且操作可以继续进行而不会出现更大的中断。
配置基础设施
服务供应商
我的测试红队基础设施是通过利用以下服务和提供商构建的:
-
适用于所有服务器和重定向器的 DigitalOcean Droplets
-
DigitalOcean 的 smtp 中继 DNS 管理(网络钓鱼重定向器)——主要是因为我们需要
PTR
为 smtp 中继设置 DNS 记录,以减少我们的网络钓鱼电子邮件被目标用户的邮件网关归类为垃圾邮件的可能性 -
CloudFlare DNS 管理,用于控制指向我们长期服务器的任何其他域的 DNS 记录
但请注意,只要Terraform支持,您就可以使用 Amazon AWS 或其他流行的 VPS 提供商构建服务器。DNS 管理部分也是如此。我使用了 DigitalOcean 和 CloudFlare,因为我已经有账户了,而且我喜欢它们 ¯_(ツ)/¯
文件结构
我的红队基础设施由 Terraform 状态配置文件定义,当前组织方式如下:
我认为文件名是不言自明的,但下面提供了有关一些配置文件的附加信息:
<ul class="list-none space-y-2 [&>li]:relative [&>li]:ps-[2.25ch] [&>li>div_div]:mt-0 [&>li>.bullet]:before:bg-dark/6 [&>li>.bullet]:before:absolute [&>li>.bullet]:before:left-0 [&>li>.bullet]:before:w-[1ch] [&>li>.bullet]:before:h-[1lh] [&>li>.bullet]:before:[mask-repeat:no-repeat] [&>li>.bullet]:before:[mask-position:left] dark:[&>li>.bullet]:before:bg-light/6 [&>li>.bullet:before]:bullet-circleFilled [&&>li>.bullet:before]:bullet-circle [&&&>li>.bullet:before]:bullet-dash [&&&&>li>.bullet:before]:bullet-squareFilled [&&&&&>li>.bullet:before]:bullet-square [&&&&&&>li>.bullet:before]:bullet-circleFilled max-w-3xl w-full mx-auto decoration-primary/6 page-api-block:ml-0">
-
Configs
文件夹 - 使用 Terraform 的配置程序创建 Droplet 时,所有配置文件太大或不方便修改。它包括有效负载重定向器(apache:.htaccess
,apache2.conf
)、smtp 重定向器(postfix:header_checks
- 用于剥离原始 smtp 服务器的电子邮件标头,master.cf
- 用于 TLS 和 opendkim 的常规 postfix 配置,opendkim.conf
- 配置与 postfix 的 DKIM 集成)的配置 -
提供商——需要构建基础设施,例如我所举的 DigitalOcean 和 CloudFlare
-
变量 - 存储 API 密钥和不同 Terraform 状态文件中使用的类似数据
-
sshkeys - 存储我们的服务器和重定向器将接受登录的 ssh 密钥
-
dns - 定义 DNS 记录并指定如何访问我们的服务器和重定向器
-
防火墙 - 定义访问规则 - 谁可以访问哪个服务器
-
输出 - 打印出构建基础设施的关键 IP 地址和域名的文件
-
Cobalt Strike 已启动并连接到托管在 68.183.150.191 上的主要 C2 服务器 - 可以通过以下方式访问
css.ired.team
-
在 C2 主机 68.183.150.191 上创建了端口 443 上的新监听器
-
信标主机名在 C2 重定向器上设置为两个子域名 -
static.redteam.me
以及ads.redteam.me
-
通过 SMB 在目标系统上生成并执行无阶段信标
-
信标回调
.redteam.me
将流量重定向到 68.183.150.191 上的 C2 团队服务器,我们看到 CS 会话弹出: -
设置 SPF 记录
-
设置 DKIM
-
设置加密
-
配置 postfix 作为中继
-
清理电子邮件标头以混淆原始电子邮件服务器(网络钓鱼服务器)
下面概述了几个文件的其他要点。
变量
Variables.tf 存储 API 令牌、重定向器和 c2 的域名、防火墙规则中使用的操作员 IP 等内容(即,仅允许从操作员拥有的 IP 传入到团队服务器或 GoPhish 的连接):
此外,还variables.tf
包含受密码保护的 Cobalt Strike zip 存档的链接和密码本身:
C2
对于这个实验,我选择 Cobalt Strike 作为我的 C2 服务器。
下面是remote-exec
C2 服务器的 Terraform 配置文件,它下载 CS zip 文件,使用给定的 CS 密码解压它,并创建一个 cron 作业,以确保服务器启动后启动 C2 服务器:
C2重定向器
我使用socat
简单地将端口 80 和 443 上的所有传入流量重定向到运行 Cobalt Strike 团队服务器的主 HTTP C2 服务器:
测试 C2 和 C2 重定向器
测试你的 C2 及其重定向器是否按预期工作很容易。
请注意以下 - 执行 output.tf 文件时 Terraform 打印出几个 FQDN:static.redteam.me
并且ads.redteam.me
都指向159.203.122.243
- 这是 C2 重定向器 IP - 端口 80 和 443 上的任何流量都将被重定向到主 C2 服务器,该服务器托管在68.183.150.191
下面的第二张图上:
下面的 gif 显示了测试的实际操作,步骤如下:
下面是 C2 服务器上 tcpdump 的屏幕截图,显示重定向器 IP(organge,159.203.122.243)已启动与 C2(蓝色,68.183.150.191)的连接:
网络钓鱼
我的网络钓鱼服务器正在运行 GoPhish 框架,我在这里对其进行了说明:
使用 GoPhish 和 DigitalOcean 进行网络钓鱼
GoPhish 设置为监听我向互联网公开的端口 3333,但只允许使用 DigitalOcean 防火墙的操作员访问:
再次 -var.operator-ip
设置在variables.tf
网络钓鱼重定向器
这是最耗时的部分。众所周知,设置 SMTP 服务器通常非常麻烦。自动化红队基础设施是值得的,因为一旦 SMTP 服务器在交战期间损坏,您就永远不需要从头开始重建它。
这部分的难点在于设置 smtp 中继,因为它涉及多个活动部件:
测试网络钓鱼重定向器
一旦基础设施建立起来,网络钓鱼重定向器(smtp 中继)的 DNS 区域应该具有 spf、dkim 和 dmarc 记录,类似于此处看到的记录:
DNS 记录完成后,我们可以通过中继服务器从实际的网络钓鱼服务器向 Gmail 发送一封快速测试电子邮件,并查看 spf、dkim 和 dmarc 是否检查PASS
,我们可以在下面看到它们在我们的案例中确实如此,表明网络钓鱼/smtp 中继设置正确:
攻击者@kali
复制
<span class="grid [grid-template-columns:subgrid] col-span-2 relative ring-1 ring-transparent hover:ring-dark-4/5 hover:z-[1] dark:hover:ring-light-4/4 rounded [&.highlighted:first-child]:rounded-t-md [&.highlighted:first-child>]:mt-1 [&.highlighted:last-child]:rounded-b-md [&.highlighted:last-child>]:mb-1 [&:only-child]:hover:ring-transparent [&.highlighted]:rounded-none [&:not(.highlighted)+.highlighted]:rounded-t-md [&:not(.highlighted)+.highlighted>]:mt-1 [&.highlighted:has(+:not(.highlighted))]:rounded-b-md [&.highlighted:has(+:not(.highlighted))>]:mb-1 [&:not(.highlighted)+.highlighted:has(+:not(.highlighted))]:rounded-md">telnetredteam.me25
<span class="grid [grid-template-columns:subgrid] col-span-2 relative ring-1 ring-transparent hover:ring-dark-4/5 hover:z-[1] dark:hover:ring-light-4/4 rounded [&.highlighted:first-child]:rounded-t-md [&.highlighted:first-child>]:mt-1 [&.highlighted:last-child]:rounded-b-md [&.highlighted:last-child>]:mb-1 [&:only-child]:hover:ring-transparent [&.highlighted]:rounded-none [&:not(.highlighted)+.highlighted]:rounded-t-md [&:not(.highlighted)+.highlighted>]:mt-1 [&.highlighted:has(+:not(.highlighted))]:rounded-b-md [&.highlighted:has(+:not(.highlighted))>]:mb-1 [&:not(.highlighted)+.highlighted:has(+:not(.highlighted))]:rounded-md">heloredteam.me
<span class="grid [grid-template-columns:subgrid] col-span-2 relative ring-1 ring-transparent hover:ring-dark-4/5 hover:z-[1] dark:hover:ring-light-4/4 rounded [&.highlighted:first-child]:rounded-t-md [&.highlighted:first-child>]:mt-1 [&.highlighted:last-child]:rounded-b-md [&.highlighted:last-child>]:mb-1 [&:only-child]:hover:ring-transparent [&.highlighted]:rounded-none [&:not(.highlighted)+.highlighted]:rounded-t-md [&:not(.highlighted)+.highlighted>]:mt-1 [&.highlighted:has(+:not(.highlighted))]:rounded-b-md [&.highlighted:has(+:not(.highlighted))>]:mb-1 [&:not(.highlighted)+.highlighted:has(+:not(.highlighted))]:rounded-md">mailfrom:[email protected]
<span class="grid [grid-template-columns:subgrid] col-span-2 relative ring-1 ring-transparent hover:ring-dark-4/5 hover:z-[1] dark:hover:ring-light-4/4 rounded [&.highlighted:first-child]:rounded-t-md [&.highlighted:first-child>]:mt-1 [&.highlighted:last-child]:rounded-b-md [&.highlighted:last-child>]:mb-1 [&:only-child]:hover:ring-transparent [&.highlighted]:rounded-none [&:not(.highlighted)+.highlighted]:rounded-t-md [&:not(.highlighted)+.highlighted>]:mt-1 [&.highlighted:has(+:not(.highlighted))]:rounded-b-md [&.highlighted:has(+:not(.highlighted))>]:mb-1 [&:not(.highlighted)+.highlighted:has(+:not(.highlighted))]:rounded-md">rcptto:[email protected]
<span class="grid [grid-template-columns:subgrid] col-span-2 relative ring-1 ring-transparent hover:ring-dark-4/5 hover:z-[1] dark:hover:ring-light-4/4 rounded [&.highlighted:first-child]:rounded-t-md [&.highlighted:first-child>]:mt-1 [&.highlighted:last-child]:rounded-b-md [&.highlighted:last-child>]:mb-1 [&:only-child]:hover:ring-transparent [&.highlighted]:rounded-none [&:not(.highlighted)+.highlighted]:rounded-t-md [&:not(.highlighted)+.highlighted>]:mt-1 [&.highlighted:has(+:not(.highlighted))]:rounded-b-md [&.highlighted:has(+:not(.highlighted))>]:mb-1 [&:not(.highlighted)+.highlighted:has(+:not(.highlighted))]:rounded-md">data
<span class="grid [grid-template-columns:subgrid] col-span-2 relative ring-1 ring-transparent hover:ring-dark-4/5 hover:z-[1] dark:hover:ring-light-4/4 rounded [&.highlighted:first-child]:rounded-t-md [&.highlighted:first-child>]:mt-1 [&.highlighted:last-child]:rounded-b-md [&.highlighted:last-child>]:mb-1 [&:only-child]:hover:ring-transparent [&.highlighted]:rounded-none [&:not(.highlighted)+.highlighted]:rounded-t-md [&:not(.highlighted)+.highlighted>]:mt-1 [&.highlighted:has(+:not(.highlighted))]:rounded-b-md [&.highlighted:has(+:not(.highlighted))>]:mb-1 [&:not(.highlighted)+.highlighted:has(+:not(.highlighted))]:rounded-md">to:MantvydasBaranauskas<[email protected]m>
<span class="grid [grid-template-columns:subgrid] col-span-2 relative ring-1 ring-transparent hover:ring-dark-4/5 hover:z-[1] dark:hover:ring-light-4/4 rounded [&.highlighted:first-child]:rounded-t-md [&.highlighted:first-child>]:mt-1 [&.highlighted:last-child]:rounded-b-md [&.highlighted:last-child>]:mb-1 [&:only-child]:hover:ring-transparent [&.highlighted]:rounded-none [&:not(.highlighted)+.highlighted]:rounded-t-md [&:not(.highlighted)+.highlighted>]:mt-1 [&.highlighted:has(+:not(.highlighted))]:rounded-b-md [&.highlighted:has(+:not(.highlighted))>]:mb-1 [&:not(.highlighted)+.highlighted:has(+:not(.highlighted))]:rounded-md">from:OlaSenor<[email protected]e>
<span class="grid [grid-template-columns:subgrid] col-span-2 relative ring-1 ring-transparent hover:ring-dark-4/5 hover:z-[1] dark:hover:ring-light-4/4 rounded [&.highlighted:first-child]:rounded-t-md [&.highlighted:first-child>]:mt-1 [&.highlighted:last-child]:rounded-b-md [&.highlighted:last-child>]:mb-1 [&:only-child]:hover:ring-transparent [&.highlighted]:rounded-none [&:not(.highlighted)+.highlighted]:rounded-t-md [&:not(.highlighted)+.highlighted>]:mt-1 [&.highlighted:has(+:not(.highlighted))]:rounded-b-md [&.highlighted:has(+:not(.highlighted))>]:mb-1 [&:not(.highlighted)+.highlighted:has(+:not(.highlighted))]:rounded-md">subject:dailyreport
<span class="grid [grid-template-columns:subgrid] col-span-2 relative ring-1 ring-transparent hover:ring-dark-4/5 hover:z-[1] dark:hover:ring-light-4/4 rounded [&.highlighted:first-child]:rounded-t-md [&.highlighted:first-child>]:mt-1 [&.highlighted:last-child]:rounded-b-md [&.highlighted:last-child>]:mb-1 [&:only-child]:hover:ring-transparent [&.highlighted]:rounded-none [&:not(.highlighted)+.highlighted]:rounded-t-md [&:not(.highlighted)+.highlighted>]:mt-1 [&.highlighted:has(+:not(.highlighted))]:rounded-b-md [&.highlighted:has(+:not(.highlighted))>]:mb-1 [&:not(.highlighted)+.highlighted:has(+:not(.highlighted))]:rounded-md">
<span class="grid [grid-template-columns:subgrid] col-span-2 relative ring-1 ring-transparent hover:ring-dark-4/5 hover:z-[1] dark:hover:ring-light-4/4 rounded [&.highlighted:first-child]:rounded-t-md [&.highlighted:first-child>]:mt-1 [&.highlighted:last-child]:rounded-b-md [&.highlighted:last-child>]:mb-1 [&:only-child]:hover:ring-transparent [&.highlighted]:rounded-none [&:not(.highlighted)+.highlighted]:rounded-t-md [&:not(.highlighted)+.highlighted>]:mt-1 [&.highlighted:has(+:not(.highlighted))]:rounded-b-md [&.highlighted:has(+:not(.highlighted))>]:mb-1 [&:not(.highlighted)+.highlighted:has(+:not(.highlighted))]:rounded-md">HeyMantvydas,
<span class="grid [grid-template-columns:subgrid] col-span-2 relative ring-1 ring-transparent hover:ring-dark-4/5 hover:z-[1] dark:hover:ring-light-4/4 rounded [&.highlighted:first-child]:rounded-t-md [&.highlighted:first-child>]:mt-1 [&.highlighted:last-child]:rounded-b-md [&.highlighted:last-child>]:mb-1 [&:only-child]:hover:ring-transparent [&.highlighted]:rounded-none [&:not(.highlighted)+.highlighted]:rounded-t-md [&:not(.highlighted)+.highlighted>]:mt-1 [&.highlighted:has(+:not(.highlighted))]:rounded-b-md [&.highlighted:has(+:not(.highlighted))>]:mb-1 [&:not(.highlighted)+.highlighted:has(+:not(.highlighted))]:rounded-md">Asyouwererequestinglastweek-attachingaspromisedthedocumentsneededtokeeptheprojectgoingforward.
<span class="grid [grid-template-columns:subgrid] col-span-2 relative ring-1 ring-transparent hover:ring-dark-4/5 hover:z-[1] dark:hover:ring-light-4/4 rounded [&.highlighted:first-child]:rounded-t-md [&.highlighted:first-child>]:mt-1 [&.highlighted:last-child]:rounded-b-md [&.highlighted:last-child>]:mb-1 [&:only-child]:hover:ring-transparent [&.highlighted]:rounded-none [&:not(.highlighted)+.highlighted]:rounded-t-md [&:not(.highlighted)+.highlighted>]:mt-1 [&.highlighted:has(+:not(.highlighted))]:rounded-b-md [&.highlighted:has(+:not(.highlighted))>]:mb-1 [&:not(.highlighted)+.highlighted:has(+:not(.highlighted))]:rounded-md">.
3KB
每日报告.eml
有效载荷重定向器
有效负载重定向服务器建立在 apache2mod_rewrite
和proxy
模块之上。Mod_rewrite
模块允许我们编写细粒度的 URL 重写规则,并根据操作员认为合适的方式将受害者的 HTTP 请求代理到适当的有效负载。
.htaccess
下面是一个 .htaccess 文件,它指示 apache(或者准确地说是mod_rewrite
模块)何时、何地以及如何(即代理或重定向)重写传入的 HTTP 请求:
.htaccess
复制
<span class="grid [grid-template-columns:subgrid] col-span-2 relative ring-1 ring-transparent hover:ring-dark-4/5 hover:z-[1] dark:hover:ring-light-4/4 rounded [&.highlighted:first-child]:rounded-t-md [&.highlighted:first-child>]:mt-1 [&.highlighted:last-child]:rounded-b-md [&.highlighted:last-child>]:mb-1 [&:only-child]:hover:ring-transparent [&.highlighted]:rounded-none [&:not(.highlighted)+.highlighted]:rounded-t-md [&:not(.highlighted)+.highlighted>]:mt-1 [&.highlighted:has(+:not(.highlighted))]:rounded-b-md [&.highlighted:has(+:not(.highlighted))>]:mb-1 [&:not(.highlighted)+.highlighted:has(+:not(.highlighted))]:rounded-md">RewriteEngine On
<span class="grid [grid-template-columns:subgrid] col-span-2 relative ring-1 ring-transparent hover:ring-dark-4/5 hover:z-[1] dark:hover:ring-light-4/4 rounded [&.highlighted:first-child]:rounded-t-md [&.highlighted:first-child>]:mt-1 [&.highlighted:last-child]:rounded-b-md [&.highlighted:last-child>]:mb-1 [&:only-child]:hover:ring-transparent [&.highlighted]:rounded-none [&:not(.highlighted)+.highlighted]:rounded-t-md [&:not(.highlighted)+.highlighted>]:mt-1 [&.highlighted:has(+:not(.highlighted))]:rounded-b-md [&.highlighted:has(+:not(.highlighted))>]:mb-1 [&:not(.highlighted)+.highlighted:has(+:not(.highlighted))]:rounded-md">RewriteCond %{HTTP_USER_AGENT} "android|blackberry|googlebot-mobile|iemobile|ipad|iphone|ipod|opera mobile|palmos|webos" [NC]
<span class="grid [grid-template-columns:subgrid] col-span-2 relative ring-1 ring-transparent hover:ring-dark-4/5 hover:z-[1] dark:hover:ring-light-4/4 rounded [&.highlighted:first-child]:rounded-t-md [&.highlighted:first-child>]:mt-1 [&.highlighted:last-child]:rounded-b-md [&.highlighted:last-child>]:mb-1 [&:only-child]:hover:ring-transparent [&.highlighted]:rounded-none [&:not(.highlighted)+.highlighted]:rounded-t-md [&:not(.highlighted)+.highlighted>]:mt-1 [&.highlighted:has(+:not(.highlighted))]:rounded-b-md [&.highlighted:has(+:not(.highlighted))>]:mb-1 [&:not(.highlighted)+.highlighted:has(+:not(.highlighted))]:rounded-md">RewriteRule ^.$ http://payloadURLForMobiles/login [P]
RewriteRule ^.*$ http://payloadURLForOtherClients/%{REQUEST_URI} [P]
文件细目:
-
第 2 行的意思是:嘿,apache,如果你看到一个传入的 http 请求,其用户代理包含任何单词“android、blackberry、...”等,请移至第 3 行
-
第 3 行指示 Apache 将http 请求代理([P] )
http://payloadURLForMobiles/login
到。如果第 2 行中的条件不成立,则转到第 4 行 -
如果第 2 行中的条件失败,则 http 请求将被代理到附加
http://payloadURLForOtherClients/%{REQUEST_URI}
在REQUEST_URI
域名后面的 http 请求部分 - 即 someDomain.com/?thisIsTheRequestUri=true
下面的截图可以说明上述概念:
-
绿色高亮 - 我们使用了 curl(及其默认 UA),根据 .htaccess 文件,它应该将我们重定向到
payloadURLForOtherClients
- 我们看到它尝试这样做,但当然失败了,因为它是一个测试,并且指定了一个不可解析的主机 -
粉红色 - 我们再次卷曲了有效载荷重定向器,但这次使用伪造的 UA,伪装 http 请求,好像它来自 iphone - 我们可以看到 apache 正确地尝试将请求代理到主机
payloadURLForMobiles
:
输出
Outputs.tf
包含关键服务器 DNS 名称及其 IP 地址,供操作员参考:
./finalize.sh
另外,请注意最后突出显示的部分 - 操作员从工作目录执行命令的指令。它将LetsEncrypt
在 smtp 中继服务器上安装证书,并打印出需要添加到 smtp 中继域的 DigitalOcean DNS 记录中的 DKIM DNS TXT 记录:
mail.domainkey
为了方便起见,创建了具有虚拟值“我是 DKIM,但使用 finalize.sh 中的 DKIM 进行更改”的DNS 记录占位符(dns.tr
文件) - 该值需要替换为 finalize.sh 脚本提供的上面突出显示的 DKIM 值。
理想情况下,这一步将在 droplet 引导期间自动完成,但由于遇到了一些 Terraform 错误,我还无法做到这一点。
下面显示(从上到下):
<ul class="list-none space-y-2 [&>li]:relative [&>li]:ps-[2.25ch] [&>li>div_div]:mt-0 [&>li>.bullet]:before:bg-dark/6 [&>li>.bullet]:before:absolute [&>li>.bullet]:before:left-0 [&>li>.bullet]:before:w-[1ch] [&>li>.bullet]:before:h-[1lh] [&>li>.bullet]:before:[mask-repeat:no-repeat] [&>li>.bullet]:before:[mask-position:left] dark:[&>li>.bullet]:before:bg-light/6 [&>li>.bullet:before]:bullet-circleFilled [&&>li>.bullet:before]:bullet-circle [&&&>li>.bullet:before]:bullet-dash [&&&&>li>.bullet:before]:bullet-squareFilled [&&&&&>li>.bullet:before]:bullet-square [&&&&&&>li>.bullet:before]:bullet-circleFilled max-w-3xl w-full mx-auto decoration-primary/6 page-api-block:ml-0">
terraform 配置为 DKIM 设置新的 DNS TXT 记录占位符
terraform 根据上述配置创建 DNS TXT 记录dns.tf
实际结果 -redteam.me
域的 DNS TXT 记录占位符
下载地址
点击下方名片进入公众号
回复关键字【240730】获取下载链接
原文始发于微信公众号(红云谈安全):使用 Terraform 实现红队基础设施自动化
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论