From 8bd87bbc3c80986df4d0cd44b7aeb90c003d27c5 Mon Sep 17 00:00:00 2001 From: Samreet Singh Date: Wed, 1 Oct 2025 09:33:55 +0200 Subject: [PATCH 1/2] Set tunnel attriute by default to none servicescans use http/ssl notation which results into confusion with the matching of cascadingscans So tunnel is given a default value so the https can be matched with tunnel Signed-off-by: Samreet Singh --- .../parser/__testFiles__/service-scan.xml | 37 +++++ scanners/nmap/parser/parser.js | 3 +- scanners/nmap/parser/parser.test.js | 154 +++++++++++++----- 3 files changed, 156 insertions(+), 38 deletions(-) create mode 100644 scanners/nmap/parser/__testFiles__/service-scan.xml diff --git a/scanners/nmap/parser/__testFiles__/service-scan.xml b/scanners/nmap/parser/__testFiles__/service-scan.xml new file mode 100644 index 0000000000..33d7397dee --- /dev/null +++ b/scanners/nmap/parser/__testFiles__/service-scan.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+ + + + + +
+ + + + + + + +cpe:/a:igor_sysoev:nginx +cpe:/a:igor_sysoev:nginx + + + + + + diff --git a/scanners/nmap/parser/parser.js b/scanners/nmap/parser/parser.js index 38f388adc5..afa97cfb55 100644 --- a/scanners/nmap/parser/parser.js +++ b/scanners/nmap/parser/parser.js @@ -332,7 +332,8 @@ function parseResultFile(fileContent) { "version", ]); - const tunnel = get(portItem, ["service", 0, "$", "tunnel"]); + const tunnel = + get(portItem, ["service", 0, "$", "tunnel"]) || "none"; const method = get(portItem, ["service", 0, "$", "method"]); const product = get(portItem, ["service", 0, "$", "tunnel"]); diff --git a/scanners/nmap/parser/parser.test.js b/scanners/nmap/parser/parser.test.js index b6baedb458..a51481639b 100644 --- a/scanners/nmap/parser/parser.test.js +++ b/scanners/nmap/parser/parser.test.js @@ -60,7 +60,7 @@ test("should properly parse nmap xml file", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 8021 is open using tcp protocol.", @@ -85,7 +85,7 @@ test("should properly parse nmap xml file", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 8080 is open using tcp protocol.", @@ -110,7 +110,7 @@ test("should properly parse nmap xml file", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 9200 is open using tcp protocol.", @@ -143,7 +143,7 @@ test("should properly parse a nmap xml without any ports", async () => { import.meta.dirname + "/__testFiles__/no-ports.xml", { encoding: "utf8", - }, + } ); const findings = await parse(xmlContent); @@ -174,7 +174,7 @@ test("should properly parse a nmap xml without any host", async () => { import.meta.dirname + "/__testFiles__/no-host.xml", { encoding: "utf8", - }, + } ); const findings = await parse(xmlContent); @@ -187,7 +187,7 @@ test("should properly parse a nmap xml with missing service information", async import.meta.dirname + "/__testFiles__/no-service.xml", { encoding: "utf8", - }, + } ); const findings = await parse(xmlContent); @@ -210,7 +210,7 @@ test("should properly parse a nmap xml with missing service information", async "serviceProduct": null, "serviceVersion": null, "state": "filtered", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 10250 is filtered using tcp protocol.", @@ -243,7 +243,7 @@ test("Should properly parse a nmap xml with script specific SMB findings", async import.meta.dirname + "/__testFiles__/localhost-smb-script.xml", { encoding: "utf8", - }, + } ); const findings = await parse(xmlContent); @@ -266,7 +266,7 @@ test("Should properly parse a nmap xml with script specific SMB findings", async "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 445 is open using tcp protocol.", @@ -449,7 +449,7 @@ test("should properly parse a script finding for ftp in an xml file", async () = import.meta.dirname + "/__testFiles__/ftp.xml", { encoding: "utf8", - }, + } ); const findings = await parse(xmlContent); expect(validateParser(findings)).toBeUndefined(); @@ -481,7 +481,7 @@ test("should properly parse a script finding for ftp in an xml file", async () = "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 21 is open using tcp protocol.", @@ -541,7 +541,7 @@ test("should parse scanme.nmap.org results properly", async () => { import.meta.dirname + "/__testFiles__/scanme.nmap.org-ipv6.xml", { encoding: "utf8", - }, + } ); const findings = await parse(xmlContent); expect(validateParser(findings)).toBeUndefined(); @@ -563,7 +563,7 @@ test("should parse scanme.nmap.org results properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 22 is open using tcp protocol.", @@ -588,7 +588,7 @@ test("should parse scanme.nmap.org results properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 80 is open using tcp protocol.", @@ -613,7 +613,7 @@ test("should parse scanme.nmap.org results properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 31337 is open using tcp protocol.", @@ -646,7 +646,7 @@ test("should parse output of runs run --verbose properly", async () => { import.meta.dirname + "/__testFiles__/local-network-verbose.xml", { encoding: "utf8", - }, + } ); const findings = await parse(xmlContent); await validateParser(findings); @@ -668,7 +668,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 21 is open using tcp protocol.", @@ -693,7 +693,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 53 is open using tcp protocol.", @@ -718,7 +718,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 80 is open using tcp protocol.", @@ -743,7 +743,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 443 is open using tcp protocol.", @@ -768,7 +768,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 554 is open using tcp protocol.", @@ -793,7 +793,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 5060 is open using tcp protocol.", @@ -818,7 +818,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 8089 is open using tcp protocol.", @@ -843,7 +843,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 8181 is open using tcp protocol.", @@ -868,7 +868,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 80 is open using tcp protocol.", @@ -893,7 +893,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 7000 is open using tcp protocol.", @@ -918,7 +918,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 8082 is open using tcp protocol.", @@ -943,7 +943,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 8083 is open using tcp protocol.", @@ -968,7 +968,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 8085 is open using tcp protocol.", @@ -993,7 +993,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 8200 is open using tcp protocol.", @@ -1018,7 +1018,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 80 is open using tcp protocol.", @@ -1043,7 +1043,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 5000 is open using tcp protocol.", @@ -1068,7 +1068,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 7000 is open using tcp protocol.", @@ -1093,7 +1093,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 8080 is open using tcp protocol.", @@ -1118,7 +1118,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 8081 is open using tcp protocol.", @@ -1143,7 +1143,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 80 is open using tcp protocol.", @@ -1168,7 +1168,7 @@ test("should parse output of runs run --verbose properly", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 443 is open using tcp protocol.", @@ -1255,3 +1255,83 @@ test("should parse output of runs run --verbose properly", async () => { ] `); }); + +test("should parse output of service scan properly", async () => { + const xmlContent = await readFile( + import.meta.dirname + "/__testFiles__/service-scan.xml", + { + encoding: "utf8", + } + ); + const findings = await parse(xmlContent); + await validateParser(findings); + expect(await parse(xmlContent)).toMatchInlineSnapshot(` + [ + { + "attributes": { + "hostname": "example.com", + "ip_addresses": [ + "10.50.0.2", + ], + "mac_address": null, + "method": "probed", + "operating_system": null, + "port": 80, + "protocol": "tcp", + "scripts": null, + "service": "http", + "serviceProduct": "nginx", + "serviceVersion": null, + "state": "open", + "tunnel": "none", + }, + "category": "Open Port", + "description": "Port 80 is open using tcp protocol.", + "location": "tcp://example.com:80", + "name": "Open Port: 80 (http)", + "osi_layer": "NETWORK", + "severity": "INFORMATIONAL", + }, + { + "attributes": { + "hostname": "example.com", + "ip_addresses": [ + "10.50.0.2", + ], + "mac_address": null, + "method": "probed", + "operating_system": null, + "port": 443, + "protocol": "tcp", + "scripts": null, + "service": "http", + "serviceProduct": "nginx", + "serviceVersion": null, + "state": "open", + "tunnel": "ssl", + }, + "category": "Open Port", + "description": "Port 443 is open using tcp protocol.", + "location": "tcp://example.com:443", + "name": "Open Port: 443 (http)", + "osi_layer": "NETWORK", + "severity": "INFORMATIONAL", + }, + { + "attributes": { + "hostname": "example.com", + "ip_addresses": [ + "10.50.0.2", + ], + "operating_system": null, + }, + "category": "Host", + "description": "Found a host", + "location": "example.com", + "name": "Host: example.com", + "osi_layer": "NETWORK", + "severity": "INFORMATIONAL", + }, + ] + `); +}); From ed6cdb75ae3d32df020844dfc8f77bfb5db0fd2c Mon Sep 17 00:00:00 2001 From: Samreet Singh Date: Wed, 1 Oct 2025 10:08:38 +0200 Subject: [PATCH 2/2] Fix unit test Signed-off-by: Samreet Singh --- scanners/nmap/parser/parser.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scanners/nmap/parser/parser.test.js b/scanners/nmap/parser/parser.test.js index a51481639b..3d4083192b 100644 --- a/scanners/nmap/parser/parser.test.js +++ b/scanners/nmap/parser/parser.test.js @@ -35,7 +35,7 @@ test("should properly parse nmap xml file", async () => { "serviceProduct": null, "serviceVersion": null, "state": "open", - "tunnel": null, + "tunnel": "none", }, "category": "Open Port", "description": "Port 53 is open using tcp protocol.",