Commit 80d92852 authored by robertdavidgraham's avatar robertdavidgraham
Browse files

changes

parent 30e420d7
Loading
Loading
Loading
Loading
+44 −17
Original line number Diff line number Diff line
@@ -2,13 +2,13 @@

This is a port scanner. It spews out packets at a high rate, then catches any
responses asynchronously. Because it's asynchronous, it's a lot faster than 
''nmap'' -- and a lot less feature rich.
`nmap` -- and a lot less feature rich.

The intent is to be a 48-bit scanner -- scanning all ports (16-bits) on all
This is a 48-bit scanner: scanning all ports (16-bits) on all
IPv4 addresses (32-bits). It's also useful on smaller problems, such as the
10.x.x.x address space within a company.

It randomizes the IPv4+port combination, whereas nmap only randomizes the
It randomizes the IPv4+port combination, whereas `nmap only randomizes the
IPv4 address. This is so that we can send out 10-million packet per second
when scanning the entire Internet, but the owner of a Class C network will
only see 1 packet per second comming in.
@@ -45,7 +45,7 @@ should be a lot faster than Linux.
The project contains a built-in self-test:

	$ make regress
	bin/masscan --selftest
	bin/masscan --regress
	selftest: success!

If the self-test fails, the program returns an exit code of '1' and an
@@ -59,28 +59,55 @@ that what's transmitted is the same thing that was specified to be sent.

# Usage

Usage is similar to ''nmap'', such as the following scan:
Usage is similar to `nmap`, such as the following scan:

	# bin/masscan -p80,8000-8100 10.0.0.0/8
	# masscan -p80,8000-8100 10.0.0.0/8

This will:
* scan the 10.x.x.x subnet, all 16 million addresses
* scans port 80 and the range 8000 to 8100, or 102 addresses total
* print output to <stdout> that can be redirected to a file

Some comparison with ''nmap'':
* no default ports to scan, you must specify ''-p <ports>''
* the ''-sS'' option is enabled: this does SYN scan only
* the ''-n'' option is enabled: no DNS resolution happens
* the ''-Pn'' option is enabled: doesn't ping hosts first
* target hosts are IP addresses or ranges, not DNS names
* specify ''--rate <rate>''
To see the complete list of options, use the `--echo` feature. This
dumps the current configuration and exits. This ouput can be used as input back
into the program:

I've tried to make this familiar to ''nmap'' users, but fundamentally
it's a vastly different scanner. You can try some ''nmap'' options you
think might work -- it'll quickly tell you if they don't.
	# masscan masscan -p80,8000-8100 10.0.0.0/8 --echo > xxx.conf
	# masscan -c xxx.conf --rate 1000


## Transmit rate (IMPORTANT!!)
# Comparison with Nmap

Where reasonable, every effort has been taken to make the program familiar
to `nmap` users, even though it's fundamentally different. Two important
differences are:

* no default ports to scan, you must specify `-p <ports>`
* target hosts are IP addresses or simple ranges, not DNS names, nor 
  the funky subnet ranges `nmap` can use.

You can think of `masscan` as having the following settings permanently
enabled:
* `-sS`: this does SYN scan only (currently, will change in future)
* `-Pn`: doesn't ping hosts first, which is fundamental to the async operation
* `-n`: no DNS resolution happens
* `--randomize-hosts`: scan completely randomized
* `--send-eth`: sends using raw `libpcap`

If you want a list of additional `nmap` compatible settings, use the following
command:

	# masscan --nmap

# Tips on reading the code

The file `main.c` contains the `main()` function, as you'd expect. Also,
this file contains the main scanning thread that spews packets, as well
as the catching thread that catches responses. This is the core functionality
of the program, everything else is secondary.


# Transmit rate (IMPORTANT!!)

This program spews out packets very fast. On Windows, or from VMs,
it can do 300,000 packets/second. On a Linux (no virtualization) it'll

VULNINFO.md

0 → 100644
+67 −0
Original line number Diff line number Diff line
# Vulnerability Information and Policy

This document contains information about robustness of this project against
hacker attacks. It describes known vulnerabilities that have been found
in previous versions, and describes policies how vulnerabilities are handled.

## Security contact

robert_david_graham@yahoo.com
@ErrataRob on twitter


## Known vulnerabilities and advisories

none

## Bounty

I'm offering $100, payable in cash or Bitcoin, for security vulnerabilities.
This is primarily for remote vulnerabilities, such as the ability of a target
to buffer-overflow the scanner, or even cause it to crash.

But I'd consider other vulnerabilities as well. Does Kali ship this with suid
and there's a preload bug? That's not really a vuln in this code, but if it's 
something I could fix, I'd consider it paying a bounty for it.


## Disclosure policy

If you've got a vuln, just announce it. Please send info to the contact above
as well, please.

I'll probably get around to fixing it within a month or so. This really isn't
heavily used software, so I'm lax on this.

## Threats

The primary threat is from hostile targets on the Internet sending back back
responses in order to:
* exploit a buffer-overflow vulnerability
* spoof packets trying to give fraudulent scan results (mitigated with our
  SYN cookies)
* flood packets trying to overload bandwidth/storage
* bad data, such as corrupting banners or DNS names trying to exploit
  downstream consumers with bad <html> or <script> tags.

The secondary threat is from use of the program. For example, when a bad
parameter is entered on the command-line, the program spits it back out
in a helpful error message. This is fine for a command-line program that
should run as `root` anyway, but if somebody tries to make it into a 
scriptable service, this becomes a potential vulnerability.

## Safe code policy

Unsafe functions like `strcpy()` are banned.

The code contains an automated regression test by running with the 
`--regress` option.








+57 −32
Original line number Diff line number Diff line
@@ -27,44 +27,65 @@ void masscan_usage(void)
    printf("usage:\n");
    printf("masscan --echo\n");
    printf(" view default configuration\n");
    printf("masscan -c mass.conf -p80,8000-8100 10.0.0.0/8 --rate=10000\n");
    printf("masscan -p80,8000-8100 10.0.0.0/8 --rate=10000\n");
    printf(" scan some web ports on 10.x.x.x at 10kpps\n");
    printf("masscan --nmap\n");
    printf(" list all the options (nmap format)\n");
    printf("masscan --echo\n");
    printf(" list all options AND their current settings (non-nmap format)\n");
	exit(1);
}

/***************************************************************************
 ***************************************************************************/
static void
parse_port_list(struct RangeList *ports, const char *string)
print_nmap_help(void)
{
	char *p = (char*)string;

	while (*p) {
		unsigned port;
		unsigned end;

		while (*p && isspace(*p & 0xFF))
			p++;
		if (*p == 0)
			break;

		port = strtoul(p, &p, 0);
		end = port;
		if (*p == '-') {
			p++;
			end = strtoul(p, &p, 0);
    printf("Masscan (https://github.com/robertdavidgraham/masscan)\n"
"Usage: masscan [Options] -p{Target-Ports} {Target-IP-Ranges}\n"
"TARGET SPECIFICATION:\n"
"  Can pass only IPv4 address, CIDR networks, or ranges (non-nmap style)\n"
"  Ex: 10.0.0.0/8, 192.168.0.1, 10.0.0.1-10.0.0.254\n"
"  -iL <inputfilename>: Input from list of hosts/networks\n"
"  --exclude <host1[,host2][,host3],...>: Exclude hosts/networks\n"
"  --excludefile <exclude_file>: Exclude list from file\n"
"  --randomize-hosts: Randomize order of hosts (default)\n"
"HOST DISCOVERY:\n"
"  -Pn: Treat all hosts as online (default)\n"
"  -n: Never do DNS resolution (default)\n"
"SCAN TECHNIQUES:\n"
"  -sS: TCP SYN (always on, default)\n"
"PORT SPECIFICATION AND SCAN ORDER:\n"
"  -p <port ranges>: Only scan specified ports\n"
"    Ex: -p22; -p1-65535; -p 111,137,80,139,8080\n"
"TIMING AND PERFORMANCE:\n"
"  --max-rate <number>: Send packets no faster than <number> per second\n"
"FIREWALL/IDS EVASION AND SPOOFING:\n"
"  -S <IP_Address>: Spoof source address\n"
"  -e <iface>: Use specified interface\n"
"  -g/--source-port <portnum>: Use given port number\n"
"  --ttl <val>: Set IP time-to-live field\n"
"  --spoof-mac <mac address/prefix/vendor name>: Spoof your MAC address\n"
"OUTPUT:\n"
"  -oL/-oJ <file>: Output scan in List or JSON format, respectively,\n"
"     to the given filename.\n"
"  -v: Increase verbosity level (use -vv or more for greater effect)\n"
"  -d: Increase debugging level (use -dd or more for greater effect)\n"
"  --open: Only show open (or possibly open) ports\n"
"  --packet-trace: Show all packets sent and received\n"
"  --iflist: Print host interfaces and routes (for debugging)\n"
"  --append-output: Append to rather than clobber specified output files\n"
"  --resume <filename>: Resume an aborted scan\n"
"MISC:\n"
"  --send-eth: Send using raw ethernet frames (default)\n"
"  -V: Print version number\n"
"  -h: Print this help summary page.\n"
"EXAMPLES:\n"
"  masscan -v -sS 192.168.0.0/16 10.0.0.0/8 -p 80\n"
"SEE THE MAN PAGE (http://nmap.org/book/man.html) FOR MORE OPTIONS AND EXAMPLES\n"
"}\n");
}
		if (*p == ',')
			p++;

		if (port > 0xFFFF || end > 0xFFFF || end < port) {
			fprintf(stderr, "CONF: bad ports: %u-%u\n", port, end);
			break;
		} else {
			rangelist_add_range(ports, port, end);
		}
	}
}

/***************************************************************************
 * Prints the current configuration to the command-line then exits.
@@ -412,7 +433,7 @@ masscan_set_parameter(struct Masscan *masscan, const char *name, const char *val
        
    }
    else if (EQUALS("ports", name) || EQUALS("port", name)) {
    	parse_port_list(&masscan->ports, value);
    	rangelist_parse_ports(&masscan->ports, value);
		masscan->op = Operation_Scan;
    }
    else if (
@@ -420,7 +441,7 @@ masscan_set_parameter(struct Masscan *masscan, const char *name, const char *val
            EQUALS("exclude.ports", name) || EQUALS("exclude.port", name) ||
            EQUALS("excludeports", name) || EQUALS("excludeport", name)
        ) {
    	parse_port_list(&masscan->exclude_port, value);
    	rangelist_parse_ports(&masscan->exclude_port, value);
    }
    else if (EQUALS("range", name) || EQUALS("ranges", name) || EQUALS("ip", name) || EQUALS("ipv4", name)) {
        const char *ranges = value;
@@ -534,8 +555,11 @@ masscan_set_parameter(struct Masscan *masscan, const char *name, const char *val
    } else if (EQUALS("mtu", name)) {
        fprintf(stderr, "nmap(%s): fragmentation not yet supported\n", name);
        exit(1);
    } else if (EQUALS("nmap", name)) {
        print_nmap_help();
        exit(1);
    } else if (EQUALS("open", name)) {
        /* This is the default behavior */
        masscan->nmap.open_only = 1;
    } else if (EQUALS("osscan-limit", name)) {
        fprintf(stderr, "nmap(%s): OS scanning unsupported\n", name);
        exit(1);
@@ -663,6 +687,7 @@ is_singleton(const char *name)
        "log-errors", "append-output", "webxml", "no-stylesheet",
        "no-stylesheet",
        "send-eth", "send-ip", "iflist", "randomize-hosts",
        "nmap",
        0};
    size_t i;

+18 −12
Original line number Diff line number Diff line
@@ -23,11 +23,9 @@
#include <signal.h>


unsigned control_c_pressed=0;
void control_c_handler(int x)
{
	control_c_pressed = 1+x;
}

static unsigned control_c_pressed = 0;



/***************************************************************************
@@ -517,6 +515,13 @@ main_scan(struct Masscan *masscan)
    return 0;
}

/***************************************************************************
 ***************************************************************************/
static void control_c_handler(int x)
{
	control_c_pressed = 1+x;
}

/***************************************************************************
 ***************************************************************************/
int main(int argc, char *argv[])
@@ -524,12 +529,6 @@ int main(int argc, char *argv[])
    struct Masscan masscan[1];


   	/*
	 * Register a signal handler for the <ctrl-c> key. This allows
     * us to pause and then resume a scan.
     */
	signal(SIGINT, control_c_handler);


    /* We need to do a separate "raw socket" initialization step */
	rawsock_init();
@@ -577,6 +576,13 @@ int main(int argc, char *argv[])
        /*
         * THIS IS THE NORMAL THING
         */
    	
        /*
         * trap <ctrl-c> to pause
         */
        signal(SIGINT, control_c_handler);


        {
            char buffer[80];
            time_t now  = time(0);
@@ -586,7 +592,7 @@ int main(int argc, char *argv[])
            strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S GMT", &x); 
            fprintf(stderr, "\nStarting masscan 1.0 (http://github.com/robertdavidgraham/masscan) at %s\n", buffer);
        }
        fprintf(stderr, " -- forced options: -sS -Pn -n --randomize-hosts -v\n");
        fprintf(stderr, " -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth\n");
        fprintf(stderr, "Initiating SYN Stealth Scan\n");
        return main_scan(masscan);

+1 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ struct Masscan

        /* ouput options */
        unsigned packet_trace:1; /* print transmit messages */
        unsigned open_only:1; /* show only open ports */
        unsigned reason; /* print reason port is open, which is redundant for us */
        unsigned format; /* see enum OutputFormat */
        unsigned append; /* append instead of clobber file */
Loading