This is a low-level network debugging utility that utilizes raw packet i/o to construct and deconstruct tcp, udp, ipv4, arp, and icmp packets over ethernet.

Dependencies:   mbed

Committer:
etherealflaim
Date:
Tue Oct 12 06:46:22 2010 +0000
Revision:
6:66c4cd9073aa
Parent:
5:c56386b9fc33
File documentation updates

Who changed what in which revision?

UserRevisionLine numberNew contents of line
etherealflaim 0:d494b853ce97 1 #ifndef SCANNER_H
etherealflaim 0:d494b853ce97 2 #define SCANNER_H
etherealflaim 0:d494b853ce97 3
etherealflaim 0:d494b853ce97 4 #include "main.h"
etherealflaim 0:d494b853ce97 5 #include "net/net.h"
etherealflaim 0:d494b853ce97 6 #include "util/log.h"
etherealflaim 0:d494b853ce97 7 #include "sniffer.h"
etherealflaim 0:d494b853ce97 8
etherealflaim 0:d494b853ce97 9 #include <cstring>
etherealflaim 0:d494b853ce97 10 #include <set>
etherealflaim 0:d494b853ce97 11
etherealflaim 6:66c4cd9073aa 12 /**
etherealflaim 6:66c4cd9073aa 13 \file scanner.h
etherealflaim 6:66c4cd9073aa 14 \brief Basic TCP Port Scanner
etherealflaim 6:66c4cd9073aa 15
etherealflaim 6:66c4cd9073aa 16 The class in this file facilitates a very fast (3 second scan, 7 second wait) TCP port scan
etherealflaim 6:66c4cd9073aa 17 of all ports from 1-65535, keeping and printing a list of all ports on which a TCP SYN/ACK
etherealflaim 6:66c4cd9073aa 18 is received (which should indicate that the port is open and waiting for connections).
etherealflaim 6:66c4cd9073aa 19 */
etherealflaim 6:66c4cd9073aa 20
etherealflaim 0:d494b853ce97 21 #define SCANNER_PADSIZE 0
etherealflaim 0:d494b853ce97 22 #define SCANNER_FRAMESIZE (sizeof(Ethernet_FrameHeader) + sizeof(IP_PacketHeader) + sizeof(TCP_SegmentHeader) + SCANNER_PADSIZE)
etherealflaim 0:d494b853ce97 23
etherealflaim 4:88fc7fa58931 24 /// Demo - TCP Port Scanner
etherealflaim 0:d494b853ce97 25 class Scanner
etherealflaim 0:d494b853ce97 26 {
etherealflaim 0:d494b853ce97 27 private:
etherealflaim 0:d494b853ce97 28 Sniffer *sniffer;
etherealflaim 0:d494b853ce97 29 Ticker scan_timer;
etherealflaim 0:d494b853ce97 30 Timeout scan_timeout;
etherealflaim 0:d494b853ce97 31
etherealflaim 0:d494b853ce97 32 u8 raw_frame[SCANNER_FRAMESIZE];
etherealflaim 0:d494b853ce97 33
etherealflaim 0:d494b853ce97 34 IP_Address destip;
etherealflaim 0:d494b853ce97 35 u16 port_idx;
etherealflaim 0:d494b853ce97 36 u16 pseudo_checksum;
etherealflaim 0:d494b853ce97 37
etherealflaim 0:d494b853ce97 38 set<u16> open_ports;
etherealflaim 0:d494b853ce97 39
etherealflaim 0:d494b853ce97 40 LocalFileSystem local;
etherealflaim 0:d494b853ce97 41
etherealflaim 0:d494b853ce97 42 public:
etherealflaim 5:c56386b9fc33 43 /// Constructor
etherealflaim 0:d494b853ce97 44 inline Scanner(Sniffer *_sniffer)
etherealflaim 0:d494b853ce97 45 : sniffer(_sniffer), local("local")
etherealflaim 0:d494b853ce97 46 {
etherealflaim 0:d494b853ce97 47 sniffer->attach_tcp(this, &Scanner::handle_tcp);
etherealflaim 0:d494b853ce97 48 }
etherealflaim 0:d494b853ce97 49
etherealflaim 5:c56386b9fc33 50 /// Handle incoming TCP packets
etherealflaim 0:d494b853ce97 51 inline void handle_tcp(TCP_SegmentHeader *packet, u32 data_bytes)
etherealflaim 0:d494b853ce97 52 {
etherealflaim 0:d494b853ce97 53 if (packet->syn && packet->ack)
etherealflaim 0:d494b853ce97 54 {
etherealflaim 0:d494b853ce97 55 open_ports.insert(packet->source_port);
etherealflaim 0:d494b853ce97 56 }
etherealflaim 0:d494b853ce97 57 }
etherealflaim 0:d494b853ce97 58
etherealflaim 5:c56386b9fc33 59 /// Handle the conclusion of the port scan (should not be called externally)
etherealflaim 0:d494b853ce97 60 inline void finish()
etherealflaim 0:d494b853ce97 61 {
etherealflaim 0:d494b853ce97 62 FILE *fp = fopen("/local/PortScan.txt", "w");
etherealflaim 0:d494b853ce97 63 fprintf(fp, "Open Ports on %d.%d.%d.%d:\n", destip.octet[0], destip.octet[1], destip.octet[2], destip.octet[3]);
etherealflaim 0:d494b853ce97 64 for (set<u16>::iterator iter = open_ports.begin(); iter != open_ports.end(); ++iter)
etherealflaim 0:d494b853ce97 65 {
etherealflaim 0:d494b853ce97 66 fprintf(fp, " TCP:%-5d OPEN\n", *iter);
etherealflaim 0:d494b853ce97 67 }
etherealflaim 0:d494b853ce97 68 fclose(fp);
etherealflaim 0:d494b853ce97 69
etherealflaim 0:d494b853ce97 70 main_log.printf("Open ports:");
etherealflaim 0:d494b853ce97 71 for (set<u16>::iterator iter = open_ports.begin(); iter != open_ports.end(); ++iter)
etherealflaim 0:d494b853ce97 72 {
etherealflaim 0:d494b853ce97 73 main_log.printf(" TCP:%-5d OPEN", *iter);
etherealflaim 0:d494b853ce97 74 }
etherealflaim 0:d494b853ce97 75 main_log.printf("Port scan complete.");
etherealflaim 0:d494b853ce97 76 }
etherealflaim 0:d494b853ce97 77
etherealflaim 5:c56386b9fc33 78 /// Start a TCP port scan
etherealflaim 0:d494b853ce97 79 inline void start(Ethernet_MAC src, Ethernet_MAC dst, IP_Address srcip, IP_Address dstip)
etherealflaim 0:d494b853ce97 80 {
etherealflaim 0:d494b853ce97 81 // Create the ethernet frame, IP packet, and TCP segment memory mapping
etherealflaim 0:d494b853ce97 82 static Ethernet_FrameHeader *frame = (Ethernet_FrameHeader*)raw_frame;
etherealflaim 0:d494b853ce97 83 static IP_PacketHeader *packet = (IP_PacketHeader*)frame->payload;
etherealflaim 0:d494b853ce97 84 static TCP_SegmentHeader *segment = (TCP_SegmentHeader*)packet->data;
etherealflaim 0:d494b853ce97 85
etherealflaim 0:d494b853ce97 86 destip = dstip;
etherealflaim 0:d494b853ce97 87 main_log.printf("Starting TCP port scan of %d.%d.%d.%d...", dstip.octet[0], dstip.octet[1], dstip.octet[2], dstip.octet[3]);
etherealflaim 0:d494b853ce97 88
etherealflaim 0:d494b853ce97 89 // Zero the frame
etherealflaim 0:d494b853ce97 90 memset(raw_frame, '\0', SCANNER_FRAMESIZE);
etherealflaim 0:d494b853ce97 91
etherealflaim 0:d494b853ce97 92 //sniffer->inject(dst, frame->ethertype, packet, 0); //sizeof(raw_frame)-sizeof(Ethernet_FrameHeader));
etherealflaim 0:d494b853ce97 93
etherealflaim 0:d494b853ce97 94 // Fill in the frame (constant for all TCP connections)
etherealflaim 0:d494b853ce97 95 frame->destination = dst;
etherealflaim 0:d494b853ce97 96 frame->source = src;
etherealflaim 0:d494b853ce97 97 frame->ethertype = ETHERTYPE_IPV4;
etherealflaim 0:d494b853ce97 98
etherealflaim 0:d494b853ce97 99 // Fill in the IP packet
etherealflaim 0:d494b853ce97 100 packet->source = srcip; // Can't change with destination back-to-back? lol
etherealflaim 0:d494b853ce97 101 packet->version = 0x04;
etherealflaim 0:d494b853ce97 102 packet->header_bytes_div4 = 5; // *4 = 20
etherealflaim 0:d494b853ce97 103 packet->packet_bytes = SCANNER_FRAMESIZE-sizeof(Ethernet_FrameHeader);
etherealflaim 0:d494b853ce97 104 packet->ttl = 64;
etherealflaim 0:d494b853ce97 105 packet->protocol = IPPROTO_TCP;
etherealflaim 0:d494b853ce97 106 packet->destination = dstip;
etherealflaim 0:d494b853ce97 107
etherealflaim 0:d494b853ce97 108 // Fill in the TCP segment
etherealflaim 0:d494b853ce97 109 segment->sequence_number = 0xBADBEEF0;
etherealflaim 0:d494b853ce97 110 segment->data_offset_bytes_div4 = sizeof(TCP_SegmentHeader)/4;
etherealflaim 0:d494b853ce97 111 segment->syn = 1;
etherealflaim 0:d494b853ce97 112 segment->window_size = 8192;
etherealflaim 0:d494b853ce97 113 pseudo_checksum = pseudo_header_checksum(srcip, dstip, sizeof(TCP_SegmentHeader));
etherealflaim 0:d494b853ce97 114
etherealflaim 0:d494b853ce97 115 // Initialize the scanning
etherealflaim 0:d494b853ce97 116 port_idx = 0;
etherealflaim 0:d494b853ce97 117
etherealflaim 0:d494b853ce97 118 open_ports.clear();
etherealflaim 0:d494b853ce97 119 scan_timer.attach_us(this, &Scanner::scan, 50);
etherealflaim 0:d494b853ce97 120 //scan();
etherealflaim 0:d494b853ce97 121 }
etherealflaim 0:d494b853ce97 122
etherealflaim 5:c56386b9fc33 123 /// Incremental scan updates (should not be called externally)
etherealflaim 0:d494b853ce97 124 inline void scan()
etherealflaim 0:d494b853ce97 125 {
etherealflaim 5:c56386b9fc33 126 // Common ports... currently unused
etherealflaim 0:d494b853ce97 127 static u16 ports[] = {1, 2, 3, 5, 7, 9, 11, 13, 17, 18, 19, 20, 21, 22, 23, 24, 25, 35, 37, 39,
etherealflaim 0:d494b853ce97 128 41, 42, 43, 47, 49, 50, 51, 52, 53, 54, 56, 58, 70, 79, 80, 83, 88, 90, 101, 102,
etherealflaim 0:d494b853ce97 129 104, 105, 107, 108, 109, 110, 111, 113, 113, 115, 117, 118, 119, 135, 137, 138, 139, 143, 152, 153,
etherealflaim 0:d494b853ce97 130 156, 162, 170, 177, 179, 194, 199, 201, 209, 210, 213, 218, 220, 259, 264, 308, 311, 318, 350, 351,
etherealflaim 0:d494b853ce97 131 366, 369, 371, 383, 384, 387, 389, 401, 427, 443, 444, 445, 464, 475, 497, 504, 512, 513, 514, 515,
etherealflaim 0:d494b853ce97 132 520, 524, 530, 532, 540, 542, 543, 544, 546, 547, 548, 554, 556, 563, 587, 591, 593, 604, 631, 635,
etherealflaim 0:d494b853ce97 133 636, 639, 641, 646, 647, 648, 653, 654, 657, 660, 674, 691, 692, 694, 695, 699, 700, 701, 702, 706,
etherealflaim 0:d494b853ce97 134 711, 712, 749, 750, 751, 752, 753, 754, 760, 860, 873, 902, 989, 990, 991, 992, 993, 995, 1058,
etherealflaim 0:d494b853ce97 135 1080, 1085, 1098, 1099, 1140, 1169, 1176, 1182, 1194, 1198, 1200, 1214, 1220, 1223, 1241, 1270, 1293, 1337, 1352, 1387,
etherealflaim 0:d494b853ce97 136 1414, 1417, 1418, 1419, 1420, 1431, 1433, 1470, 1494, 1512, 1513, 1521, 1524, 1533, 1547, 1677, 1720, 1723, 1755, 1761,
etherealflaim 0:d494b853ce97 137 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1801, 1812, 1813, 1863, 1935, 1947, 1970, 1971, 1972, 1984, 1994, 1998, 2000,
etherealflaim 0:d494b853ce97 138 2031, 2053, 2073, 2074, 2082, 2083, 2086, 2102, 2103, 2104, 2105, 2144, 2145, 2161, 2181, 2210, 2211, 2212, 2219, 2220,
etherealflaim 0:d494b853ce97 139 2261, 2262, 2369, 2370, 2404, 2447, 2483, 2484, 2500, 2612, 2713, 2714, 2735, 2809, 2868, 2947, 2948, 2949, 3050, 3051,
etherealflaim 0:d494b853ce97 140 3074, 3225, 3233, 3235, 3260, 3268, 3269, 3283, 3305, 3306, 3386, 3389, 3396, 3412, 3455, 3423, 3424, 3478, 3483, 3516,
etherealflaim 0:d494b853ce97 141 3532, 3533, 3606, 3632, 3689, 3690, 3702, 3880, 3868, 3900, 3945, 3999, 4018, 4089, 4093, 4096, 4111, 4116, 4321, 4662,
etherealflaim 0:d494b853ce97 142 4728, 4840, 4843, 4847, 4993, 4894, 4899, 4950, 5000, 5001, 5003, 5004, 5005, 5051, 5060, 5061, 5070, 5084, 5085, 5099,
etherealflaim 0:d494b853ce97 143 5151, 5154, 5190, 5222, 5269, 5298, 5351, 5355, 5402, 5405, 5421, 5432, 5556, 5631, 5814, 5900, 5984, 5999, 6000, 6005,
etherealflaim 0:d494b853ce97 144 6086, 6110, 6111, 6112, 6129, 6346, 6347, 6350, 6432, 6444, 6445, 6619, 6665, 6666, 6667, 6668, 6669, 6888, 6969, 7005,
etherealflaim 0:d494b853ce97 145 7006, 7400, 7401, 7402, 7547, 7787, 7788, 8000, 8008, 8078, 8080, 8118, 8123, 8243, 8280, 8400, 8442, 8880, 8888, 9009,
etherealflaim 0:d494b853ce97 146 9080, 9100, 9105, 9119, 9306, 9312, 9418, 9535, 9536, 9800, 9898, 9996, 10008, 10010, 10050, 10051, 10113, 10114, 10115,
etherealflaim 0:d494b853ce97 147 10116, 13076, 13720, 13721, 13724, 13782, 13783, 13785, 13786, 15000, 15345, 17500, 18104, 19283, 19315, 22347, 22350,
etherealflaim 0:d494b853ce97 148 24465, 24554, 26000, 31457, 33434, 40000, 43047, 43048, 47808};
etherealflaim 0:d494b853ce97 149
etherealflaim 0:d494b853ce97 150 // Create the ethernet frame, IP packet, and TCP segment memory mapping
etherealflaim 0:d494b853ce97 151 static Ethernet_FrameHeader *frame = (Ethernet_FrameHeader*)raw_frame;
etherealflaim 0:d494b853ce97 152 static IP_PacketHeader *packet = (IP_PacketHeader*)frame->payload;
etherealflaim 0:d494b853ce97 153 static TCP_SegmentHeader *segment = (TCP_SegmentHeader*)packet->data;
etherealflaim 0:d494b853ce97 154
etherealflaim 0:d494b853ce97 155 segment->source_port = port_idx; //ports[port_idx];
etherealflaim 0:d494b853ce97 156 segment->destination_port = port_idx; //ports[port_idx];
etherealflaim 0:d494b853ce97 157
etherealflaim 0:d494b853ce97 158 fix_endian_tcp(segment);
etherealflaim 0:d494b853ce97 159 segment->checksum = checksum(segment, sizeof(TCP_SegmentHeader), &segment->checksum, sizeof(segment->checksum), pseudo_checksum);
etherealflaim 0:d494b853ce97 160
etherealflaim 0:d494b853ce97 161 fix_endian_ip(packet);
etherealflaim 0:d494b853ce97 162 packet->header_checksum = checksum(packet, sizeof(IP_PacketHeader), &packet->header_checksum, sizeof(packet->header_checksum));
etherealflaim 0:d494b853ce97 163
etherealflaim 0:d494b853ce97 164 fix_endian_ethernet(frame);
etherealflaim 0:d494b853ce97 165 sniffer->inject(frame, SCANNER_FRAMESIZE);
etherealflaim 0:d494b853ce97 166
etherealflaim 0:d494b853ce97 167 fix_endian_ethernet(frame);
etherealflaim 0:d494b853ce97 168 fix_endian_ip(packet);
etherealflaim 0:d494b853ce97 169 fix_endian_tcp(segment);
etherealflaim 0:d494b853ce97 170
etherealflaim 0:d494b853ce97 171 // Update sequence number
etherealflaim 0:d494b853ce97 172 segment->sequence_number++;
etherealflaim 0:d494b853ce97 173
etherealflaim 0:d494b853ce97 174 //if (port_idx >= sizeof(ports)/sizeof(u16)) scan_timer.detach();
etherealflaim 0:d494b853ce97 175 if (port_idx >= 65535)
etherealflaim 0:d494b853ce97 176 {
etherealflaim 0:d494b853ce97 177 scan_timer.detach();
etherealflaim 0:d494b853ce97 178 scan_timeout.attach(this, &Scanner::finish, 7);
etherealflaim 0:d494b853ce97 179 }
etherealflaim 0:d494b853ce97 180 port_idx++;
etherealflaim 0:d494b853ce97 181 }
etherealflaim 0:d494b853ce97 182 };
etherealflaim 0:d494b853ce97 183
etherealflaim 0:d494b853ce97 184 #endif