# 利用 Nebula 实现红队基础设施安全性

# 前言

本文的全部内容均建立在 “红队团队服务器应该是本地的,位于可以物理访问且可以控制其他人能否物理访问它的位置” 这一理论之上。由于红队的团队服务器作为整个渗透攻击的中心服务器,上面存储着大量的敏感数据,将其托管在云上存在一定的风险。

Tim MalcomVetter 在其博客的 “Safe Red Team Infrastructure” 一文中对如何建立安全的红队运营网络进行了高级概述。

img

这是来自 Tim MalcomVetter 博客文章中的架构图。我们将使用它作为参考,完成红队基础设施安全性的实现与改进。

# 服务器配置

为了实现 Nebula 网络的搭建,除了本地的团队服务器外还需要准备至少两台拥有公网 IP 的服务器(例如云服务器),出于安全和便捷的考虑,我们需要使用 SSH 密钥来连接至这两台服务器。

在本地的团队服务器上创建一个 SSH 密钥对并绑定至实例,生成的私钥不要保存在任何云上,任何身份验证 / 加密材料都应存储在本地。这包括制作的密钥对以及 Nebula 的证书。

image-20221124145248337

或者直接通过云创建 SSH 密钥并绑定至实例。

image-20221209154911466

image-20221209154856079

测试下能否成功连接到云服务器。注意,如果 Linux 的 SSH 客户端使用 pem 格式私钥连接到服务端的话,需要修改 pem 文件权限为 400。

image-20221215105512235

# 安装 Nebula

Nebula 是制作网状覆盖 VPN 的一种极其简单的方法,只要它们可以到达中间主机,网络上的任何两点都可以进行通信。

# 本地团队服务器端

在本地团队服务器上下载并解压 Nebula。

mkdir nebula && cd nebula
wget https://github.com/slackhq/nebula/releases/download/v1.6.1/nebula-linux-amd64.tar.gz
tar -xvf nebula-linux-amd64.tar.gz

image-20221215105728137

# 监听站(Listeningpost)

仅开放 SSH 端口且限定其来源为我使用的 IP,后面需要时再开启其他端口。

image-20221215110549447

安装后面需要用到的 socat 和 Nebula。

sudo apt-get update -y && sudo apt-get install socat
wget https://github.com/slackhq/nebula/releases/download/v1.6.1/nebula-linux-amd64.tar.gz
tar -xvf nebula-linux-amd64.tar.gz

# 中间服务器 - 灯塔(Lighthouse)

Nebula 不是传统的中心辐射型 VPN。它是一个网状覆盖 VPN,其中任何两点都可以直接通信,只要它们都能找到 Nebula 网络的焦点,即称为灯塔(Lighthouse)的中间服务器。需要注意的是,流量不一定要经过 Lighthouse 从 A 点到达 B 点。相反,A 点通过查询 Lighthouse 来确定 B 点的位置,然后计算出最快的数据传输方式。设置完成后,我们就可以无限的向外扩展,甚至可以在不同的云提供商上托管基础设施的每个部分。

灯塔(Lighthouse)的配置与监听站(Listeningpost) 完全相同

也为这个主机安装 socat 和 Nebula

sudo apt-get update -y && sudo apt-get install socat
wget https://github.com/slackhq/nebula/releases/download/v1.6.1/nebula-linux-amd64.tar.gz
tar -xvf nebula-linux-amd64.tar.gz

我们为 Lighthouse 制定了一个新的安全组规则,允许入站 UDP 的 4242 端口。这允许我们 Nebula 网络中的主机向 Lighthouse 查询网络中相应的主机。不用担心向所有来源开放此端口是否存在风险,因为连接与查询是需要通过我们接下来要创建的证书进行加密验证的。

image-20221215110315598

# 配置 Nebula

在所有的服务器上安装好需要的组件后,是时候来设置我们的 Nebula 网络了,我们要在本地的团队服务器上设置所有需要用到的证书和配置文件,并且为了安全起见将它们保存在这里。

# 创建 Nebula 证书文件

在本地的团队服务器上的 Nebula 目录下运行以下命令:

