diff --git a/senicup.pl b/senicup.pl index 43f8431..ddefdeb 100755 --- a/senicup.pl +++ b/senicup.pl @@ -2,62 +2,171 @@ #use diagnostics; use strict; use warnings; +use utf8; use File::Path qw(make_path); -use Net::EmptyPort qw(check_port); +use Net::Ping; use Net::DNS; -#use Selenium::Remote::Driver; use Selenium::Firefox; use Selenium::Firefox::Profile; -chomp(my $connectivity = `cat /sys/class/net/*/operstate|grep -m 1 '^up\$'`); # Will do for now. +my ($continue_from, $ii1, $ii2, $ii3, $initvar); +if ($ARGV[0]) { +chomp($continue_from = $ARGV[0]); +if ($continue_from !~ m/^[0-9]+([.][0-9]+){3}$/) {die $!, "\"$continue_from\" is not a valid ipv4 address:" +} else {($ii1, $ii2, $ii3) = split /\./, $continue_from; print 'Continuing from ipv4 address ', $continue_from, "\n"}} else {print "\n\n"; foreach (0..4) {print 'Starting a new tcp/udp 80/443 ipv4 scan in ', (5-${_}), "s.\n"; sleep 1}; print 'Starting...', "\n"} my $ii = 0; -my (%args, %args2); -$args2{'profile_dir'} = '/home/miami/.Mozilla/Firefox/ud8j40yn.default'; # Ghacks user.js is a good start. +my (%args, %args2, %hoa, @host); +$args2{'profile_dir'} = '/home/miami/.Mozilla3/Firefox/ud8j40yn.default'; # Ghacks user.js is a good start. my $profile = Selenium::Firefox::Profile->new(%args2); my $driver = Selenium::Firefox->new('firefox_profile' => $profile); -open my $FILEH_A, '>>', "./data/domains.txt"; # Here, we'll store all the domains from all ipv4 addresses. - +$driver->set_timeout('script', 10000); +$driver->set_timeout('implicit', 20000); +$driver->set_timeout('page load', 15000); +my $p = Net::Ping->new("syn", 3); sub connectivity_check { +my $flag = 0; my $exp = 0; -while (1) {unless ($connectivity eq 'up') {warn "$!: No wireless connectivity."; sleep 2**$exp; $exp++; if ($exp >= 10) {$exp -= int(rand(11))}; next}; last} +chomp(my $connectivity = `ip a | grep -A 2 -Ei '^[0-9]+: wl[^:]+:' | grep -E '\\s+?inet\\b' | sed -E 's/^\\s+?inet\\s+?([^/]+).*\$/\\1/'`); # Will do for now. +while (1) {eval open my $TMP_FH, '<', (glob '/sys/class/net/wl*/carrier')[0]; unless ($connectivity =~ m/^[0-9]+([.][0-9]+){3}$/ and <$TMP_FH> == 1) {warn "$!: No wireless connectivity on (lexicographically) first wireless network."; $flag = 1; sleep 2**$exp; $exp++; chomp($connectivity = `ip a | grep -A 2 -Ei '^[0-9]+: wl[^:]+:' | grep -E '\\s+?inet\\b' | sed -E 's/^\\s+?inet\\s+?([^/]+).*\$/\\1/'`); if ($exp >= 10) {$exp -= int(rand(11))}; next}; +if ($flag == 1) { +if (defined($_[1])) {unlink "$_[1]"; $_[1] =~ s,/[^/]+$,,; unlink "$_[1]/title.txt"; rmdir "$_[1]/"} # Delete potentially incomplete items from the last ipv4 address/domain, for unskipping. +if (defined($_[0])) { # If true, assume everything in $i4 failed before detection of the connectivity issue (i.e., redo /24). +my $alpha = time; +splice @host, 0, $#host; +undef %hoa; +$args{'port'} = '80'; $args{'proto'} = 'tcp'; +$p->port_number($args{'port'}); +&connectivity_check; +foreach my $i4 (0..254) { +$args{'host'} = $_[0].'.'.$i4; +$p->ping($args{'host'}); +$host[$i4] = $args{'host'}; +} +while (my ($host) = $p->ack) {push @{$hoa{'80'}}, $host; $host =~ s/^[0-9.]+[.]//; splice @host, $host} + +&syn_ping_elmn(80, 'udp'); +&syn_ping_elmn(443, 'udp'); +&syn_ping_elmn(443, 'tcp'); + +open my $FILEH_A, '>>', "./data/domains.txt"; # Here, we'll store all the domains from all ipv4 addresses. +foreach my $host (@{$hoa{'80'}}) { + next unless defined($host); + &connectivity_check($_[0]); + print $FILEH_A $host.':80'."\n"; + my @rray = &reverse_dns_doms($host); + if ($#rray == 0 and $rray[0] eq '') {&double_80_screenshot($host, $_[0])} else { + foreach (@rray) {if (-d "./data/$_/view-source:http:/$_/" or -d "./data/$_/view-source:https:/$_/") {print $FILEH_A "\n"; next}; + sleep rand(1)/10; + print $FILEH_A $_.','; &double_80_screenshot($_, $_[0])} + print $FILEH_A "\n"} + print $FILEH_A "\n"} +foreach my $host (@{$hoa{'443'}}) { + next unless defined($host); + &connectivity_check($_[0]); + print $FILEH_A $host.':443'."\n"; + my @rray = &reverse_dns_doms($host); + if ($#rray == 0 and $rray[0] eq '') {&double_443_screenshot($host, $_[0])} else { + foreach (@rray) {if (-d "./data/$_/view-source:http:/$_/" or -d "./data/$_/view-source:https:/$_/") {print $FILEH_A "\n"; next}; + sleep rand(1)/10; + print $FILEH_A $_.','; &double_443_screenshot($_, $_[0])} + print $FILEH_A "\n"} + print $FILEH_A "\n"} +&connectivity_check($_[0]); # TODO: Potential infinite recursion on __very__ unstable networks with parameter? +my $beta = time; +my $delta = $beta-$alpha; +my $gamma = $delta*255**3-255*$ii; +while (0 > $gamma) {$alpha = time; &connectivity_check($_[0]); $beta = time; $delta = $beta-$alpha; $gamma = $delta*255**3-255*$ii;} +$ii++; print 'Progress: ', 0.00000603*$ii, "%\n", 'ETA: ', $gamma, "s\n"; +close $FILEH_A; +print "\n", 'To continue after quitting, provide', $_[0].'.0', 'as first argument.', "\n"; +}} +last} } sub double_80_screenshot { -if ($#_ > 0) {die "$!: Too much arguments: \"$_[1]\"...\"$_[$#_]\"."} +if ($#_ > 1) {die "$!: Too much arguments: \"$_[1]\"...\"$_[$#_]\"."} &connectivity_check; my $time_in_s = time; -$driver->get("http://$_[0]"); # Fetch the eye-candy. -my $current_url = $driver->get_current_url(); +eval {$driver->get("http://$_[0]")}; # Fetch the eye-candy. +eval {$driver->dismiss_alert}; eval {$driver->accept_alert}; -make_path("./data/$_[0]/$current_url/") or die "$!: Insufficient permissions."; +my $current_url; +eval {$current_url = $driver->get_current_url()}; +if ($current_url) { +eval {make_path("./data/$_[0]/$current_url/")}; open my $FILEH_B, '>', "./data/$_[0]/$current_url/screenshot-$time_in_s.png.base64"; -print $FILEH_B $driver->screenshot({'full' => 1}); -&connectivity_check; +open my $FILEH_C, '>', "./data/$_[0]/$current_url/title.txt"; +eval {print $FILEH_B $driver->screenshot({'full' => 1})}; +print $FILEH_C $driver->get_title(); +&connectivity_check($_[1], "./data/$_[0]/$current_url/screenshot-$time_in_s.png.base64"); +} else {eval {make_path("./data/$_[0]/-/")}; +open my $FILEH_B, '>', "./data/$_[0]/-/screenshot-$time_in_s.png.base64"; +open my $FILEH_C, '>', "./data/$_[0]/-/title.txt"; +eval {print $FILEH_B $driver->screenshot({'full' => 1})}; +print $FILEH_C $driver->get_title(); +&connectivity_check($_[1], "./data/$_[0]/-/screenshot-$time_in_s.png.base64"); +} $time_in_s = time; -$driver->get("view-source:http://$_[0]"); # Fetch the page source for (partly) reproduction. -$current_url = $driver->get_current_url(); -make_path("./data/$_[0]/$current_url/") or die "$!: Insufficient permissions."; -open $FILEH_B, '>', "./data/$_[0]/$current_url/screenshot-$time_in_s.png.base64"; -print $FILEH_B $driver->screenshot({'full' => 1}); +eval {$driver->get("view-source:http://$_[0]")}; # Fetch the page source for (partly) reproduction. +undef $current_url; +eval {$current_url = $driver->get_current_url()}; +if ($current_url) { +eval {make_path("./data/$_[0]/$current_url/")}; +open my $FILEH_B, '>', "./data/$_[0]/$current_url/screenshot-$time_in_s.png.base64"; +open my $FILEH_C, '>', "./data/$_[0]/$current_url/title.txt"; +eval {print $FILEH_B $driver->screenshot({'full' => 1})}; +print $FILEH_C $driver->get_title(); +&connectivity_check($_[1], "./data/$_[0]/$current_url/screenshot-$time_in_s.png.base64"); +} else {eval {make_path("./data/$_[0]/-/")}; +open my $FILEH_B, '>', "./data/$_[0]/-/screenshot-$time_in_s.png.base64"; +open my $FILEH_C, '>', "./data/$_[0]/-/title.txt"; +eval {print $FILEH_B $driver->screenshot({'full' => 1})}; +print $FILEH_C $driver->get_title(); +&connectivity_check($_[1], "./data/$_[0]/-/screenshot-$time_in_s.png.base64"); +} } sub double_443_screenshot { -if ($#_ > 0) {die "$!: Too much arguments: \"$_[1]\"...\"$_[$#_]\"."} +if ($#_ > 1) {die "$!: Too much arguments: \"$_[1]\"...\"$_[$#_]\"."} &connectivity_check; my $time_in_s = time; -$driver->get("https://$_[0]"); -my $current_url = $driver->get_current_url(); +eval {$driver->get("https://$_[0]")}; +eval {$driver->dismiss_alert}; eval {$driver->accept_alert}; -make_path("./data/$_[0]/$current_url/") or die "$!: Insufficient permissions."; +my $current_url; +eval {$current_url = $driver->get_current_url()}; +if ($current_url) { +eval {make_path("./data/$_[0]/$current_url/")}; open my $FILEH_B, '>', "./data/$_[0]/$current_url/screenshot-$time_in_s.png.base64"; -print $FILEH_B $driver->screenshot({'full' => 1}); -&connectivity_check; +open my $FILEH_C, '>', "./data/$_[0]/$current_url/title.txt"; +eval {print $FILEH_B $driver->screenshot({'full' => 1})}; +print $FILEH_C $driver->get_title(); +&connectivity_check($_[1], "./data/$_[0]/$current_url/screenshot-$time_in_s.png.base64"); +} else {eval {make_path("./data/$_[0]/-/")}; +open my $FILEH_B, '>', "./data/$_[0]/-/screenshot-$time_in_s.png.base64"; +open my $FILEH_C, '>', "./data/$_[0]/-/title.txt"; +eval {print $FILEH_B $driver->screenshot({'full' => 1})}; +print $FILEH_C $driver->get_title(); +&connectivity_check($_[1], "./data/$_[0]/-/screenshot-$time_in_s.png.base64"); +} $time_in_s = time; -$driver->get("view-source:https://$_[0]"); -$current_url = $driver->get_current_url(); -make_path("./data/$_[0]/$current_url/") or die "$!: Insufficient permissions."; -open $FILEH_B, '>', "./data/$_[0]/$current_url/screenshot-$time_in_s.png.base64"; -print $FILEH_B $driver->screenshot({'full' => 1}); +eval {$driver->get("view-source:https://$_[0]")}; +undef $current_url; +eval {$current_url = $driver->get_current_url()}; +if ($current_url) { +eval {make_path("./data/$_[0]/$current_url/")}; +open my $FILEH_B, '>', "./data/$_[0]/$current_url/screenshot-$time_in_s.png.base64"; +open my $FILEH_C, '>', "./data/$_[0]/$current_url/title.txt"; +eval {print $FILEH_B $driver->screenshot({'full' => 1})}; +print $FILEH_C $driver->get_title(); +&connectivity_check($_[1], "./data/$_[0]/$current_url/screenshot-$time_in_s.png.base64"); +} else {eval {make_path("./data/$_[0]/-/")}; +open my $FILEH_B, '>', "./data/$_[0]/-/screenshot-$time_in_s.png.base64"; +open my $FILEH_C, '>', "./data/$_[0]/-/title.txt"; +eval {print $FILEH_B $driver->screenshot({'full' => 1})}; +print $FILEH_C $driver->get_title(); +&connectivity_check($_[1], "./data/$_[0]/-/screenshot-$time_in_s.png.base64"); +} } sub reverse_dns_doms { @@ -66,58 +175,95 @@ my $res = Net::DNS::Resolver->new; my $reply = $res->search("$_[0]", "PTR"); if ($reply) { foreach my $rr ($reply->answer) { -push @obj, $rr->ptrdname; +print $rr->ptrdname, ' <--- This shouldn', "'", 't happen.', "\n" if $rr->ptrdname !~ m/^[a-z0-9.-]+$/; +eval {push @obj, $rr->ptrdname}; # Looped over a CNAME for 1.9.30.40? } } return @obj; } -foreach my $i1 (1..9,11..126,128..255) { # Skip huge private blocks. -foreach my $i2 (0..255) { -foreach my $i3 (0..255) { +sub syn_ping_elmn { +$p->port_number($_[0]); +foreach my $host (@host) { +next unless defined($host); +(my $check = $host) =~ s/[.][0-9]+$//; +&connectivity_check($check); +last} +foreach my $host (@host) { +#next unless defined($host); +$args{'host'} = $host; +$p->ping($args{'host'}); +$host =~ s/^[0-9.]+[.]//; +$host[$host] = $args{'host'}; +} +while (my ($host) = $p->ack) {push @{$hoa{$_[0]}}, $host; $host =~ s/^[0-9.]+[.]//; splice @host, $host} +} + +$initvar=1; +unless (defined($continue_from)) {($ii1, $ii2, $ii3) = (1, 0, 0)} +LABEL1: foreach my $i1 (1..9,11..126,128..254) { # Skip large private blocks. +if ($initvar == 1) { +until ($i1 >= $ii1) {next LABEL1} +} +LABEL2: foreach my $i2 (0..254) { +if ($initvar == 1) { +until (int($i1*255**3+$i2*255**2) >= int($ii1*255**3+$ii2*255**2)) {next LABEL2} +} +LABEL3: foreach my $i3 (0..254) { +if ($initvar == 1) { +until (int($i1*255**3+$i2*255**2+$i3*255) >= int($ii1*255**3+$ii2*255**2+$ii3*255)) {next LABEL3} +} +$initvar=0; my $alpha = time; -foreach my $i4 (0..255) { -$args{'host'} = $i1.'.'.$i2.'.'.$i3.'.'.$i4; +splice @host, 0, $#host; +undef %hoa; $args{'port'} = '80'; $args{'proto'} = 'tcp'; - +$p->port_number($args{'port'}); &connectivity_check; -if (check_port(\%args)) { - print $FILEH_A $args{'host'}.':'.$args{'port'}.' is in use:'."\n"; - my @rray = &reverse_dns_doms($args{'host'}); - if ($#rray == 0 and $rray[0] eq '') {&double_80_screenshot($args{'host'})} else { - foreach (@rray) {print $FILEH_A $_.','; &double_80_screenshot($_)}} - print $FILEH_A "\n\n"; - } else {$args{'proto'} = 'udp'; - &connectivity_check; - if (check_port(\%args)) { - print $FILEH_A $args{'host'}.':'.$args{'port'}.' is in use:'."\n"; - my @rray = &reverse_dns_doms($args{'host'}); - if ($#rray == 0 and $rray[0] eq '') {&double_80_screenshot($args{'host'})} else { - foreach (@rray) {print $FILEH_A $_.','; &double_80_screenshot($_)}} - print $FILEH_A "\n\n"; - } else {$args{'port'} = '443'; - &connectivity_check; - if (check_port(\%args)) { - print $FILEH_A $args{'host'}.':'.$args{'port'}.' is in use:'."\n"; - my @rray = &reverse_dns_doms($args{'host'}); - if ($#rray == 0 and $rray[0] eq '') {&double_443_screenshot($args{'host'})} else { - foreach (@rray) {print $FILEH_A $_.','; &double_443_screenshot($_)}} - print $FILEH_A "\n\n"; - } else {$args{'proto'} = 'tcp'; - &connectivity_check; - if (check_port(\%args)) { - print $FILEH_A $args{'host'}.':'.$args{'port'}.' is in use:'."\n"; - my @rray = &reverse_dns_doms($args{'host'}); - if ($#rray == 0 and $rray[0] eq '') {&double_443_screenshot($args{'host'})} else { - foreach (@rray) {print $FILEH_A $_.','; &double_443_screenshot($_)}} - print $FILEH_A "\n\n"; -}}}}} +foreach my $i4 (0..254) { +$args{'host'} = $i1.'.'.$i2.'.'.$i3.'.'.$i4; +$p->ping($args{'host'}); +$host[$i4] = $args{'host'}; +} +while (my ($host) = $p->ack) {push @{$hoa{'80'}}, $host; $host =~ s/^[0-9.]+[.]//; splice @host, $host} + +&syn_ping_elmn(80, 'udp'); +&syn_ping_elmn(443, 'udp'); +&syn_ping_elmn(443, 'tcp'); + +open my $FILEH_A, '>>', "./data/domains.txt"; # Here, we'll store all the domains from the ipv4 addresses. +foreach my $host (@{$hoa{'80'}}) { + next unless defined($host); + &connectivity_check($i1.'.'.$i2.'.'.$i3); + print $FILEH_A $host.':80'."\n"; + my @rray = &reverse_dns_doms($host); + if ($#rray == 0 and $rray[0] eq '') {&double_80_screenshot($host, $i1.'.'.$i2.'.'.$i3)} else { + foreach (@rray) {if (-d "./data/$_/view-source:http:/$_/" or -d "./data/$_/view-source:https:/$_/") {print $FILEH_A "\n"; next}; + sleep rand(1)/10; + print $FILEH_A $_.','; &double_80_screenshot($_, $i1.'.'.$i2.'.'.$i3)} + print $FILEH_A "\n"} + print $FILEH_A "\n"} +foreach my $host (@{$hoa{'443'}}) { + next unless defined($host); + &connectivity_check($i1.'.'.$i2.'.'.$i3); + print $FILEH_A $host.':443'."\n"; + my @rray = &reverse_dns_doms($host); + if ($#rray == 0 and $rray[0] eq '') {&double_443_screenshot($host, $i1.'.'.$i2.'.'.$i3)} else { + foreach (@rray) {if (-d "./data/$_/view-source:http:/$_/" or -d "./data/$_/view-source:https:/$_/") {print $FILEH_A "\n"; next}; + sleep rand(1)/10; + print $FILEH_A $_.','; &double_443_screenshot($_, $i1.'.'.$i2.'.'.$i3)} + print $FILEH_A "\n"} + print $FILEH_A "\n"} +&connectivity_check($i1.'.'.$i2.'.'.$i3); my $beta = time; my $delta = $beta-$alpha; -$ii++; print 'Progress: ', 0.00000603*$ii, "%\n", 'ETA: ', $delta*255**3-255*$ii, "s\n"; +my $gamma = $delta*255**3-255*$ii; +while (0 > $gamma) {print $gamma, ' ETA shouldn', "'", 't be negative. Retrying from ', $i1.'.'.$i2.'.'.$i3.'.'.0; $alpha = time; &connectivity_check($_[0]); $beta = time; $delta = $beta-$alpha; $gamma = $delta*255**3-255*$ii;} +$ii++; print 'Progress: ', 0.00000603*$ii, "%\n", 'ETA: ', $gamma, "s\n"; +close $FILEH_A; +print "\n", 'To continue after quitting, provide ', $i1.'.'.$i2.'.'.$i3.'.'.'0', ' as first argument.', "\n\n"; }}} print 'Cleaning up...'."\n"; -close $FILEH_A; $driver->quit(); `killall geckodriver` and print 'Done!'."\n";