906 lines
31 KiB
C
906 lines
31 KiB
C
|
/*
|
||
|
Reads in UDP payload templates.
|
||
|
|
||
|
This supports two formats. The first format is the "nmap-payloads" file
|
||
|
included with the nmap port scanner.
|
||
|
|
||
|
The second is the "libpcap" format that reads in real packets,
|
||
|
extracting just the payloads, associated them with the destination
|
||
|
UDP port.
|
||
|
|
||
|
*/
|
||
|
#include "templ-payloads.h"
|
||
|
#include "massip-port.h"
|
||
|
#include "rawsock-pcapfile.h" /* for reading payloads from pcap files */
|
||
|
#include "proto-preprocess.h" /* parse packets */
|
||
|
#include "util-logger.h"
|
||
|
#include "proto-zeroaccess.h" /* botnet p2p protocol */
|
||
|
#include "proto-snmp.h"
|
||
|
#include "proto-memcached.h"
|
||
|
#include "proto-coap.h" /* constrained app proto for IoT udp/5683*/
|
||
|
#include "proto-ntp.h"
|
||
|
#include "proto-dns.h"
|
||
|
#include "proto-isakmp.h"
|
||
|
#include "util-malloc.h"
|
||
|
#include "massip.h"
|
||
|
#include "templ-nmap-payloads.h"
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include <ctype.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
struct PayloadUDP_Item {
|
||
|
unsigned port;
|
||
|
unsigned source_port; /* not used yet */
|
||
|
unsigned length;
|
||
|
unsigned xsum;
|
||
|
unsigned rarity;
|
||
|
SET_COOKIE set_cookie;
|
||
|
unsigned char buf[1];
|
||
|
};
|
||
|
struct PayloadUDP_Default {
|
||
|
unsigned port;
|
||
|
unsigned source_port;
|
||
|
unsigned length;
|
||
|
unsigned xsum;
|
||
|
SET_COOKIE set_cookie;
|
||
|
char *buf;
|
||
|
|
||
|
};
|
||
|
|
||
|
struct PayloadsUDP {
|
||
|
unsigned count;
|
||
|
size_t max;
|
||
|
struct PayloadUDP_Item **list;
|
||
|
};
|
||
|
|
||
|
|
||
|
struct PayloadUDP_Default hard_coded_oproto_payloads[] = {
|
||
|
/* ECHO protocol - echoes back whatever we send */
|
||
|
{47, 65536, 4, 0, 0, "\0\0\0\0"},
|
||
|
{0,0,0,0,0}
|
||
|
};
|
||
|
|
||
|
|
||
|
struct PayloadUDP_Default hard_coded_udp_payloads[] = {
|
||
|
/* ECHO protocol - echoes back whatever we send */
|
||
|
{7, 65536, 12, 0, 0, "superbowl 0x00000000"},
|
||
|
|
||
|
/* QOTD - quote of the day (amplifier) */
|
||
|
{17, 65536, 12, 0, 0, "superbowl"},
|
||
|
|
||
|
/* chargen - character generator (amplifier) */
|
||
|
{19, 65536, 12, 0, 0, "superbowl"},
|
||
|
|
||
|
{53, 65536, 0x1f, 0, dns_set_cookie,
|
||
|
/* 00 */"\x50\xb6" /* transaction id */
|
||
|
/* 02 */"\x01\x20" /* query */
|
||
|
/* 04 */"\x00\x01" /* query = 1 */
|
||
|
/* 06 */"\x00\x00\x00\x00\x00\x00"
|
||
|
/* 0c */"\x07" "version" "\x04" "bind" "\x00"
|
||
|
/* 1b */"\x00\x10" /* TXT */
|
||
|
/* 1d */"\x00\x03" /* CHAOS */
|
||
|
/* 1f */
|
||
|
},
|
||
|
|
||
|
{69, 65536, 24, 0, 0,
|
||
|
"\x00\x01" /* opcode = read */
|
||
|
"superbowl" "\0" /* filename = "masscan-test" */
|
||
|
"netascii" "\0" /* type = "netascii" */
|
||
|
},
|
||
|
/* portmapper */
|
||
|
{111, 65536, 40, 0, dns_set_cookie,
|
||
|
"\x00\x00\x00\x00" /* xid - first two bytes set by dns_set_cookie() */
|
||
|
"\x00\x00\x00\x00" /* RPC opcode = CALL*/
|
||
|
"\x00\x00\x00\x02" /* RPC version = 2 */
|
||
|
"\x00\x01\x86\xa0" /* RPC program = NFS */
|
||
|
"\x00\x00\x00\x02" /* portmapper version = 2 */
|
||
|
"\x00\x00\x00\x00" /* portmapper procedure = 0 (NULL, ping) */
|
||
|
"\x00\x00\x00\x00\x00\x00\x00\x00" /* credentials = none*/
|
||
|
"\x00\x00\x00\x00\x00\x00\x00\x00" /* verifier = none */
|
||
|
},
|
||
|
|
||
|
{123, 65536, 48, 0, ntp_set_cookie,
|
||
|
"\x17\x00\x03\x2a\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"
|
||
|
},
|
||
|
{137, 65536, 50, 0, dns_set_cookie,
|
||
|
"\xab\x12" /* transaction id */
|
||
|
"\x00\x00" /* query */
|
||
|
"\x00\x01\x00\x00\x00\x00\x00\x00" /* one question */
|
||
|
"\x20" /*name length*/
|
||
|
"CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||
|
"\x00"
|
||
|
"\x00\x21" /* type = nbt */
|
||
|
"\x00\x01" /* class = iternet*/
|
||
|
},
|
||
|
|
||
|
/* NetBIOS-SMB BROWSER protocol */
|
||
|
{138, 65536, 174, 0, 0,
|
||
|
"\x11" /* broadcast datagram */
|
||
|
"\x0a" /* flags */
|
||
|
"\xc1\x00" /* datagram id */
|
||
|
"\x0a\x01\x01\xd5" /* source IP */
|
||
|
"\x00\x8a" /* source port */
|
||
|
"\x00\xa0" /* length */
|
||
|
"\x00\x00" /* packet offset */
|
||
|
"\x20" /* namelength = 32 bytes*/
|
||
|
"ENEBFDFDEDEBEOCNFEEFFDFECACACAAA" /* "MASSCAN-TEST<00>" */
|
||
|
"\x00"
|
||
|
"\x20"
|
||
|
"FHEPFCELEHFCEPFFFACACACACACACABN" /* "WORKGROUP<1D>*/
|
||
|
"\x00"
|
||
|
"\xff\x53\x4d\x42\x25\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"
|
||
|
|
||
|
"\x11\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x03\x00"
|
||
|
"\x00\x00\x00\x00\x00\x00\x00\x06\x00\x56\x00\x03\x00\x01\x00\x01"
|
||
|
"\x00\x02\x00\x17\x00\x5c\x4d\x41\x49\x4c\x53\x4c\x4f\x54\x5c\x42"
|
||
|
"\x52\x4f\x57\x53\x45\x00"
|
||
|
|
||
|
"\x09\x04\x01\x00\x00\x00"
|
||
|
},
|
||
|
|
||
|
{161, 65536, 59, 0, snmp_set_cookie,
|
||
|
"\x30" "\x39"
|
||
|
"\x02\x01\x00" /* version */
|
||
|
"\x04\x06" "public" /* community = public */
|
||
|
"\xa0" "\x2c" /* type = GET */
|
||
|
"\x02\x04\x00\x00\x00\x00" /* transaction id = ???? */
|
||
|
"\x02\x01\x00" /* error = 0 */
|
||
|
"\x02\x01\x00" /* error index = 0 */
|
||
|
"\x30\x1e"
|
||
|
"\x30\x0d"
|
||
|
"\x06\x09\x2b\x06\x01\x80\x02\x01\x01\x01\x00" /*sysName*/
|
||
|
"\x05\x00" /*^^^^_____IDS LULZ HAH HA HAH*/
|
||
|
"\x30\x0d"
|
||
|
"\x06\x09\x2b\x06\x01\x80\x02\x01\x01\x05\x00" /*sysDesc*/
|
||
|
"\x05\x00"}, /*^^^^_____IDS LULZ HAH HA HAH*/
|
||
|
|
||
|
{443, 65536, 115, 0, 0,
|
||
|
"\x16" /* opcode = handshake */
|
||
|
"\xfe\xff" /* version = dTLS v1.0 */
|
||
|
"\x00\x00" /* epoch = 0 */
|
||
|
"\x00\x00\x00\x00\x00\x07" /* sequence number = 7 */
|
||
|
"\x00\x66" /* length 104 */
|
||
|
|
||
|
"\x01" /* opcode = client hello */
|
||
|
"\x00\x00\x5a" /* length 90 */
|
||
|
"\x00\x00" /* sequence number = 0 */
|
||
|
"\x00\x00\x00" /* fragment offset = 0 */
|
||
|
"\x00\x00\x5a" /* framgent length = 90 */
|
||
|
"\xfe\xfd" /* version = dTLS v1.2 */
|
||
|
"\x1d\xb1\xe3\x52\x2e\x89\x94\xb7\x15\x33\x2f\x30\xff\xff\xcf\x76"
|
||
|
"\x27\x77\xab\x04\xe4\x86\x6f\x21\x18\x0e\xf8\xdd\x70\xcc\xab\x9e"
|
||
|
"\x00" /* session id length = 0 */
|
||
|
"\x00" /* cookie length = 0 */
|
||
|
"\x00\x04" /* cipher suites length = 4 */
|
||
|
"\xc0\x30" /* TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 */
|
||
|
"\x00\xff"
|
||
|
"\x01" /* compression methods length = 1*/
|
||
|
"\x00" /* NULL compression */
|
||
|
"\x00\x2c" /* extensions length = 44 */
|
||
|
"\x00\x0b\x00\x04\x03\x00\x01\x02"
|
||
|
"\x00\x0a\x00\x0c\x00\x0a\x00\x1d\x00\x17\x00\x1e\x00\x19\x00\x18"
|
||
|
"\x00\x23\x00\x00"
|
||
|
"\x00\x16\x00\x00"
|
||
|
"\x00\x17\x00\x00"
|
||
|
"\x00\x0d\x00\x04\x00\x02\x05\x01"
|
||
|
},
|
||
|
|
||
|
{520, 65536, 24, 0, 0,
|
||
|
"\x01" /* opcode = request */
|
||
|
"\x01" /* version = 1 */
|
||
|
"\x00\x00" /* padding */
|
||
|
"\x00\x02" /* address familly = IPv4 */
|
||
|
"\x00\x00"
|
||
|
"\x00\x00\x00\x00"
|
||
|
"\x00\x00\x00\x00"
|
||
|
"\x00\x00\x00\x00"
|
||
|
"\x00\x00\x00\x10" /* metric = 16 */
|
||
|
|
||
|
},
|
||
|
|
||
|
/* RADIUS */
|
||
|
{1645, 65536, 20, 0, 0,
|
||
|
"\x01" /* opcode = access request */
|
||
|
"\x00" /* packet id = 0 */
|
||
|
"\x00\x14" /* length = 20 */
|
||
|
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||
|
},
|
||
|
{1812, 65536, 20, 0, 0,
|
||
|
"\x01" /* opcode = access request */
|
||
|
"\x00" /* packet id = 0 */
|
||
|
"\x00\x14" /* length = 20 */
|
||
|
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||
|
},
|
||
|
{1646, 65536, 20, 0, 0,
|
||
|
"\x04" /* opcode = access request */
|
||
|
"\x00" /* packet id = 0 */
|
||
|
"\x00\x14" /* length = 20 */
|
||
|
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||
|
},
|
||
|
{1813, 65536, 20, 0, 0,
|
||
|
"\x04" /* opcode = access request */
|
||
|
"\x00" /* packet id = 0 */
|
||
|
"\x00\x14" /* length = 20 */
|
||
|
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||
|
},
|
||
|
|
||
|
/* L2TP */
|
||
|
{1701, 65536, 60, 0, 0,
|
||
|
"\xc8\x02" /* flags */
|
||
|
"\x00\x3c" /* length = 60 */
|
||
|
"\x00\x00" /* tunnel id = 0 */
|
||
|
"\x00\x00" /* session id = 0 */
|
||
|
"\x00\x00" /* Nsent = 0 */
|
||
|
"\x00\x00" /* Nrecvd = 0 */
|
||
|
"\x80\x08\x00\x00\x00\x00\x00\x01" /* control message */
|
||
|
"\x80\x08\x00\x00\x00\x02\x01\x00" /* protocol version */
|
||
|
"\x80\x0e\x00\x00\x00\x07" "superbowl1" /* hostname */
|
||
|
"\x80\x0a\x00\x00\x00\x03\x00\x00\x00\x03" /* framing capabilities */
|
||
|
"\x80\x08\x00\x00\x00\x09\x00\x00" /* assigned tunnel */
|
||
|
},
|
||
|
|
||
|
/* UPnP SSDP - Univeral Plug-n-Play Simple Service Discovery Protocol */
|
||
|
{1900, 65536, 0xFFFFFFFF, 0, 0,
|
||
|
"M-SEARCH * HTTP/1.1\r\n"
|
||
|
"HOST: 239.255.255.250:1900\r\n"
|
||
|
"MAN: \"ssdp:discover\"\r\n"
|
||
|
"MX: 1\r\n"
|
||
|
"ST: ssdp:all\r\n"
|
||
|
"USER-AGENT: solaris/1.3.3.7 UPnP/1.1 ezbakeoven/1.0\r\n"},
|
||
|
|
||
|
/* NFS - kludge: use the DNS cookie, setting first 2 bytes instead of 4 */
|
||
|
{2049, 65536, 40, 0, dns_set_cookie,
|
||
|
"\x00\x00\x00\x00" /* xid - first two bytes set by dns_set_cookie() */
|
||
|
"\x00\x00\x00\x00" /* RPC opcode = CALL*/
|
||
|
"\x00\x00\x00\x02" /* RPC version = 2 */
|
||
|
"\x00\x01\x86\xa3" /* RPC program = NFS */
|
||
|
"\x00\x00\x00\x02" /* NFS version = 2 */
|
||
|
"\x00\x00\x00\x00" /* NFS procedure = 0 (NULL, ping) */
|
||
|
"\x00\x00\x00\x00\x00\x00\x00\x00" /* credentials = none*/
|
||
|
"\x00\x00\x00\x00\x00\x00\x00\x00" /* verifier = none */
|
||
|
},
|
||
|
{5060, 65536, 0xFFFFFFFF, 0, 0,
|
||
|
"OPTIONS sip:gill@fbi.gov SIP/2.0\r\n"
|
||
|
"Via: SIP/2.0/UDP pc1337.costco.com;branch=hhhG4bKgill8asgreg\r\n"
|
||
|
"Max-Forwards: 80\r\n"
|
||
|
"To: <sip:gill@fbi.gov>\r\n"
|
||
|
"From: Alice <sip:greg@nsa.gov>;tag=1337691776\r\n"
|
||
|
"Call-ID: a84b4c76e66710\r\n"
|
||
|
"CSeq: 63104 OPTIONS\r\n"
|
||
|
"Contact: <sip:greg@nsa.gov>\r\n"
|
||
|
"Accept: application/sdp\r\n"
|
||
|
"Content-Length: 0\r\n"
|
||
|
},
|
||
|
|
||
|
/* CoAP (contrained app proto for IoT) GET /.well-known/core request */
|
||
|
{5683, 65536, 21, 0, coap_udp_set_cookie,
|
||
|
"\x40" /* ver=1 type=con */
|
||
|
"\x01" /* code=GET */
|
||
|
"\x01\xce" /* message id (changed by set-cookie) */
|
||
|
"\xbb" /* ".well-known */
|
||
|
"\x2e\x77\x65\x6c\x6c\x2d\x6b\x6e\x6f\x77\x6e"
|
||
|
"\x04" /* "core" */
|
||
|
"\x63\x6f\x72\x65"
|
||
|
|
||
|
},
|
||
|
|
||
|
/* memcached "stats" request. This looks for memcached systems that can
|
||
|
* be used for DDoS amplifiers */
|
||
|
{11211, 65536, 15, 0, memcached_udp_set_cookie,
|
||
|
"\x00\x00\x00\x00\x00\x01\x00\x00stats\r\n"
|
||
|
},
|
||
|
|
||
|
//16464,16465,16470, 16471
|
||
|
{16464, 65536, zeroaccess_getL_length, 0, 0,
|
||
|
(char *)zeroaccess_getL},
|
||
|
{16465, 65536, zeroaccess_getL_length, 0, 0,
|
||
|
(char *)zeroaccess_getL},
|
||
|
{16470, 65536, zeroaccess_getL_length, 0, 0,
|
||
|
(char *)zeroaccess_getL},
|
||
|
{16471, 65536, zeroaccess_getL_length, 0, 0,
|
||
|
(char *)zeroaccess_getL},
|
||
|
|
||
|
/* Quake 3 (amplifier)
|
||
|
* http://blog.alejandronolla.com/2013/06/24/amplification-ddos-attack-with-quake3-servers-an-analysis-1-slash-2/
|
||
|
*/
|
||
|
{27960, 65536, 0xFFFFFFFF, 0, 0,
|
||
|
"\xFF\xFF\xFF\xFF\x67\x65\x74\x73\x74\x61\x74\x75\x73\x10"},
|
||
|
|
||
|
/* ISAKMP */
|
||
|
{500, 500, 352, 0, isakmp_set_cookie,
|
||
|
/* ISAKMP */
|
||
|
"\x00\x11\x22\x33\x44\x55\x66\x77"/* init_cookie, overwritten on send() */
|
||
|
"\x00\x00\x00\x00\x00\x00\x00\x00" /* resp_cookie*/
|
||
|
"\x01" /* next_payload: SA */
|
||
|
"\x10" /* version */
|
||
|
"\x02" /* exch_type: identity prot. */
|
||
|
"\x00" /* flags */
|
||
|
"\x00\x00\x00\x00" /* id */
|
||
|
"\x00\x00\x01\x60" /* length: 352 */
|
||
|
/* ISAKMP_SA */
|
||
|
"\x00" /* next_payload: None */
|
||
|
"\x00" /* reserved */
|
||
|
"\x01\x44" /* length: 324 */
|
||
|
"\x00\x00\x00\x01" /* DOI: IPSEC */
|
||
|
"\x00\x00\x00\x01" /* situation: identity */
|
||
|
/* Proposal */
|
||
|
"\x00" /* next_payload: None */
|
||
|
"\x00" /* reserved */
|
||
|
"\x01\x38" /* length: 312 */
|
||
|
"\x01" /* proposal: 1 */
|
||
|
"\x01" /* protocol: ISAKMP */
|
||
|
"\x00" /* SPIsize: 0 */
|
||
|
"\x0d" /* trans_count: 13 */
|
||
|
"" /* SPI */
|
||
|
/* Tranforms */
|
||
|
"\x03" /* next_payload: Transform */
|
||
|
"\x00" /* reserved */
|
||
|
"\x00\x20" /* length: 32 */
|
||
|
"\x00" /* num */
|
||
|
"\x01" /* id: KEY_IKE */
|
||
|
"\x00\x00" /* reserved */
|
||
|
"\x80\x01\x00\x05\x80\x02\x00\x02\x80\x03\x00\x01\x80\x04\x00\x02"
|
||
|
"\x80\x0b\x00\x01\x80\x0c\x00\x01"
|
||
|
/* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'), ('Authentication', 'PSK'),
|
||
|
('GroupDesc', '1024MODPgr'), ('LifeType', 'Seconds'),
|
||
|
('LifeDuration', 1) */
|
||
|
"\x03" /* next_payload: Transform */
|
||
|
"\x00" /* reserved */
|
||
|
"\x00\x20" /* length: 32 */
|
||
|
"\x00" /* num */
|
||
|
"\x01" /* id: KEY_IKE */
|
||
|
"\x00\x00" /* reserved */
|
||
|
"\x80\x01\x00\x01\x80\x02\x00\x01\x80\x03\x00\x01\x80\x04\x00\x02"
|
||
|
"\x80\x0b\x00\x01\x80\x0c\x00\x01"
|
||
|
/* ('Encryption', 'DES-CBC'), ('Hash', 'MD5'), ('Authentication', 'PSK'),
|
||
|
('GroupDesc', '1024MODPgr'), ('LifeType', 'Seconds'),
|
||
|
('LifeDuration', 1) */
|
||
|
"\x03" /* next_payload: Transform */
|
||
|
"\x00" /* reserved */
|
||
|
"\x00\x20" /* length: 32 */
|
||
|
"\x00" /* num */
|
||
|
"\x01" /* id: KEY_IKE */
|
||
|
"\x00\x00" /* reserved */
|
||
|
"\x80\x01\x00\x07\x80\x02\x00\x04\x80\x03\x00\x01\x80\x04\x00\x0e"
|
||
|
"\x80\x0b\x00\x01\x80\x0c\x00\x01"
|
||
|
/* ('Encryption', 'AES-CBC'), ('Hash', 'SHA2-256'),
|
||
|
('Authentication', 'PSK'), ('GroupDesc', '2048MODPgr'),
|
||
|
('LifeType', 'Seconds'), ('LifeDuration', 1) */
|
||
|
"\x03" /* next_payload: Transform */
|
||
|
"\x00" /* reserved */
|
||
|
"\x00\x14" /* length: 20 */
|
||
|
"\x00" /* num */
|
||
|
"\x01" /* id: KEY_IKE */
|
||
|
"\x00\x00" /* reserved */
|
||
|
"\x80\x01\x00\x05\x80\x02\x00\x02\x80\x03\x00\x02"
|
||
|
/* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),
|
||
|
('Authentication', 'DSS') */
|
||
|
"\x03" /* next_payload: Transform */
|
||
|
"\x00" /* reserved */
|
||
|
"\x00\x14" /* length: 20 */
|
||
|
"\x00" /* num */
|
||
|
"\x01" /* id: KEY_IKE */
|
||
|
"\x00\x00" /* reserved */
|
||
|
"\x80\x01\x00\x05\x80\x02\x00\x02\x80\x03\x00\x03"
|
||
|
/* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),
|
||
|
('Authentication', 'RSA Sig') */
|
||
|
"\x03" /* next_payload: Transform */
|
||
|
"\x00" /* reserved */
|
||
|
"\x00\x14" /* length: 20 */
|
||
|
"\x00" /* num */
|
||
|
"\x01" /* id: KEY_IKE */
|
||
|
"\x00\x00" /* reserved */
|
||
|
"\x80\x01\x00\x05\x80\x02\x00\x02\x80\x03\x00\x04"
|
||
|
/* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),
|
||
|
('Authentication', 'RSA Encryption') */
|
||
|
"\x03" /* next_payload: Transform */
|
||
|
"\x00" /* reserved */
|
||
|
"\x00\x14" /* length: 20 */
|
||
|
"\x00" /* num */
|
||
|
"\x01" /* id: KEY_IKE */
|
||
|
"\x00\x00" /* reserved */
|
||
|
"\x80\x01\x00\x05\x80\x02\x00\x02\x80\x03\x00\x08"
|
||
|
/* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),
|
||
|
('Authentication', 'ECDSA Sig') */
|
||
|
"\x03" /* next_payload: Transform */
|
||
|
"\x00" /* reserved */
|
||
|
"\x00\x14" /* length: 20 */
|
||
|
"\x00" /* num */
|
||
|
"\x01" /* id: KEY_IKE */
|
||
|
"\x00\x00" /* reserved */
|
||
|
"\x80\x01\x00\x05\x80\x02\x00\x02\x80\x03\xfa\xdd"
|
||
|
/* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),
|
||
|
('Authentication', 'HybridInitRSA') */
|
||
|
"\x03" /* next_payload: Transform */
|
||
|
"\x00" /* reserved */
|
||
|
"\x00\x14" /* length: 20 */
|
||
|
"\x00" /* num */
|
||
|
"\x01" /* id: KEY_IKE */
|
||
|
"\x00\x00" /* reserved */
|
||
|
"\x80\x01\x00\x05\x80\x02\x00\x02\x80\x03\xfa\xdf"
|
||
|
/* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),
|
||
|
('Authentication', 'HybridInitDSS') */
|
||
|
"\x03" /* next_payload: Transform */
|
||
|
"\x00" /* reserved */
|
||
|
"\x00\x14" /* length: 20 */
|
||
|
"\x00" /* num */
|
||
|
"\x01" /* id: KEY_IKE */
|
||
|
"\x00\x00" /* reserved */
|
||
|
"\x80\x01\x00\x05\x80\x02\x00\x02\x80\x03\xfd\xe9"
|
||
|
/* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),
|
||
|
('Authentication', 'XAUTHInitPreShared') */
|
||
|
"\x03" /* next_payload: Transform */
|
||
|
"\x00" /* reserved */
|
||
|
"\x00\x14" /* length: 20 */
|
||
|
"\x00" /* num */
|
||
|
"\x01" /* id: KEY_IKE */
|
||
|
"\x00\x00" /* reserved */
|
||
|
"\x80\x01\x00\x05\x80\x02\x00\x02\x80\x03\xfd\xeb"
|
||
|
/* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),
|
||
|
('Authentication', 'XAUTHInitDSS') */
|
||
|
"\x03" /* next_payload: Transform */
|
||
|
"\x00" /* reserved */
|
||
|
"\x00\x14" /* length: 20 */
|
||
|
"\x00" /* num */
|
||
|
"\x01" /* id: KEY_IKE */
|
||
|
"\x00\x00" /* reserved */
|
||
|
"\x80\x01\x00\x05\x80\x02\x00\x02\x80\x03\xfd\xed"
|
||
|
/* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),
|
||
|
('Authentication', 'XAUTHInitRSA') */
|
||
|
"\x03" /* next_payload: Transform */
|
||
|
"\x00" /* reserved */
|
||
|
"\x00\x14" /* length: 20 */
|
||
|
"\x00" /* num */
|
||
|
"\x01" /* id: KEY_IKE */
|
||
|
"\x00\x00" /* reserved */
|
||
|
"\x80\x01\x00\x05\x80\x02\x00\x02\x80\x03\xfd\xef"
|
||
|
/* ('Encryption', '3DES-CBC'), ('Hash', 'SHA'),
|
||
|
('Authentication', 'XAUTHInitRSAEncryption') */
|
||
|
"\x00" /* next_payload: None */
|
||
|
"\x00" /* reserved */
|
||
|
"\x00\x08" /* length: 8 */
|
||
|
"\x00" /* num */
|
||
|
"\x01" /* id: KEY_IKE */
|
||
|
"\x00\x00" /* reserved */},
|
||
|
|
||
|
{0,0,0,0,0}
|
||
|
};
|
||
|
|
||
|
|
||
|
/***************************************************************************
|
||
|
* Calculate the partial checksum of the payload. This allows us to simply
|
||
|
* add this to the checksum when transmitting instead of recalculating
|
||
|
* everything.
|
||
|
***************************************************************************/
|
||
|
static unsigned
|
||
|
partial_checksum(const unsigned char *px, size_t icmp_length)
|
||
|
{
|
||
|
uint64_t xsum = 0;
|
||
|
unsigned i;
|
||
|
|
||
|
for (i=0; i<icmp_length; i += 2) {
|
||
|
xsum += px[i]<<8 | px[i + 1];
|
||
|
}
|
||
|
|
||
|
xsum -= (icmp_length & 1) * px[i - 1]; /* yea I know going off end of packet is bad so sue me */
|
||
|
xsum = (xsum & 0xFFFF) + (xsum >> 16);
|
||
|
xsum = (xsum & 0xFFFF) + (xsum >> 16);
|
||
|
xsum = (xsum & 0xFFFF) + (xsum >> 16);
|
||
|
|
||
|
return (unsigned)xsum;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************
|
||
|
* If we have the port, return the best payload for that port.
|
||
|
***************************************************************************/
|
||
|
int
|
||
|
payloads_udp_lookup(
|
||
|
const struct PayloadsUDP *payloads,
|
||
|
unsigned port,
|
||
|
const unsigned char **px,
|
||
|
unsigned *length,
|
||
|
unsigned *source_port,
|
||
|
uint64_t *xsum,
|
||
|
SET_COOKIE *set_cookie)
|
||
|
{
|
||
|
unsigned i;
|
||
|
if (payloads == 0)
|
||
|
return 0;
|
||
|
|
||
|
port &= 0xFFFF;
|
||
|
|
||
|
/* This is just a linear search, done once at startup, to search
|
||
|
* through all the payloads for the best match. */
|
||
|
for (i=0; i<payloads->count; i++) {
|
||
|
if (payloads->list[i]->port == port) {
|
||
|
*px = payloads->list[i]->buf;
|
||
|
*length = payloads->list[i]->length;
|
||
|
*source_port = payloads->list[i]->source_port;
|
||
|
*xsum = payloads->list[i]->xsum;
|
||
|
*set_cookie = payloads->list[i]->set_cookie;
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
/***************************************************************************
|
||
|
* cleanup on program shutdown
|
||
|
***************************************************************************/
|
||
|
void
|
||
|
payloads_udp_destroy(struct PayloadsUDP *payloads)
|
||
|
{
|
||
|
unsigned i;
|
||
|
if (payloads == NULL)
|
||
|
return;
|
||
|
|
||
|
for (i=0; i<payloads->count; i++)
|
||
|
free(payloads->list[i]);
|
||
|
|
||
|
if (payloads->list)
|
||
|
free(payloads->list);
|
||
|
|
||
|
free(payloads);
|
||
|
}
|
||
|
|
||
|
/***************************************************************************
|
||
|
* We read lots of UDP payloads from the files. However, we probably
|
||
|
* aren't using most, or even any, of them. Therefore, we use this
|
||
|
* function to remove the ones we won't be using. This makes lookups
|
||
|
* faster, ideally looking up only zero or one rather than twenty.
|
||
|
***************************************************************************/
|
||
|
void
|
||
|
payloads_udp_trim(struct PayloadsUDP *payloads, const struct MassIP *targets)
|
||
|
{
|
||
|
unsigned i;
|
||
|
struct PayloadUDP_Item **list2;
|
||
|
unsigned count2 = 0;
|
||
|
|
||
|
/* Create a new list */
|
||
|
list2 = REALLOCARRAY(0, payloads->max, sizeof(list2[0]));
|
||
|
|
||
|
/* Add to the new list any used ports */
|
||
|
for (i=0; i<payloads->count; i++) {
|
||
|
unsigned found;
|
||
|
|
||
|
found = massip_has_port(targets, payloads->list[i]->port + Templ_UDP);
|
||
|
if (found) {
|
||
|
list2[count2++] = payloads->list[i];
|
||
|
} else {
|
||
|
free(payloads->list[i]);
|
||
|
}
|
||
|
//payloads->list[i] = 0;
|
||
|
}
|
||
|
|
||
|
/* Replace the old list */
|
||
|
free(payloads->list);
|
||
|
payloads->list = list2;
|
||
|
payloads->count = count2;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
payloads_oproto_trim(struct PayloadsUDP *payloads, const struct MassIP *targets)
|
||
|
{
|
||
|
unsigned i;
|
||
|
struct PayloadUDP_Item **list2;
|
||
|
unsigned count2 = 0;
|
||
|
|
||
|
/* Create a new list */
|
||
|
list2 = REALLOCARRAY(0, payloads->max, sizeof(list2[0]));
|
||
|
|
||
|
/* Add to the new list any used ports */
|
||
|
for (i=0; i<payloads->count; i++) {
|
||
|
unsigned found;
|
||
|
|
||
|
found = massip_has_port(targets, payloads->list[i]->port + Templ_Oproto_first);
|
||
|
if (found) {
|
||
|
list2[count2++] = payloads->list[i];
|
||
|
} else {
|
||
|
free(payloads->list[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Replace the old list */
|
||
|
free(payloads->list);
|
||
|
payloads->list = list2;
|
||
|
payloads->count = count2;
|
||
|
}
|
||
|
|
||
|
|
||
|
/***************************************************************************
|
||
|
* Adds a payloads template for the indicated datagram protocol, which
|
||
|
* is UDP or Oproto ("other IP protocol").
|
||
|
***************************************************************************/
|
||
|
static unsigned
|
||
|
payloads_datagram_add(struct PayloadsUDP *payloads,
|
||
|
const unsigned char *buf, size_t length,
|
||
|
struct RangeList *ports, unsigned source_port,
|
||
|
SET_COOKIE set_cookie)
|
||
|
{
|
||
|
unsigned count = 1;
|
||
|
struct PayloadUDP_Item *p;
|
||
|
uint64_t port_count = rangelist_count(ports);
|
||
|
uint64_t i;
|
||
|
|
||
|
for (i=0; i<port_count; i++) {
|
||
|
/* grow the list if we need to */
|
||
|
if (payloads->count + 1 > payloads->max) {
|
||
|
size_t new_max = payloads->max*2 + 1;
|
||
|
payloads->list = REALLOCARRAY(payloads->list, new_max, sizeof(payloads->list[0]));
|
||
|
payloads->max = new_max;
|
||
|
}
|
||
|
|
||
|
/* allocate space for this record */
|
||
|
p = MALLOC(sizeof(p[0]) + length);
|
||
|
p->port = rangelist_pick(ports, i);
|
||
|
p->source_port = source_port;
|
||
|
p->length = (unsigned)length;
|
||
|
memcpy(p->buf, buf, length);
|
||
|
p->xsum = partial_checksum(buf, length);
|
||
|
p->set_cookie = set_cookie;
|
||
|
|
||
|
/* insert in sorted order */
|
||
|
{
|
||
|
unsigned j;
|
||
|
|
||
|
for (j=0; j<payloads->count; j++) {
|
||
|
if (p->port <= payloads->list[j]->port)
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (j < payloads->count) {
|
||
|
if (p->port == payloads->list[j]->port) {
|
||
|
free(payloads->list[j]);
|
||
|
count = 0; /* don't increment count */
|
||
|
} else
|
||
|
memmove(payloads->list + j + 1,
|
||
|
payloads->list + j,
|
||
|
(payloads->count-j) * sizeof(payloads->list[0]));
|
||
|
}
|
||
|
payloads->list[j] = p;
|
||
|
|
||
|
payloads->count += count;
|
||
|
count = 1;
|
||
|
}
|
||
|
}
|
||
|
return count; /* zero or one */
|
||
|
}
|
||
|
|
||
|
static unsigned
|
||
|
payloads_datagram_add_nocookie(struct PayloadsUDP *payloads,
|
||
|
const unsigned char *buf, size_t length,
|
||
|
struct RangeList *ports, unsigned source_port
|
||
|
) {
|
||
|
return payloads_datagram_add(payloads,
|
||
|
buf, length,
|
||
|
ports, source_port,
|
||
|
0);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/***************************************************************************
|
||
|
* Called during processing of the "--pcap-payloads <filename>" directive.
|
||
|
* This is the well-known 'pcap' file format. This code strips off the
|
||
|
* headers of the packets then preserves just the payload portion
|
||
|
* and port number.
|
||
|
***************************************************************************/
|
||
|
void
|
||
|
payloads_read_pcap(const char *filename,
|
||
|
struct PayloadsUDP *payloads,
|
||
|
struct PayloadsUDP *oproto_payloads)
|
||
|
{
|
||
|
struct PcapFile *pcap;
|
||
|
unsigned count = 0;
|
||
|
|
||
|
LOG(2, "payloads:'%s': opening packet capture\n", filename);
|
||
|
|
||
|
/* open packet-capture */
|
||
|
pcap = pcapfile_openread(filename);
|
||
|
if (pcap == NULL) {
|
||
|
fprintf(stderr, "payloads: can't read from file '%s'\n", filename);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* for all packets in the capture file
|
||
|
* - read in packet
|
||
|
* - parse packet
|
||
|
* - save payload
|
||
|
*/
|
||
|
for (;;) {
|
||
|
unsigned x;
|
||
|
unsigned captured_length;
|
||
|
unsigned char buf[65536];
|
||
|
struct PreprocessedInfo parsed;
|
||
|
struct RangeList ports[1] = {{0}};
|
||
|
struct Range range[1] = {{0}};
|
||
|
|
||
|
/*
|
||
|
* Read the next packet from the capture file
|
||
|
*/
|
||
|
{
|
||
|
unsigned time_secs;
|
||
|
unsigned time_usecs;
|
||
|
unsigned original_length;
|
||
|
|
||
|
x = pcapfile_readframe(pcap,
|
||
|
&time_secs, &time_usecs,
|
||
|
&original_length, &captured_length,
|
||
|
buf, (unsigned)sizeof(buf));
|
||
|
}
|
||
|
if (!x)
|
||
|
break;
|
||
|
|
||
|
/*
|
||
|
* Parse the packet up to its headers
|
||
|
*/
|
||
|
x = preprocess_frame(buf, captured_length, 1, &parsed);
|
||
|
if (!x)
|
||
|
continue; /* corrupt packet */
|
||
|
|
||
|
/*
|
||
|
* Make sure it has UDP
|
||
|
*/
|
||
|
switch (parsed.found) {
|
||
|
case FOUND_DNS:
|
||
|
case FOUND_UDP:
|
||
|
/*
|
||
|
* Kludge: mark the port in the format the API wants
|
||
|
*/
|
||
|
ports->list = range;
|
||
|
ports->count = 1;
|
||
|
ports->max = 1;
|
||
|
range->begin = parsed.port_dst;
|
||
|
range->end = range->begin;
|
||
|
|
||
|
/*
|
||
|
* Now we've completely parsed the record, so add it to our
|
||
|
* list of payloads
|
||
|
*/
|
||
|
count += payloads_datagram_add( payloads,
|
||
|
buf + parsed.app_offset,
|
||
|
parsed.app_length,
|
||
|
ports,
|
||
|
0x10000,
|
||
|
0);
|
||
|
break;
|
||
|
case FOUND_OPROTO:
|
||
|
/*
|
||
|
* Kludge: mark the port in the format the API wants
|
||
|
*/
|
||
|
ports->list = range;
|
||
|
ports->count = 1;
|
||
|
ports->max = 1;
|
||
|
range->begin = parsed.ip_protocol;
|
||
|
range->end = range->begin;
|
||
|
|
||
|
/*
|
||
|
* Now we've completely parsed the record, so add it to our
|
||
|
* list of payloads
|
||
|
*/
|
||
|
count += payloads_datagram_add(oproto_payloads,
|
||
|
buf + parsed.transport_offset,
|
||
|
parsed.transport_length,
|
||
|
ports,
|
||
|
0x10000,
|
||
|
0);
|
||
|
break;
|
||
|
default:
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
LOG(2, "payloads:'%s': imported %u unique payloads\n", filename, count);
|
||
|
LOG(2, "payloads:'%s': closed packet capture\n", filename);
|
||
|
pcapfile_close(pcap);
|
||
|
}
|
||
|
|
||
|
/***************************************************************************
|
||
|
* Called from the "conf" subsystem in order read in the file
|
||
|
* "nmap-payloads". We call the function 'read_nmap_payloads()" defined
|
||
|
* in a different file that focuses on parsing that file format.
|
||
|
***************************************************************************/
|
||
|
void
|
||
|
payloads_udp_readfile(FILE *fp, const char *filename,
|
||
|
struct PayloadsUDP *payloads) {
|
||
|
read_nmap_payloads(fp, filename, payloads, payloads_datagram_add_nocookie);
|
||
|
}
|
||
|
|
||
|
/***************************************************************************
|
||
|
***************************************************************************/
|
||
|
struct PayloadsUDP *
|
||
|
payloads_udp_create(void)
|
||
|
{
|
||
|
unsigned i;
|
||
|
struct PayloadsUDP *payloads;
|
||
|
struct PayloadUDP_Default *hard_coded = hard_coded_udp_payloads;
|
||
|
|
||
|
payloads = CALLOC(1, sizeof(*payloads));
|
||
|
|
||
|
/*
|
||
|
* For popular parts, include some hard-coded default UDP payloads
|
||
|
*/
|
||
|
for (i=0; hard_coded[i].length; i++) {
|
||
|
//struct Range range;
|
||
|
struct RangeList list = {0};
|
||
|
unsigned length;
|
||
|
|
||
|
/* Kludge: create a pseudo-rangelist to hold the one port */
|
||
|
/*list.list = ⦥
|
||
|
list.count = 1;
|
||
|
range.begin = hard_coded[i].port;
|
||
|
range.end = range.begin;*/
|
||
|
rangelist_add_range(&list, hard_coded[i].port, hard_coded[i].port);
|
||
|
|
||
|
length = hard_coded[i].length;
|
||
|
if (length == 0xFFFFFFFF)
|
||
|
length = (unsigned)strlen(hard_coded[i].buf);
|
||
|
|
||
|
/* Add this to our real payloads. This will get overwritten
|
||
|
* if the user adds their own with the same port */
|
||
|
payloads_datagram_add(payloads,
|
||
|
(const unsigned char*)hard_coded[i].buf,
|
||
|
length,
|
||
|
&list,
|
||
|
hard_coded[i].source_port,
|
||
|
hard_coded[i].set_cookie);
|
||
|
|
||
|
rangelist_remove_all(&list);
|
||
|
}
|
||
|
return payloads;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************
|
||
|
* (same code as for UDP)
|
||
|
***************************************************************************/
|
||
|
struct PayloadsUDP *
|
||
|
payloads_oproto_create(void)
|
||
|
{
|
||
|
unsigned i;
|
||
|
struct PayloadsUDP *payloads;
|
||
|
struct PayloadUDP_Default *hard_coded = hard_coded_oproto_payloads;
|
||
|
|
||
|
payloads = CALLOC(1, sizeof(*payloads));
|
||
|
|
||
|
/*
|
||
|
* Some hard-coded ones, like GRE
|
||
|
*/
|
||
|
for (i=0; hard_coded[i].length; i++) {
|
||
|
//struct Range range;
|
||
|
struct RangeList list = {0};
|
||
|
unsigned length;
|
||
|
|
||
|
/* Kludge: create a pseudo-rangelist to hold the one port */
|
||
|
rangelist_add_range(&list, hard_coded[i].port, hard_coded[i].port);
|
||
|
|
||
|
length = hard_coded[i].length;
|
||
|
if (length == 0xFFFFFFFF)
|
||
|
length = (unsigned)strlen(hard_coded[i].buf);
|
||
|
|
||
|
/* Add this to our real payloads. This will get overwritten
|
||
|
* if the user adds their own with the same port */
|
||
|
payloads_datagram_add(payloads,
|
||
|
(const unsigned char*)hard_coded[i].buf,
|
||
|
length,
|
||
|
&list,
|
||
|
hard_coded[i].source_port,
|
||
|
hard_coded[i].set_cookie);
|
||
|
|
||
|
rangelist_remove_all(&list);
|
||
|
}
|
||
|
return payloads;
|
||
|
}
|
||
|
|
||
|
|
||
|
int
|
||
|
templ_payloads_selftest(void) {
|
||
|
return templ_nmap_selftest();
|
||
|
}
|