基于NSE的DCE/RPC查询脚本问题:UDP端口异常致响应丢失
问题与解决方案:NSE UDP Socket 接收任意源端口响应
问题描述
我正在使用Nmap Scripting Engine (NSE)编写脚本,通过DCE/RPC Endpoint Mapper的Lookup Request提取产品名称和物料编号。测试时遇到异常:
- 扫描主机(IP:192.168.10.56)以随机源端口51336向UDP目标端口34964发送请求
- 第一个西门子设备(IP:192.168.10.12)按预期以34964为源端口回复,Nmap可接收
- 第二个设备(IP:192.168.10.21)使用随机源端口49344回复,导致Nmap无法接收响应
当前使用socket:connect(ip, 34964, "udp")指定扫描主机端口,因此出现此问题。想知道能否通过NSE创建类似“服务器端口”的socket,接收特定端口的所有传入消息?
原脚本片段:
send_udp_payload = function(ip, timeout, payload) local socket, try, catch -- create a new udp socket local socket = nmap.new_socket("udp") -- set timeout socket:set_timeout(tonumber(timeout)) catch = function() socket:close() end -- create new try try = nmap.new_try(catch) -- connect to port on host try(socket:connect(ip, 34964, "udp")) -- send lookup packet with PNIO Interface UUID try(socket:send(payload)) -- receive response local rcvstatus, response = socket:receive() -- close socket socket:close() if rcvstatus then return response else return nil end end
解决方案
可以通过不调用socket:connect(),改用socket:sendto()发送数据包,并绑定本地端口后用socket:receivefrom()接收任意源地址/端口的响应。具体实现如下:
修改后的脚本片段
send_udp_payload = function(target_ip, timeout, payload) local socket, try, catch local local_port = 34964 -- 绑定本地这个端口来接收所有传入响应 -- 创建UDP socket local socket = nmap.new_socket("udp") socket:set_timeout(tonumber(timeout)) catch = function() socket:close() end try = nmap.new_try(catch) -- 绑定本地端口,所有发往该端口的UDP包都会被此socket接收 try(socket:bind(nil, local_port, "udp")) -- 直接发送数据包到目标设备的34964端口 try(socket:sendto(target_ip, 34964, payload)) -- 循环接收响应,过滤目标设备的回复 while true do local rcvstatus, response, sender_ip, sender_port = socket:receivefrom() if not rcvstatus then break -- 超时退出 end -- 验证发送者是目标设备,避免干扰包 if sender_ip == target_ip then socket:close() return response end end socket:close() return nil end
关键说明
socket:bind(nil, local_port)中的nil表示绑定到所有本地IP,也可以指定扫描主机的具体IP(192.168.10.56)receivefrom()会返回发送者的IP和端口,方便过滤非目标设备的响应- 原问题根源是
connect()会让socket仅接收来自指定IP+固定端口的响应,去掉该调用即可接收任意源端口的回复
内容的提问来源于stack exchange,提问作者ckmk14
相关产品推荐
相关产品推荐

