Loading doc/masscan.8.markdown +5 −0 Original line number Diff line number Diff line Loading @@ -205,6 +205,11 @@ one port. equivelents, but require a separate step to convert back into XML or another readable format. * `--readscan <binary-files>`: reads the files created by the `-oB` option from a scan, then outputs them in one of the other formats, depending on command-line parameters. In other words, it can take the binary version of the output and convert it to an XML or JSON format. ## CONFIGURATION FILE FORMAT Loading src/in-binary.c 0 → 100644 +266 −0 Original line number Diff line number Diff line /* Read in the binary file produced by "out-binary.c". This allows you to translate the binary format into something more easily parsed, such as the XML or JSON formats. */ #include "masscan.h" #include "masscan-app.h" #include "main-globals.h" #include "output.h" #include "string_s.h" static const size_t BUF_MAX = 1024*1024; struct MasscanRecord { unsigned timestamp; unsigned ip; unsigned char ip_proto; unsigned short port; unsigned char reason; unsigned char ttl; enum ApplicationProtocol app_proto; }; /*************************************************************************** ***************************************************************************/ static void parse_status(struct Output *out, enum PortStatus status, /* open/closed */ const unsigned char *buf, size_t buf_length) { struct MasscanRecord record; if (buf_length < 12) return; /* parse record */ record.timestamp = buf[0]<<24 | buf[1]<<16 | buf[2]<<8 | buf[3]; record.ip = buf[4]<<24 | buf[5]<<16 | buf[6]<<8 | buf[7]; record.port = buf[8]<<8 | buf[9]; record.reason = buf[10]; record.ttl = buf[11]; /* * Now report ther result */ output_report_status(out, record.timestamp, status, record.ip, record.port, record.reason, record.ttl); } /*************************************************************************** * [OBSOLETE] * This parses an old version of the banner record. I've still got files * hanging around with this version, so I'm keeping it in the code for * now, but eventually I'll get rid of it. ***************************************************************************/ static void parse_banner3(struct Output *out, unsigned char *buf, size_t buf_length) { struct MasscanRecord record; /* * Parse the parts that are common to most records */ record.timestamp = buf[0]<<24 | buf[1]<<16 | buf[2]<<8 | buf[3]; record.ip = buf[4]<<24 | buf[5]<<16 | buf[6]<<8 | buf[7]; record.port = buf[8]<<8 | buf[9]; record.app_proto = buf[10]<<8 | buf[11]; /* * Now print the output */ output_report_banner( out, record.timestamp, record.ip, 6, /* this is always TCP */ record.port, record.app_proto, buf+12, (unsigned)buf_length-12 ); } /*************************************************************************** * Parse the BANNER record, extracting the timestamp, IP addres, and port * number. We also convert the banner string into a safer form. ***************************************************************************/ void parse_banner4(struct Output *out, unsigned char *buf, size_t buf_length) { struct MasscanRecord record; /* * Parse the parts that are common to most records */ record.timestamp = buf[0]<<24 | buf[1]<<16 | buf[2]<<8 | buf[3]; record.ip = buf[4]<<24 | buf[5]<<16 | buf[6]<<8 | buf[7]; record.ip_proto = buf[8]; record.port = buf[9]<<8 | buf[10]; record.app_proto = buf[11]<<8 | buf[12]; /* * Now print the output */ output_report_banner( out, record.timestamp, record.ip, record.ip_proto, /* TCP=6, UDP=17 */ record.port, record.app_proto, /* HTTP, SSL, SNMP, etc. */ buf+13, (unsigned)buf_length-13 ); } /*************************************************************************** * Read in the file, one record at a time. ***************************************************************************/ uint64_t parse_file(struct Output *out, const char *filename) { FILE *fp = 0; unsigned char *buf = 0; size_t bytes_read; uint64_t total_records = 0; int x; /* Allocate a buffer of up to one megabyte per record */ buf = (unsigned char *)malloc(BUF_MAX); if (buf == NULL) { fprintf(stderr, "memory allocation failure\n"); goto end; } /* Open the file */ x = fopen_s(&fp, filename, "rb"); if (x != 0 || fp == NULL) { perror(filename); goto end; } /* first record is pseudo-record */ bytes_read = fread(buf, 1, 'a'+2, fp); if (bytes_read < 'a'+2) { perror(filename); goto end; } /* Make sure it's got the format string */ if (memcmp(buf, "masscan/1.1", 11) != 0) { fprintf(stderr, "%s: unknown file format (expeced \"masscan/1.1\")\n", filename); goto end; } /* Now read all records */ for (;;) { unsigned type; unsigned length; /* [TYPE] * This is one or more bytes indicating the type of type of the * record */ bytes_read = fread(buf, 1, 1, fp); if (bytes_read != 1) break; type = buf[0] & 0x7F; while (buf[0] & 0x80) { bytes_read = fread(buf, 1, 1, fp); if (bytes_read != 1) break; type = (type << 7) | (buf[0] & 0x7F); } /* [LENGTH] * Is one byte for lengths smaller than 127 bytes, or two * bytes for lengths up to 16384. */ bytes_read = fread(buf, 1, 1, fp); if (bytes_read != 1) break; length = buf[0] & 0x7F; while (buf[0] & 0x80) { bytes_read = fread(buf, 1, 1, fp); if (bytes_read != 1) break; length = (length << 7) | (buf[0] & 0x7F); } if (length > BUF_MAX) { fprintf(stderr, "file corrupt\n"); goto end; } /* get the remainder fo the record */ bytes_read = fread(buf, 1, length, fp); if (bytes_read < (int)length) break; /* eof */ /* Depending on record type, do something different */ switch (type) { case 1: /* STATUS: open */ parse_status(out, Port_Open, buf, bytes_read); break; case 2: /* STATUS: closed */ parse_status(out, Port_Closed, buf, bytes_read); break; case 3: /* BANNER */ parse_banner3(out, buf, bytes_read); break; case 4: fread(buf+bytes_read,1,1,fp); bytes_read++; parse_banner4(out, buf, bytes_read); break; case 5: parse_banner4(out, buf, bytes_read); break; case 'm': /* FILEHEADER */ //goto end; break; default: fprintf(stderr, "file corrupt: unknown type %u\n", type); goto end; } total_records++; if ((total_records & 0xFFFF) == 0) fprintf(stderr, "%s: %8llu\r", filename, total_records); } end: if (buf) free(buf); if (fp) fclose(fp); return total_records; } /*************************************************************************** ***************************************************************************/ void convert_binary_files(struct Masscan *masscan, int arg_first, int arg_max, char *argv[]) { struct Output *out; int i; out = output_create(masscan); for (i=arg_first; i<arg_max; i++) { parse_file(out, argv[i]); } output_destroy(out); } src/in-binary.h 0 → 100644 +8 −0 Original line number Diff line number Diff line #ifndef IN_BINARY_H #define IN_BINARY_H void convert_binary_files(struct Masscan *masscan, int arg_first, int arg_max, char *argv[]); #endif src/logger.c +8 −5 Original line number Diff line number Diff line /* log messages to console, depending on verbose level Use -v (or -d) to get more verbose output. The more -v you add, the Use -d to get more verbose output. The more -v you add, the more verbose the output becomes. Details about the running of the program go to <stderr>. Loading @@ -13,15 +13,18 @@ #include <stdarg.h> #include <stdio.h> int verbosity = 0; /* yea! a global variable!! */ int debuglevel = 0; static int global_debug_level = 0; /* yea! a global variable!! */ void LOG_add_level(int x) { global_debug_level += x; } /*************************************************************************** ***************************************************************************/ void vLOG(int level, const char *fmt, va_list marker) { if (level <= verbosity) { if (level <= global_debug_level) { vfprintf(stderr, fmt, marker); fflush(stderr); } Loading @@ -46,7 +49,7 @@ LOG(int level, const char *fmt, ...) void vLOGip(int level, unsigned ip, unsigned port, const char *fmt, va_list marker) { if (level <= verbosity) { if (level <= global_debug_level) { char sz_ip[16]; sprintf_s(sz_ip, sizeof(sz_ip), "%u.%u.%u.%u", Loading src/logger.h +2 −2 Original line number Diff line number Diff line #ifndef LOGGER_H #define LOGGER_H extern int verbosity; /* defined in logger.c */ extern int debuglevel; void LOG(int level, const char *fmt, ...); void LOGip(int level, unsigned ip, unsigned port, const char *fmt, ...); void LOG_add_level(int level); #endif Loading
doc/masscan.8.markdown +5 −0 Original line number Diff line number Diff line Loading @@ -205,6 +205,11 @@ one port. equivelents, but require a separate step to convert back into XML or another readable format. * `--readscan <binary-files>`: reads the files created by the `-oB` option from a scan, then outputs them in one of the other formats, depending on command-line parameters. In other words, it can take the binary version of the output and convert it to an XML or JSON format. ## CONFIGURATION FILE FORMAT Loading
src/in-binary.c 0 → 100644 +266 −0 Original line number Diff line number Diff line /* Read in the binary file produced by "out-binary.c". This allows you to translate the binary format into something more easily parsed, such as the XML or JSON formats. */ #include "masscan.h" #include "masscan-app.h" #include "main-globals.h" #include "output.h" #include "string_s.h" static const size_t BUF_MAX = 1024*1024; struct MasscanRecord { unsigned timestamp; unsigned ip; unsigned char ip_proto; unsigned short port; unsigned char reason; unsigned char ttl; enum ApplicationProtocol app_proto; }; /*************************************************************************** ***************************************************************************/ static void parse_status(struct Output *out, enum PortStatus status, /* open/closed */ const unsigned char *buf, size_t buf_length) { struct MasscanRecord record; if (buf_length < 12) return; /* parse record */ record.timestamp = buf[0]<<24 | buf[1]<<16 | buf[2]<<8 | buf[3]; record.ip = buf[4]<<24 | buf[5]<<16 | buf[6]<<8 | buf[7]; record.port = buf[8]<<8 | buf[9]; record.reason = buf[10]; record.ttl = buf[11]; /* * Now report ther result */ output_report_status(out, record.timestamp, status, record.ip, record.port, record.reason, record.ttl); } /*************************************************************************** * [OBSOLETE] * This parses an old version of the banner record. I've still got files * hanging around with this version, so I'm keeping it in the code for * now, but eventually I'll get rid of it. ***************************************************************************/ static void parse_banner3(struct Output *out, unsigned char *buf, size_t buf_length) { struct MasscanRecord record; /* * Parse the parts that are common to most records */ record.timestamp = buf[0]<<24 | buf[1]<<16 | buf[2]<<8 | buf[3]; record.ip = buf[4]<<24 | buf[5]<<16 | buf[6]<<8 | buf[7]; record.port = buf[8]<<8 | buf[9]; record.app_proto = buf[10]<<8 | buf[11]; /* * Now print the output */ output_report_banner( out, record.timestamp, record.ip, 6, /* this is always TCP */ record.port, record.app_proto, buf+12, (unsigned)buf_length-12 ); } /*************************************************************************** * Parse the BANNER record, extracting the timestamp, IP addres, and port * number. We also convert the banner string into a safer form. ***************************************************************************/ void parse_banner4(struct Output *out, unsigned char *buf, size_t buf_length) { struct MasscanRecord record; /* * Parse the parts that are common to most records */ record.timestamp = buf[0]<<24 | buf[1]<<16 | buf[2]<<8 | buf[3]; record.ip = buf[4]<<24 | buf[5]<<16 | buf[6]<<8 | buf[7]; record.ip_proto = buf[8]; record.port = buf[9]<<8 | buf[10]; record.app_proto = buf[11]<<8 | buf[12]; /* * Now print the output */ output_report_banner( out, record.timestamp, record.ip, record.ip_proto, /* TCP=6, UDP=17 */ record.port, record.app_proto, /* HTTP, SSL, SNMP, etc. */ buf+13, (unsigned)buf_length-13 ); } /*************************************************************************** * Read in the file, one record at a time. ***************************************************************************/ uint64_t parse_file(struct Output *out, const char *filename) { FILE *fp = 0; unsigned char *buf = 0; size_t bytes_read; uint64_t total_records = 0; int x; /* Allocate a buffer of up to one megabyte per record */ buf = (unsigned char *)malloc(BUF_MAX); if (buf == NULL) { fprintf(stderr, "memory allocation failure\n"); goto end; } /* Open the file */ x = fopen_s(&fp, filename, "rb"); if (x != 0 || fp == NULL) { perror(filename); goto end; } /* first record is pseudo-record */ bytes_read = fread(buf, 1, 'a'+2, fp); if (bytes_read < 'a'+2) { perror(filename); goto end; } /* Make sure it's got the format string */ if (memcmp(buf, "masscan/1.1", 11) != 0) { fprintf(stderr, "%s: unknown file format (expeced \"masscan/1.1\")\n", filename); goto end; } /* Now read all records */ for (;;) { unsigned type; unsigned length; /* [TYPE] * This is one or more bytes indicating the type of type of the * record */ bytes_read = fread(buf, 1, 1, fp); if (bytes_read != 1) break; type = buf[0] & 0x7F; while (buf[0] & 0x80) { bytes_read = fread(buf, 1, 1, fp); if (bytes_read != 1) break; type = (type << 7) | (buf[0] & 0x7F); } /* [LENGTH] * Is one byte for lengths smaller than 127 bytes, or two * bytes for lengths up to 16384. */ bytes_read = fread(buf, 1, 1, fp); if (bytes_read != 1) break; length = buf[0] & 0x7F; while (buf[0] & 0x80) { bytes_read = fread(buf, 1, 1, fp); if (bytes_read != 1) break; length = (length << 7) | (buf[0] & 0x7F); } if (length > BUF_MAX) { fprintf(stderr, "file corrupt\n"); goto end; } /* get the remainder fo the record */ bytes_read = fread(buf, 1, length, fp); if (bytes_read < (int)length) break; /* eof */ /* Depending on record type, do something different */ switch (type) { case 1: /* STATUS: open */ parse_status(out, Port_Open, buf, bytes_read); break; case 2: /* STATUS: closed */ parse_status(out, Port_Closed, buf, bytes_read); break; case 3: /* BANNER */ parse_banner3(out, buf, bytes_read); break; case 4: fread(buf+bytes_read,1,1,fp); bytes_read++; parse_banner4(out, buf, bytes_read); break; case 5: parse_banner4(out, buf, bytes_read); break; case 'm': /* FILEHEADER */ //goto end; break; default: fprintf(stderr, "file corrupt: unknown type %u\n", type); goto end; } total_records++; if ((total_records & 0xFFFF) == 0) fprintf(stderr, "%s: %8llu\r", filename, total_records); } end: if (buf) free(buf); if (fp) fclose(fp); return total_records; } /*************************************************************************** ***************************************************************************/ void convert_binary_files(struct Masscan *masscan, int arg_first, int arg_max, char *argv[]) { struct Output *out; int i; out = output_create(masscan); for (i=arg_first; i<arg_max; i++) { parse_file(out, argv[i]); } output_destroy(out); }
src/in-binary.h 0 → 100644 +8 −0 Original line number Diff line number Diff line #ifndef IN_BINARY_H #define IN_BINARY_H void convert_binary_files(struct Masscan *masscan, int arg_first, int arg_max, char *argv[]); #endif
src/logger.c +8 −5 Original line number Diff line number Diff line /* log messages to console, depending on verbose level Use -v (or -d) to get more verbose output. The more -v you add, the Use -d to get more verbose output. The more -v you add, the more verbose the output becomes. Details about the running of the program go to <stderr>. Loading @@ -13,15 +13,18 @@ #include <stdarg.h> #include <stdio.h> int verbosity = 0; /* yea! a global variable!! */ int debuglevel = 0; static int global_debug_level = 0; /* yea! a global variable!! */ void LOG_add_level(int x) { global_debug_level += x; } /*************************************************************************** ***************************************************************************/ void vLOG(int level, const char *fmt, va_list marker) { if (level <= verbosity) { if (level <= global_debug_level) { vfprintf(stderr, fmt, marker); fflush(stderr); } Loading @@ -46,7 +49,7 @@ LOG(int level, const char *fmt, ...) void vLOGip(int level, unsigned ip, unsigned port, const char *fmt, va_list marker) { if (level <= verbosity) { if (level <= global_debug_level) { char sz_ip[16]; sprintf_s(sz_ip, sizeof(sz_ip), "%u.%u.%u.%u", Loading
src/logger.h +2 −2 Original line number Diff line number Diff line #ifndef LOGGER_H #define LOGGER_H extern int verbosity; /* defined in logger.c */ extern int debuglevel; void LOG(int level, const char *fmt, ...); void LOGip(int level, unsigned ip, unsigned port, const char *fmt, ...); void LOG_add_level(int level); #endif