如何让Python监听端口在Nmap扫描中显示自定义服务名称
让Nmap扫描时显示自定义服务名称的解决方案
嘿,我完全懂你想要的效果——当别人用Nmap扫你的端口时,服务名称列能显示你自定义的名字(比如你说的doom)。问题出在你当前的代码只是单纯监听了端口,并没有处理Nmap的服务探测请求,所以Nmap只能识别出端口开放,但匹配不到对应的服务名称。
为什么默认代码不行?
Nmap不是只看端口开着就给服务命名的,它会通过-sV(服务探测)功能发送特定的探针数据(比如对HTTP发GET请求、对SSH发版本字符串),然后根据你的服务返回的响应,去匹配它内置的服务数据库(nmap-services),才能显示对应的服务名称。你的原代码只是接受连接,没有返回任何Nmap期望的响应,所以它只能显示unknown或者空白。
解决思路:模拟目标服务的响应
要让Nmap显示你想要的服务名称,最简单的方法是让你的监听程序返回对应服务的典型响应(也就是服务banner)。比如你想显示doom,就模拟Doom游戏服务的连接响应。
修改后的Python代码
import socket import sys HOST = '' # 监听所有可用网卡 PORT = 8888 # 你要监听的端口 def handle_scan_connection(conn): # 先接收Nmap发送的探测数据(可能是空的,有些探测只建立连接) conn.recv(1024) # 返回Doom服务的典型banner,让Nmap识别 doom_service_banner = b"DOOM-Engine/1.9\r\n" conn.sendall(doom_service_banner) # 关闭连接 conn.close() try: # 创建TCP socket server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设置端口复用,避免程序重启后端口被占用 server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 绑定端口 server_socket.bind((HOST, PORT)) # 开始监听,最多允许5个排队连接 server_socket.listen(5) print(f"正在监听端口 {PORT},等待扫描...") # 持续处理连接 while True: client_conn, client_addr = server_socket.accept() print(f"收到来自 {client_addr[0]}:{client_addr[1]} 的连接") handle_scan_connection(client_conn) except KeyboardInterrupt: print("\n程序正在关闭...") server_socket.close() sys.exit(0) except socket.error as e: print(f"Socket错误: {e}") server_socket.close() sys.exit(1)
测试方法
让别人(或者你自己)用带服务探测参数的Nmap命令扫描:
nmap -sV <你的IP地址> -p 8888
如果一切正常,Nmap的输出里服务名称列就会显示doom(或者对应的服务名称,取决于你返回的banner)。
额外说明
- 如果想自定义完全不存在的服务名称,那需要扫描者修改自己的Nmap服务数据库,这是客户端的操作,你作为服务端没法控制。所以最好的方式是模拟一个已有的、Nmap能识别的服务响应。
- 如果你要监听UDP端口(比如Doom默认的UDP 666),需要把socket类型改成
SOCK_DGRAM,并调整接收和发送数据的逻辑(UDP是无连接的)。 - 确保你用的端口没有被其他程序占用,否则绑定会失败。
内容的提问来源于stack exchange,提问作者Jason Bourne




