Skip to content

Commit

Permalink
Add support for using Shodan.io as source for a scan result
Browse files Browse the repository at this point in the history
  • Loading branch information
xtaran committed Mar 11, 2020
1 parent 0913a84 commit 99086d2
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 5 deletions.
20 changes: 15 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ Quickly get an idea …

* … if the remote system is running an EoL release …

… just by looking at the responses of a few common network services,
i.e. very fast.
… just by looking at the responses of a few common network services
(or at [Shodan.io](https://www.shodan.io/)), i.e. very fast.

This is especially useful in heterogenous networks (e.g. with BYOD or
many self-managed machines) as common in academia, data-centers with a
Expand Down Expand Up @@ -80,10 +80,17 @@ should be no real issue.)
Includes (static) heuristics to also detect an [endlessh
tarpit](https://old.reddit.com/r/netsec/comments/b4dwjl/endlessh_an_ssh_tarpit/).

There are scripts which scan hosts themselves (IPv4 as well as IPv6)
and there's a script which queries
[Shodan.io](https://www.shodan.io/)'s API. (The latter requires a free
account there and an API key stored in `~/.shodan/api_key` as the
officialy Shodan Python library does.)


Requirements
------------

TL;DR: `apt install libclass-c3-perl libdpkg-perl libdpkg-parse-perl libfile-touch-perl libio-socket-inet6-perl libmojolicious-perl libmojo-sqlite-perl libnet-cidr-set-perl libnet-dns-perl libparams-validate-perl libtry-tiny-perl libyaml-perl`
TL;DR: `apt install libclass-c3-perl libdpkg-perl libdpkg-parse-perl libfile-touch-perl libio-socket-inet6-perl libmojolicious-perl libmojo-sqlite-perl libnet-cidr-set-perl libnet-dns-perl libparams-validate-perl libtry-tiny-perl libyaml-perl libdata-validate-ip-perl`


Dist-Detect is written in **Perl (5.14 or a higher 5.x version)** and
Expand All @@ -94,6 +101,10 @@ Debian packages names in parentheses):
([`Class-C3`](https://metacpan.org/release/Class-C3),
[`libclass-c3-perl`](https://packages.debian.org/libclass-c3-perl))

* [`Data::Validate::IP`](https://metacpan.org/pod/Data::Validate::IP)
([`Data-Validate-IP`](https://metacpan.org/release/Data-Validate-IP),
[`libdata-validate-ip-perl`](https://packages.debian.org/libdata-validate-ip-perl))

* [`Dpkg::Compression::FileHandle`](https://metacpan.org/pod/Dpkg::Compression::FileHandle)
and [`Dpkg::Version`](https://metacpan.org/pod/Dpkg::Version)
([`Dpkg`](https://metacpan.org/release/Dpkg),
Expand Down Expand Up @@ -287,8 +298,7 @@ Ideas
* [masscan](https://github.com/robertdavidgraham/masscan),
* [ZMap](https://zmap.io/)?
* [pf_ring](https://www.ntop.org/products/packet-capture/pf_ring/)?
* Online (i.e. publicly available data):
* [Shodan.io](https://www.shodan.io/)?
* Maybe further online ressources besides [Shodan.io](https://www.shodan.io/)?

* Ping (probably with [fping](https://www.fping.org/) or
[ZMap](https://zmap.io/)) before scan.
Expand Down
63 changes: 63 additions & 0 deletions bin/scanshodan.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

use Mojo::File;
use Mojo::UserAgent;
use Mojo::JSON qw(decode_json);
use Data::Validate::IP qw(is_ip);

my $api_key = Mojo::File->new($ENV{HOME}.'/.shodan/api_key')->slurp();
my $api_url = 'https://api.shodan.io/shodan/host/';
my $ua = Mojo::UserAgent->new;
$ua->max_redirects(2);
my $fmt = '%-31s | %-39s | %s';

foreach my $ip (@ARGV) {
if (!is_ip($ip)) {
warn "$ip doesn't look like an IP, skipping";
next;
}

my $res = $ua->get( $api_url . $ip . '?key=' . $api_key)->result;

if ($res->is_success) {
my $json = decode_json($res->body);

my $data = find_data_set($json->{data}, 'data', '^SSH-');
my @data = split(/\n/, $data, 2);
say sprintf($fmt,
find_data_set($json->{data}, 'ip_str'),
join(', ', @{find_data_set($json->{data}, 'hostnames')}),
$data[0]);
}
elsif ($res->is_error) {
warn "$ip: ". $res->message;
}
else {
say 'Whatever...';
}
}

sub find_data_set {
my $data = shift;
my $key = shift;
my $match = shift;

foreach my $item (@$data) {
if (exists($item->{$key})) {
if (defined $match) {
if ($item->{$key} =~ /$match/) {
return $item->{$key};
} else {
next;
}
} else {
return $item->{$key};
}
}
}
return undef;
}

0 comments on commit 99086d2

Please sign in to comment.