Skip to content

Commit

Permalink
Add sanity check for size of scan
Browse files Browse the repository at this point in the history
  • Loading branch information
sfan5 committed Feb 17, 2024
1 parent 480cc89 commit 1ae4f41
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 27 deletions.
39 changes: 22 additions & 17 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,23 +332,28 @@ int main(int argc, char *argv[])

r = 0;
} else {
// complain about missing args
const char* missing = NULL;
if(is_all_ff(source_mac, 6))
missing = "--source-mac";
else if(is_all_ff(router_mac, 6))
missing = "--router-mac";
else if(is_all_ff(source_addr, 16))
missing = "--source-ip";
else if(ip_type != IP_TYPE_ICMPV6 && !validate_ports(&ports))
missing = "-p";
else if(banners && ip_type == IP_TYPE_TCP && source_port == -1)
missing = "--source-port";

if(missing) {
printf("Option %s is required but was not given.\n", missing);
r = 1;
} else {
r = target_gen_sanity_check() < 0 ? 1 : 0;

if (r == 0) {
const char* missing = NULL;
if(is_all_ff(source_mac, 6))
missing = "--source-mac";
else if(is_all_ff(router_mac, 6))
missing = "--router-mac";
else if(is_all_ff(source_addr, 16))
missing = "--source-ip";
else if(ip_type != IP_TYPE_ICMPV6 && !validate_ports(&ports))
missing = "-p";
else if(banners && ip_type == IP_TYPE_TCP && source_port == -1)
missing = "--source-port";

if(missing) {
printf("Option %s is required but was not given.\n", missing);
r = 1;
}
}

if (r == 0) {
scan_set_general(&ports, max_rate, show_closed, banners);
scan_set_network(source_addr, source_port, ip_type);
scan_set_output(outfile, outdef);
Expand Down
62 changes: 52 additions & 10 deletions src/target-gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ static uint64_t rand64();
static int popcount(uint32_t x);
static void fill_cache(void);
static void next_addr(struct targetstate *t, uint8_t *dst);
static void count_total(const struct targetstate *t, uint64_t *total, bool *overflowed);
static void progress_single(const struct targetstate *t, uint64_t *total, uint64_t *done);


Expand Down Expand Up @@ -165,16 +166,7 @@ void target_gen_print_summary(int max_rate, int nports)
for(int i = 0; i < targets_i; i++) {
const struct targetstate *t = &targets[i];

uint64_t one = 0, tmp = 0;
progress_single(t, &one, &tmp);
if (one == 0) { // all bits shifted out of the value
total_overflowed = true;
} else {
tmp = total;
total += one;
if (total < tmp)
total_overflowed = true;
}
count_total(t, &total, &total_overflowed);

int maskbits = 0;
for(int j = 0; j < 4; j++)
Expand Down Expand Up @@ -239,6 +231,40 @@ void target_gen_print_summary(int max_rate, int nports)
}
}

int target_gen_sanity_check(void)
{
uint64_t total = 0;
bool overflowed = false;
for(int i = 0; i < targets_i; i++) {
const struct targetstate *t = &targets[i];
count_total(t, &total, &overflowed);
}

const uint64_t limit = UINT64_C(1) << TARGET_SANITY_MAX_BITS;
if (overflowed || total >= limit) {
fprintf(stderr, "Error: You are trying to scan ");
if (overflowed)
fprintf(stderr, "more than 2^64");
else
fprintf(stderr, "%" PRIu64, total);
fprintf(stderr, " addresses. Refusing.\n"
"\n"
"Even under ideal conditions this would take a tremendous amount of "
"time (check with --print-summary).\nYou were probably expecting to "
"scan an IPv6 subnet exhaustively just like you can with IPv4.\n"
"In practice common sizes like /64 would take more than tens of "
"thousands YEARS to enumerate.\nYou will need to rethink your approach. "
"Good advice on IPv6 scanning can be found on the internet.\n"
"\n"
"In case you were hoping to scan stochastically, note that fi6s "
"IP randomization is not suited for this.\nAs an alternative you can "
"let an external program generate IPs and use --stream-targets.\n"
);
return -1;
}
return 0;
}

static void shuffle(void *_buf, int stride, int n)
{
char tmp[stride], *buf = (char*) _buf;
Expand Down Expand Up @@ -354,6 +380,22 @@ static void next_addr(struct targetstate *t, uint8_t *dst)
t->done = 1;
}

static void count_total(const struct targetstate *t, uint64_t *total, bool *overflowed)
{
uint64_t one = 0, tmp = 0;
progress_single(t, &one, &tmp);
// if this target is larger than 2^64 all bits will be shifted off the end
if (one == 0) {
*overflowed = true;
} else {
// add with overflow check
tmp = *total;
*total += one;
if (*total < tmp)
*overflowed = true;
}
}

static void progress_single(const struct targetstate *t, uint64_t *total, uint64_t *done)
{
uint64_t _total = 0, _done = 0;
Expand Down
2 changes: 2 additions & 0 deletions src/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ struct targetspec {
int target_parse(const char *str, struct targetspec *dst);

#define TARGET_RANDOMIZE_SIZE 8192
#define TARGET_SANITY_MAX_BITS 48
#define TARGET_EVEN_SPREAD 1 // not sure why you would disable this, but you can

int target_gen_init(void);
void target_gen_set_randomized(int v);
void target_gen_set_streaming(FILE *f);
int target_gen_sanity_check(void);
void target_gen_fini(void);

int target_gen_add(const struct targetspec *s);
Expand Down

0 comments on commit 1ae4f41

Please sign in to comment.