mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Closes #2541. Consolidate nmap-payloads and nmap-service-probes; use port scan responses in version scan.
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
#Nmap Changelog ($Id$); -*-text-*-
|
||||
|
||||
o [GH#2541] UDP port scan (-sU) and version scan (-sV) now both use the same
|
||||
data source, nmap-service-probes, for data payloads. Previously, the
|
||||
nmap-payloads file was used for port scan. Port scan responses will be used
|
||||
to kick-start the version matching process. [Daniel Miller]
|
||||
|
||||
o Nmap's service scan (-sV) can now probe the UDP service behind a DTLS tunnel,
|
||||
the same as it already does for TCP services with SSL/TLS encryption. The
|
||||
DTLSSessionReq probe has had its rarity lowered to 2 to allow it to be sent
|
||||
|
||||
@@ -145,6 +145,11 @@ void Target::FreeInternal() {
|
||||
}
|
||||
|
||||
if (FPR) delete FPR;
|
||||
for (std::vector<EarlySvcResponse *>::iterator it=earlySvcResponses.begin();
|
||||
it != earlySvcResponses.end(); it++) {
|
||||
free(*it);
|
||||
}
|
||||
earlySvcResponses.clear();
|
||||
}
|
||||
|
||||
/* Creates a "presentation" formatted string out of the IPv4/IPv6 address.
|
||||
|
||||
8
Target.h
8
Target.h
@@ -83,6 +83,7 @@ class FingerPrintResults;
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <time.h> /* time_t */
|
||||
|
||||
#ifndef INET6_ADDRSTRLEN
|
||||
@@ -116,6 +117,12 @@ struct TracerouteHop {
|
||||
}
|
||||
};
|
||||
|
||||
struct EarlySvcResponse {
|
||||
probespec pspec;
|
||||
int len;
|
||||
u8 data[1];
|
||||
};
|
||||
|
||||
class Target {
|
||||
public: /* For now ... TODO: a lot of the data members should be made private */
|
||||
Target();
|
||||
@@ -248,6 +255,7 @@ class Target {
|
||||
enum dist_calc_method distance_calculation_method;
|
||||
FingerPrintResults *FPR; /* FP results get by the OS scan system. */
|
||||
PortList ports;
|
||||
std::vector<EarlySvcResponse *> earlySvcResponses;
|
||||
|
||||
int weird_responses; /* echo responses from other addresses, Ie a network broadcast address */
|
||||
int flags; /* HOST_UNKNOWN, HOST_UP, or HOST_DOWN. */
|
||||
|
||||
502
nmap-payloads
502
nmap-payloads
@@ -1,502 +0,0 @@
|
||||
# Nmap nmap payload database -*- mode: fundamental; -*-
|
||||
# $Id$
|
||||
#
|
||||
# These payloads are sent with every host discovery or port scan probe
|
||||
# by default. This database should only include payloads that are
|
||||
# unlikely to crash services, trip IDS alerts, or change state on the
|
||||
# server. The idea behind these is to evoke a response using a payload.
|
||||
# Some of them are taken from nmap-service-probes.
|
||||
#
|
||||
# This collection of data is (C) 1996-2022 by Nmap Software LLC. It
|
||||
# is distributed under the Nmap Public Source license as provided in
|
||||
# the LICENSE file of the source distribution or at
|
||||
# https://nmap.org/npsl/. Note that this free license does not allow
|
||||
# incorporation of Nmap or its data files within proprietary
|
||||
# software. We sell a separate Nmap OEM for that as described
|
||||
# (including pricing) at https://nmap.org/npsl/.
|
||||
#
|
||||
# Each entry begins with a protocol (only "udp" is supported) followed
|
||||
# by a comma-separated list of ports, followed by one or more quoted
|
||||
# strings containing the payload. These elements may be broken across
|
||||
# several lines. For future expansion, additional keywords may follow
|
||||
# the payload data. Any data following one of these keywords must be on
|
||||
# the same line as the keyword so that unknown keywords can be ignored
|
||||
# by the parser. Currently this file contains some entries with the
|
||||
# "source" keyword to specify a desired source port, but it is not
|
||||
# honored by Nmap.
|
||||
#
|
||||
# Multiple payloads may be defined for a single protocol and port, in
|
||||
# which case they will be all be sent concurrently. There is a limit
|
||||
# of 255 payloads per port.
|
||||
#
|
||||
# Lines longer than 1024 characters will be ignored.
|
||||
#
|
||||
# Example:
|
||||
# udp 1234 "payloaddatapayloaddata"
|
||||
# "payloaddatapayloaddata"
|
||||
# source 5678
|
||||
|
||||
# GenericLines. Use for the echo service.
|
||||
udp 7 "\x0D\x0A\x0D\x0A"
|
||||
# DNSStatusRequest
|
||||
# Sent for TFTP (69) as well due to its ability to provoke an error response
|
||||
udp 53,69,5353,26198 "\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
# DNS VER
|
||||
udp 53,5353,26198
|
||||
"\x77\x77\x01\x00\x00"
|
||||
"\x01\x00\x00\x00\x00\x00\x00\x07version\x04bind\x00\x00\x10\x00\x03"
|
||||
|
||||
# DHCP INFORM
|
||||
udp 67
|
||||
"\x01\x01\x06\x00"
|
||||
"\x01\x23\x45\x67\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x35\xd4\xd8\x51\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x63\x82\x53\x63\x35\x01"
|
||||
"\x08\xff"
|
||||
|
||||
# TFTP GET
|
||||
udp 69 "\x00\x01r7tftp.txt\x00octet\x00"
|
||||
|
||||
# QUIC packet with unsupported version Q999
|
||||
# Also found on 443, but need to check whether DTLS or QUIC is more prevalent
|
||||
udp 80 "\r12345678Q999\x00"
|
||||
# RPCCheck
|
||||
udp 111
|
||||
"\x72\xFE\x1D\x13\x00\x00\x00\x00\x00\x00\x00\x02\x00\x01\x86\xA0"
|
||||
"\x00\x01\x97\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
# ONCRPC CALL
|
||||
udp 111,2049,4045,32768-65535
|
||||
"\x3e\xec\xe3\xca\x00\x00\x00\x00\x00\x00\x00\x02\x00"
|
||||
"\xbc\x61\x4e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
# NTPRequest
|
||||
udp 123
|
||||
"\xE3\x00\x04\xFA\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xC5\x4F\x23\x4B\x71\xB1\x52\xF3"
|
||||
# NTP REQ
|
||||
udp 123
|
||||
"\xd9\x00\x0a\xfa\x00\x00\x00"
|
||||
"\x00\x00\x01\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc6"
|
||||
"\xf1\x5e\xdb\x78\x00\x00\x00"
|
||||
# DCERPC CALL
|
||||
udp 135,1025-1199
|
||||
"\x05\x00\x0b\x03\x10\x00\x00\x00\x48\x00"
|
||||
"\x00\x00\x01\x00\x00\x00\xb8\x10\xb8\x10\x00\x00\x00\x00\x01\x00\x00"
|
||||
"\x00\x00\x00\x01\x00\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67"
|
||||
"\x89\xab\xcd\xef\xe7\x03\x00\x00\xfe\xdc\xba\x98\x76\x54\x32\x10\x01"
|
||||
"\x23\x45\x67\x89\xab\xcd\xef\xe7\x03\x00\x00"
|
||||
# NBTStat
|
||||
udp 137
|
||||
"\x80\xF0\x00\x10\x00\x01\x00\x00\x00\x00\x00\x00"
|
||||
"\x20CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x00\x00\x21\x00\x01"
|
||||
# CIFS NS NAME QUERY UC
|
||||
udp 137
|
||||
"\x01\x91\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
|
||||
"\x20CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x00\x00\x21\x00\x01"
|
||||
# CIFS NS NAME QUERY BC
|
||||
udp 137
|
||||
"\x01\x91\x00\x10\x00\x01\x00\x00\x00\x00\x00\x00"
|
||||
"\x20CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x00\x00\x21\x00\x01"
|
||||
# SNMPv3GetRequest
|
||||
udp 161,260,3401
|
||||
"\x30\x3A\x02\x01\x03\x30\x0F\x02\x02\x4A\x69\x02\x03\x00\xFF\xE3"
|
||||
"\x04\x01\x04\x02\x01\x03\x04\x10\x30\x0E\x04\x00\x02\x01\x00\x02"
|
||||
"\x01\x00\x04\x00\x04\x00\x04\x00\x30\x12\x04\x00\x04\x00\xA0\x0C"
|
||||
"\x02\x02\x37\xF0\x02\x01\x00\x02\x01\x00\x30\x00"
|
||||
# SNMP PUBLIC WALK
|
||||
udp 161,260,3401
|
||||
"\x30\x1f\x02\x01\x00\x04\x06public\xa1\x12\x02\x01\x00\x02"
|
||||
"\x01\x00\x02\x01\x00\x30\x07\x30\x05\x06\x01\x00\x05\x00"
|
||||
|
||||
# Sqlping - disabled because it trips a Snort rule with SID 2049
|
||||
# ("MS-SQL ping attempt").
|
||||
# udp 1434 "\x02"
|
||||
|
||||
# xdmcp - X Display Manager Control Protocol. Version 1, packet type
|
||||
# Query (2), no authorization names. We expect a Willing or Unwilling
|
||||
# packet in reply.
|
||||
# http://cgit.freedesktop.org/xorg/doc/xorg-docs/plain/hardcopy/XDMCP/xdmcp.PS.gz
|
||||
udp 177 "\x00\x01\x00\x02\x00\x01\x00"
|
||||
|
||||
# Connectionless LDAP - used by Microsoft Active Directory
|
||||
udp 389
|
||||
"\x30\x84\x00\x00\x00\x2d\x02\x01\x07\x63\x84\x00\x00\x00\x24\x04\x00"
|
||||
"\x0a\x01\x00\x0a\x01\x00\x02\x01\x00\x02\x01\x64\x01\x01\x00\x87\x0b"
|
||||
"objectClass0\x84\x00\x00\x00\x00"
|
||||
|
||||
|
||||
# svrloc
|
||||
udp 427
|
||||
"\x02\x01\x00\x006 \x00\x00\x00\x00\x00\x01\x00\x02en\x00\x00\x00\x15"
|
||||
"service:service-agent\x00\x07default\x00\x00\x00\x00"
|
||||
|
||||
# DTLS
|
||||
udp 443,853,3391,4433,4740,5349,5684,5868,6514,6636,8232,10161,10162,12346,12446,12546,12646,12746,12846,12946,13046
|
||||
# DTLS 1.0, length 52
|
||||
"\x16\xfe\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x36"
|
||||
# ClientHello, length 40, sequence 0, offset 0
|
||||
"\x01\x00\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x2a"
|
||||
# DTLS 1.2
|
||||
"\xfe\xfd"
|
||||
# Random
|
||||
"\x00\x00\x00\x00\x7c\x77\x40\x1e\x8a\xc8\x22\xa0\xa0\x18\xff\x93"
|
||||
"\x08\xca\xac\x0a\x64\x2f\xc9\x22\x64\xbc\x08\xa8\x16\x89\x19\x3f"
|
||||
# Session id length 0, cookie length 0
|
||||
"\x00\x00"
|
||||
# Cipher suites, mandatory TLS_RSA_WITH_AES_128_CBC_SHA
|
||||
"\x00\x02\x00\x2f"
|
||||
# Compressors (NULL)
|
||||
"\x01\x00"
|
||||
|
||||
# Internet Key Exchange version 1, phase 1 Main Mode. We offer every
|
||||
# combination of (DES, 3DES) and (MD5, SHA) in the hope that one of them will
|
||||
# be acceptable. Because we use a fixed cookie, we set the association lifetime
|
||||
# to 1 second to reduce the chance that repeated probes will look like
|
||||
# retransmissions (and therefore not get a response). This payload comes from
|
||||
# ike-scan --lifetime 1 --cookie 0011223344556677 --trans=5,2,1,2 --trans=5,1,1,2 --trans=1,2,1,2 --trans=1,1,1,2
|
||||
# We expect another phase 1 message in response. This payload works better with
|
||||
# a source port of 500 or a randomized initiator cookie.
|
||||
udp 500
|
||||
# Initiator cookie 0x0011223344556677, responder cookie 0x0000000000000000.
|
||||
"\x00\x11\x22\x33\x44\x55\x66\x77\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
# Version 1, Main Mode, flags 0x00, message ID 0x00000000, length 192.
|
||||
"\x01\x10\x02\x00\x00\x00\x00\x00\x00\x00\x00\xC0"
|
||||
# Security Association payload, length 164, IPSEC, IDENTITY.
|
||||
"\x00\x00\x00\xA4\x00\x00\x00\x01\x00\x00\x00\x01"
|
||||
# Proposal 1, length 152, ISAKMP, 4 transforms.
|
||||
"\x00\x00\x00\x98\x01\x01\x00\x04"
|
||||
# Transform 1, 3DES-CBC, SHA, PSK, group 2.
|
||||
"\x03\x00\x00\x24\x01\x01\x00\x00\x80\x01\x00\x05\x80\x02\x00\x02"
|
||||
"\x80\x03\x00\x01\x80\x04\x00\x02"
|
||||
"\x80\x0B\x00\x01\x00\x0C\x00\x04\x00\x00\x00\x01"
|
||||
# Transform 2, 3DES-CBC, MD5, PSK, group 2.
|
||||
"\x03\x00\x00\x24\x02\x01\x00\x00\x80\x01\x00\x05\x80\x02\x00\x01"
|
||||
"\x80\x03\x00\x01\x80\x04\x00\x02"
|
||||
"\x80\x0B\x00\x01\x00\x0C\x00\x04\x00\x00\x00\x01"
|
||||
# Transform 3, DES-CBC, SHA, PSK, group 2.
|
||||
"\x03\x00\x00\x24\x03\x01\x00\x00\x80\x01\x00\x01\x80\x02\x00\x02"
|
||||
"\x80\x03\x00\x01\x80\x04\x00\x02"
|
||||
"\x80\x0B\x00\x01\x00\x0C\x00\x04\x00\x00\x00\x01"
|
||||
# Transform 4, DES-CBC, MD5, PSK, group 2.
|
||||
"\x00\x00\x00\x24\x04\x01\x00\x00\x80\x01\x00\x01\x80\x02\x00\x01"
|
||||
"\x80\x03\x00\x01\x80\x04\x00\x02"
|
||||
"\x80\x0B\x00\x01\x00\x0C\x00\x04\x00\x00\x00\x01"
|
||||
source 500
|
||||
# IPSEC START
|
||||
udp 500,4500
|
||||
"\x31\x27\xfc"
|
||||
"\xb0\x38\x10\x9e\x89\x00\x00\x00\x00\x00\x00\x00\x00\x01\x10\x02\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\xcc\x0d\x00\x00\x5c\x00\x00\x00\x01\x00"
|
||||
"\x00\x00\x01\x00\x00\x00\x50\x01\x01\x00\x02\x03\x00\x00\x24\x01\x01"
|
||||
"\x00\x00\x80\x01\x00\x05\x80\x02\x00\x02\x80\x04\x00\x02\x80\x03\x00"
|
||||
"\x03\x80\x0b\x00\x01\x00\x0c\x00\x04\x00\x00\x0e\x10\x00\x00\x00\x24"
|
||||
"\x02\x01\x00\x00\x80\x01\x00\x05\x80\x02\x00\x01\x80\x04\x00\x02\x80"
|
||||
"\x03\x00\x03\x80\x0b\x00\x01\x00\x0c\x00\x04\x00\x00\x0e\x10\x0d\x00"
|
||||
"\x00\x18\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4"
|
||||
"\x61\x00\x00\x00\x04\x0d\x00\x00\x14\x40\x48\xb7\xd5\x6e\xbc\xe8\x85"
|
||||
"\x25\xe7\xde\x7f\x00\xd6\xc2\xd3\x0d\x00\x00\x14\x90\xcb\x80\x91\x3e"
|
||||
"\xbb\x69\x6e\x08\x63\x81\xb5\xec\x42\x7b\x1f\x00\x00\x00\x14\x26\x24"
|
||||
"\x4d\x38\xed\xdb\x61\xb3\x17\x2a\x36\xe3\xd0\xcf\xb8\x19"
|
||||
source 500
|
||||
|
||||
# Routing Information Protocol version 1. Special-case request for the entire
|
||||
# routing table (address family 0, address 0.0.0.0, metric 16). RFC 1058,
|
||||
# section 3.4.1.
|
||||
udp 520
|
||||
"\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x10"
|
||||
|
||||
# RMCP ASF ping
|
||||
udp 623
|
||||
"\x06\x00\xff\x06" # RMCP version 6, sequence 0xff, normal RMCP class ASF
|
||||
"\x00\x00\x11\xbe" # IAN ASF code 4542
|
||||
"\x80\x00\x00\x00" # payload-less ASF presence ping
|
||||
|
||||
# IPMI
|
||||
# RMCP Get Channel Auth Capabilities
|
||||
udp 623
|
||||
"\x06\x00\xff\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x20\x18"
|
||||
"\xc8\x81\x00\x38\x8e\x04\xb5"
|
||||
|
||||
# serialnumberd. This service runs on Mac OS X Server. This probe
|
||||
# requests the serial number of another server. In response we expect a
|
||||
# packet starting with "SNRESPS:", followed by some data whose purpose
|
||||
# is not known.
|
||||
udp 626 "SNQUERY: 127.0.0.1:AAAAAA:xsvr"
|
||||
|
||||
# OpenVPN P_CONTROL_HARD_RESET_CLIENT_V2
|
||||
# Byte 0; 0x38 opcode
|
||||
# Byte 1-8: Session ID, random
|
||||
# Byte 9: Message packet-id array length (0)
|
||||
# Byte 10-13: Message packet-id (0)
|
||||
udp 1194 "8d\xc1x\x01\xb8\x9b\xcb\x8f\0\0\0\0\0"
|
||||
# OpenVPN when in PKI mode and without the "HMAC Firewall" setting enabled
|
||||
# (tls-auth) should respond to the following probe, which is
|
||||
# 0x38<8 random bytes><4 null bytes>
|
||||
udp 1194
|
||||
"\x38\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x00"
|
||||
|
||||
# Citrix MetaFrame application browser service
|
||||
# Original idea from http://sh0dan.org/oldfiles/hackingcitrix.html
|
||||
# Payload contents copied from Wireshark capture of Citrix Program
|
||||
# Neighborhood client application. The application uses this payload to
|
||||
# locate Citrix servers on the local network. Response to this probe is
|
||||
# a 48 byte UDP payload as shown here:
|
||||
#
|
||||
# 0000 30 00 02 31 02 fd a8 e3 02 00 06 44 c0 a8 80 55
|
||||
# 0010 00 00 00 00 00 00 00 00 00 00 00 00 02 00 06 44
|
||||
# 0020 c0 a8 80 56 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
#
|
||||
# The first 12 bytes appear to be the same in all responses.
|
||||
#
|
||||
# Bytes 0x00 appears to be a packet length field
|
||||
# Bytes 0x0C - 0x0F are the IP address of the server
|
||||
# Bytes 0x10 - 0x13 may vary, 0x14 - 0x1F do not appear to
|
||||
# Bytes 0x20 - 0x23 are the IP address of the primary system in a server farm
|
||||
# configuration
|
||||
# Bytes 0x24 - 0x27 can vary, 0x28 - 0x2F do not appear to
|
||||
udp 1604
|
||||
"\x1e\x00\x01\x30\x02\xfd\xa8\xe3\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
|
||||
# RADIUS Access-Request. This is a degenerate packet with no username or
|
||||
# password; we expect an Access-Reject in response. The Identifier and Request
|
||||
# Authenticator are both 0. It was generated by running
|
||||
# echo 'User-Password = ""' | radclient <ip> auth ""
|
||||
# and then manually stripping out the password.
|
||||
#
|
||||
# Section 2 of the RFC says "A request from a client for which the
|
||||
# RADIUS server does not have a shared secret MUST be silently
|
||||
# discarded." So this payload only works when the server is configured
|
||||
# (or misconfigured) to know the scanning machine as a client.
|
||||
#
|
||||
# RFC 2865: "The early deployment of RADIUS was done using UDP port
|
||||
# number 1645, which conflicts with the "datametrics" service. The
|
||||
# officially assigned port number for RADIUS is 1812.
|
||||
udp 1645,1812
|
||||
"\x01\x00\x00\x14"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
|
||||
# L2TP ICRQ
|
||||
udp 1701
|
||||
"\xc8\x02"
|
||||
"\x00\x3c\x00\x00\x00\x00\x00\x00\x00\x00\x80\x08\x00\x00\x00\x00\x00"
|
||||
"\x01\x80\x08\x00\x00\x00\x02\x01\x00\x80\x0e\x00\x00\x00\x07"
|
||||
"nxp-scan\x80\x0a\x00\x00\x00\x03\x00\x00\x00\x03\x80"
|
||||
"\x08\x00\x00\x00\x09\x00\x00"
|
||||
|
||||
# UPNP MSEARCH
|
||||
udp 1900
|
||||
"M-SEARCH * HTTP/1.1\r\nHost: 239.255.255.250:1900\r\n"
|
||||
"Man: \"ssdp:discover\"\r\nMX: 5\r\nST: ssdp:all\r\n\r\n"
|
||||
|
||||
# NFS version 2, RFC 1831. XID 0x00000000, program 100003 (NFS), procedure
|
||||
# NFSPROC_NULL (does nothing, see section 2.2.1), null authentication (see
|
||||
# section 9.1).
|
||||
udp 2049
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x01\x86\xA3"
|
||||
"\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
|
||||
# GPRS Tunneling Protocol (GTP)
|
||||
udp 2123,2152
|
||||
# GTPv1, protocol 1
|
||||
"\x32"
|
||||
# EchoRequest
|
||||
"\x01"
|
||||
# message length
|
||||
"\x00\x04"
|
||||
# Tunnel endpoint identifier
|
||||
"\x00\x00\x42\x00"
|
||||
# sequence number
|
||||
"\x13\x37"
|
||||
# N-PDU number
|
||||
"\x00"
|
||||
# next extension header type
|
||||
"\x00"
|
||||
|
||||
# GPRS Tunneling Protocol (GTP) "prime" v2
|
||||
# This same packet can be used for GTP v2 on ports 2123 and 2152 if you change
|
||||
# the first byte from \x4e to \x40
|
||||
udp 3386
|
||||
# GTP'v2
|
||||
"\x4e"
|
||||
# EchoRequest
|
||||
"\x01"
|
||||
# message length
|
||||
"\x00\x04"
|
||||
# sequence number
|
||||
"\xde\xfe\xc8\x00"
|
||||
|
||||
# Freelancer game server status query
|
||||
# http://sourceforge.net/projects/gameq/
|
||||
# (relevant files: games.ini, packets.ini, freelancer.php)
|
||||
udp 2302 "\x00\x02\xf1\x26\x01\x26\xf0\x90\xa6\xf0\x26\x57\x4e\xac\xa0\xec\xf8\x68\xe4\x8d\x21"
|
||||
|
||||
# Apple Remote Desktop (ARD)
|
||||
udp 3283 "\0\x14\0\x01\x03"
|
||||
|
||||
# STUN Binding request, see RFC 5389 Section 6
|
||||
# message type = 0x001, Binding (see Section 18.1)
|
||||
# message length = 0
|
||||
# magic cookie = 0x2112a442
|
||||
# transaction ID = "\x00"*12
|
||||
udp 3478 "\x00\x01\x00\x00\x21\x12\xa4\x42\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
|
||||
# Sun Service Tag Discovery protocol (stdiscover)
|
||||
# http://arc.opensolaris.org/caselog/PSARC/2006/638/stdiscover_protocolv2.pdf
|
||||
# Would work better with a varying cookie; the second and later sends of this
|
||||
# probe will be interpreted as resends by the server and will be ignored.
|
||||
udp 6481 "[PROBE] 0000"
|
||||
|
||||
# NAT-PMP external IP address request. See section 3.2 of
|
||||
# http://files.dns-sd.org/draft-cheshire-nat-pmp.txt.
|
||||
udp 5351 "\x00\x00"
|
||||
|
||||
# DNS Service Discovery (DNS-SD) service query, as used in Zeroconf.
|
||||
# Transaction ID 0x0000, flags 0x0000, 1 question: PTR query for
|
||||
# _services._dns-sd._udp.local. If the remote host supports DNS-SD it will send
|
||||
# back a list of all its services. This is the same as a packet capture of
|
||||
# dns-sd -B _services._dns-sd._udp .
|
||||
# See section 9 of
|
||||
# http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt.
|
||||
# This first probe is a QU probe, meaning a unicast response is desired
|
||||
udp 5353
|
||||
"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
|
||||
"\x09_services\x07_dns-sd\x04_udp\x05local\x00\x00\x0C\x80\x01"
|
||||
# This second probe is a QM probe, meaning a unicast response is desired
|
||||
udp 5353
|
||||
"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
|
||||
"\x09_services\x07_dns-sd\x04_udp\x05local\x00\x00\x0C\x00\x01"
|
||||
|
||||
# PCANY STATUS
|
||||
udp 5632 "ST"
|
||||
|
||||
# CoAP GET .well-known/core
|
||||
udp 5683 "@\x01\x01\xce\xbb.well-known\x04core"
|
||||
|
||||
# UT2K PING
|
||||
udp 7777 "None\x00"
|
||||
|
||||
# Ubiquiti Discovery Service - v1
|
||||
udp 10001 "\x01\x00\x00\x00"
|
||||
|
||||
# Amanda backup service noop request. I think that this does nothing on the
|
||||
# server but only asks it to send back its feature list. In reply we expect an
|
||||
# ACK or (more likely) an ERROR. I couldn't find good online documentation of
|
||||
# the Amanda network protocol. There is parsing code in the Amanda source at
|
||||
# common-src/security-util.c. This is based on a packet capture of
|
||||
# amcheck <config> <host>
|
||||
udp 10080
|
||||
"Amanda 2.6 REQ HANDLE 000-00000000 SEQ 0\n"
|
||||
"SERVICE noop\n"
|
||||
|
||||
# VxWorks Wind River Debugger
|
||||
udp 17185
|
||||
# Random XID
|
||||
"\x00\x00\x00\x00"
|
||||
# RPC version 2 procedure call
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x02"
|
||||
# WDB version 1
|
||||
"\x55\x55\x55\x55\x00\x00\x00\x01"
|
||||
# WDB_TARGET_PING
|
||||
"\x00\x00\x00\x00"
|
||||
# RPC Auth NULL
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
# Checksum
|
||||
"\xff\xff\x55\x13"
|
||||
# WDB wrapper (length and sequence number)
|
||||
"\x00\x00\x00\x30\x00\x00\x00\x01"
|
||||
# Empty data?
|
||||
"\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
# VXWORKS DEBUG (alternative?)
|
||||
udp 17185
|
||||
"\x72\x37\x72\x37\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x02\x55\x55\x55\x55\x00\x00\x00\x01\x00\x00\x00\x01"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff"
|
||||
"\xff\x55\x10\x00\x00\x00\x3c\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00"
|
||||
|
||||
# Quake 2 and Quake 3 game servers (and servers of derived games like Nexuiz).
|
||||
# Gets game information from the server (see probe responses in
|
||||
# nmap-service-probes). These services typically run on a base port or a
|
||||
# few numbers higher.
|
||||
# Quake 2. Typical ports: 27910-27914.
|
||||
udp 27910-27914 "\xff\xff\xff\xffstatus"
|
||||
# Quake 3. Typical ports:
|
||||
# 26000-26004: Nexuiz
|
||||
# 27960-27964: Various games
|
||||
# 30720-30724: Tremulous
|
||||
# 44400: Warsow
|
||||
udp 26000-26004,27960-27964,30720-30724,44400 "\xff\xff\xff\xffgetstatus"
|
||||
|
||||
# Murmur 1.2.X (Mumble server)
|
||||
# UDP ping. "abcdefgh" is an identifier. See
|
||||
# http://mumble.sourceforge.net/Protocol.
|
||||
udp 64738 "\x00\x00\x00\x00abcdefgh"
|
||||
|
||||
# Ventrilo 2.1.2+
|
||||
# UDP general status request (encrypted).
|
||||
# See http://aluigi.altervista.org/papers.htm#ventrilo
|
||||
udp 3784
|
||||
"\x01\xe7\xe5\x75\x31\xa3\x17\x0b\x21\xcf\xbf\x2b\x99\x4e\xdd\x19\xac\xde\x08\x5f\x8b\x24\x0a\x11\x19\xb6\x73\x6f\xad\x28\x13\xd2\x0a\xb9\x12\x75"
|
||||
|
||||
# Kademlia (kad) as used by various P2P applications. Send a Kademlia ping
|
||||
# 4665, 4666, 4672, 6429: eDonkey/eMule and variants
|
||||
udp 4665,4666,4672,6429 "\xE4\x60"
|
||||
|
||||
# TeamSpeak 2
|
||||
# UDP login request
|
||||
# See http://wiki.wireshark.org/TeamSpeak2
|
||||
udp 8767
|
||||
"\xf4\xbe\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x002x\xba\x85\tTeamSpeak\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\nWindows XP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00 \x00<\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08nickname\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
|
||||
# TS3INIT1
|
||||
udp 9987
|
||||
"TS3INIT1\x00\x65\x00\x00\x88\x0a\x39\x7b\x0f\x00\x5b\x55\x72\xef\xdc\x78\x32\x6b\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
|
||||
# TeamSpeak 3
|
||||
# UDP login request (encrypted)
|
||||
# http://seclists.org/nmap-dev/2013/q3/72
|
||||
udp 9987
|
||||
"\x05\xca\x7f\x16\x9c\x11\xf9\x89\x00\x00\x00\x00\x02\x9d\x74\x8b\x45\xaa\x7b\xef\xb9\x9e\xfe\xad\x08\x19\xba\xcf\x41\xe0\x16\xa2\x32\x6c\xf3\xcf\xf4\x8e\x3c\x44\x83\xc8\x8d\x51\x45\x6f\x90\x95\x23\x3e\x00\x97\x2b\x1c\x71\xb2\x4e\xc0\x61\xf1\xd7\x6f\xc5\x7e\xf6\x48\x52\xbf\x82\x6a\xa2\x3b\x65\xaa\x18\x7a\x17\x38\xc3\x81\x27\xc3\x47\xfc\xa7\x35\xba\xfc\x0f\x9d\x9d\x72\x24\x9d\xfc\x02\x17\x6d\x6b\xb1\x2d\x72\xc6\xe3\x17\x1c\x95\xd9\x69\x99\x57\xce\xdd\xdf\x05\xdc\x03\x94\x56\x04\x3a\x14\xe5\xad\x9a\x2b\x14\x30\x3a\x23\xa3\x25\xad\xe8\xe6\x39\x8a\x85\x2a\xc6\xdf\xe5\x5d\x2d\xa0\x2f\x5d\x9c\xd7\x2b\x24\xfb\xb0\x9c\xc2\xba\x89\xb4\x1b\x17\xa2\xb6"
|
||||
|
||||
# Memcached
|
||||
# version request (shorter response than stats)
|
||||
# https://github.com/memcached/memcached/blob/master/doc/protocol.txt
|
||||
udp 11211
|
||||
"\0\x01\0\0\0\x01\0\0version\r\n"
|
||||
|
||||
# Steam, typically using a port in 27015-27030. Send a "Source Engine query"
|
||||
udp 27015-27030
|
||||
"\xff\xff\xff\xffTSource Engine Query\x00"
|
||||
|
||||
# TRIN00 UNIX PING
|
||||
udp 27444 "png l44adsl"
|
||||
|
||||
# BO PING
|
||||
udp 31337
|
||||
"\xce\x63\xd1\xd2\x16\xe7\x13\xcf\x38"
|
||||
"\xa5\xa5\x86\xb2\x75\x4b\x99\xaa\x32\x58"
|
||||
|
||||
# TRIN00 WIN PING
|
||||
udp 34555 "png []..Ks"
|
||||
|
||||
# Beckhoff ADS discovery request
|
||||
# https://github.com/ONE75/adsclient/blob/master/src/AdsClient.Finder/DeviceFinder.cs#L49-L64
|
||||
udp 48899
|
||||
"\x03\x66\x14\x71\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x01\x10\x27\x00\x00\x00\x00"
|
||||
@@ -12444,7 +12444,7 @@ match dtls m|^\x15\xfe[\xfd\xff]\0\0\0\0\0\0\0\0..\x02.\0\0\0\0\0|
|
||||
##############################NEXT PROBE##############################
|
||||
Probe UDP DNSVersionBindReq q|\0\x06\x01\0\0\x01\0\0\0\0\0\0\x07version\x04bind\0\0\x10\0\x03|
|
||||
rarity 1
|
||||
ports 53,1967,2967
|
||||
ports 53,1967,2967,26198
|
||||
|
||||
# Matches here have been grouped by product and roughly ordered based on prevalence
|
||||
# on the Internet
|
||||
@@ -12770,7 +12770,7 @@ match ssl m|^\x15\x03[\x00-\x04]\0\x02\x02[\nF\x28]|
|
||||
##############################NEXT PROBE##############################
|
||||
Probe UDP DNSStatusRequest q|\0\0\x10\0\0\0\0\0\0\0\0\0|
|
||||
rarity 5
|
||||
ports 53,69,135,1761
|
||||
ports 53,69,135,1761,26198
|
||||
|
||||
# Note when generating match lines - TCP DNS responses have two bytes at the beginning
|
||||
# of the response that the UDP doesn't, otherwise they are the same. Account for this
|
||||
@@ -14977,7 +14977,7 @@ softmatch radmin m|^\x01\x00\x00\x00\x25.\x00..\x08.\x00..|s p/Famatech Radmin/
|
||||
match srcds m|^\n\0\0\0\0\0\0\0\0\0\0\0\0\0$| p/srcds game server/
|
||||
|
||||
##############################NEXT PROBE##############################
|
||||
Probe UDP Sqlping q|\x02|
|
||||
Probe UDP Sqlping q|\x02| no-payload
|
||||
rarity 6
|
||||
ports 1434,19131-19133
|
||||
match ms-sql-m m|^\x05..ServerName;([\w\-]+);InstanceName;[\w\-]+;IsClustered;\w{2,3};Version;([\d\.]+);np;.+;tcp;(\d{1,5});| p/Microsoft SQL Server/ v/$2/ i/ServerName: $1; TCPPort: $3/ o/Windows/ cpe:/a:microsoft:sql_server:$2/ cpe:/o:microsoft:windows/a
|
||||
@@ -15069,7 +15069,7 @@ match zabbix m|^NOT OK\n$| p/Zabbix Monitoring System/ cpe:/a:zabbix:zabbix/
|
||||
##############################NEXT PROBE##############################
|
||||
Probe UDP SNMPv1public q|0\x82\0/\x02\x01\0\x04\x06public\xa0\x82\0\x20\x02\x04\x4c\x33\xa7\x56\x02\x01\0\x02\x01\0\x30\x82\0\x10\x30\x82\0\x0c\x06\x08\x2b\x06\x01\x02\x01\x01\x05\0\x05\0|
|
||||
rarity 4
|
||||
ports 161
|
||||
ports 161,260,3401
|
||||
|
||||
match bittorrent-udp-tracker m|^\x03\0\0\0lic\xa0Connection ID missmatch\.\0| p/opentracker UDP tracker/ cpe:/a:dirk_engling:opentracker/
|
||||
match snmp m|^0.*\x02\x01\0\x04\x06public\xa2.*\x06\x08\+\x06\x01\x02\x01\x01\x05\0\x04[^\0]([^\0]+)|s p/SNMPv1 server/ i/public/ h/$1/
|
||||
@@ -15081,7 +15081,7 @@ match echo m|^0\x82\0/\x02\x01\0\x04\x06public\xa0\x82\0\x20\x02\x04\x4c\x33\xa7
|
||||
##############################NEXT PROBE##############################
|
||||
Probe UDP SNMPv3GetRequest q|\x30\x3a\x02\x01\x03\x30\x0f\x02\x02\x4a\x69\x02\x03\0\xff\xe3\x04\x01\x04\x02\x01\x03\x04\x10\x30\x0e\x04\0\x02\x01\0\x02\x01\0\x04\0\x04\0\x04\0\x30\x12\x04\0\x04\0\xa0\x0c\x02\x02\x37\xf0\x02\x01\0\x02\x01\0\x30\0|
|
||||
rarity 4
|
||||
ports 161
|
||||
ports 161,260,3401
|
||||
|
||||
match echo m|^\x30\x3a\x02\x01\x03\x30\x0f\x02\x02\x4a\x69\x02\x03\0\xff\xe3\x04\x01\x04\x02\x01\x03\x04\x10\x30\x0e\x04\0\x02\x01\0\x02\x01\0\x04\0\x04\0\x04\0\x30\x12\x04\0\x04\0\xa0\x0c\x02\x02\x37\xf0\x02\x01\0\x02\x01\0\x30\0$|
|
||||
# H.225 bandwidthReject
|
||||
@@ -16166,7 +16166,7 @@ match teamspeak2 m|^\xf4\xbe\x04\x00\x00\x00\x00\x00....\x02\x00\x00\x00....\0{6
|
||||
# UDP login request (encrypted)
|
||||
# http://seclists.org/nmap-dev/2013/q3/72
|
||||
Probe UDP TeamSpeak3 q|\x05\xca\x7f\x16\x9c\x11\xf9\x89\x00\x00\x00\x00\x02\x9d\x74\x8b\x45\xaa\x7b\xef\xb9\x9e\xfe\xad\x08\x19\xba\xcf\x41\xe0\x16\xa2\x32\x6c\xf3\xcf\xf4\x8e\x3c\x44\x83\xc8\x8d\x51\x45\x6f\x90\x95\x23\x3e\x00\x97\x2b\x1c\x71\xb2\x4e\xc0\x61\xf1\xd7\x6f\xc5\x7e\xf6\x48\x52\xbf\x82\x6a\xa2\x3b\x65\xaa\x18\x7a\x17\x38\xc3\x81\x27\xc3\x47\xfc\xa7\x35\xba\xfc\x0f\x9d\x9d\x72\x24\x9d\xfc\x02\x17\x6d\x6b\xb1\x2d\x72\xc6\xe3\x17\x1c\x95\xd9\x69\x99\x57\xce\xdd\xdf\x05\xdc\x03\x94\x56\x04\x3a\x14\xe5\xad\x9a\x2b\x14\x30\x3a\x23\xa3\x25\xad\xe8\xe6\x39\x8a\x85\x2a\xc6\xdf\xe5\x5d\x2d\xa0\x2f\x5d\x9c\xd7\x2b\x24\xfb\xb0\x9c\xc2\xba\x89\xb4\x1b\x17\xa2\xb6|
|
||||
rarity 9
|
||||
rarity 8
|
||||
ports 9987
|
||||
|
||||
# These are the bytes in common, but a lot of the bytes are close in value
|
||||
@@ -16394,7 +16394,7 @@ softmatch openvpn m|^\0\x1e@........\x02\0\0\0\0\0\0\0\x007\xa5&\x08\xa2\x1b\xa0
|
||||
# P_CONTROL_HARD_RESET_CLIENT_V2
|
||||
Probe UDP OpenVPN q|8d\xc1x\x01\xb8\x9b\xcb\x8f\0\0\0\0\0|
|
||||
ports 1194,443,500
|
||||
rarity 9
|
||||
rarity 8
|
||||
match openvpn m|^@........\x01\0\0\0\0d\xc1x\x01\xb8\x9b\xcb\x8f\0\0\0\0|s p/OpenVPN/
|
||||
# INVALID-MAJOR-VERSION
|
||||
softmatch isakmp m|^................\x0b\x10\x05\0\0\0\0\0\0\0\0\(\0\0\0\x0c\0\0\0\x01\x01\0\0\x05|
|
||||
@@ -16438,7 +16438,7 @@ match mqtt m|^\x20\x02\x00.$|
|
||||
##############################NEXT PROBE##############################
|
||||
# RMCP Get Channel Auth Capabilities
|
||||
Probe UDP ipmi-rmcp q|\x06\0\xff\x07\0\0\0\0\0\0\0\0\0\x09\x20\x18\xc8\x81\0\x38\x8e\x04\xb5|
|
||||
rarity 9
|
||||
rarity 8
|
||||
ports 623
|
||||
|
||||
softmatch asf-rmcp m|^\x06\0\xff\x07\0\0\0\0\0\0\0\0\0\x10|
|
||||
@@ -16456,7 +16456,7 @@ softmatch coap m|^`E|
|
||||
# DTLS Client Hello. Dissection available in nmap-payloads
|
||||
Probe UDP DTLSSessionReq q|\x16\xfe\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x36\x01\x00\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x2a\xfe\xfd\x00\x00\x00\x00\x7c\x77\x40\x1e\x8a\xc8\x22\xa0\xa0\x18\xff\x93\x08\xca\xac\x0a\x64\x2f\xc9\x22\x64\xbc\x08\xa8\x16\x89\x19\x30\x00\x00\x00\x02\x00\x2f\x01\x00|
|
||||
rarity 2
|
||||
ports 443,853,4433,4740,5349,5684,5868,6514,6636,8232,10161,10162,12346,12446,12546,12646,12746,12846,12946,13046
|
||||
ports 443,853,3391,4433,4740,5349,5684,5868,6514,6636,8232,10161,10162,12346,12446,12546,12646,12746,12846,12946,13046
|
||||
|
||||
# OpenSSL 1.1.0 s_server -dtls -listen
|
||||
# HelloVerifyRequest always uses DTLS 1.1 version, per RFC 6347
|
||||
@@ -16647,3 +16647,124 @@ ports 9761
|
||||
# 06 - ACK (15 is NACK)
|
||||
match insteon-plm m|^\x02\x60...(.).\x9b\x06$| p/Insteon SmartLinc PLM/ i/device type: $I(1,">")/
|
||||
match insteon-plm m|^\x02\x60...(.).[\x9c\x9d]\x06$| p/Insteon Hub PLM/ i/device type: $I(1,">")/
|
||||
|
||||
##############################NEXT PROBE##############################
|
||||
Probe UDP DHCP_INFORM q|\x01\x01\x06\0\x01\x23\x45\x67\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\x0e\x35\xd4\xd8\x51\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x63\x82\x53\x63\x35\x01\x08\xff|
|
||||
rarity 8
|
||||
ports 67
|
||||
|
||||
##############################NEXT PROBE##############################
|
||||
Probe UDP TFTP_GET q|\0\x01r7tftp.txt\0octet\0|
|
||||
rarity 8
|
||||
ports 69
|
||||
|
||||
Probe UDP ONCRPC_CALL q|\x3e\xec\xe3\xca\0\0\0\0\0\0\0\x02\0\xbc\x61\x4e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|
|
||||
rarity 8
|
||||
ports 111,2049,4045,32768-65535
|
||||
Probe UDP NTP_REQ q|\xd9\0\x0a\xfa\0\0\0\0\0\x01\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc6\xf1\x5e\xdb\x78\0\0\0|
|
||||
rarity 8
|
||||
ports 123
|
||||
Probe UDP DCERPC_CALL q|\x05\0\x0b\x03\x10\0\0\0\x48\0\0\0\x01\0\0\0\xb8\x10\xb8\x10\0\0\0\0\x01\0\0\0\0\0\x01\0\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef\xe7\x03\0\0\xfe\xdc\xba\x98\x76\x54\x32\x10\x01\x23\x45\x67\x89\xab\xcd\xef\xe7\x03\0\0|
|
||||
rarity 8
|
||||
ports 135,1025-1199
|
||||
Probe UDP CIFS_NS_UC q|\x01\x91\0\0\0\x01\0\0\0\0\0\0\x20CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\0\0\x21\0\x01|
|
||||
rarity 8
|
||||
ports 137
|
||||
Probe UDP CIFS_NS_BC q|\x01\x91\0\x10\0\x01\0\0\0\0\0\0\x20CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\0\0\x21\0\x01|
|
||||
rarity 8
|
||||
ports 137
|
||||
# Initiator cookie 0x0011223344556677, responder cookie 0x0000000000000000.
|
||||
# Version 1, Main Mode, flags 0x00, message ID 0x00000000, length 192.
|
||||
# Security Association payload, length 164, IPSEC, IDENTITY.
|
||||
# Proposal 1, length 152, ISAKMP, 4 transforms.
|
||||
# Transform 1, 3DES-CBC, SHA, PSK, group 2.
|
||||
# Transform 2, 3DES-CBC, MD5, PSK, group 2.
|
||||
# Transform 3, DES-CBC, SHA, PSK, group 2.
|
||||
# Transform 4, DES-CBC, MD5, PSK, group 2.
|
||||
Probe UDP IKE_MAIN_MODE q|\0\x11\x22\x33\x44\x55\x66\x77\0\0\0\0\0\0\0\0\x01\x10\x02\0\0\0\0\0\0\0\0\xC0\0\0\0\xA4\0\0\0\x01\0\0\0\x01\0\0\0\x98\x01\x01\0\x04\x03\0\0\x24\x01\x01\0\0\x80\x01\0\x05\x80\x02\0\x02\x80\x03\0\x01\x80\x04\0\x02\x80\x0B\0\x01\0\x0C\0\x04\0\0\0\x01\x03\0\0\x24\x02\x01\0\0\x80\x01\0\x05\x80\x02\0\x01\x80\x03\0\x01\x80\x04\0\x02\x80\x0B\0\x01\0\x0C\0\x04\0\0\0\x01\x03\0\0\x24\x03\x01\0\0\x80\x01\0\x01\x80\x02\0\x02\x80\x03\0\x01\x80\x04\0\x02\x80\x0B\0\x01\0\x0C\0\x04\0\0\0\x01\0\0\0\x24\x04\x01\0\0\x80\x01\0\x01\x80\x02\0\x01\x80\x03\0\x01\x80\x04\0\x02\x80\x0B\0\x01\0\x0C\0\x04\0\0\0\x01| source=500
|
||||
rarity 8
|
||||
ports 500
|
||||
Probe UDP IPSEC_START q|\x31\x27\xfc\xb0\x38\x10\x9e\x89\0\0\0\0\0\0\0\0\x01\x10\x02\0\0\0\0\0\0\0\0\xcc\x0d\0\0\x5c\0\0\0\x01\0\0\0\x01\0\0\0\x50\x01\x01\0\x02\x03\0\0\x24\x01\x01\0\0\x80\x01\0\x05\x80\x02\0\x02\x80\x04\0\x02\x80\x03\0\x03\x80\x0b\0\x01\0\x0c\0\x04\0\0\x0e\x10\0\0\0\x24\x02\x01\0\0\x80\x01\0\x05\x80\x02\0\x01\x80\x04\0\x02\x80\x03\0\x03\x80\x0b\0\x01\0\x0c\0\x04\0\0\x0e\x10\x0d\0\0\x18\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4\x61\0\0\0\x04\x0d\0\0\x14\x40\x48\xb7\xd5\x6e\xbc\xe8\x85\x25\xe7\xde\x7f\0\xd6\xc2\xd3\x0d\0\0\x14\x90\xcb\x80\x91\x3e\xbb\x69\x6e\x08\x63\x81\xb5\xec\x42\x7b\x1f\0\0\0\x14\x26\x24\x4d\x38\xed\xdb\x61\xb3\x17\x2a\x36\xe3\xd0\xcf\xb8\x19| source=500
|
||||
rarity 8
|
||||
ports 500
|
||||
Probe UDP RIPv1 q|\x01\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10|
|
||||
rarity 8
|
||||
ports 520
|
||||
Probe UDP RMCP_ASF_PING q|\x06\0\xff\x06\0\0\x11\xbe\x80\0\0\0|
|
||||
rarity 9
|
||||
ports 623
|
||||
Probe UDP OPENVPN_PKI q|\x38\x01\x02\x03\x04\x05\x06\x07\x08\0\0\0\0|
|
||||
rarity 9
|
||||
ports 1194
|
||||
Probe UDP RADIUS_ACCESS q|\x01\0\0\x14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|
|
||||
rarity 8
|
||||
ports 1645,1812
|
||||
Probe UDP L2TP_ICRQ q|\xc8\x02\0\x3c\0\0\0\0\0\0\0\0\x80\x08\0\0\0\0\0\x01\x80\x08\0\0\0\x02\x01\0\x80\x0e\0\0\0\x07nxp-scan\x80\x0a\0\0\0\x03\0\0\0\x03\x80\x08\0\0\0\x09\0\0|
|
||||
rarity 8
|
||||
ports 1701
|
||||
Probe UDP UPNP_MSEARCH q|M-SEARCH * HTTP/1.1\r\nHost: 239.255.255.250:1900\r\nMan: "ssdp:discover"\r\nMX: 5\r\nST: ssdp:all\r\n\r\n|
|
||||
rarity 8
|
||||
ports 1900
|
||||
Probe UDP NFSPROC_NULL q|\0\0\0\0\0\0\0\0\0\0\0\x02\0\x01\x86\xA3\0\0\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|
|
||||
rarity 8
|
||||
ports 2049
|
||||
Probe UDP GPRS_GTPv1 q|\x32\x01\0\x04\0\0\x42\0\x13\x37\0\0|
|
||||
rarity 9
|
||||
ports 2123,2152
|
||||
Probe UDP GPRS_GTPv2prime q|\x4e\x01\0\x04\xde\xfe\xc8\0|
|
||||
rarity 8
|
||||
ports 3386
|
||||
Probe UDP GPRS_GTPv2 q|\x4e\x01\0\x04\xde\xfe\xc8\0|
|
||||
rarity 8
|
||||
ports 2123,2152
|
||||
Probe UDP STUN_BIND q|\0\x01\0\0\x21\x12\xa4\x42\0\0\0\0\0\0\0\0\0\0\0\0|
|
||||
rarity 8
|
||||
ports 3478
|
||||
Probe UDP STD_DISCOVER q|[PROBE] 0000|
|
||||
rarity 8
|
||||
ports 6481
|
||||
Probe UDP NAT_PMP_ADDR q|\0\0|
|
||||
rarity 8
|
||||
ports 5351
|
||||
Probe UDP DNS_SD_QU q|\0\0\0\0\0\x01\0\0\0\0\0\0\x09_services\x07_dns-sd\x04_udp\x05local\0\0\x0c\x80\x01|
|
||||
rarity 8
|
||||
ports 5353
|
||||
Probe UDP PCANY_STATUS q|ST|
|
||||
rarity 8
|
||||
ports 5632
|
||||
Probe UDP UT2K_PING q|None\0|
|
||||
rarity 8
|
||||
ports 7777
|
||||
Probe UDP AMANDA_NOOP q|Amanda 2.6 REQ HANDLE 000-00000000 SEQ 0\nSERVICE noop\n|
|
||||
rarity 8
|
||||
ports 10080
|
||||
Probe UDP WDB_TARGET_PING q|\0\0\0\0\0\0\0\0\0\0\0\x02\x55\x55\x55\x55\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\x55\x13\0\0\0\x30\0\0\0\x01\0\0\0\x02\0\0\0\0\0\0\0\0|
|
||||
rarity 8
|
||||
ports 17185
|
||||
Probe UDP WDB_TARGET_CONNECT q|\x72\x37\x72\x37\0\0\0\0\0\0\0\x02\x55\x55\x55\x55\0\0\0\x01\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\x55\x10\0\0\0\x3c\0\0\0\x03\0\0\0\x02\0\0\0\0\0\0\0\0|
|
||||
rarity 9
|
||||
ports 17185
|
||||
Probe UDP KADEMLIA_PING q|\xE4\x60|
|
||||
rarity 8
|
||||
ports 4665,4666,4672,6429
|
||||
Probe UDP TS3INIT1 q|TS3INIT1\0\x65\0\0\x88\x0a\x39\x7b\x0f\0\x5b\x55\x72\xef\xdc\x78\x32\x6b\0\0\0\0\0\0\0\0|
|
||||
rarity 9
|
||||
ports 9987
|
||||
Probe UDP MEMCACHED_VERSION q|\0\x01\0\0\0\x01\0\0version\r\n|
|
||||
rarity 9
|
||||
ports 11211
|
||||
Probe UDP STEAM q|\xff\xff\xff\xffTSourceEngineQuery\0|
|
||||
rarity 8
|
||||
ports 27015-27030
|
||||
Probe UDP TRIN00_UNIX_PING q|png l44adsl|
|
||||
rarity 9
|
||||
ports 27444
|
||||
Probe UDP BO_PING q|\xce\x63\xd1\xd2\x16\xe7\x13\xcf\x38\xa5\xa5\x86\xb2\x75\x4b\x99\xaa\x32\x58|
|
||||
rarity 9
|
||||
ports 31337
|
||||
Probe UDP TRIN00_WIN_PING q|png []..Ks|
|
||||
rarity 9
|
||||
ports 34555
|
||||
Probe UDP BECKHOFF_ADS q|\x03\x66\x14\x71\0\0\0\0\x01\0\0\0\0\0\0\0\x01\x01\x10\x27\0\0\0\0|
|
||||
rarity 8
|
||||
ports 48899
|
||||
|
||||
1
nmap.cc
1
nmap.cc
@@ -1792,7 +1792,6 @@ void nmap_free_mem() {
|
||||
cp_free();
|
||||
free_services();
|
||||
freeinterfaces();
|
||||
free_payloads();
|
||||
AllProbes::service_scan_free();
|
||||
traceroute_hop_cache_clear();
|
||||
nsock_set_default_engine(NULL);
|
||||
|
||||
379
payload.cc
379
payload.cc
@@ -77,374 +77,83 @@
|
||||
#include "utils.h"
|
||||
#include "nmap_error.h"
|
||||
#include "scan_lists.h"
|
||||
#include "service_scan.h"
|
||||
|
||||
extern NmapOps o;
|
||||
|
||||
struct payload {
|
||||
std::string data;
|
||||
/* The key for the payload lookup map is u16 dport. We can make it a u32 and
|
||||
* add proto later if needed. */
|
||||
|
||||
payload (const char *c, size_t n)
|
||||
: data(c, n)
|
||||
{}
|
||||
/* Extra data such as source port goes here. */
|
||||
static std::map<u16, std::vector<ServiceProbe *> > portPayloads;
|
||||
|
||||
/* If 2 payloads are equivalent according to this operator, we'll only keep
|
||||
* the first one, so be sure you update it when adding other attributes. */
|
||||
bool operator==(const payload& other) const {
|
||||
return data == other.data;
|
||||
}
|
||||
};
|
||||
|
||||
/* The key for the payload lookup map is a (proto, port) pair. */
|
||||
struct proto_dport {
|
||||
u8 proto;
|
||||
u16 dport;
|
||||
|
||||
proto_dport(u8 proto, u16 dport) {
|
||||
this->proto = proto;
|
||||
this->dport = dport;
|
||||
}
|
||||
|
||||
bool operator<(const proto_dport& other) const {
|
||||
if (proto == other.proto)
|
||||
return dport < other.dport;
|
||||
else
|
||||
return proto < other.proto;
|
||||
}
|
||||
};
|
||||
|
||||
static std::map<struct proto_dport, std::vector<struct payload *> > portPayloads;
|
||||
static std::vector<struct payload *> uniquePayloads; // for accounting
|
||||
|
||||
/* Newlines are significant because keyword directives (like "source") that
|
||||
follow the payload string are significant to the end of the line. */
|
||||
typedef enum token_type {
|
||||
TOKEN_ERROR = -1,
|
||||
TOKEN_EOF = 0,
|
||||
TOKEN_NEWLINE,
|
||||
TOKEN_SYMBOL,
|
||||
TOKEN_STRING,
|
||||
} token_t;
|
||||
|
||||
struct token {
|
||||
token_t type;
|
||||
size_t len;
|
||||
char text[1024];
|
||||
};
|
||||
|
||||
static unsigned long line_no;
|
||||
|
||||
/* Get the next token from fp. The return value is the token type, or -1 on
|
||||
error. The token type is also stored in token->type. For TOKEN_SYMBOL and
|
||||
TOKEN_STRING, the text is stored in token->text and token->len. The text is
|
||||
null terminated. */
|
||||
static token_t next_token(FILE *fp, struct token *token) {
|
||||
unsigned int i, tmplen;
|
||||
int c;
|
||||
|
||||
token->len = 0;
|
||||
|
||||
/* Skip whitespace and comments. */
|
||||
while (isspace(c = fgetc(fp)) && c != '\n')
|
||||
;
|
||||
|
||||
switch(c) {
|
||||
case EOF:
|
||||
token->type = TOKEN_EOF;
|
||||
break;
|
||||
case '\n':
|
||||
line_no++;
|
||||
token->type = TOKEN_NEWLINE;
|
||||
break;
|
||||
case '#':
|
||||
while ((c = fgetc(fp)) != EOF && c != '\n')
|
||||
;
|
||||
if (c == EOF) {
|
||||
token->type = TOKEN_EOF;
|
||||
} else {
|
||||
line_no++;
|
||||
token->type = TOKEN_NEWLINE;
|
||||
}
|
||||
break;
|
||||
case '"':
|
||||
token->type = TOKEN_STRING;
|
||||
i = 0;
|
||||
while ((c = fgetc(fp)) != EOF && c != '\n' && c != '"') {
|
||||
if (i + 1 >= sizeof(token->text))
|
||||
return TOKEN_ERROR;
|
||||
if (c == '\\') {
|
||||
token->text[i++] = '\\';
|
||||
if (i + 1 >= sizeof(token->text))
|
||||
return TOKEN_ERROR;
|
||||
c = fgetc(fp);
|
||||
if (c == EOF)
|
||||
return TOKEN_ERROR;
|
||||
}
|
||||
token->text[i++] = c;
|
||||
}
|
||||
if (c != '"')
|
||||
return TOKEN_ERROR;
|
||||
token->text[i] = '\0';
|
||||
if (cstring_unescape(token->text, &tmplen) == NULL)
|
||||
return TOKEN_ERROR;
|
||||
token->len = tmplen;
|
||||
break;
|
||||
default:
|
||||
token->type = TOKEN_SYMBOL;
|
||||
i = 0;
|
||||
token->text[i++] = c;
|
||||
while ((c = fgetc(fp)) != EOF && (isalnum(c) || c == ',' || c == '-')) {
|
||||
if (i + 1 >= sizeof(token->text))
|
||||
return TOKEN_ERROR;
|
||||
token->text[i++] = c;
|
||||
}
|
||||
ungetc(c, fp);
|
||||
token->text[i] = '\0';
|
||||
token->len = i;
|
||||
break;
|
||||
}
|
||||
|
||||
return token->type;
|
||||
}
|
||||
|
||||
/* Loop over fp, reading tokens and adding payloads to the global payloads map
|
||||
as they are completed. Returns -1 on error. */
|
||||
static int load_payloads_from_file(FILE *fp) {
|
||||
struct token token;
|
||||
unsigned long firstline = 0;
|
||||
|
||||
line_no = 1;
|
||||
token_t type = next_token(fp, &token);
|
||||
for (;;) {
|
||||
unsigned short *ports;
|
||||
int count;
|
||||
bool duplicate = false;
|
||||
|
||||
/* Skip everything (unknown keywords from previous payload, unknown file
|
||||
* keywords, etc.) until the next payload entry or EOF */
|
||||
while (type != TOKEN_EOF && !(type == TOKEN_SYMBOL && strcmp(token.text, "udp") == 0))
|
||||
type = next_token(fp, &token);
|
||||
if (type == TOKEN_EOF)
|
||||
break;
|
||||
|
||||
firstline = line_no;
|
||||
|
||||
type = next_token(fp, &token);
|
||||
if (type != TOKEN_SYMBOL) {
|
||||
fprintf(stderr, "Expected a port list at line %lu of %s.\n", line_no, PAYLOAD_FILENAME);
|
||||
return -1;
|
||||
}
|
||||
getpts_simple(token.text, SCAN_UDP_PORT, &ports, &count);
|
||||
if (ports == NULL) {
|
||||
fprintf(stderr, "Can't parse port list \"%s\" at line %lu of %s.\n", token.text, line_no, PAYLOAD_FILENAME);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while(TOKEN_NEWLINE == (type = next_token(fp, &token)))
|
||||
; // skip newlines
|
||||
|
||||
if (type != TOKEN_STRING) {
|
||||
log_write(LOG_STDERR, "Payload missing data at line %lu of %s.\n", line_no, PAYLOAD_FILENAME);
|
||||
// Try a new payload
|
||||
free(ports);
|
||||
continue;
|
||||
}
|
||||
|
||||
struct payload *portPayload = NULL;
|
||||
// Peek at the next significant token
|
||||
struct token peek_token;
|
||||
while (TOKEN_NEWLINE == (type = next_token(fp, &peek_token)))
|
||||
; // skip newlines
|
||||
|
||||
// If it's a string continuation, see if we can squeeze it into the current token.
|
||||
while (type == TOKEN_STRING) {
|
||||
if (token.len + peek_token.len < sizeof(token.text)) {
|
||||
// Next string fits in this one's buffer!
|
||||
memcpy(token.text + token.len, peek_token.text, peek_token.len);
|
||||
token.len += peek_token.len;
|
||||
}
|
||||
else {
|
||||
// Token is full
|
||||
if (portPayload == NULL) {
|
||||
// Allocate new payload
|
||||
portPayload = new struct payload (token.text, token.len);
|
||||
}
|
||||
else {
|
||||
// append token to current payload
|
||||
portPayload->data.append(token.text, token.len);
|
||||
}
|
||||
// peek_token becomes the previous token
|
||||
token = peek_token;
|
||||
}
|
||||
// Keep peeking forward
|
||||
while (TOKEN_NEWLINE == (type = next_token(fp, &peek_token)))
|
||||
; // skip newlines
|
||||
}
|
||||
|
||||
// If the string is still going, but we got an error, abandon this payload.
|
||||
if (type == TOKEN_ERROR && peek_token.type == TOKEN_STRING) {
|
||||
log_write(LOG_STDERR, "Error parsing payload data at line %lu of %s.\n", line_no, PAYLOAD_FILENAME);
|
||||
if (portPayload)
|
||||
delete portPayload;
|
||||
// maybe we can pick up at the next payload.
|
||||
type = next_token(fp, &token);
|
||||
free(ports);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise, stash the last token in the payload and move on.
|
||||
if (portPayload == NULL) {
|
||||
// Allocate new payload
|
||||
portPayload = new struct payload (token.text, token.len);
|
||||
}
|
||||
else {
|
||||
// append token to current payload
|
||||
portPayload->data.append(token.text, token.len);
|
||||
}
|
||||
token = peek_token;
|
||||
|
||||
// Here we would parse additional keywords like "source" that we might care about.
|
||||
|
||||
// Make sure these payloads are actually unique!
|
||||
for (std::vector<struct payload *>::const_iterator it = uniquePayloads.begin();
|
||||
it != uniquePayloads.end(); ++it) {
|
||||
if (**it == *portPayload) {
|
||||
// Probably not what they intended.
|
||||
log_write(LOG_STDERR, "Duplicate payload on line %lu of %s.\n", firstline, PAYLOAD_FILENAME);
|
||||
// Since they're functionally equivalent, only keep one copy.
|
||||
duplicate = true;
|
||||
delete portPayload;
|
||||
portPayload = *it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!duplicate) {
|
||||
uniquePayloads.push_back(portPayload);
|
||||
duplicate = false;
|
||||
}
|
||||
|
||||
for (int p = 0; p < count; p++) {
|
||||
const struct proto_dport key(IPPROTO_UDP, ports[p]);
|
||||
|
||||
std::vector<struct payload *> &portPayloadVector = portPayloads[key];
|
||||
|
||||
// Ports are unique, and we ensured payloads are unique earlier, so no chance of duplicate here.
|
||||
portPayloadVector.push_back(portPayload);
|
||||
if (portPayloadVector.size() > MAX_PAYLOADS_PER_PORT) {
|
||||
fatal("Number of UDP payloads for port %u exceeds the limit of %u.\n", ports[p], MAX_PAYLOADS_PER_PORT);
|
||||
}
|
||||
}
|
||||
|
||||
free(ports);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ensure that the payloads map is initialized from the nmap-payloads file. This
|
||||
function keeps track of whether it has been called and does nothing after it
|
||||
is called the first time. */
|
||||
int init_payloads(void) {
|
||||
static bool payloads_loaded = false;
|
||||
char filename[256];
|
||||
FILE *fp;
|
||||
int ret;
|
||||
|
||||
if (payloads_loaded)
|
||||
return 0;
|
||||
|
||||
AllProbes *AP = AllProbes::service_scan_init();
|
||||
for (std::vector<ServiceProbe *>::const_iterator it = AP->probes.begin();
|
||||
it != AP->probes.end(); it++) {
|
||||
ServiceProbe *current_probe = *it;
|
||||
if (current_probe->getProbeProtocol() == IPPROTO_UDP && !current_probe->notForPayload) {
|
||||
for (std::vector<u16>::const_iterator pt = current_probe->probablePortsBegin();
|
||||
pt != current_probe->probablePortsEnd(); pt++) {
|
||||
std::vector<ServiceProbe *> &portPayloadVector = portPayloads[*pt];
|
||||
portPayloadVector.push_back(current_probe);
|
||||
if (portPayloadVector.size() > MAX_PAYLOADS_PER_PORT) {
|
||||
fatal("Number of UDP payloads for port %u exceeds the limit of %u.\n", *pt, MAX_PAYLOADS_PER_PORT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
payloads_loaded = true;
|
||||
|
||||
if (nmap_fetchfile(filename, sizeof(filename), PAYLOAD_FILENAME) != 1) {
|
||||
error("Cannot find %s. UDP payloads are disabled.", PAYLOAD_FILENAME);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fp = fopen(filename, "r");
|
||||
if (fp == NULL) {
|
||||
gh_perror("Can't open %s for reading.\n", filename);
|
||||
return -1;
|
||||
}
|
||||
/* Record where this data file was found. */
|
||||
o.loaded_data_files[PAYLOAD_FILENAME] = filename;
|
||||
|
||||
ret = load_payloads_from_file(fp);
|
||||
fclose(fp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void free_payloads(void) {
|
||||
std::vector<struct payload *>::iterator vec_it;
|
||||
|
||||
for (vec_it = uniquePayloads.begin(); vec_it != uniquePayloads.end(); ++vec_it) {
|
||||
delete *vec_it;
|
||||
}
|
||||
uniquePayloads.clear();
|
||||
portPayloads.clear();
|
||||
}
|
||||
|
||||
/* Get a payload appropriate for the given UDP port. For certain selected ports
|
||||
a payload is returned, and for others a zero-length payload is returned. The
|
||||
length is returned through the length pointer. */
|
||||
const char *udp_port2payload(u16 dport, size_t *length, u8 index) {
|
||||
static const char *payload_null = "";
|
||||
std::map<struct proto_dport, std::vector<struct payload *> >::const_iterator portPayloadIterator;
|
||||
std::vector<struct payload *>::const_iterator portPayloadVectorIterator;
|
||||
const proto_dport key(IPPROTO_UDP, dport);
|
||||
static const u8 *udp_port2payload(u16 dport, int *length, u8 index) {
|
||||
const u8 *payload = NULL;
|
||||
std::map<u16, std::vector<ServiceProbe *> >::const_iterator portPayloadIterator;
|
||||
int portPayloadVectorSize;
|
||||
|
||||
portPayloadIterator = portPayloads.find(key);
|
||||
*length = 0;
|
||||
portPayloadIterator = portPayloads.find(dport);
|
||||
|
||||
if (portPayloadIterator != portPayloads.end()) {
|
||||
const std::vector<struct payload *>& portPayloadVector = portPayloads.find(key)->second;
|
||||
const std::vector<ServiceProbe *>& portPayloadVector = portPayloadIterator->second;
|
||||
portPayloadVectorSize = portPayloadVector.size();
|
||||
assert(portPayloadVectorSize > 0);
|
||||
|
||||
index %= portPayloadVectorSize;
|
||||
const ServiceProbe *SP = portPayloadVector[index % portPayloadVectorSize];
|
||||
payload = SP->getProbeString(length);
|
||||
|
||||
if (portPayloadVectorSize > 0) {
|
||||
portPayloadVectorIterator = portPayloadVector.begin();
|
||||
|
||||
while (index > 0 && portPayloadVectorIterator != portPayloadVector.end()) {
|
||||
index--;
|
||||
portPayloadVectorIterator++;
|
||||
}
|
||||
|
||||
assert (index == 0);
|
||||
assert (portPayloadVectorIterator != portPayloadVector.end());
|
||||
|
||||
const std::string &data = (*portPayloadVectorIterator)->data;
|
||||
*length = data.size();
|
||||
return data.data();
|
||||
} else {
|
||||
*length = 0;
|
||||
return payload_null;
|
||||
}
|
||||
} else {
|
||||
*length = 0;
|
||||
return payload_null;
|
||||
}
|
||||
return payload;
|
||||
}
|
||||
|
||||
/* Get a payload appropriate for the given UDP port. If --data-length was used,
|
||||
returns the global random payload. Otherwise, for certain selected ports a
|
||||
payload is returned, and for others a zero-length payload is returned. The
|
||||
length is returned through the length pointer. */
|
||||
const char *get_udp_payload(u16 dport, size_t *length, u8 index) {
|
||||
const u8 *get_udp_payload(u16 dport, int *length, u8 index) {
|
||||
if (o.extra_payload != NULL) {
|
||||
*length = o.extra_payload_length;
|
||||
return o.extra_payload;
|
||||
return (u8 *) o.extra_payload;
|
||||
} else {
|
||||
return udp_port2payload(dport, length, index);
|
||||
}
|
||||
}
|
||||
|
||||
u8 udp_payload_count(u16 dport) {
|
||||
std::map<struct proto_dport, std::vector<struct payload *> >::const_iterator portPayloadIterator;
|
||||
const proto_dport key(IPPROTO_UDP, dport);
|
||||
std::map<u16, std::vector<ServiceProbe *> >::const_iterator portPayloadIterator;
|
||||
size_t portPayloadVectorSize = 0;
|
||||
|
||||
portPayloadIterator = portPayloads.find(key);
|
||||
portPayloadIterator = portPayloads.find(dport);
|
||||
|
||||
if (portPayloadIterator != portPayloads.end()) {
|
||||
portPayloadVectorSize = portPayloadIterator->second.size();
|
||||
@@ -452,3 +161,25 @@ u8 udp_payload_count(u16 dport) {
|
||||
|
||||
return portPayloadVectorSize;
|
||||
}
|
||||
|
||||
const struct MatchDetails *payload_service_match(u16 dport, const u8 *buf, int buflen) {
|
||||
std::map<u16, std::vector<ServiceProbe *> >::const_iterator portPayloadIterator;
|
||||
|
||||
portPayloadIterator = portPayloads.find(dport);
|
||||
if (portPayloadIterator != portPayloads.end()) {
|
||||
const std::vector<ServiceProbe *>& portPayloadVector = portPayloadIterator->second;
|
||||
// We don't know which payload triggered this, since we send all at once
|
||||
// with the same source port.
|
||||
for (std::vector<ServiceProbe *>::const_iterator sp = portPayloadVector.begin();
|
||||
sp != portPayloadVector.end(); sp++) {
|
||||
ServiceProbe *probe = *sp;
|
||||
const struct MatchDetails *MD = NULL;
|
||||
for (int fb = 0; probe->fallbacks[fb] != NULL; fb++) {
|
||||
MD = probe->fallbacks[fb]->testMatch(buf, buflen, 0);
|
||||
if (MD)
|
||||
return MD;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -64,14 +64,16 @@
|
||||
#ifndef PAYLOAD_H
|
||||
#define PAYLOAD_H
|
||||
|
||||
#include "service_scan.h"
|
||||
#define PAYLOAD_FILENAME "nmap-payloads"
|
||||
|
||||
// Semi-arbitrary limit, but we use u8 for indexing/retrieval
|
||||
// and we send all payloads at once and need to not overwhelm.
|
||||
#define MAX_PAYLOADS_PER_PORT 0xff
|
||||
|
||||
const char *get_udp_payload(u16 dport, size_t *length, u8 index);
|
||||
const u8 *get_udp_payload(u16 dport, int *length, u8 index);
|
||||
u8 udp_payload_count(u16 dport);
|
||||
const struct MatchDetails *payload_service_match(u16 dport, const u8 *buf, int buflen);
|
||||
int init_payloads(void);
|
||||
void free_payloads(void);
|
||||
|
||||
|
||||
@@ -1292,8 +1292,8 @@ UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss,
|
||||
}
|
||||
}
|
||||
} else if (pspec->type == PS_UDP) {
|
||||
const char *payload;
|
||||
size_t payload_length;
|
||||
const u8 *payload;
|
||||
int payload_length;
|
||||
u8 numpayloads = udp_payload_count(pspec->pd.udp.dport);
|
||||
// Even if no payloads, we can send with null payload
|
||||
numpayloads = MAX(numpayloads, 1);
|
||||
@@ -2166,6 +2166,14 @@ bool get_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
|
||||
newstate = PORT_OPEN;
|
||||
current_reason = ER_UDPRESPONSE;
|
||||
goodone = true;
|
||||
/* Store the data response in case service_scan wants it later */
|
||||
if (datalen > UDP_HDR_LEN) {
|
||||
struct EarlySvcResponse *esr = (EarlySvcResponse *) safe_zalloc(sizeof(struct EarlySvcResponse) + datalen - UDP_HDR_LEN);
|
||||
esr->pspec = *(probe->pspec());
|
||||
esr->len = datalen - UDP_HDR_LEN;
|
||||
memcpy(esr->data, (u8 *)data + UDP_HDR_LEN, esr->len);
|
||||
hss->target->earlySvcResponses.push_back(esr);
|
||||
}
|
||||
}
|
||||
} else continue; /* Unexpected protocol */
|
||||
} while (!goodone && !timedout);
|
||||
|
||||
262
service_scan.cc
262
service_scan.cc
@@ -71,6 +71,7 @@
|
||||
#include "Target.h"
|
||||
#include "utils.h"
|
||||
#include "nmap_error.h"
|
||||
#include "payload.h"
|
||||
#include "protocols.h"
|
||||
#include "scan_lists.h"
|
||||
#include "charpool.h"
|
||||
@@ -239,7 +240,10 @@ struct substargs {
|
||||
static void servicescan_read_handler(nsock_pool nsp, nsock_event nse, void *mydata);
|
||||
static void servicescan_write_handler(nsock_pool nsp, nsock_event nse, void *mydata);
|
||||
static void servicescan_connect_handler(nsock_pool nsp, nsock_event nse, void *mydata);
|
||||
static void end_svcprobe(nsock_pool nsp, enum serviceprobestate probe_state, ServiceGroup *SG, ServiceNFO *svc, nsock_iod nsi);
|
||||
static void end_svcprobe(enum serviceprobestate probe_state, ServiceGroup *SG, ServiceNFO *svc, nsock_iod nsi);
|
||||
static int scanThroughTunnel(ServiceNFO *svc);
|
||||
static bool processMatch(const struct MatchDetails *MD, ServiceNFO *svc,
|
||||
const char *probeName, const char *fallbackName);
|
||||
|
||||
ServiceProbeMatch::ServiceProbeMatch() {
|
||||
deflineno = -1;
|
||||
@@ -1076,6 +1080,7 @@ ServiceProbe::ServiceProbe() {
|
||||
// The default rarity level for a probe without a rarity
|
||||
// directive - should almost never have to be relied upon.
|
||||
rarity = 5;
|
||||
notForPayload = false;
|
||||
fallbackStr = NULL;
|
||||
for (i=0; i<MAXFALLBACKS+1; i++) fallbacks[i] = NULL;
|
||||
}
|
||||
@@ -1130,6 +1135,16 @@ void ServiceProbe::setProbeDetails(char *pd, int lineno) {
|
||||
fatal("Parse error on line %d of nmap-service-probes: bad probe string escaping", lineno);
|
||||
}
|
||||
setProbeString((const u8 *)pd, len);
|
||||
// Optional extensible flags
|
||||
pd = p+1;
|
||||
while (*pd != '\0' && *pd != '\n') {
|
||||
while(*pd && isspace((int) (unsigned char) *pd)) pd++;
|
||||
if (0 == strncmp(pd, "no-payload", 10)) {
|
||||
notForPayload = true;
|
||||
break; // Remove this if we handle more than 1 flag in the future
|
||||
}
|
||||
while (*pd && !isspace((int) (unsigned char) *pd)) pd++;
|
||||
}
|
||||
}
|
||||
|
||||
void ServiceProbe::setProbeString(const u8 *ps, int stringlen) {
|
||||
@@ -1913,39 +1928,58 @@ ServiceGroup::ServiceGroup(std::vector<Target *> &Targets, AllProbes *AP) {
|
||||
num_hosts_timedout = 0;
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
SPM = new ScanProgressMeter("Service scan");
|
||||
for(targetno = 0 ; targetno < Targets.size(); targetno++) {
|
||||
Target *target = Targets[targetno];
|
||||
assert(target);
|
||||
nxtport = NULL;
|
||||
if (Targets[targetno]->timedOut(&now)) {
|
||||
if (target->timedOut(&now)) {
|
||||
num_hosts_timedout++;
|
||||
continue;
|
||||
}
|
||||
while((nxtport = Targets[targetno]->ports.nextPort(nxtport, &port, TCPANDUDPANDSCTP, PORT_OPEN))) {
|
||||
while((nxtport = target->ports.nextPort(nxtport, &port, TCPANDUDPANDSCTP, PORT_OPEN))) {
|
||||
svc = new ServiceNFO(AP);
|
||||
svc->target = Targets[targetno];
|
||||
svc->target = target;
|
||||
svc->portno = nxtport->portno;
|
||||
svc->proto = nxtport->proto;
|
||||
services_remaining.push_back(svc);
|
||||
}
|
||||
}
|
||||
|
||||
/* Use a whole new loop for PORT_OPENFILTERED so that we try all the
|
||||
known open ports first before bothering with this speculative
|
||||
stuff */
|
||||
for(targetno = 0 ; targetno < Targets.size(); targetno++) {
|
||||
nxtport = NULL;
|
||||
if (Targets[targetno]->timedOut(&now)) {
|
||||
continue;
|
||||
}
|
||||
while((nxtport = Targets[targetno]->ports.nextPort(nxtport, &port, TCPANDUDPANDSCTP, PORT_OPENFILTERED))) {
|
||||
while((nxtport = target->ports.nextPort(nxtport, &port, TCPANDUDPANDSCTP, PORT_OPENFILTERED))) {
|
||||
svc = new ServiceNFO(AP);
|
||||
svc->target = Targets[targetno];
|
||||
svc->target = target;
|
||||
svc->portno = nxtport->portno;
|
||||
svc->proto = nxtport->proto;
|
||||
services_remaining.push_back(svc);
|
||||
}
|
||||
|
||||
/* Check if any early responses can help */
|
||||
for (std::vector<EarlySvcResponse *>::iterator it = target->earlySvcResponses.begin();
|
||||
it != target->earlySvcResponses.end(); it++) {
|
||||
EarlySvcResponse *esr = *it;
|
||||
assert(esr);
|
||||
const struct MatchDetails *MD = payload_service_match(esr->pspec.pd.udp.dport,
|
||||
esr->data, esr->len);
|
||||
if (MD) {
|
||||
// Find the appropriate ServiceNFO and process it.
|
||||
for (std::list<ServiceNFO *>::iterator i = services_remaining.begin();
|
||||
i != services_remaining.end(); i++) {
|
||||
svc = *i;
|
||||
if (svc->proto == IPPROTO_UDP && svc->portno == esr->pspec.pd.udp.dport) {
|
||||
if (processMatch(MD, svc, "port scan", "udp payload")
|
||||
&& !scanThroughTunnel(svc)) {
|
||||
end_svcprobe(PROBESTATE_FINISHED_HARDMATCHED, this, svc, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SPM = new ScanProgressMeter("Service scan");
|
||||
desired_par = 1;
|
||||
if (o.timing_level == 3) desired_par = 20;
|
||||
if (o.timing_level == 4) desired_par = 30;
|
||||
@@ -2046,16 +2080,17 @@ static void startNextProbe(nsock_pool nsp, nsock_iod nsi, ServiceGroup *SG,
|
||||
} else {
|
||||
// Should only happen if someone has a highly perverse nmap-service-probes
|
||||
// file. Null scan should generally never be the only probe.
|
||||
end_svcprobe(nsp, (svc->softMatchFound)? PROBESTATE_FINISHED_SOFTMATCHED : PROBESTATE_FINISHED_NOMATCH, SG, svc, NULL);
|
||||
end_svcprobe((svc->softMatchFound)? PROBESTATE_FINISHED_SOFTMATCHED : PROBESTATE_FINISHED_NOMATCH, SG, svc, NULL);
|
||||
}
|
||||
} else {
|
||||
// The finished probe was not a NULL probe. So we close the
|
||||
// connection, and if further probes are available, we launch the
|
||||
// next one.
|
||||
if (nsi)
|
||||
nsock_iod_delete(nsi, NSOCK_PENDING_SILENT);
|
||||
if (!isInitial)
|
||||
probe = svc->nextProbe(true); // if was initial, currentProbe() returned the right one to execute.
|
||||
if (probe) {
|
||||
nsock_iod_delete(nsi, NSOCK_PENDING_SILENT);
|
||||
if ((svc->niod = nsock_iod_new(nsp, svc)) == NULL) {
|
||||
fatal("Failed to allocate Nsock I/O descriptor in %s()", __func__);
|
||||
}
|
||||
@@ -2092,8 +2127,7 @@ static void startNextProbe(nsock_pool nsp, nsock_iod nsi, ServiceGroup *SG,
|
||||
}
|
||||
} else {
|
||||
// No more probes remaining! Failed to match
|
||||
nsock_iod_delete(nsi, NSOCK_PENDING_SILENT);
|
||||
end_svcprobe(nsp, (svc->softMatchFound)? PROBESTATE_FINISHED_SOFTMATCHED :
|
||||
end_svcprobe((svc->softMatchFound)? PROBESTATE_FINISHED_SOFTMATCHED :
|
||||
PROBESTATE_FINISHED_NOMATCH,
|
||||
SG, svc, NULL);
|
||||
}
|
||||
@@ -2115,8 +2149,7 @@ static void startNextProbe(nsock_pool nsp, nsock_iod nsi, ServiceGroup *SG,
|
||||
That is a special case.
|
||||
*/
|
||||
|
||||
static int scanThroughTunnel(nsock_pool nsp, nsock_iod nsi, ServiceGroup *SG,
|
||||
ServiceNFO *svc) {
|
||||
static int scanThroughTunnel(ServiceNFO *svc) {
|
||||
|
||||
if (svc->probe_matched && strncmp(svc->probe_matched, "ssl/", 4) == 0) {
|
||||
/* The service has been detected without having to make an SSL connection */
|
||||
@@ -2145,7 +2178,6 @@ static int scanThroughTunnel(nsock_pool nsp, nsock_iod nsi, ServiceGroup *SG,
|
||||
svc->cpe_a_matched[0] = svc->cpe_h_matched[0] = svc->cpe_o_matched[0] = '\0';
|
||||
svc->softMatchFound = false;
|
||||
svc->resetProbes(true);
|
||||
startNextProbe(nsp, nsi, SG, svc, true);
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
@@ -2153,7 +2185,7 @@ static int scanThroughTunnel(nsock_pool nsp, nsock_iod nsi, ServiceGroup *SG,
|
||||
}
|
||||
|
||||
/* Prints completion estimates and the like when appropriate */
|
||||
static void considerPrintingStats(nsock_pool nsp, ServiceGroup *SG) {
|
||||
static void considerPrintingStats(ServiceGroup *SG) {
|
||||
/* Check for status requests */
|
||||
if (keyWasPressed()) {
|
||||
nmap_adjust_loglevel(o.versionTrace());
|
||||
@@ -2193,7 +2225,8 @@ static void handleHostIfDone(ServiceGroup *SG, Target *target) {
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
target->stopTimeOutClock(nsock_gettimeofday());
|
||||
if (target->timeOutClockRunning())
|
||||
target->stopTimeOutClock(nsock_gettimeofday());
|
||||
if (target->timedOut(NULL)) {
|
||||
SG->num_hosts_timedout++;
|
||||
}
|
||||
@@ -2203,7 +2236,7 @@ static void handleHostIfDone(ServiceGroup *SG, Target *target) {
|
||||
// A simple helper function to cancel further work on a service and
|
||||
// set it to the given probe_state pass NULL for nsi if you don't want
|
||||
// it to be deleted (for example, if you already have done so).
|
||||
static void end_svcprobe(nsock_pool nsp, enum serviceprobestate probe_state, ServiceGroup *SG, ServiceNFO *svc, nsock_iod nsi) {
|
||||
static void end_svcprobe(enum serviceprobestate probe_state, ServiceGroup *SG, ServiceNFO *svc, nsock_iod nsi) {
|
||||
std::list<ServiceNFO *>::iterator member;
|
||||
Target *target = svc->target;
|
||||
|
||||
@@ -2225,7 +2258,7 @@ static void end_svcprobe(nsock_pool nsp, enum serviceprobestate probe_state, Ser
|
||||
|
||||
SG->services_finished.push_back(svc);
|
||||
|
||||
considerPrintingStats(nsp, SG);
|
||||
considerPrintingStats(SG);
|
||||
|
||||
if (nsi)
|
||||
nsock_iod_delete(nsi, NSOCK_PENDING_SILENT);
|
||||
@@ -2239,9 +2272,6 @@ static void end_svcprobe(nsock_pool nsp, enum serviceprobestate probe_state, Ser
|
||||
// appropriate ones and then starts them up.
|
||||
static int launchSomeServiceProbes(nsock_pool nsp, ServiceGroup *SG) {
|
||||
ServiceNFO *svc;
|
||||
ServiceProbe *nextprobe;
|
||||
struct sockaddr_storage ss;
|
||||
size_t ss_len;
|
||||
static int warn_no_scanning=1;
|
||||
|
||||
while (SG->services_in_progress.size() < SG->ideal_parallelism &&
|
||||
@@ -2249,48 +2279,24 @@ static int launchSomeServiceProbes(nsock_pool nsp, ServiceGroup *SG) {
|
||||
// Start executing a probe from the new list and move it to in_progress
|
||||
svc = SG->services_remaining.front();
|
||||
if (svc->target->timedOut(nsock_gettimeofday())) {
|
||||
end_svcprobe(nsp, PROBESTATE_INCOMPLETE, SG, svc, NULL);
|
||||
end_svcprobe(PROBESTATE_INCOMPLETE, SG, svc, NULL);
|
||||
continue;
|
||||
}
|
||||
else if (!svc->target->timeOutClockRunning()) {
|
||||
svc->target->startTimeOutClock(nsock_gettimeofday());
|
||||
}
|
||||
nextprobe = svc->nextProbe(true);
|
||||
|
||||
if (nextprobe == NULL) {
|
||||
// Launch it! If there were no probes, we'll get a NOMATCH immediately.
|
||||
startNextProbe(nsp, NULL, SG, svc, true);
|
||||
|
||||
if (svc->probe_state == PROBESTATE_FINISHED_NOMATCH) {
|
||||
if (warn_no_scanning && o.debugging) {
|
||||
log_write(LOG_PLAIN, "Service scan: Not probing some ports due to low intensity\n");
|
||||
warn_no_scanning=0;
|
||||
}
|
||||
end_svcprobe(nsp, PROBESTATE_FINISHED_NOMATCH, SG, svc, NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
// We start by requesting a connection to the target
|
||||
if ((svc->niod = nsock_iod_new(nsp, svc)) == NULL) {
|
||||
fatal("Failed to allocate Nsock I/O descriptor in %s()", __func__);
|
||||
}
|
||||
if (o.debugging > 1) {
|
||||
log_write(LOG_PLAIN, "Starting probes against new service: %s:%hu (%s)\n", svc->target->targetipstr(), svc->portno, proto2ascii_lowercase(svc->proto));
|
||||
}
|
||||
if (o.spoofsource) {
|
||||
o.SourceSockAddr(&ss, &ss_len);
|
||||
nsock_iod_set_localaddr(svc->niod, &ss, ss_len);
|
||||
}
|
||||
if (o.ipoptionslen)
|
||||
nsock_iod_set_ipoptions(svc->niod, o.ipoptions, o.ipoptionslen);
|
||||
svc->target->TargetSockAddr(&ss, &ss_len);
|
||||
if (svc->proto == IPPROTO_TCP)
|
||||
nsock_connect_tcp(nsp, svc->niod, servicescan_connect_handler,
|
||||
DEFAULT_CONNECT_TIMEOUT, svc,
|
||||
(struct sockaddr *)&ss, ss_len,
|
||||
svc->portno);
|
||||
else {
|
||||
assert(svc->proto == IPPROTO_UDP);
|
||||
nsock_connect_udp(nsp, svc->niod, servicescan_connect_handler,
|
||||
svc, (struct sockaddr *) &ss, ss_len,
|
||||
svc->portno);
|
||||
}
|
||||
// Check that the service is still where we left it.
|
||||
// servicescan_connect_handler can call end_svcprobe before this point,
|
||||
// putting it into services_finished already.
|
||||
@@ -2316,7 +2322,7 @@ static void servicescan_connect_handler(nsock_pool nsp, nsock_event nse, void *m
|
||||
assert(type == NSE_TYPE_CONNECT || type == NSE_TYPE_CONNECT_SSL);
|
||||
|
||||
if (svc->target->timedOut(nsock_gettimeofday())) {
|
||||
end_svcprobe(nsp, PROBESTATE_INCOMPLETE, SG, svc, nsi);
|
||||
end_svcprobe(PROBESTATE_INCOMPLETE, SG, svc, nsi);
|
||||
} else if (status == NSE_STATUS_SUCCESS) {
|
||||
|
||||
#if HAVE_OPENSSL
|
||||
@@ -2355,13 +2361,13 @@ static void servicescan_connect_handler(nsock_pool nsp, nsock_event nse, void *m
|
||||
// and move it to the finished bin.
|
||||
if (o.debugging)
|
||||
error("Got nsock CONNECT response with status %s - aborting this service", nse_status2str(status));
|
||||
end_svcprobe(nsp, PROBESTATE_INCOMPLETE, SG, svc, nsi);
|
||||
end_svcprobe(PROBESTATE_INCOMPLETE, SG, svc, nsi);
|
||||
break;
|
||||
|
||||
case NSE_STATUS_KILL:
|
||||
/* User probably specified host_timeout and so the service scan is
|
||||
* shutting down */
|
||||
end_svcprobe(nsp, PROBESTATE_INCOMPLETE, SG, svc, nsi);
|
||||
end_svcprobe(PROBESTATE_INCOMPLETE, SG, svc, nsi);
|
||||
return;
|
||||
|
||||
default:
|
||||
@@ -2392,7 +2398,7 @@ static void servicescan_write_handler(nsock_pool nsp, nsock_event nse, void *myd
|
||||
|
||||
|
||||
if (svc->target->timedOut(nsock_gettimeofday())) {
|
||||
end_svcprobe(nsp, PROBESTATE_INCOMPLETE, SG, svc, nsi);
|
||||
end_svcprobe(PROBESTATE_INCOMPLETE, SG, svc, nsi);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2402,7 +2408,7 @@ static void servicescan_write_handler(nsock_pool nsp, nsock_event nse, void *myd
|
||||
if (status == NSE_STATUS_KILL) {
|
||||
/* User probably specified host_timeout and so the service scan is
|
||||
shutting down */
|
||||
end_svcprobe(nsp, PROBESTATE_INCOMPLETE, SG, svc, nsi);
|
||||
end_svcprobe(PROBESTATE_INCOMPLETE, SG, svc, nsi);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2415,7 +2421,7 @@ static void servicescan_write_handler(nsock_pool nsp, nsock_event nse, void *myd
|
||||
// on us unexpectedly?
|
||||
if (o.debugging)
|
||||
error("Got nsock WRITE response with status %s - aborting this service", nse_status2str(status));
|
||||
end_svcprobe(nsp, PROBESTATE_INCOMPLETE, SG, svc, nsi);
|
||||
end_svcprobe(PROBESTATE_INCOMPLETE, SG, svc, nsi);
|
||||
|
||||
// We may have room for more probes!
|
||||
launchSomeServiceProbes(nsp, SG);
|
||||
@@ -2423,6 +2429,54 @@ static void servicescan_write_handler(nsock_pool nsp, nsock_event nse, void *myd
|
||||
return;
|
||||
}
|
||||
|
||||
/* Returns true if this is a new hard match, false if not a match or if a softmatch */
|
||||
static bool processMatch(const struct MatchDetails *MD, ServiceNFO *svc,
|
||||
const char *probeName, const char *fallbackName) {
|
||||
if (!MD || !MD->serviceName) {
|
||||
return false;
|
||||
}
|
||||
// WOO HOO!!!!!! MATCHED! But might be soft
|
||||
if (MD->isSoft && svc->probe_matched) {
|
||||
if (strcmp(svc->probe_matched, MD->serviceName) != 0)
|
||||
error("WARNING: Service %s:%hu had already soft-matched %s, but now soft-matched %s; ignoring second value", svc->target->targetipstr(), svc->portno, svc->probe_matched, MD->serviceName);
|
||||
// No error if its the same - that happens frequently. For
|
||||
// example, if we read more data for the same probe response
|
||||
// it will probably still match.
|
||||
return false;
|
||||
}
|
||||
if (o.debugging > 1 || o.versionTrace()) {
|
||||
log_write(LOG_PLAIN, "Service scan %s match (Probe %s matched with %s line %d): %s:%hu is %s%s. Version: |%s|%s|%s|\n",
|
||||
(MD->isSoft)? "soft" : "hard",
|
||||
probeName, fallbackName,
|
||||
MD->lineno,
|
||||
svc->target->targetipstr(), svc->portno, (svc->tunnel == SERVICE_TUNNEL_SSL)? "SSL/" : "",
|
||||
MD->serviceName, (MD->product)? MD->product : "", (MD->version)? MD->version : "",
|
||||
(MD->info)? MD->info : "");
|
||||
}
|
||||
svc->probe_matched = MD->serviceName;
|
||||
svc->tcpwrap_possible = false;
|
||||
if (MD->product)
|
||||
Strncpy(svc->product_matched, MD->product, sizeof(svc->product_matched));
|
||||
if (MD->version)
|
||||
Strncpy(svc->version_matched, MD->version, sizeof(svc->version_matched));
|
||||
if (MD->info)
|
||||
Strncpy(svc->extrainfo_matched, MD->info, sizeof(svc->extrainfo_matched));
|
||||
if (MD->hostname)
|
||||
Strncpy(svc->hostname_matched, MD->hostname, sizeof(svc->hostname_matched));
|
||||
if (MD->ostype)
|
||||
Strncpy(svc->ostype_matched, MD->ostype, sizeof(svc->ostype_matched));
|
||||
if (MD->devicetype)
|
||||
Strncpy(svc->devicetype_matched, MD->devicetype, sizeof(svc->devicetype_matched));
|
||||
if (MD->cpe_a)
|
||||
Strncpy(svc->cpe_a_matched, MD->cpe_a, sizeof(svc->cpe_a_matched));
|
||||
if (MD->cpe_h)
|
||||
Strncpy(svc->cpe_h_matched, MD->cpe_h, sizeof(svc->cpe_h_matched));
|
||||
if (MD->cpe_o)
|
||||
Strncpy(svc->cpe_o_matched, MD->cpe_o, sizeof(svc->cpe_o_matched));
|
||||
svc->softMatchFound = MD->isSoft;
|
||||
return !MD->isSoft;
|
||||
}
|
||||
|
||||
static void servicescan_read_handler(nsock_pool nsp, nsock_event nse, void *mydata) {
|
||||
nsock_iod nsi = nse_iod(nse);
|
||||
enum nse_status status = nse_status(nse);
|
||||
@@ -2432,14 +2486,12 @@ static void servicescan_read_handler(nsock_pool nsp, nsock_event nse, void *myda
|
||||
ServiceGroup *SG = (ServiceGroup *) nsock_pool_get_udata(nsp);
|
||||
const u8 *readstr;
|
||||
int readstrlen;
|
||||
const struct MatchDetails *MD;
|
||||
int fallbackDepth=0;
|
||||
|
||||
assert(type == NSE_TYPE_READ);
|
||||
|
||||
if (svc->target->timedOut(nsock_gettimeofday())) {
|
||||
svc->tcpwrap_possible = false;
|
||||
end_svcprobe(nsp, PROBESTATE_INCOMPLETE, SG, svc, nsi);
|
||||
end_svcprobe(PROBESTATE_INCOMPLETE, SG, svc, nsi);
|
||||
} else if (status == NSE_STATUS_SUCCESS) {
|
||||
// w00p, w00p, we read something back from the port.
|
||||
svc->tcpwrap_possible = false;
|
||||
@@ -2449,65 +2501,28 @@ static void servicescan_read_handler(nsock_pool nsp, nsock_event nse, void *myda
|
||||
// now get the full version
|
||||
readstr = svc->getcurrentproberesponse(&readstrlen);
|
||||
|
||||
for (MD = NULL; probe->fallbacks[fallbackDepth] != NULL; fallbackDepth++) {
|
||||
MD = (probe->fallbacks[fallbackDepth])->testMatch(readstr, readstrlen);
|
||||
const struct MatchDetails *MD = NULL;
|
||||
ServiceProbe *fallback = NULL;
|
||||
for (int fallbackDepth=0; fallbackDepth < MAXFALLBACKS + 1; fallbackDepth++) {
|
||||
fallback = probe->fallbacks[fallbackDepth];
|
||||
if (fallback == NULL)
|
||||
break;
|
||||
MD = fallback->testMatch(readstr, readstrlen);
|
||||
if (MD && MD->serviceName) break; // Found one!
|
||||
}
|
||||
|
||||
if (MD && MD->serviceName) {
|
||||
// WOO HOO!!!!!! MATCHED! But might be soft
|
||||
if (MD->isSoft && svc->probe_matched) {
|
||||
if (strcmp(svc->probe_matched, MD->serviceName) != 0)
|
||||
error("WARNING: Service %s:%hu had already soft-matched %s, but now soft-matched %s; ignoring second value", svc->target->targetipstr(), svc->portno, svc->probe_matched, MD->serviceName);
|
||||
// No error if its the same - that happens frequently. For
|
||||
// example, if we read more data for the same probe response
|
||||
// it will probably still match.
|
||||
} else {
|
||||
if (o.debugging > 1 || o.versionTrace()) {
|
||||
if (MD->product || MD->version || MD->info)
|
||||
log_write(LOG_PLAIN, "Service scan match (Probe %s matched with %s line %d): %s:%hu is %s%s. Version: |%s|%s|%s|\n",
|
||||
probe->getName(), (*probe->fallbacks[fallbackDepth]).getName(),
|
||||
MD->lineno,
|
||||
svc->target->targetipstr(), svc->portno, (svc->tunnel == SERVICE_TUNNEL_SSL)? "SSL/" : "",
|
||||
MD->serviceName, (MD->product)? MD->product : "", (MD->version)? MD->version : "",
|
||||
(MD->info)? MD->info : "");
|
||||
else
|
||||
log_write(LOG_PLAIN, "Service scan %s match (Probe %s matched with %s line %d): %s:%hu is %s%s\n",
|
||||
(MD->isSoft)? "soft" : "hard",
|
||||
probe->getName(), (*probe->fallbacks[fallbackDepth]).getName(),
|
||||
MD->lineno,
|
||||
svc->target->targetipstr(), svc->portno, (svc->tunnel == SERVICE_TUNNEL_SSL)? "SSL/" : "", MD->serviceName);
|
||||
}
|
||||
svc->probe_matched = MD->serviceName;
|
||||
if (MD->product)
|
||||
Strncpy(svc->product_matched, MD->product, sizeof(svc->product_matched));
|
||||
if (MD->version)
|
||||
Strncpy(svc->version_matched, MD->version, sizeof(svc->version_matched));
|
||||
if (MD->info)
|
||||
Strncpy(svc->extrainfo_matched, MD->info, sizeof(svc->extrainfo_matched));
|
||||
if (MD->hostname)
|
||||
Strncpy(svc->hostname_matched, MD->hostname, sizeof(svc->hostname_matched));
|
||||
if (MD->ostype)
|
||||
Strncpy(svc->ostype_matched, MD->ostype, sizeof(svc->ostype_matched));
|
||||
if (MD->devicetype)
|
||||
Strncpy(svc->devicetype_matched, MD->devicetype, sizeof(svc->devicetype_matched));
|
||||
if (MD->cpe_a)
|
||||
Strncpy(svc->cpe_a_matched, MD->cpe_a, sizeof(svc->cpe_a_matched));
|
||||
if (MD->cpe_h)
|
||||
Strncpy(svc->cpe_h_matched, MD->cpe_h, sizeof(svc->cpe_h_matched));
|
||||
if (MD->cpe_o)
|
||||
Strncpy(svc->cpe_o_matched, MD->cpe_o, sizeof(svc->cpe_o_matched));
|
||||
svc->softMatchFound = MD->isSoft;
|
||||
if (!svc->softMatchFound) {
|
||||
// We might be able to continue scan through a tunnel protocol
|
||||
// like SSL
|
||||
if (scanThroughTunnel(nsp, nsi, SG, svc) == 0)
|
||||
end_svcprobe(nsp, PROBESTATE_FINISHED_HARDMATCHED, SG, svc, nsi);
|
||||
}
|
||||
if (fallback && processMatch(MD, svc, probe->getName(), fallback->getName())) {
|
||||
// hard match!
|
||||
// We might be able to continue scan through a tunnel protocol
|
||||
// like SSL
|
||||
if (scanThroughTunnel(svc)) {
|
||||
startNextProbe(nsp, nsi, SG, svc, true);
|
||||
}
|
||||
else {
|
||||
end_svcprobe(PROBESTATE_FINISHED_HARDMATCHED, SG, svc, nsi);
|
||||
}
|
||||
}
|
||||
|
||||
if (!MD || !MD->serviceName || MD->isSoft) {
|
||||
else {
|
||||
// Didn't match... maybe reading more until timeout will help
|
||||
// TODO: For efficiency I should be able to test if enough data
|
||||
// has been received rather than always waiting for the reading
|
||||
@@ -2547,7 +2562,7 @@ static void servicescan_read_handler(nsock_pool nsp, nsock_event nse, void *myda
|
||||
}
|
||||
if (svc->tcpwrap_possible && probe->isNullProbe() && readstrlen == 0 && svc->probe_timemsused(probe) < probe->tcpwrappedms) {
|
||||
// TODO: Perhaps should do further verification before making this assumption
|
||||
end_svcprobe(nsp, PROBESTATE_FINISHED_TCPWRAPPED, SG, svc, nsi);
|
||||
end_svcprobe(PROBESTATE_FINISHED_TCPWRAPPED, SG, svc, nsi);
|
||||
} else {
|
||||
// Perhaps this service didn't like the particular probe text.
|
||||
// We'll try the next one
|
||||
@@ -2564,7 +2579,7 @@ static void servicescan_read_handler(nsock_pool nsp, nsock_event nse, void *myda
|
||||
// Jerk hung up on us. Probably didn't like our probe. We treat it as with EOF above.
|
||||
if (svc->tcpwrap_possible && probe->isNullProbe() && svc->probe_timemsused(probe) < probe->tcpwrappedms) {
|
||||
// TODO: Perhaps should do further verification before making this assumption
|
||||
end_svcprobe(nsp, PROBESTATE_FINISHED_TCPWRAPPED, SG, svc, nsi);
|
||||
end_svcprobe(PROBESTATE_FINISHED_TCPWRAPPED, SG, svc, nsi);
|
||||
} else {
|
||||
// Perhaps this service didn't like the particular probe text. We'll try the
|
||||
// next one
|
||||
@@ -2585,7 +2600,7 @@ static void servicescan_read_handler(nsock_pool nsp, nsock_event nse, void *myda
|
||||
// That is funny. The port scanner listed the port as open. Maybe it got unplugged, or firewalled us, or did
|
||||
// something else nasty during the scan. Shrug. I'll give up on this port
|
||||
svc->tcpwrap_possible = false;
|
||||
end_svcprobe(nsp, PROBESTATE_INCOMPLETE, SG, svc, nsi);
|
||||
end_svcprobe(PROBESTATE_INCOMPLETE, SG, svc, nsi);
|
||||
break;
|
||||
#ifdef ENOPROTOOPT
|
||||
case ENOPROTOOPT: // ICMP_PROT_UNREACH
|
||||
@@ -2625,7 +2640,7 @@ static void servicescan_read_handler(nsock_pool nsp, nsock_event nse, void *myda
|
||||
/* User probably specified host_timeout and so the service scan is
|
||||
shutting down */
|
||||
svc->tcpwrap_possible = false;
|
||||
end_svcprobe(nsp, PROBESTATE_INCOMPLETE, SG, svc, nsi);
|
||||
end_svcprobe(PROBESTATE_INCOMPLETE, SG, svc, nsi);
|
||||
return;
|
||||
} else {
|
||||
fatal("Unexpected status (%d) in NSE_TYPE_READ callback.", (int) status);
|
||||
@@ -2751,6 +2766,7 @@ int service_scan(std::vector<Target *> &Targets) {
|
||||
}
|
||||
|
||||
if (SG->services_remaining.size() == 0) {
|
||||
processResults(SG);
|
||||
delete SG;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -273,6 +273,9 @@ class ServiceProbe {
|
||||
|
||||
char *fallbackStr;
|
||||
ServiceProbe *fallbacks[MAXFALLBACKS+1];
|
||||
std::vector<u16>::const_iterator probablePortsBegin() const {return probableports.begin();}
|
||||
std::vector<u16>::const_iterator probablePortsEnd() const {return probableports.end();}
|
||||
bool notForPayload;
|
||||
|
||||
private:
|
||||
void setPortVector(std::vector<u16> *portv, const char *portstr,
|
||||
|
||||
@@ -713,8 +713,8 @@ public:
|
||||
: Probe(host, pspec, ttl) {
|
||||
}
|
||||
unsigned char *build_packet(const struct sockaddr_storage *source, u32 *len) const {
|
||||
const char *payload;
|
||||
size_t payload_length;
|
||||
const u8 *payload;
|
||||
int payload_length;
|
||||
|
||||
payload = get_udp_payload(pspec.pd.udp.dport, &payload_length, 0);
|
||||
|
||||
@@ -724,13 +724,13 @@ public:
|
||||
return build_udp_raw(&sin->sin_addr, host->target->v4hostip(), ttl,
|
||||
get_random_u16(), get_random_u8(), false, NULL, 0,
|
||||
token ^ global_id, pspec.pd.udp.dport,
|
||||
payload, payload_length, len);
|
||||
(char *) payload, payload_length, len);
|
||||
} else if (source->ss_family == AF_INET6) {
|
||||
const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) source;
|
||||
return build_udp_raw_ipv6(&sin6->sin6_addr, host->target->v6hostip(),
|
||||
0, 0, ttl,
|
||||
token ^ global_id, pspec.pd.udp.dport,
|
||||
payload, payload_length, len);
|
||||
(char *) payload, payload_length, len);
|
||||
} else {
|
||||
fatal("Unknown address family %u in %s.", source->ss_family, __func__);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user