diff --git a/src/main-conf.c b/src/main-conf.c index f16ecc616a2a4547b66e016a9616392f1e71a531..fa2980f2f339ed0c13f83de21f8b15203ce0ef88 100644 --- a/src/main-conf.c +++ b/src/main-conf.c @@ -1345,7 +1345,7 @@ masscan_set_parameter(struct Masscan *masscan, } else if (EQUALS("datadir", name)) { strcpy_s(masscan->nmap.datadir, sizeof(masscan->nmap.datadir), value); } else if (EQUALS("data-length", name)) { - unsigned x = strtoul(value, 0, 0); + unsigned x = (unsigned)strtoul(value, 0, 0); if (x >= 1514 - 14 - 40) { fprintf(stderr, "error: %s=<n>: expected number less than 1500\n", name); } else { @@ -1655,7 +1655,7 @@ masscan_set_parameter(struct Masscan *masscan, while (offset < max_offset && isspace(value[offset])) offset++; if (offset+1 < max_offset && value[offset] == ':' && isdigit(value[offset+1]&0xFF)) { - port = strtoul(value+offset+1, 0, 0); + port = (unsigned)strtoul(value+offset+1, 0, 0); if (port > 65535 || port == 0) { LOG(0, "FAIL: bad redis port: %s\n", value+offset+1); exit(1); @@ -1679,7 +1679,7 @@ masscan_set_parameter(struct Masscan *masscan, } else if (EQUALS("resume-count", name)) { masscan->resume.count = parseInt(value); } else if (EQUALS("retries", name) || EQUALS("retry", name)) { - unsigned x = strtoul(value, 0, 0); + unsigned x = (unsigned)strtoul(value, 0, 0); if (x >= 1000) { fprintf(stderr, "error: retries=<n>: expected number less than 1000\n"); } else { @@ -1809,7 +1809,7 @@ masscan_set_parameter(struct Masscan *masscan, if (EQUALS("csv", value)) masscan->is_test_csv = 0; } else if (EQUALS("ttl", name)) { - unsigned x = strtoul(value, 0, 0); + unsigned x = (unsigned)strtoul(value, 0, 0); if (x >= 256) { fprintf(stderr, "error: %s=<n>: expected number less than 256\n", name); } else { diff --git a/src/masscan-app.h b/src/masscan-app.h index 854ed6621cf6e33fdf11a4eca0295acb66c2b662..402bd1b8a7270b1b77dac7836e7c3393bc79413d 100644 --- a/src/masscan-app.h +++ b/src/masscan-app.h @@ -30,6 +30,10 @@ enum ApplicationProtocol { PROTO_VNC_RFB, PROTO_SAFE, PROTO_MEMCACHED, + + + + PROTO_end_of_list /* must be last one */ }; const char * diff --git a/src/proto-banner1.c b/src/proto-banner1.c index b3bb5871b6fd252108c709035558f6d254082c3e..b1d8b03d86ae4242f9ae116caf4433b7662809fc 100644 --- a/src/proto-banner1.c +++ b/src/proto-banner1.c @@ -141,7 +141,7 @@ banner1_parse( banout, more); break; - case PROTO_SMTP: + case PROTO_SMTP: banner_smtp.parse( banner1, banner1->http_fields, tcb_state, @@ -238,7 +238,9 @@ banner1_create(void) memset(b, 0, sizeof(*b)); /* - * These patterns match the start of the TCP stream + * This creates a pattern-matching blob for heuristically determining + * a protocol that runs on wrong ports, such as how FTP servers + * often respond with "220 " or VNC servers respond with "RFB". */ b->smack = smack_create("banner1", SMACK_CASE_INSENSITIVE); for (i=0; patterns[i].pattern; i++) @@ -251,9 +253,19 @@ banner1_create(void) smack_compile(b->smack); + /* + * This goes down the list of all the TCP protocol handlers and initializes + * them. + */ + banner_ftp.init(b); banner_http.init(b); - banner_vnc.init(b); + banner_imap4.init(b); banner_memcached.init(b); + banner_pop3.init(b); + banner_smtp.init(b); + banner_ssh.init(b); + banner_ssl.init(b); + banner_vnc.init(b); b->tcp_payloads[80] = &banner_http; b->tcp_payloads[8080] = &banner_http; diff --git a/src/proto-banner1.h b/src/proto-banner1.h index 0eb1998dc91178b37b01341cf9ea3bd401aad1ef..ce99ce7b6c76f2393c124bbe4e94188b0565164b 100644 --- a/src/proto-banner1.h +++ b/src/proto-banner1.h @@ -3,11 +3,21 @@ #include <stdint.h> #define STATE_DONE 0xFFFFFFFF #include <stdio.h> +#include "masscan-app.h" #include "proto-banout.h" #include "proto-x509.h" struct InteractiveData; - +struct Banner1; +struct ProtocolState; + +typedef void (*BannerParser)( + const struct Banner1 *banner1, + void *banner1_private, + struct ProtocolState *stream_state, + const unsigned char *px, size_t length, + struct BannerOutput *banout, + struct InteractiveData *more); struct Banner1 { struct SMACK *smack; @@ -25,6 +35,8 @@ struct Banner1 unsigned is_poodle_sslv3:1; struct ProtocolParserStream *tcp_payloads[65536]; + + BannerParser parser[PROTO_end_of_list]; }; struct BannerBase64 diff --git a/src/proto-banout.c b/src/proto-banout.c index ec07b26ef4f4fc0bb2294bf5105c404b2d578e88..e24553e39f4ac8c9d2740d23e7fdcd6bfb3c07a4 100644 --- a/src/proto-banout.c +++ b/src/proto-banout.c @@ -37,6 +37,7 @@ banout_release(struct BannerOutput *banout) free(banout->next); banout->next = next; } + banout_init(banout); } diff --git a/src/proto-tcp.c b/src/proto-tcp.c index 1a81a3cc58c2b011fe6d9564c1f50ee486b6537d..f04f1df118ef18383893152d56ceca6aad74125f 100644 --- a/src/proto-tcp.c +++ b/src/proto-tcp.c @@ -313,7 +313,7 @@ tcpcon_set_parameter(struct TCP_ConnectionTable *tcpcon, fprintf(stderr, "tcpcon: parmeter: expected array []: %s\n", name); exit(1); } - port = strtoul(p+1, 0, 0); + port = (unsigned)strtoul(p+1, 0, 0); x = banner1->tcp_payloads[port]; if (x == NULL) { @@ -460,6 +460,42 @@ enum DestroyReason { }; +/*************************************************************************** + * Flush all the banners asssociated with this TCP connection. This always + * called when TCB is destroyed. This may also be called earlier, such + * as when a FIN is received. + ***************************************************************************/ +static void +tcpcon_flush_banners(struct TCP_ConnectionTable *tcpcon, struct TCP_Control_Block *tcb) +{ + struct BannerOutput *banout; + + /* Go through and print all the banners. Some protocols have + * multiple banners. For example, web servers have both + * HTTP and HTML banners, and SSL also has several + * X.509 certificate banners */ + for (banout = &tcb->banout; banout != NULL; banout = banout->next) { + if (banout->length && banout->protocol) { + tcpcon->report_banner( + tcpcon->out, + global_now, + tcb->ip_them, + 6, /*TCP protocol*/ + tcb->port_them, + banout->protocol & 0x0FFFFFFF, + tcb->ttl, + banout->banner, + banout->length); + } + } + + /* + * Free up all the banners. + */ + banout_release(&tcb->banout); + +} + /*************************************************************************** * Destroy a TCP connection entry. We have to unlink both from the * TCB-table as well as the timeout-table. @@ -473,8 +509,7 @@ tcpcon_destroy_tcb( { unsigned index; struct TCP_Control_Block **r_entry; - struct BannerOutput *banout; - + UNUSEDPARM(reason); //printf("." "tcb age = %u-sec, reason=%u \n", time(0) - tcb->when_created, reason); @@ -512,27 +547,10 @@ tcpcon_destroy_tcb( /* * Print out any banners associated with this TCP session. Most of the - * time, there'll only be one. + * time, there'll only be one. After printing them out, delete the + * banners. */ - for (banout = &tcb->banout; banout != NULL; banout = banout->next) { - if (banout->length && banout->protocol) { - tcpcon->report_banner( - tcpcon->out, - global_now, - tcb->ip_them, - 6, /*TCP protocol*/ - tcb->port_them, - banout->protocol & 0x0FFFFFFF, - tcb->ttl, - banout->banner, - banout->length); - } - } - - /* - * If there are multiple banners, then free the additional ones - */ - banout_release(&tcb->banout); + tcpcon_flush_banners(tcpcon, tcb); /* * Unlink this from the timeout system. @@ -1238,6 +1256,7 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon, 0x11, 0, 0, 0); tcb->seqno_me++; + tcpcon_flush_banners(tcpcon, tcb); break; case STATE_WAITING_FOR_RESPONSE<<8 | TCP_WHAT_TIMEOUT: diff --git a/src/ranges.c b/src/ranges.c index df53fd36ac6e2f3d204d65c5108c61218ae11284..2a636eb04f10ec380493a62b3fc1dfcd6eebec41 100644 --- a/src/ranges.c +++ b/src/ranges.c @@ -642,11 +642,11 @@ rangelist_parse_ports(struct RangeList *ports, const char *string, unsigned *is_ if (!isdigit(p[0] & 0xFF)) break; - port = strtoul(p, &p, 0); + port = (unsigned)strtoul(p, &p, 0); end = port; if (*p == '-') { p++; - end = strtoul(p, &p, 0); + end = (unsigned)strtoul(p, &p, 0); } if (port > 0xFFFF || end > 0xFFFF || end < port) { diff --git a/src/rawsock-getif.c b/src/rawsock-getif.c index 77d6e2259afb8bf722f2ee0e8a13b9b6609f40c4..4da549255d3fd32f8d7d641e3cc8fb83d65e0d5c 100644 --- a/src/rawsock-getif.c +++ b/src/rawsock-getif.c @@ -43,7 +43,7 @@ int rawsock_get_default_interface(char *ifname, size_t sizeof_ifname) { int fd; - int seq = time(0); + int seq = (int)time(0); int err; struct rt_msghdr *rtm; size_t sizeof_buffer; diff --git a/src/rawsock-getroute.c b/src/rawsock-getroute.c index 95af493774fc3f0e29ae05804bf8fdb60a15a679..cbc399ad085b0d442795199e0e13792baa41dc4a 100644 --- a/src/rawsock-getroute.c +++ b/src/rawsock-getroute.c @@ -99,7 +99,7 @@ int rawsock_get_default_gateway(const char *ifname, unsigned *ipv4) { int fd; - int seq = time(0); + int seq = (int)time(0); int err; struct rt_msghdr *rtm; size_t sizeof_buffer; diff --git a/src/rawsock-pcapfile.c b/src/rawsock-pcapfile.c index cd879bacab2dbb63f2a4ac3aadc74cf8d546e0c3..d6c583f1a5915b7cf8ae5c593e3073f84c406637 100644 --- a/src/rawsock-pcapfile.c +++ b/src/rawsock-pcapfile.c @@ -613,7 +613,7 @@ struct PcapFile *pcapfile_openread(const char *capfilename) /* Read the first frame's timestamp */ { - int loc; + long loc; char tsbuf[8]; size_t x;