Skip to content

Commit

Permalink
udp spoofing
Browse files Browse the repository at this point in the history
  • Loading branch information
zardus committed Feb 24, 2025
1 parent 48ca562 commit 0961aad
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 11 deletions.
4 changes: 2 additions & 2 deletions intercepting-communication/module.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ challenges:
name: UDP 2
- id: udp-spoof-host
name: UDP Spoofing 1
visibility:
start: "2029-11-04T13:00:00-07:00"
- id: udp-spoof-host-2
name: UDP Spoofing 2
- id: level-12
name: ARP
- id: level-13
Expand Down
1 change: 1 addition & 0 deletions intercepting-communication/udp-spoof-host-2/.init
11 changes: 11 additions & 0 deletions intercepting-communication/udp-spoof-host-2/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
There is a fairly wide gap between the features that TCP provides and UDP's barebones nature.
Sometimes, developers want _some_ of those features, and end up reimplementing just those that they need on top of UDP.
This leads to weird situations, such as the ability to trigger outbound traffic to other servers, with a potential application to Denial of Service [amplification](https://www.cisa.gov/news-events/alerts/2014/01/17/udp-based-amplification-attacks).

Rather than leaking the flag directly, this challenge allows you to redirect it to another server.
Can you catch it on the other side?

----

**HINT:**
You'll need to either use a UDP server to actually receive the flag (e.g., python or netcat), or just sniff it off the network with Wireshark when it comes to you, even if you don't have a server listening!
47 changes: 47 additions & 0 deletions intercepting-communication/udp-spoof-host-2/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/exec-suid --real -- /usr/bin/python -I

import psutil
import socket
import time
import os

from dojjail import Host, Network

flag = open("/flag").read()
parent_process = psutil.Process(os.getppid())

class ServerHost(Host):
def entrypoint(self):
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(("0.0.0.0", 31337))
while True:
try:
client_message, (client_host, client_port) = server_socket.recvfrom(1024)
if client_message.strip() == b"ACTION?":
server_socket.sendto(b"NONE", (client_host, client_port))
except ConnectionError:
continue

class ClientHost(Host):
def entrypoint(self):
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client_socket.bind(("0.0.0.0", 31338))
while True:
try:
client_socket.sendto(b"ACTION?", ("10.0.0.3", 31337))
message, (peer_host, peer_port) = client_socket.recvfrom(1024)
if peer_port == 31337 and message.startswith(b"FLAG"):
_, flag_host, flag_port = message.strip().split(b":")
client_socket.sendto(flag.encode(), (flag_host, int(flag_port)))

time.sleep(1)
except (ConnectionError, ValueError):
continue

user_host = Host("ip-10-0-0-1", privileged_uid=parent_process.uids().effective)
client_host = ClientHost("ip-10-0-0-2")
server_host = ServerHost("ip-10-0-0-3")
network = Network(hosts={user_host: "10.0.0.1", client_host: "10.0.0.2", server_host: "10.0.0.3"}, subnet="10.0.0.0/24")
network.run()

user_host.interactive(environ=parent_process.environ())
13 changes: 8 additions & 5 deletions intercepting-communication/udp-spoof-host/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
Though we didn't explore this for TCP, in addition to selecting the destination port, both TCP and UDP can set their _source_ port.
We'll practice that here --- you can set the source port with `s.bind` on the socket, exactly how a server does it to set their listening port.
Read the source code of `/challenge/run` to see what source port you'll need!
There are two dangers to UDP: first, it is often used in places where people are already cutting corners for performence's sake.
Second, it forces the programmer to keep track of sessions explicitly.
This combination can cause security issues.

In this challenge, one side of the connection can confuse a non-trusted connection for a trusted connection, and print the flag.
Can you trigger this confusion?

----

**NOTE:**
You must set the source port _before_ sending data!
Otherwise, Linux will pick a random source port (the default behavior, when `bind` is not called).
In this level, the flag will just be printed to the console when you trigger the confusion.
We'll work on realistically exfiltrating it later.
6 changes: 2 additions & 4 deletions intercepting-communication/udp-spoof-host/run
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import psutil
import socket
import time
import os

from dojjail import Host, Network
Expand Down Expand Up @@ -30,9 +29,8 @@ class ClientHost(Host):
try:
client_socket.sendto(b"ACTION?", ("10.0.0.3", 31337))
message, (peer_host, peer_port) = client_socket.recvfrom(1024)
if peer_port == 31337 and message.startswith(b"FLAG"):
_, flag_host, flag_port = message.strip().split(b":")
client_socket.sendto(flag.encode(), (flag_host, int(flag_port)))
if peer_port == 31337 and message.strip() == b"FLAG":
print(f"YOUR FLAG: {flag}")

time.sleep(1)
except ConnectionError:
Expand Down

0 comments on commit 0961aad

Please sign in to comment.