Commit 384096be authored by Adam Greene's avatar Adam Greene
Browse files

adds support for unicornscan compatible output

use '-oU' or '--output-format unicornscan'

Only supported for TCP SYN scanning. Other scans
will fall back to grep style output since unicornscan
has no support for non-TCP scanning.
parent b299d5c6
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -175,10 +175,10 @@ print_nmap_help(void)
"  --ttl <val>: Set IP time-to-live field\n"
"  --spoof-mac <mac address/prefix/vendor name>: Spoof your MAC address\n"
"OUTPUT:\n"
"  --output-format <format>: Sets output to binary/list/json/grepable/xml\n"
"  --output-format <format>: Sets output to binary/list/unicornscan/json/grepable/xml\n"
"  --output-file <file>: Write scan results to file. If --output-format is\n"
"     not given default is xml\n"
"  -oL/-oJ/-oG/-oB/-oX <file>: Output scan in List/JSON/Grepable/Binary/XML format,\n"
"  -oL/-oJ/-oG/-oB/-oX/-oU <file>: Output scan in List/JSON/Grepable/Binary/XML/Unicornscan format,\n"
"     respectively, to the given filename. Shortcut for\n"
"     --output-format <format> --output-file <file>\n"
"  -v: Increase verbosity level (use -vv or more for greater effect)\n"
@@ -314,6 +314,7 @@ masscan_echo(struct Masscan *masscan, FILE *fp)
    switch (masscan->output.format) {
    case Output_Interactive:fprintf(fp, "output-format = interactive\n"); break;
    case Output_List:       fprintf(fp, "output-format = list\n"); break;
    case Output_Unicornscan:fprintf(fp, "output-format = unicornscan\n"); break;
    case Output_XML:        fprintf(fp, "output-format = xml\n"); break;
    case Output_Binary:     fprintf(fp, "output-format = binary\n"); break;
    case Output_Grepable:   fprintf(fp, "output-format = grepable\n"); break;
@@ -1382,6 +1383,7 @@ masscan_set_parameter(struct Masscan *masscan,
        if (EQUALS("interactive", value))
            masscan->output.format = Output_Interactive;
        else if (EQUALS("list", value))         x = Output_List;
        else if (EQUALS("unicornscan", value))         x = Output_Unicornscan;
        else if (EQUALS("xml", value))          x = Output_XML;
        else if (EQUALS("binary", value))       x = Output_Binary;
        else if (EQUALS("greppable", value))    x = Output_Grepable;
@@ -1867,6 +1869,9 @@ masscan_command_line(struct Masscan *masscan, int argc, char *argv[])
                case 'L':
                    masscan_set_parameter(masscan, "output-format", "list");
                    break;
                case 'U':
                    masscan_set_parameter(masscan, "output-format", "unicornscan");
                    break;
                default:
                    fprintf(stderr, "nmap(%s): unknown output format\n", argv[i]);
                    exit(1);
+3 −2
Original line number Diff line number Diff line
@@ -51,8 +51,9 @@ enum OutputFormat {
    Output_ScriptKiddie = 0x0040,
    Output_Grepable     = 0x0080,   /* -oG, "grepable" */
    Output_Redis        = 0x0100, 
    Output_None         = 0x0200,
    Output_Certs        = 0x0400,
    Output_Unicornscan  = 0x0200,   /* -oU, "unicornscan" */
    Output_None         = 0x0400,
    Output_Certs        = 0x0800,
    Output_All          = 0xFFBF,   /* not supported */
};

src/out-unicornscan.c

0 → 100644
+129 −0
Original line number Diff line number Diff line
#include "output.h"
#include "masscan.h"
#include "masscan-app.h"
#include "masscan-status.h"
#include "unusedparm.h"

#include <netdb.h>
#include <ctype.h>

static char * tcp_services[65536];

static void init_tcp_services();
static char *tcp_service_name(int port);

static void init_tcp_services()
{
  int i;
  for (i=0;i<65536;i++)
    tcp_services[i] = tcp_service_name(i);
}

static char *tcp_service_name(int port)
{
    int r;
    struct servent result_buf;
    struct servent *result;
    char buf[2048];

    r = getservbyport_r(htons(port), "tcp", &result_buf,buf, sizeof(buf), &result);

    /* ignore ERANGE - if the result can't fit in 2k, just return unknown */
    if (r != 0 || result == NULL)
        return "unknown";

    return strdup(result_buf.s_name);
}

static void
unicornscan_out_open(struct Output *out, FILE *fp)
{
    UNUSEDPARM(out);
    fprintf(fp, "#masscan\n");
    init_tcp_services();
}


static void
unicornscan_out_close(struct Output *out, FILE *fp)
{
    UNUSEDPARM(out);
    fprintf(fp, "# end\n");
}

static void
unicornscan_out_status(struct Output *out, FILE *fp, time_t timestamp,
    int status, unsigned ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl)
{
    UNUSEDPARM(reason);
    UNUSEDPARM(out);

    if (ip_proto == 6) {
      fprintf(fp,"TCP open\t%16s[%5d]\t\tfrom %u.%u.%u.%u  ttl %-3d\n",
              tcp_services[port],
              port,
              (ip>>24)&0xFF,
              (ip>>16)&0xFF,
              (ip>> 8)&0xFF,
              (ip>> 0)&0xFF,
              ttl);
    }
    else
    { 
    /* unicornscan is TCP only, so just use grepable format for other protocols */
    fprintf(fp, "Host: %u.%u.%u.%u ()",
                    (unsigned char)(ip>>24),
                    (unsigned char)(ip>>16),
                    (unsigned char)(ip>> 8),
                    (unsigned char)(ip>> 0)
                    );
    fprintf(fp, "\tPorts: %u/%s/%s/%s/%s/%s/%s\n",
                port,
                status_string(status),      //"open", "closed"
                name_from_ip_proto(ip_proto),  //"tcp", "udp", "sctp"
                "", //owner
                "", //service
                "", //SunRPC info
                "" //Version info
                );
    }
}


/*************************************** *************************************
 ****************************************************************************/
static void
unicornscan_out_banner(struct Output *out, FILE *fp, time_t timestamp,
        unsigned ip, unsigned ip_proto, unsigned port,
        enum ApplicationProtocol proto, unsigned ttl,
        const unsigned char *px, unsigned length)
{ /* SYN only - no banner */
    UNUSEDPARM(out);
    UNUSEDPARM(ttl);
    UNUSEDPARM(port);
    UNUSEDPARM(fp);
    UNUSEDPARM(timestamp);
    UNUSEDPARM(ip);
    UNUSEDPARM(ip_proto);
    UNUSEDPARM(proto);
    UNUSEDPARM(px);
    UNUSEDPARM(length);

    return;
} 
 


/****************************************************************************
 ****************************************************************************/
const struct OutputType unicornscan_output = {
    "uni",
    0,
    unicornscan_out_open,
    unicornscan_out_close,
    unicornscan_out_status,
    unicornscan_out_banner
};


+3 −0
Original line number Diff line number Diff line
@@ -407,6 +407,9 @@ output_create(const struct Masscan *masscan, unsigned thread_index)
    case Output_List:
        out->funcs = &text_output;
        break;
    case Output_Unicornscan:
        out->funcs = &unicornscan_output;
        break;
    case Output_XML:
        out->funcs = &xml_output;
        break;
+1 −0
Original line number Diff line number Diff line
@@ -121,6 +121,7 @@ const char *normalize_string(const unsigned char *px, size_t length,


extern const struct OutputType text_output;
extern const struct OutputType unicornscan_output;
extern const struct OutputType xml_output;
extern const struct OutputType json_output;
extern const struct OutputType certs_output;