#!/usr/bin/env perl
BEGIN {
my
@libs
= (
"lib"
,
"local/lib"
,
"../libcif/lib"
,
"../libcif-dbi/lib"
,
"../cif-router/lib"
,
"../cif-smrt/lib"
,
);
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
{
no
warnings
"once"
;
$bin_path
=
$FindBin::Bin
;
}
}
$lib
= File::Spec->catfile(
$bin_path
, File::Spec->updir,
$lib
);
}
unshift
@INC
,
$lib
;
}
}
our
$debug
= 0;
my
$config_file
=
$ENV
{
'HOME'
}.
'/.cikl'
;
my
$outfile
;
my
@queries
;
my
$nolog
= 0;
my
$confidence
;
my
$group
;
my
$limit
;
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'
);
my
$cli
= Cikl::Client::Factory->instantiate(
$client_config
);
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
;
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);
}