#!/usr/bin/env perl
use strict;
# fix lib paths, some may be relative
BEGIN {
require File::Spec;
my @libs = (
"lib",
"local/lib",
"../libcif/lib", # in case we're in -dev mode
"../libcif-dbi/lib", # in case we're in -dev mode
"../cif-router/lib", # in case we're in -dev mode
"../cif-smrt/lib", # in case we're in -dev mode
);
my $bin_path;
for my $lib (@libs) {
unless ( File::Spec->file_name_is_absolute($lib) ) {
unless ($bin_path) {
if ( File::Spec->file_name_is_absolute(__FILE__) ) {
$bin_path = ( File::Spec->splitpath(__FILE__) )[1];
}
else {
require FindBin;
no warnings "once";
$bin_path = $FindBin::Bin;
}
}
$lib = File::Spec->catfile( $bin_path, File::Spec->updir, $lib );
}
unshift @INC, $lib;
}
}
use Cikl qw/debug/;
our $debug = 0;
# config opts
my $config_file = $ENV{'HOME'}.'/.cikl';
my $outfile;
my @queries;
# query options
my $nolog = 0;
my $confidence;
my $group;
my $limit;
# plugin opts
my $plugin = 'Table';
my $fields;
my $help = 0;
Getopt::Long::Configure ("bundling");
GetOptions(
'config|C=s' => \$config_file,
'outfile|O=s' => \$outfile,
'debug|d|v+' => \$debug,
'query|q=s' => \@queries,
'nolog|n' => \$nolog,
'confidence|c=i' => \$confidence,
'group|g=s' => \$group,
'limit|l=i' => \$limit,
'plugin|p=s' => \$plugin,
'fields|f=s' => \$fields,
'help|h' => => \$help
) or die($!);
die usage() if($help);
sub usage {
return <<EOF;
Usage: perl $0 -q xyz.com
Standard Options:
-h --help: this message
-C --config: specify cofiguration file, default: $config_file
Query Options:
-q --query: query string
-n --nolog: perform a "silent" query (no log query), default: $nolog
-l --limit: set the default result limit (queries only), default is set on server, usually around 500.
-c --confidence: lowest tolerated confidence (0.00 -- 100.00), default $confidence
Format Options:
-p --plugin: output plugin ('Table','Csv'), default: Table
-f --fields: set default output fields for default table display
-g --group: filter by a specific group name, ex: group1.example.com
Nonstandard Options:
Example Queries:
\$> perl $0 -q 1.2.3.4
\$> perl $0 -q 1.2.3.0/24
\$> perl $0 -q f8e74165fb840026fd0fce1fd7d62f5d0e57e7ac
\$> perl $0 -q hut2.ru
\$> perl $0 -q hut2.ru,f8e74165fb840026fd0fce1fd7d62f5d0e57e7ac
\$> perl $0 hut2.ru
\$> perl $0 -q malware
\$> perl $0 -q malware
\$> perl $0 -q infrastructure/botnet -p csv
\$> perl $0 -q domain/malware -p bindzone -c 95
\$> perl $0 -q domain -c 40
\$ $0 -d -q example.com -e search
Configuration:
configuration file ~/.cikl should be readable and look something like:
[client]
apikey = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
driver = 'http'
# table_nowarning = 1
# csv_noseperator = 1
[client_http]
timeout = 60
# add this if you have a self signed cert
verify_tls = 0
# proxy settings
EOF
}
$plugin = lc($plugin);
my $formatter;
if ($plugin eq 'csv') {
$formatter = Cikl::Report::CSVFormatter->new();
} elsif ($plugin eq 'table') {
$formatter = Cikl::Report::TableFormatter->new();
}
if (!defined($formatter)) {
print usage();
print "ERROR: Unknown formatter ($plugin) specified.\n";
exit(0);
}
my $config = Config::Simple->new($config_file) or die("Failed to open config file $config_file: " . $!);
my $err;
my $client_config = $config->get_block('client');
#$client_config->{global_config} = $config;
my $cli = Cikl::Client::Factory->instantiate($client_config);
# else we're doing query
if($outfile){
open(F,">",$outfile) || die($!);
}
my %args;
if ($limit) {
$args{limit} = $limit;
}
if ($group) {
$args{group} = $group;
}
if ($confidence) {
$args{confidence} = Cikl::Models::QueryRange->new(min => $confidence);
}
my @address_criteria;
foreach my $query (@queries) {
my @query_parts = split(':', $query, 2);
if (!defined($query_parts[1])) {
die("Invalid query: $query");
}
push(@address_criteria, Cikl::Models::QueryAddress->new(
operator => $query_parts[0],
value => $query_parts[1]
));
}
$args{address_criteria} = \@address_criteria;
use Time::HiRes qw/tv_interval gettimeofday/;
my $start = [gettimeofday];
my $query_results = $cli->query(%args);
my $runtime = tv_interval($start);
debug("Query round trip: $runtime seconds");
$cli->shutdown();
if($err){
print 'ERROR: '.$err."\n";
exit(-1);
}
unless($query_results){
debug('no results...') if($debug);
exit(0);
}
debug('formatting as '.ucfirst($plugin).'...');
$fields = [ split(/,/,$fields) ] if($fields);
my @text;
my $output = *STDOUT;
if($outfile){
$output = *F;
}
my $report = Cikl::Report::QueryResultsReport->new($query_results);
$formatter->generate_report($report, $output);
if ($outfile) {
close(F);
}