Webhacking.kr old-31

Challenge

Receive the callback sent to one port in the range 10000–10100.

接收服务端发送到 10000–10100 端口范围内某个端口的回连请求。

1
https://webhacking.kr/challenge/web-16/

Solution

题目服务端会在 10000 到 10100 之间选择端口,并尝试连接 server 参数指定的主机。当前 live source 明确要求访问 ?server=<listener-host>;只刷新无参数 URL 只会得到 Undefined index: server,不会触发有效回连。

题目会从 10000–10100 中选择一个端口,因此监听端点需要同时占用整个范围。下面的脚本只负责监听授权题目产生的回连,不主动向题目服务发起额外请求:

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
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/bin/env python3
import socket
import threading

HOST = "0.0.0.0"
PORT_START = 10000
PORT_END = 10100


def listen(port: int) -> None:
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
server.bind((HOST, port))
server.listen(1)
client, address = server.accept()
with client:
data = client.recv(4096)
print(f"port={port} peer={address}")
print(data.decode("utf-8", errors="replace"))
except OSError as exc:
print(f"port={port} error={exc}")
finally:
server.close()


def main() -> None:
threads = []
for port in range(PORT_START, PORT_END + 1):
thread = threading.Thread(target=listen, args=(port,), daemon=True)
thread.start()
threads.append(thread)

for thread in threads:
thread.join()


if __name__ == "__main__":
main()

监听整个端口范围后,在浏览器或 HTTP 客户端访问 ?server=<listener-host>。<listener-host> 必须是题目服务器可以连接到的地址。回连请求的路径包含题目 flag

FLAG{i_have_a_big_and_beautiful_server}