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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers scanner.h Source File

scanner.h

Go to the documentation of this file.
00001 #ifndef SCANNER_H
00002 #define SCANNER_H
00003 
00004 #include "main.h"
00005 #include "net/net.h"
00006 #include "util/log.h"
00007 #include "sniffer.h"
00008 
00009 #include <cstring>
00010 #include <set>
00011 
00012 /**
00013   \file scanner.h
00014   \brief Basic TCP Port Scanner
00015   
00016   The class in this file facilitates a very fast (3 second scan, 7 second wait) TCP port scan
00017   of all ports from 1-65535, keeping and printing a list of all ports on which a TCP SYN/ACK
00018   is received (which should indicate that the port is open and waiting for connections).
00019 */
00020 
00021 #define SCANNER_PADSIZE   0
00022 #define SCANNER_FRAMESIZE (sizeof(Ethernet_FrameHeader) + sizeof(IP_PacketHeader) + sizeof(TCP_SegmentHeader) + SCANNER_PADSIZE)
00023 
00024 /// Demo - TCP Port Scanner
00025 class Scanner
00026 {
00027 private:
00028   Sniffer *sniffer;
00029   Ticker scan_timer;
00030   Timeout scan_timeout;
00031   
00032   u8 raw_frame[SCANNER_FRAMESIZE];
00033   
00034   IP_Address destip;
00035   u16 port_idx;
00036   u16 pseudo_checksum;
00037   
00038   set<u16> open_ports;
00039   
00040   LocalFileSystem local;
00041 
00042 public:
00043   /// Constructor
00044   inline Scanner(Sniffer *_sniffer)
00045   : sniffer(_sniffer), local("local")
00046   {
00047     sniffer->attach_tcp(this, &Scanner::handle_tcp);
00048   }
00049   
00050   /// Handle incoming TCP packets
00051   inline void handle_tcp(TCP_SegmentHeader *packet, u32 data_bytes)
00052   {
00053     if (packet->syn && packet->ack)
00054     {
00055       open_ports.insert(packet->source_port);
00056     }
00057   }
00058   
00059   /// Handle the conclusion of the port scan (should not be called externally)
00060   inline void finish()
00061   {
00062     FILE *fp = fopen("/local/PortScan.txt", "w");
00063     fprintf(fp, "Open Ports on %d.%d.%d.%d:\n", destip.octet[0], destip.octet[1], destip.octet[2], destip.octet[3]);
00064     for (set<u16>::iterator iter = open_ports.begin(); iter != open_ports.end(); ++iter)
00065     {
00066       fprintf(fp, "  TCP:%-5d OPEN\n", *iter);
00067     }
00068     fclose(fp);  
00069     
00070     main_log.printf("Open ports:");
00071     for (set<u16>::iterator iter = open_ports.begin(); iter != open_ports.end(); ++iter)
00072     {
00073       main_log.printf("  TCP:%-5d OPEN", *iter);
00074     }
00075     main_log.printf("Port scan complete.");
00076   }
00077   
00078   /// Start a TCP port scan
00079   inline void start(Ethernet_MAC src, Ethernet_MAC dst, IP_Address srcip, IP_Address dstip)
00080   {
00081     // Create the ethernet frame, IP packet, and TCP segment memory mapping
00082     static Ethernet_FrameHeader *frame = (Ethernet_FrameHeader*)raw_frame;
00083     static IP_PacketHeader *packet = (IP_PacketHeader*)frame->payload;
00084     static TCP_SegmentHeader *segment = (TCP_SegmentHeader*)packet->data;
00085     
00086     destip = dstip;
00087     main_log.printf("Starting TCP port scan of %d.%d.%d.%d...", dstip.octet[0], dstip.octet[1], dstip.octet[2], dstip.octet[3]);
00088     
00089     // Zero the frame
00090     memset(raw_frame, '\0', SCANNER_FRAMESIZE);
00091     
00092     //sniffer->inject(dst, frame->ethertype, packet, 0); //sizeof(raw_frame)-sizeof(Ethernet_FrameHeader));
00093 
00094     // Fill in the frame (constant for all TCP connections)
00095     frame->destination = dst;
00096     frame->source = src;
00097     frame->ethertype = ETHERTYPE_IPV4;
00098     
00099     // Fill in the IP packet
00100     packet->source = srcip; // Can't change with destination back-to-back? lol
00101     packet->version = 0x04;
00102     packet->header_bytes_div4 = 5; // *4 = 20
00103     packet->packet_bytes = SCANNER_FRAMESIZE-sizeof(Ethernet_FrameHeader);
00104     packet->ttl = 64;
00105     packet->protocol = IPPROTO_TCP;
00106     packet->destination = dstip;
00107     
00108     // Fill in the TCP segment
00109     segment->sequence_number = 0xBADBEEF0;
00110     segment->data_offset_bytes_div4 = sizeof(TCP_SegmentHeader)/4;
00111     segment->syn = 1;
00112     segment->window_size = 8192;
00113     pseudo_checksum = pseudo_header_checksum(srcip, dstip, sizeof(TCP_SegmentHeader));
00114     
00115     // Initialize the scanning
00116     port_idx = 0;
00117     
00118     open_ports.clear();
00119     scan_timer.attach_us(this, &Scanner::scan, 50);
00120     //scan();
00121   }
00122   
00123   /// Incremental scan updates (should not be called externally)
00124   inline void scan()
00125   {
00126     // Common ports... currently unused
00127     static u16 ports[] = {1, 2, 3, 5, 7, 9, 11, 13, 17, 18, 19, 20, 21, 22, 23, 24, 25, 35, 37, 39,
00128       41, 42, 43, 47, 49, 50, 51, 52, 53, 54, 56, 58, 70, 79, 80, 83, 88, 90, 101, 102,
00129       104, 105, 107, 108, 109, 110, 111, 113, 113, 115, 117, 118, 119, 135, 137, 138, 139, 143, 152, 153,
00130       156, 162, 170, 177, 179, 194, 199, 201, 209, 210, 213, 218, 220, 259, 264, 308, 311, 318, 350, 351,
00131       366, 369, 371, 383, 384, 387, 389, 401, 427, 443, 444, 445, 464, 475, 497, 504, 512, 513, 514, 515,
00132       520, 524, 530, 532, 540, 542, 543, 544, 546, 547, 548, 554, 556, 563, 587, 591, 593, 604, 631, 635,
00133       636, 639, 641, 646, 647, 648, 653, 654, 657, 660, 674, 691, 692, 694, 695, 699, 700, 701, 702, 706,
00134       711, 712, 749, 750, 751, 752, 753, 754, 760, 860, 873, 902, 989, 990, 991, 992, 993, 995, 1058,
00135       1080, 1085, 1098, 1099, 1140, 1169, 1176, 1182, 1194, 1198, 1200, 1214, 1220, 1223, 1241, 1270, 1293, 1337, 1352, 1387,
00136       1414, 1417, 1418, 1419, 1420, 1431, 1433, 1470, 1494, 1512, 1513, 1521, 1524, 1533, 1547, 1677, 1720, 1723, 1755, 1761,
00137       1762, 1763, 1764, 1765, 1766, 1767, 1768, 1801, 1812, 1813, 1863, 1935, 1947, 1970, 1971, 1972, 1984, 1994, 1998, 2000,
00138       2031, 2053, 2073, 2074, 2082, 2083, 2086, 2102, 2103, 2104, 2105, 2144, 2145, 2161, 2181, 2210, 2211, 2212, 2219, 2220,
00139       2261, 2262, 2369, 2370, 2404, 2447, 2483, 2484, 2500, 2612, 2713, 2714, 2735, 2809, 2868, 2947, 2948, 2949, 3050, 3051,
00140       3074, 3225, 3233, 3235, 3260, 3268, 3269, 3283, 3305, 3306, 3386, 3389, 3396, 3412, 3455, 3423, 3424, 3478, 3483, 3516,
00141       3532, 3533, 3606, 3632, 3689, 3690, 3702, 3880, 3868, 3900, 3945, 3999, 4018, 4089, 4093, 4096, 4111, 4116, 4321, 4662,
00142       4728, 4840, 4843, 4847, 4993, 4894, 4899, 4950, 5000, 5001, 5003, 5004, 5005, 5051, 5060, 5061, 5070, 5084, 5085, 5099,
00143       5151, 5154, 5190, 5222, 5269, 5298, 5351, 5355, 5402, 5405, 5421, 5432, 5556, 5631, 5814, 5900, 5984, 5999, 6000, 6005,
00144       6086, 6110, 6111, 6112, 6129, 6346, 6347, 6350, 6432, 6444, 6445, 6619, 6665, 6666, 6667, 6668, 6669, 6888, 6969, 7005,
00145       7006, 7400, 7401, 7402, 7547, 7787, 7788, 8000, 8008, 8078, 8080, 8118, 8123, 8243, 8280, 8400, 8442, 8880, 8888, 9009,
00146       9080, 9100, 9105, 9119, 9306, 9312, 9418, 9535, 9536, 9800, 9898, 9996, 10008, 10010, 10050, 10051, 10113, 10114, 10115,
00147       10116, 13076, 13720, 13721, 13724, 13782, 13783, 13785, 13786, 15000, 15345, 17500, 18104, 19283, 19315, 22347, 22350,
00148       24465, 24554, 26000, 31457, 33434, 40000, 43047, 43048, 47808};
00149     
00150     // Create the ethernet frame, IP packet, and TCP segment memory mapping
00151     static Ethernet_FrameHeader *frame = (Ethernet_FrameHeader*)raw_frame;
00152     static IP_PacketHeader *packet = (IP_PacketHeader*)frame->payload;
00153     static TCP_SegmentHeader *segment = (TCP_SegmentHeader*)packet->data;
00154     
00155     segment->source_port = port_idx; //ports[port_idx];
00156     segment->destination_port = port_idx; //ports[port_idx];
00157     
00158     fix_endian_tcp(segment);
00159     segment->checksum = checksum(segment, sizeof(TCP_SegmentHeader), &segment->checksum, sizeof(segment->checksum), pseudo_checksum);
00160     
00161     fix_endian_ip(packet);
00162     packet->header_checksum = checksum(packet, sizeof(IP_PacketHeader), &packet->header_checksum, sizeof(packet->header_checksum));
00163     
00164     fix_endian_ethernet(frame);
00165     sniffer->inject(frame, SCANNER_FRAMESIZE);
00166     
00167     fix_endian_ethernet(frame);
00168     fix_endian_ip(packet);
00169     fix_endian_tcp(segment);
00170     
00171     // Update sequence number
00172     segment->sequence_number++;
00173     
00174     //if (port_idx >= sizeof(ports)/sizeof(u16)) scan_timer.detach();
00175     if (port_idx >= 65535)
00176     {
00177       scan_timer.detach();
00178       scan_timeout.attach(this, &Scanner::finish, 7);
00179     }
00180     port_idx++;
00181   }
00182 };
00183 
00184 #endif