1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 04:31:29 +00:00

Improve parsing of CLIENT LIST responses

- Avoid crash due to unhandled connection line termination
    (fixes #2296, closes #2342)
  - Gracefully handle absence of the "addr" attribute
  - Avoid false negative matching if the "addr" attribute was the last listed
  - Avoid false positive matching on the "laddr" attribute
This commit is contained in:
nnposter
2022-04-25 18:46:04 +00:00
parent 35b543b291
commit a5d57b3280
2 changed files with 21 additions and 22 deletions

View File

@@ -1,5 +1,8 @@
#Nmap Changelog ($Id$); -*-text-*-
o [GH#2296][GH#2342] Script redis-info was crashing or producing inaccurate
information about client connections. [nnposter]
o [GH#2379] Nmap and Nping were unable to obtain system routes on FreeBSD
[benpratt, nnposter]

View File

@@ -6,6 +6,7 @@ local stdnse = require "stdnse"
local string = require "string"
local stringaux = require "stringaux"
local table = require "table"
local tableaux = require "tableaux"
local ipOps = require "ipOps"
description = [[
@@ -126,37 +127,32 @@ local extras = {
end
},
{
-- https://redis.io/commands/client-list/
"Client connections", {"CLIENT", "LIST"}, function(data)
local restab = stringaux.strsplit("\n", data)
if not restab or 0 == #restab then
if not data then
stdnse.debug1("Failed to parse response from server")
return nil
end
local client_ips = {}
for _, item in ipairs(restab) do
local ip = item:match("addr=%[?([0-9a-f:.]+)%]?:[0-9]+ ")
client_ips[ip] = true;
end
if not next(client_ips) then
return nil
end
local out = {}
for ip, _ in pairs(client_ips) do
local sortable = ipOps.ip_to_str(ip)
if sortable then
-- prepending length sorts IPv4 and IPv6 separately
out[#out+1] = string.pack("s1", sortable)
for conn in data:gmatch("[^\n]+") do
local ip = conn:match("%f[^%s\0]addr=%[?([%x:.]+)%]?:%d+%f[%s\0]")
if ip then
local binip = ipOps.ip_to_str(ip)
if binip then
-- prepending length sorts IPv4 and IPv6 separately
client_ips[string.pack("s1", binip)] = binip
end
end
end
if not next(out) then
return nil
local out = {}
local keys = tableaux.keys(client_ips)
table.sort(keys)
for _, packed in ipairs(keys) do
table.insert(out, ipOps.str_to_ip(client_ips[packed]))
end
table.sort(out)
for i, packed in ipairs(out) do
out[i] = ipOps.str_to_ip(string.unpack("s1", packed))
end
return out
return (#out > 0 and out) or nil
end
},
{