diff --git a/examples/udp-probes/README b/examples/udp-probes/README new file mode 100644 index 0000000..21318a5 --- /dev/null +++ b/examples/udp-probes/README @@ -0,0 +1,44 @@ + +UDP Data Probes +====== + +This directory contains a set of data files that can be used with the UDP probe module. + + +USING: +----- + +$ zmap -M udp -p 137 --probe-args=file:examples/udp-probes/netbios_137.pkt + + +PROBES: +----- + +citrix_1604.pkt This probe triggers a response from Citrix application discovery services on UDP port 1604 +db2disco_523.pkt This probe triggers a response from IBM DB2 discovery services on UDP port 523 +digi1_2362.pkt This probe triggers a response from Digi ADDP discovery services on UDP port 2362 (default magic) +digi2_2362.pkt This probe triggers a response from Digi ADDP discovery services on UDP port 2362 (devkit magic) +digi3_2362.pkt This probe triggers a response from Digi ADDP discovery services on UDP port 2362 (oem magic) +dns_53.pkt This probe queries for the DNS vendor and version using the BIND version TXT record over UDP port 53 +ipmi_623.pkt This probe triggers a Get Channel Authentication reply from IPMI endpoints on UDP port 623 +mdns_5353.pkt This probe triggers a response from mDNS/Avahi/Bonjour discovery services on UDP port 5353 +mssql_1434.pkt This probe triggers a response from Microsoft SQL Server discovery services on UDP port 1434 +natpmp_5351.pkt This probe triggers a response from NATPMP-enabled devices on UDP port 5351 +netbios_137.pkt This probe triggers a status reply from NetBIOS services on UDP port 137 +ntp_123.pkt This probe triggers a response from NTP servies on UDP port 123 +pca_nq_5632.pkt This probe triggers a response from PC Anywhere services on UDP port 5632 (network query) +pca_st_5632.pkt This probe triggers a response from PC Anywhere services on UDP port 5632 (status) +portmap_111.pkt This probe triggers a response from SunRPC portmapper services on UDP port 111 +sentinel_5093.pkt This probe triggers a response from the Sentinel license manager service on UDP port 5093 +snmp1_161.pkt This probe queries for the system description field of SNMP v1 services using community string public over UDP port 161 +snmp2_161.pkt This probe queries for the system description field of aNMP v2 services using community string public over UDP port 161 +upnp_1900.pkt This probe triggers a response from UPnP SSDP services on UDP port 1900 +wdbrpc_17185.pkt This probe triggers a response from VxWorks WDBRPC services on UDP port 17185 +wsd_3702.pkt This probe triggers a response from WSD/DPWS services on UDP port 3702 + +NOTES: +----- + +Most of these probes return useful data in the response. Parsing this data requires capturing the raw output +and decoding this using a protocol-specific dissector. In most cases, Wireshark is capable of decoding these +replies. \ No newline at end of file diff --git a/examples/udp-probes/citrix_1604.pkt b/examples/udp-probes/citrix_1604.pkt new file mode 100755 index 0000000..acc5a73 Binary files /dev/null and b/examples/udp-probes/citrix_1604.pkt differ diff --git a/examples/udp-probes/db2disco_523.pkt b/examples/udp-probes/db2disco_523.pkt new file mode 100755 index 0000000..3883745 Binary files /dev/null and b/examples/udp-probes/db2disco_523.pkt differ diff --git a/examples/udp-probes/digi1_2362.pkt b/examples/udp-probes/digi1_2362.pkt new file mode 100755 index 0000000..74f57b8 Binary files /dev/null and b/examples/udp-probes/digi1_2362.pkt differ diff --git a/examples/udp-probes/digi2_2362.pkt b/examples/udp-probes/digi2_2362.pkt new file mode 100755 index 0000000..d962606 Binary files /dev/null and b/examples/udp-probes/digi2_2362.pkt differ diff --git a/examples/udp-probes/digi3_2362.pkt b/examples/udp-probes/digi3_2362.pkt new file mode 100755 index 0000000..ffba125 Binary files /dev/null and b/examples/udp-probes/digi3_2362.pkt differ diff --git a/examples/udp-probes/dns_53.pkt b/examples/udp-probes/dns_53.pkt new file mode 100755 index 0000000..616e17e Binary files /dev/null and b/examples/udp-probes/dns_53.pkt differ diff --git a/examples/udp-probes/ipmi_623.pkt b/examples/udp-probes/ipmi_623.pkt new file mode 100755 index 0000000..025d0fa Binary files /dev/null and b/examples/udp-probes/ipmi_623.pkt differ diff --git a/examples/udp-probes/mdns_5353.pkt b/examples/udp-probes/mdns_5353.pkt new file mode 100755 index 0000000..8221eae Binary files /dev/null and b/examples/udp-probes/mdns_5353.pkt differ diff --git a/examples/udp-probes/mssql_1434.pkt b/examples/udp-probes/mssql_1434.pkt new file mode 100755 index 0000000..25cb955 --- /dev/null +++ b/examples/udp-probes/mssql_1434.pkt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/udp-probes/natpmp_5351.pkt b/examples/udp-probes/natpmp_5351.pkt new file mode 100755 index 0000000..593f470 Binary files /dev/null and b/examples/udp-probes/natpmp_5351.pkt differ diff --git a/examples/udp-probes/netbios_137.pkt b/examples/udp-probes/netbios_137.pkt new file mode 100755 index 0000000..5177cf6 Binary files /dev/null and b/examples/udp-probes/netbios_137.pkt differ diff --git a/examples/udp-probes/ntp_123.pkt b/examples/udp-probes/ntp_123.pkt new file mode 100755 index 0000000..ef66e7e Binary files /dev/null and b/examples/udp-probes/ntp_123.pkt differ diff --git a/examples/udp-probes/pca_nq_5632.pkt b/examples/udp-probes/pca_nq_5632.pkt new file mode 100755 index 0000000..8d51173 --- /dev/null +++ b/examples/udp-probes/pca_nq_5632.pkt @@ -0,0 +1 @@ +NQ \ No newline at end of file diff --git a/examples/udp-probes/pca_st_5632.pkt b/examples/udp-probes/pca_st_5632.pkt new file mode 100755 index 0000000..86aa1fa --- /dev/null +++ b/examples/udp-probes/pca_st_5632.pkt @@ -0,0 +1 @@ +ST \ No newline at end of file diff --git a/examples/udp-probes/portmap_111.pkt b/examples/udp-probes/portmap_111.pkt new file mode 100755 index 0000000..9143734 Binary files /dev/null and b/examples/udp-probes/portmap_111.pkt differ diff --git a/examples/udp-probes/sentinel_5093.pkt b/examples/udp-probes/sentinel_5093.pkt new file mode 100755 index 0000000..158b3a9 Binary files /dev/null and b/examples/udp-probes/sentinel_5093.pkt differ diff --git a/examples/udp-probes/snmp1_161.pkt b/examples/udp-probes/snmp1_161.pkt new file mode 100755 index 0000000..209e3cf Binary files /dev/null and b/examples/udp-probes/snmp1_161.pkt differ diff --git a/examples/udp-probes/snmp2_161.pkt b/examples/udp-probes/snmp2_161.pkt new file mode 100755 index 0000000..6c10b43 Binary files /dev/null and b/examples/udp-probes/snmp2_161.pkt differ diff --git a/examples/udp-probes/upnp_1900.pkt b/examples/udp-probes/upnp_1900.pkt new file mode 100755 index 0000000..29a439a --- /dev/null +++ b/examples/udp-probes/upnp_1900.pkt @@ -0,0 +1,7 @@ +M-SEARCH * HTTP/1.1 +Host:239.255.255.250:1900 +ST:upnp:rootdevice +Man:"ssdp:discover" +MX:3 + + diff --git a/examples/udp-probes/wdbrpc_17185.pkt b/examples/udp-probes/wdbrpc_17185.pkt new file mode 100755 index 0000000..2d0a676 Binary files /dev/null and b/examples/udp-probes/wdbrpc_17185.pkt differ diff --git a/examples/udp-probes/wsd_3702.pkt b/examples/udp-probes/wsd_3702.pkt new file mode 100755 index 0000000..87704a5 --- /dev/null +++ b/examples/udp-probes/wsd_3702.pkt @@ -0,0 +1,3 @@ + + +urn:schemas-xmlsoap-org:ws:2005:04:discoveryhttp://schemas.xmlsoap.org/ws/2005/04/discovery/Probeurn:uuid:ce04dad0-5d2c-4026-9146-1aabfc1e4111wsdp:Device diff --git a/src/probe_modules/module_udp.c b/src/probe_modules/module_udp.c index d7e2278..e280a1a 100644 --- a/src/probe_modules/module_udp.c +++ b/src/probe_modules/module_udp.c @@ -25,12 +25,111 @@ #include "probe_modules.h" #include "packet.h" +#include "logger.h" + +#define MAX_UDP_PAYLOAD_LEN 1472 + +char *udp_send_msg = NULL; // Must be null-terminated +int udp_send_msg_len = 0; + +const char *udp_send_msg_default = "GET / HTTP/1.1\r\n\r\n"; -const char *udp_send_msg = "GET / HTTP/1.1\r\n\r\n"; // Must be null-terminated static int num_ports = 1; probe_module_t module_udp; + +int udp_global_initialize(struct state_conf * zconf) { + char *args, *c; + int i; + unsigned int n; + + FILE *inp; + + udp_send_msg = strdup(udp_send_msg_default); + udp_send_msg_len = strlen(udp_send_msg); + + if (! (zconf->probe_args && strlen(zconf->probe_args) > 0)) + return(0); + + args = strdup(zconf->probe_args); + if (! args) exit(1); + + c = strchr(args, ':'); + if (! c) { + free(args); + free(udp_send_msg); + log_fatal("udp", "unknown UDP probe specification (expected file:/path or text:STRING or hex:01020304)"); + exit(1); + } + + *c++ = 0; + + if (strcmp(args, "text") == 0) { + udp_send_msg = strdup(c); + udp_send_msg_len = strlen(udp_send_msg); + + } else if (strcmp(args, "file") == 0) { + inp = fopen(c, "rb"); + if (!inp) { + free(args); + free(udp_send_msg); + log_fatal("udp", "could not open UDP data file '%s'\n", c); + exit(1); + } + udp_send_msg = malloc(MAX_UDP_PAYLOAD_LEN); + if (! udp_send_msg) { + free(args); + free(udp_send_msg); + log_fatal("udp", "failed to malloc payload buffer"); + exit(1); + } + udp_send_msg_len = fread(udp_send_msg, 1, MAX_UDP_PAYLOAD_LEN, inp); + fclose(inp); + + } else if (strcmp(args, "hex") == 0) { + udp_send_msg_len = strlen(c) / 2; + udp_send_msg = malloc(udp_send_msg_len); + if (! udp_send_msg) { + free(args); + free(udp_send_msg); + log_fatal("udp", "failed to malloc payload buffer"); + exit(1); + } + + for (i=0; i < udp_send_msg_len; i++) { + if (sscanf(c + (i*2), "%2x", &n) != 1) { + free(args); + free(udp_send_msg); + log_fatal("udp", "non-hex character: '%c'", c[i*2]); + exit(1); + } + udp_send_msg[i] = (n & 0xff); + } + } else { + log_fatal("udp", "unknown UDP probe specification (expected file:/path, text:STRING, or hex:01020304)"); + free(args); + exit(1); + } + + if (udp_send_msg_len > MAX_UDP_PAYLOAD_LEN) { + fprintf(stderr, "warning: reducing UDP payload to %d bytes (from %d) to fit on the wire\n", + MAX_UDP_PAYLOAD_LEN, udp_send_msg_len); + udp_send_msg_len = MAX_UDP_PAYLOAD_LEN; + } + free(args); + return(0); +} + +int udp_global_cleanup(__attribute__((unused)) struct state_conf *zconf, + __attribute__((unused)) struct state_send *zsend, + __attribute__((unused)) struct state_recv *zrecv) { + if (udp_send_msg) free(udp_send_msg); + udp_send_msg = NULL; + return(0); +} + + int udp_init_perthread(void* buf, macaddr_t *src, macaddr_t *gw, __attribute__((unused)) port_h_t dst_port) { @@ -38,20 +137,20 @@ int udp_init_perthread(void* buf, macaddr_t *src, struct ethhdr *eth_header = (struct ethhdr *)buf; make_eth_header(eth_header, src, gw); struct iphdr *ip_header = (struct iphdr*)(ð_header[1]); - uint16_t len = htons(sizeof(struct iphdr) + sizeof(struct udphdr) + strlen(udp_send_msg)); + uint16_t len = htons(sizeof(struct iphdr) + sizeof(struct udphdr) + udp_send_msg_len); make_ip_header(ip_header, IPPROTO_UDP, len); struct udphdr *udp_header = (struct udphdr*)(&ip_header[1]); - len = sizeof(struct udphdr) + strlen(udp_send_msg); + len = sizeof(struct udphdr) + udp_send_msg_len; make_udp_header(udp_header, zconf.target_port, len); char* payload = (char*)(&udp_header[1]); module_udp.packet_length = sizeof(struct ethhdr) + sizeof(struct iphdr) - + sizeof(struct udphdr) + strlen(udp_send_msg); + + sizeof(struct udphdr) + udp_send_msg_len; assert(module_udp.packet_length <= MAX_PACKET_SIZE); - strcpy(payload, udp_send_msg); + memcpy(payload, udp_send_msg, udp_send_msg_len); num_ports = zconf.source_port_last - zconf.source_port_first + 1; @@ -212,16 +311,17 @@ static response_type_t responses[] = { probe_module_t module_udp = { .name = "udp", - .packet_length = 96, + .packet_length = 1, .pcap_filter = "udp || icmp", - .pcap_snaplen = 96, + .pcap_snaplen = 1500, .port_args = 1, .thread_initialize = &udp_init_perthread, + .global_initialize = &udp_global_initialize, .make_packet = &udp_make_packet, .print_packet = &udp_print_packet, .validate_packet = &udp_validate_packet, .classify_packet = &udp_classify_packet, - .close = NULL, + .close = &udp_global_cleanup, .responses = responses };