adding ability to scan specific CIDR blocks or addresses.
This commit is contained in:
parent
45918feced
commit
df68f4e57d
103
lib/blacklist.c
103
lib/blacklist.c
@ -51,7 +51,38 @@ void whitelist_prefix(char *ip, int prefix_len)
|
|||||||
constraint_set(constraint, ntohl(inet_addr(ip)), prefix_len, ADDR_ALLOWED);
|
constraint_set(constraint, ntohl(inet_addr(ip)), prefix_len, ADDR_ALLOWED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int init(char *file, const char *name, int value)
|
static int init_from_string(char *ip, int value)
|
||||||
|
{
|
||||||
|
int prefix_len = 32;
|
||||||
|
char *slash = strchr(ip, '/');
|
||||||
|
if (slash) { // split apart network and prefix length
|
||||||
|
*slash = '\0';
|
||||||
|
char *end;
|
||||||
|
char *len = slash+1;
|
||||||
|
errno = 0;
|
||||||
|
prefix_len = strtol(len, &end, 10);
|
||||||
|
if (end == len || errno != 0 || prefix_len < 0 || prefix_len > 32) {
|
||||||
|
log_fatal("constraint", "'%s' is not a valid prefix length", len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
struct in_addr addr;
|
||||||
|
if (inet_aton(ip, &addr) == 0) {
|
||||||
|
log_error("constraint", "'%s' is not a valid IP address", ip);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
constraint_set(constraint, ntohl(addr.s_addr), prefix_len, value);
|
||||||
|
char *name;
|
||||||
|
if (value == ADDR_DISALLOWED)
|
||||||
|
name = "blacklisting";
|
||||||
|
else
|
||||||
|
name = "whitelisting";
|
||||||
|
log_trace(name, "%s %s/%i",
|
||||||
|
name, ip, prefix_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int init_from_file(char *file, const char *name, int value)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char line[1000];
|
char line[1000];
|
||||||
@ -70,31 +101,22 @@ static int init(char *file, const char *name, int value)
|
|||||||
if ((sscanf(line, "%32s", ip)) == EOF) {
|
if ((sscanf(line, "%32s", ip)) == EOF) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int prefix_len = 32;
|
if (init_from_string(ip, value)) {
|
||||||
char *slash = strchr(ip, '/');
|
log_fatal(name, "unable to parse %s file: %s", name, file);
|
||||||
if (slash) { // split apart network and prefix length
|
|
||||||
*slash = '\0';
|
|
||||||
char *end;
|
|
||||||
char *len = slash+1;
|
|
||||||
errno = 0;
|
|
||||||
prefix_len = strtol(len, &end, 10);
|
|
||||||
if (end == len || errno != 0 || prefix_len < 0 || prefix_len > 32) {
|
|
||||||
log_fatal(name, "Unable to parse %s file: %s ('%s' is not a valid prefix length)", name, file, len);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
struct in_addr addr;
|
|
||||||
if (inet_aton(ip, &addr) == 0) {
|
|
||||||
log_fatal(name, "Unable to parse %s file: %s ('%s' is not a valid IP address)", name, file, ip);
|
|
||||||
}
|
|
||||||
constraint_set(constraint, ntohl(addr.s_addr), prefix_len, value);
|
|
||||||
log_trace(name, "%sing %s/%i",
|
|
||||||
name, ip, prefix_len);
|
|
||||||
}
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void static init_from_array(char **cidrs, size_t len, int value)
|
||||||
|
{
|
||||||
|
for (int i=0; i < (int) len; i++) {
|
||||||
|
init_from_string(cidrs[i], value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t blacklist_count_allowed()
|
uint64_t blacklist_count_allowed()
|
||||||
{
|
{
|
||||||
assert(constraint);
|
assert(constraint);
|
||||||
@ -107,42 +129,43 @@ uint64_t blacklist_count_not_allowed()
|
|||||||
return constraint_count_ips(constraint, ADDR_DISALLOWED);
|
return constraint_count_ips(constraint, ADDR_DISALLOWED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Initialize address constraints from whitelist and blacklist files.
|
// Initialize address constraints from whitelist and blacklist files.
|
||||||
// Either can be set to NULL to omit.
|
// Either can be set to NULL to omit.
|
||||||
int blacklist_init_from_files(char *whitelist_filename, char *blacklist_filename)
|
int blacklist_init(char *whitelist_filename, char *blacklist_filename,
|
||||||
|
char **whitelist_entries, size_t whitelist_entries_len,
|
||||||
|
char **blacklist_entries, size_t blacklist_entries_len)
|
||||||
{
|
{
|
||||||
assert(!constraint);
|
assert(!constraint);
|
||||||
if (whitelist_filename) {
|
if (whitelist_filename && whitelist_entries) {
|
||||||
|
log_warn("whitelist", "both a whitelist file and destination addresses "
|
||||||
|
"were specified. The union of these two sources "
|
||||||
|
"will be utilized.");
|
||||||
|
}
|
||||||
|
if (whitelist_filename || whitelist_entries) {
|
||||||
// using a whitelist, so default to allowing nothing
|
// using a whitelist, so default to allowing nothing
|
||||||
constraint = constraint_init(ADDR_DISALLOWED);
|
constraint = constraint_init(ADDR_DISALLOWED);
|
||||||
log_trace("whitelist", "blacklisting 0.0.0.0/0");
|
log_trace("whitelist", "blacklisting 0.0.0.0/0");
|
||||||
init(whitelist_filename, "whitelist", ADDR_ALLOWED);
|
if (whitelist_filename) {
|
||||||
|
init_from_file(whitelist_filename, "whitelist", ADDR_ALLOWED);
|
||||||
|
}
|
||||||
|
if (whitelist_entries) {
|
||||||
|
init_from_array(whitelist_entries,
|
||||||
|
whitelist_entries_len, ADDR_ALLOWED);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// no whitelist, so default to allowing everything
|
// no whitelist, so default to allowing everything
|
||||||
constraint = constraint_init(ADDR_ALLOWED);
|
constraint = constraint_init(ADDR_ALLOWED);
|
||||||
}
|
}
|
||||||
if (blacklist_filename) {
|
if (blacklist_filename) {
|
||||||
init(blacklist_filename, "blacklist", ADDR_DISALLOWED);
|
init_from_file(blacklist_filename, "blacklist", ADDR_DISALLOWED);
|
||||||
|
}
|
||||||
|
if (blacklist_entries) {
|
||||||
|
init_from_array(blacklist_entries, blacklist_entries_len, ADDR_DISALLOWED);
|
||||||
}
|
}
|
||||||
constraint_paint_value(constraint, ADDR_ALLOWED);
|
constraint_paint_value(constraint, ADDR_ALLOWED);
|
||||||
uint64_t allowed = blacklist_count_allowed();
|
uint64_t allowed = blacklist_count_allowed();
|
||||||
log_debug("blacklist", "%lu addresses allowed to be scanned (%0.0f%% of address space)",
|
log_debug("blacklist", "%lu addresses allowed to be scanned (%0.0f%% of address space)",
|
||||||
allowed, allowed*100./((long long int)1 << 32));
|
allowed, allowed*100./((long long int)1 << 32));
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// test
|
|
||||||
log_debug("blacklist", "testing started");
|
|
||||||
uint64_t count = constraint_count_ips(constraint, ADDR_ALLOWED);
|
|
||||||
for (unsigned int i=0; i < count; i++) {
|
|
||||||
int ip = constraint_lookup_index(constraint, i, ADDR_ALLOWED);
|
|
||||||
if ((i & 0xFFFFFF) == 0)
|
|
||||||
log_info("blacklist", "%x", i & 0xFF000000);
|
|
||||||
if (constraint_lookup_ip(constraint, ip) != ADDR_ALLOWED) {
|
|
||||||
log_error("blacklist", "test failed for index %d", i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log_debug("blacklist", "testing complete");
|
|
||||||
*/
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifndef BLACKLIST_H
|
#ifndef BLACKLIST_H
|
||||||
@ -7,7 +8,11 @@ uint32_t blacklist_lookup_index(uint64_t index);
|
|||||||
int blacklist_is_allowed(uint32_t s_addr);
|
int blacklist_is_allowed(uint32_t s_addr);
|
||||||
void blacklist_prefix(char *ip, int prefix_len);
|
void blacklist_prefix(char *ip, int prefix_len);
|
||||||
void whitelist_prefix(char *ip, int prefix_len);
|
void whitelist_prefix(char *ip, int prefix_len);
|
||||||
int blacklist_init_from_files(char *whitelist, char*blacklist);
|
int blacklist_init(char *whitelist, char *blacklist,
|
||||||
|
char **whitelist_entries,
|
||||||
|
size_t whitelist_entries_len,
|
||||||
|
char **blacklist_entries,
|
||||||
|
size_t blacklist_entries_len);
|
||||||
uint64_t blacklist_count_allowed();
|
uint64_t blacklist_count_allowed();
|
||||||
uint64_t blacklist_count_not_allowed();
|
uint64_t blacklist_count_not_allowed();
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ if (WITH_REDIS)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_custom_command(OUTPUT zopt.h
|
add_custom_command(OUTPUT zopt.h
|
||||||
COMMAND gengetopt -C --no-help --no-version -i "${CMAKE_CURRENT_SOURCE_DIR}/zopt.ggo" -F "${CMAKE_CURRENT_BINARY_DIR}/zopt"
|
COMMAND gengetopt -C --no-help --no-version --unamed-opts=SUBNETS -i "${CMAKE_CURRENT_SOURCE_DIR}/zopt.ggo" -F "${CMAKE_CURRENT_BINARY_DIR}/zopt"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(zmap ${SOURCES})
|
add_executable(zmap ${SOURCES})
|
||||||
|
18
src/cyclic.c
18
src/cyclic.c
@ -148,17 +148,25 @@ static uint64_t find_primroot(const cyclic_group_t *group)
|
|||||||
int cyclic_init(uint32_t primroot_, uint32_t current_)
|
int cyclic_init(uint32_t primroot_, uint32_t current_)
|
||||||
{
|
{
|
||||||
assert(!(!primroot_ && current_));
|
assert(!(!primroot_ && current_));
|
||||||
|
|
||||||
// Initialize blacklist
|
// Initialize blacklist
|
||||||
if (blacklist_init_from_files(zconf.whitelist_filename,
|
if (blacklist_init(zconf.whitelist_filename, zconf.blacklist_filename,
|
||||||
zconf.blacklist_filename)) {
|
zconf.destination_cidrs, zconf.destination_cidrs_len,
|
||||||
|
NULL, 0)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
num_addrs = blacklist_count_allowed();
|
num_addrs = blacklist_count_allowed();
|
||||||
|
if (!num_addrs) {
|
||||||
|
log_error("blacklist", "no addresses are eligible to be scanned in the "
|
||||||
|
"current configuration. This may be because the "
|
||||||
|
"blacklist being used by ZMap (%s) prevents "
|
||||||
|
"any addresses from receiving probe packets.",
|
||||||
|
zconf.blacklist_filename
|
||||||
|
);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t i;
|
|
||||||
const cyclic_group_t *cur_group = NULL;
|
const cyclic_group_t *cur_group = NULL;
|
||||||
for (i=0; i<sizeof(groups)/sizeof(groups[0]); i++) {
|
for (uint32_t i=0; i<sizeof(groups)/sizeof(groups[0]); i++) {
|
||||||
if (groups[i].prime > num_addrs) {
|
if (groups[i].prime > num_addrs) {
|
||||||
cur_group = &groups[i];
|
cur_group = &groups[i];
|
||||||
log_debug("cyclic", "using prime %lu, known_primroot %lu", cur_group->prime, cur_group->known_primroot);
|
log_debug("cyclic", "using prime %lu, known_primroot %lu", cur_group->prime, cur_group->known_primroot);
|
||||||
|
@ -77,6 +77,8 @@ struct state_conf {
|
|||||||
char *output_filename;
|
char *output_filename;
|
||||||
char *blacklist_filename;
|
char *blacklist_filename;
|
||||||
char *whitelist_filename;
|
char *whitelist_filename;
|
||||||
|
char **destination_cidrs;
|
||||||
|
int destination_cidrs_len;
|
||||||
char *raw_output_fields;
|
char *raw_output_fields;
|
||||||
char **output_fields;
|
char **output_fields;
|
||||||
struct fieldset_conf fsconf;
|
struct fieldset_conf fsconf;
|
||||||
|
18
src/zmap.c
18
src/zmap.c
@ -180,8 +180,6 @@ static void summary(void)
|
|||||||
static void start_zmap(void)
|
static void start_zmap(void)
|
||||||
{
|
{
|
||||||
log_info("zmap", "started");
|
log_info("zmap", "started");
|
||||||
|
|
||||||
// finish setting up configuration
|
|
||||||
if (zconf.iface == NULL) {
|
if (zconf.iface == NULL) {
|
||||||
char errbuf[PCAP_ERRBUF_SIZE];
|
char errbuf[PCAP_ERRBUF_SIZE];
|
||||||
char *iface = pcap_lookupdev(errbuf);
|
char *iface = pcap_lookupdev(errbuf);
|
||||||
@ -223,7 +221,6 @@ static void start_zmap(void)
|
|||||||
zconf.gw_mac[0], zconf.gw_mac[1], zconf.gw_mac[2],
|
zconf.gw_mac[0], zconf.gw_mac[1], zconf.gw_mac[2],
|
||||||
zconf.gw_mac[3], zconf.gw_mac[4], zconf.gw_mac[5]);
|
zconf.gw_mac[3], zconf.gw_mac[4], zconf.gw_mac[5]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialization
|
// initialization
|
||||||
if (zconf.output_module && zconf.output_module->init) {
|
if (zconf.output_module && zconf.output_module->init) {
|
||||||
zconf.output_module->init(&zconf, zconf.output_fields,
|
zconf.output_module->init(&zconf, zconf.output_fields,
|
||||||
@ -446,7 +443,6 @@ int main(int argc, char *argv[])
|
|||||||
CMDLINE_PARSER_PACKAGE, args.probe_module_arg);
|
CMDLINE_PARSER_PACKAGE, args.probe_module_arg);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now that we know the probe module, let's find what it supports
|
// now that we know the probe module, let's find what it supports
|
||||||
memset(&zconf.fsconf, 0, sizeof(struct fieldset_conf));
|
memset(&zconf.fsconf, 0, sizeof(struct fieldset_conf));
|
||||||
// the set of fields made available to a user is constructed
|
// the set of fields made available to a user is constructed
|
||||||
@ -498,6 +494,7 @@ int main(int argc, char *argv[])
|
|||||||
&zconf.fsconf.defs, zconf.output_fields,
|
&zconf.fsconf.defs, zconf.output_fields,
|
||||||
zconf.output_fields_len);
|
zconf.output_fields_len);
|
||||||
|
|
||||||
|
|
||||||
SET_BOOL(zconf.dryrun, dryrun);
|
SET_BOOL(zconf.dryrun, dryrun);
|
||||||
SET_BOOL(zconf.quiet, quiet);
|
SET_BOOL(zconf.quiet, quiet);
|
||||||
SET_BOOL(zconf.summary, summary);
|
SET_BOOL(zconf.summary, summary);
|
||||||
@ -505,7 +502,6 @@ int main(int argc, char *argv[])
|
|||||||
zconf.senders = args.sender_threads_arg;
|
zconf.senders = args.sender_threads_arg;
|
||||||
SET_IF_GIVEN(zconf.output_filename, output_file);
|
SET_IF_GIVEN(zconf.output_filename, output_file);
|
||||||
SET_IF_GIVEN(zconf.blacklist_filename, blacklist_file);
|
SET_IF_GIVEN(zconf.blacklist_filename, blacklist_file);
|
||||||
SET_IF_GIVEN(zconf.whitelist_filename, whitelist_file);
|
|
||||||
SET_IF_GIVEN(zconf.probe_args, probe_args);
|
SET_IF_GIVEN(zconf.probe_args, probe_args);
|
||||||
SET_IF_GIVEN(zconf.output_args, output_args);
|
SET_IF_GIVEN(zconf.output_args, output_args);
|
||||||
SET_IF_GIVEN(zconf.iface, interface);
|
SET_IF_GIVEN(zconf.iface, interface);
|
||||||
@ -514,6 +510,18 @@ int main(int argc, char *argv[])
|
|||||||
SET_IF_GIVEN(zconf.rate, rate);
|
SET_IF_GIVEN(zconf.rate, rate);
|
||||||
SET_IF_GIVEN(zconf.packet_streams, probes);
|
SET_IF_GIVEN(zconf.packet_streams, probes);
|
||||||
|
|
||||||
|
// find if zmap wants any specific cidrs scanned instead
|
||||||
|
// of the entire Internet
|
||||||
|
zconf.destination_cidrs = args.inputs;
|
||||||
|
zconf.destination_cidrs_len = args.inputs_num;
|
||||||
|
if (zconf.destination_cidrs && zconf.blacklist_filename
|
||||||
|
&& !strcmp(zconf.blacklist_filename, "/etc/zmap/blacklist.conf")) {
|
||||||
|
log_warn("blacklist", "ZMap is currently using the default blacklist located "
|
||||||
|
"at /etc/zmap/blacklist.conf. By default, this blacklist excludes locally "
|
||||||
|
"scoped networks (e.g. 10.0.0.0/8, 127.0.0.1/8, and 192.168.0.0/16). If you are"
|
||||||
|
" trying to scan local networks, you can change the default blacklist by "
|
||||||
|
"editing the default ZMap configuration at /etc/zmap/zmap.conf.");
|
||||||
|
}
|
||||||
|
|
||||||
if (zconf.probe_module->port_args) {
|
if (zconf.probe_module->port_args) {
|
||||||
if (args.source_port_given) {
|
if (args.source_port_given) {
|
||||||
|
Loading…
Reference in New Issue
Block a user