mkdir certs && mv nebula-cert certs/
cd certs
./nebula-cert ca -name "ShellCorp, LLC" 
./nebula-cert sign -name "lighthouse" -ip "192.168.100.1/24"
./nebula-cert sign -name "listeningpost" -ip "192.168.100.2/24" -groups "listening_posts"
./nebula-cert sign -name "teamserver" -ip "192.168.100.3/24" -groups "teamservers"

image-20221209173220358

ca.key 文件是整个网络设置中最敏感的文件,请妥善保管。

# 创建 Nebula 配置文件

Nebula 网络中的主机需要一个配置文件。配置文件是用 YAML 编写的,非常容易阅读和理解。再次从 Marcello 的帖子中借用并进行修改:

# lighthouse-conf.yml

pki:
  ca: /home/ubuntu/ca.crt
  cert: /home/ubuntu/lighthouse.crt
  key: /home/ubuntu/lighthouse.key
static_host_map:
  "192.168.100.1": ["<LIGHTHOUSE IP>:4242"]
lighthouse:
  am_lighthouse: true
listen:
  host: 0.0.0.0
  port: 4242
punchy:
  punch: true
tun:
  disabled: false
  dev: nebula1
  drop_local_broadcast: false
  drop_multicast: false
  tx_queue: 500
  mtu: 1300
  routes:
  unsafe_routes:
logging:
  level: info
  format: text
firewall:
  conntrack:
    tcp_timeout: 12m
    udp_timeout: 3m
    default_timeout: 10m
    max_connections: 100000
  outbound:
    - port: any
      proto: any
      host: any
  inbound:
    - port: any
      proto: icmp
      host: any
    
    - port: 4789
      proto: any
      host: any
    - port: 22
      proto: any
      cidr: 192.168.100.0/24

# listeningpost-conf.yml

pki:
  ca: /home/ubuntu/ca.crt
  cert: /home/ubuntu/listeningpost.crt
  key: /home/ubuntu/listeningpost.key
static_host_map:
  "192.168.100.1": ["<LIGHTHOUSE IP>:4242"]
lighthouse:
  am_lighthouse: false
  interval: 60
  hosts:
    - "192.168.100.1"
listen:
  host: 0.0.0.0
  port: 4242
punchy:
  punch: true
tun:
  disabled: false
  dev: nebula1
  drop_local_broadcast: false
  drop_multicast: false
  tx_queue: 500
  mtu: 1300
  routes:
  unsafe_routes:
logging:
  level: info
  format: text
firewall:
  conntrack:
    tcp_timeout: 12m
    udp_timeout: 3m
    default_timeout: 10m
    max_connections: 100000
  outbound:
    - port: any
      proto: any
      host: any
  inbound:
    - port: any
      proto: icmp
      host: any
    - port: 80
      proto: any
      host: any
    - port: 443
      proto: any
      host: any
    - port: 4789
      proto: any
      host: any
    - port: 22
      proto: any
      cidr: 192.168.100.0/24

# teamserver-conf.yml

pki:
  ca: /root/c2/nebula/certs/ca.crt
  cert: /root/c2/nebula/certs/teamserver.crt
  key: /root/c2/nebula/certs/teamserver.key
static_host_map:
  "192.168.100.1": ["<LIGHTHOUSE IP>:4242"]
lighthouse:
  am_lighthouse: false
  interval: 60
  hosts:
    - "192.168.100.1"
listen:
  host: 0.0.0.0
  port: 4242
punchy:
  punch: true
tun:
  disabled: false
  dev: nebula1
  drop_local_broadcast: false
  drop_multicast: false
  tx_queue: 500
  mtu: 1300
  routes:
  unsafe_routes:
logging:
  level: info
  format: text
firewall:
  conntrack:
    tcp_timeout: 12m
    udp_timeout: 3m
    default_timeout: 10m
    max_connections: 100000
  outbound:
    - port: any
      proto: any
      host: any
  inbound:
    - port: any
      proto: icmp
      host: any
    - port: 80
      proto: any
      host: any
    - port: 443
      proto: any
      host: any
    - port: 4789
      proto: any
      host: any
    - port: 22
      proto: any
      cidr: 192.168.100.0/24

根据具体情况修改配置文件中的内容,例如 crt 和密钥文件的位置,确认 Lighthouse 的公共 IP 地址是否填写正确。当 Nebula 网络运行时,Lighthouse 的 IP 地址不应该发生改变。

