Commit 67d96b53 authored by robertdavidgraham's avatar robertdavidgraham
Browse files
parents 142510f9 ac9f6eca
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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

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
+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>.
@@ -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);
    }
@@ -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", 
+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