为了便于故障排除,端口 80 和 443 被设置为允许任何进入 Listeningpost 主机的流量。这本身并不是特别安全,但我们将在 Nebula 配置中将它们保持打开状态,让防火墙来阻止我们不想要的流量。我们将使用安全组设置将其锁定到特定的 IP 地址,以便稍后保留在这里。

我们还可以在防火墙规则中提高安全性并指定主机和协议。也许您希望 SSH 对 Nebula 网络内部的所有内容开放,但也许有一些您不想通信的主机。这个文件是你可以锁定它们的地方。锁定来自 Nebula 网络中其他主机的 Teamserver 上的入口 SSH 可能是一个很好的举措。确实没有任何其他主机需要启动登录到 Teamserver 的 SSH 会话的理由,但我们绝对希望能够从 Teamserver 启动 SSH 会话并访问其他主机。

将以下文件拷贝到各主机:

  • 其指定的配置 YAML 文件
  • ca.crt
  • 其指定文件 [hostname].crt
  • 其指定文件 [hostname].key

例如使用 csp,将文件拷贝至服务器 ubuntu 用户的根目录下

scp -i ../../c2.pem lighthouse* ubuntu@lighthouse的IP地址:~/

image-20221215111420469

最终 Lighthouse 服务器上文件:

image-20221212094126205

最终 Listeningpost 服务器上文件:

image-20221212094453363

# 启动 Nebula

Lighthouse 服务器:

sudo ./nebula -config lighthouse-conf.yml

image-20221212095131742

Listeningpost 服务器:

sudo ./nebula -config listeningpost-conf.yml

image-20221212102801216

本地团队服务器:

sudo ./nebula -config certs/teamserver-conf.yml

image-20221215131902398

运行后本地团队服务器会多出一张 nebula1 的网卡

image-20221215132155286

通过 ping 验证一下连通性

image-20221215132248646

# 设置反向端口转发和 SOCAT

接下来是确保流量可以从 listeningpost 的 IP 地址返回到我们本地的团队服务器。

首先在本地的团队服务器创建一个简单页面,测试能否成功通过 listeningpost 的公网地址访问到

mkdir test && cd test
echo "hello world\!" > index.html
python3 -m http.server 80               

Listeningpost 的防火墙记得要开放 80 端口

image-20221215134530538

本地服务器上使用 ssh 将流量转到 listeningpost 上

ssh -N -R 8080:localhost:80 -i certs/id_rsa ubuntu@listeningpost

注意这里我为了方便起见,我将其他 Nebula 内的服务器 IP 地址添加到了 hosts 文件,即

192.168.100.1 lighthouse

192.168.100.2 listeningpost

image-20221215142358781

listeningpost 上执行 ss -plont 查看连接状态

image-20221215142436515

sudo socat tcp-listen:80,reuseaddr,fork,bind=Listeningpost的公网IP地址 tcp:127.0.0.1:8080

这里要注意,有些云服务器网卡只有内网地址,配置 socat 时使用公网 IP 地址的话会报错,改用内网地址即可

image-20221215152211562

image-20221215152329810

通过访问 listeningpost 的公网地址,成功访问到本地服务器的测试页面

image-20221215151929981

# 使用测试

这里以 C2 上线进行使用测试,我使用的 C2 选择了 Sliver,关于它的详细使用方法,之后可能会单独进行说明,它的安装十分简单:

curl https://sliver.sh/install | sudo bash

安装完成后输入 sliver 启动。

image-20221124144410757

在团队服务器上,设置 HTTPS 侦听器并将其指向 ssl 证书。

image-20221215170304994

生成 shell。

image-20221215170602829

这里为了演示效果,是直接在受害主机上的 hosts 文件绑定了 listeningpost 的 IP 地址,在受害主机上运行 shell,成功上线。

image-20221215171727046

image-20221215171834386

# 总结

按照上述操作,可成功搭建一个小型的红队基础设施网络。这个小型网络能够在 Nebula 的网状覆盖 VPN 上无限扩展,不仅仅限于 C2 服务端。最重要的是,从红队的角度来看,这个基础设施将是相对安全的,它将最大限度地降低客户数据安全的风险。

# 参考链接

本文仅为学习目的,如有侵权,请联系我删除

本文提及的工具仅供学习使用,禁止用于非法用途,本文不承担任何责任