#!perl
post
'/*'
=>
sub
(
$c
) {
the_stuff(
$c
);
};
post
'/'
=>
sub
(
$c
) {
the_stuff(
$c
);
};
sub
log_drek {
my
(
$level
,
$message
) =
@_
;
if
( !
defined
(
$level
) ) {
$level
=
'info'
;
}
openlog(
'mojo_cape_submit'
,
'cons,pid'
,
'daemon'
);
syslog(
$level
,
'%s'
,
$message
);
closelog();
}
sub
the_stuff {
my
$c
=
$_
[0];
my
$remote_ip
=
$c
->{tx}{original_remote_address};
my
$apikey
=
$c
->param(
'apikey'
);
my
$message
=
'Started. Remote IP: '
.
$remote_ip
.
' API key: '
;
if
(
defined
(
$apikey
) ) {
$message
=
$message
.
$apikey
;
}
else
{
$message
=
$message
.
'undef'
;
}
log_drek(
'info'
,
$message
);
my
$cape_util
;
eval
{
$cape_util
= CAPE::Utils->new(); };
if
($@) {
log_drek(
'err'
, $@ );
$c
->render(
text
=>
"Error... please see syslog\n"
,
status
=> 400, );
return
;
}
if
( !-d
$cape_util
->{config}->{_}->{incoming} ) {
log_drek(
'err'
,
'incoming directory, "'
.
$cape_util
->{config}->{_}->{incoming} .
'", does not exist'
);
$c
->render(
text
=>
"Error... please see syslog\n"
,
status
=> 400, );
return
;
}
my
$allow_remote
;
eval
{
$allow_remote
=
$cape_util
->check_remote(
apikey
=>
$apikey
,
ip
=>
$remote_ip
); };
if
($@) {
log_drek(
'err'
, $@ );
$c
->render(
text
=>
"Error... please see syslog\n"
,
status
=> 400, );
return
;
}
if
( !
$allow_remote
) {
log_drek(
'info'
,
'API key or IP not allowed'
);
$c
->render(
text
=>
"IP not allowed or invalid API key\n"
,
status
=> 403, );
return
;
}
if
(
$c
->req->is_limit_exceeded ) {
log_drek(
'err'
,
'Log size exceeded'
);
$c
->render(
text
=>
'File is too big.'
,
status
=> 400 );
return
;
}
my
$file
=
$c
->param(
'filename'
);
if
( !
$file
) {
log_drek(
'err'
,
'No file specified'
);
$c
->render(
text
=>
'No file specified'
,
status
=> 400 );
}
my
$name
=
$file
->filename;
my
$size
=
$file
->size;
if
(
$size
== 10 ) {
my
$file_data
=
$file
->slurp;
if
(
$file_data
=~ /1234567890/ ) {
log_drek(
'info'
,
'got ping test, size=10 payload=01234567890'
);
$c
->render(
text
=>
"TEST RECIEVED\n"
,
status
=> 200, );
return
;
}
}
my
$orig_name
=
$name
;
$name
=~ s/\///;
log_drek(
'info'
,
'Got File... size='
.
$size
.
' filename="'
.
$name
.
'"'
);
$name
=
$cape_util
->{config}->{_}->{incoming} .
'/'
.
$name
;
my
$raw_json
=
$c
->param(
'json'
);
my
$json
;
eval
{
$json
= decode_json(
$raw_json
); };
if
($@) {
log_drek(
'err'
,
'json param decode error: '
. $@ );
$json
= {};
}
$json
->{cape_submit} = {
orig_name
=>
$orig_name
,
name
=>
$name
,
apikey
=>
$apikey
,
remote_ip
=>
$remote_ip
,
size
=>
$size
,
time
=>
time
,
host
=> hostname,
};
my
%additional_info
;
$additional_info
{src_ip} =
$c
->param(
'src_ip'
);
$additional_info
{src_port} =
$c
->param(
'src_port'
);
$additional_info
{dest_ip} =
$c
->param(
'dest_ip'
);
$additional_info
{dest_port} =
$c
->param(
'dest_port'
);
$additional_info
{proto} =
$c
->param(
'proto'
);
$additional_info
{app_proto} =
$c
->param(
'app_proto'
);
$additional_info
{flow_id} =
$c
->param(
'flow_id'
);
$additional_info
{http_host} =
$c
->param(
'http_host'
);
$additional_info
{http_url} =
$c
->param(
'http_url'
);
$additional_info
{http_method} =
$c
->param(
'http_method'
);
$additional_info
{http_proto} =
$c
->param(
'http_proto'
);
$additional_info
{http_status} =
$c
->param(
'http_status'
);
$additional_info
{http_ctype} =
$c
->param(
'http_ctype'
);
$additional_info
{http_ua} =
$c
->param(
'http_ua'
);
$additional_info
{det_sub_type} =
$c
->param(
'type'
);
$additional_info
{src_host} =
$c
->param(
'src_host'
);
foreach
my
$item
(
keys
(
%additional_info
) ) {
if
( !
defined
(
$additional_info
{
$item
} ) ) {
$additional_info
{
$item
} =
'undef'
;
}
}
$json
->{det_sub_type} =
$additional_info
{det_sub_type};
log_drek(
'info'
,
'Source Host: '
.
$additional_info
{src_host} );
log_drek(
'info'
,
'Submission Type: '
.
$additional_info
{det_sub_type} );
log_drek(
'info'
,
'proto='
.
$additional_info
{proto}
.
' src_ip='
.
$additional_info
{src_ip}
.
' src_port='
.
$additional_info
{src_port}
.
' dest_ip='
.
$additional_info
{dest_ip}
.
' dest_port='
.
$additional_info
{dest_port}
.
' flow_id='
.
$additional_info
{flow_id} );
if
(
$additional_info
{app_proto} eq
'http'
) {
log_drek(
'info'
,
$additional_info
{http_proto} .
' '
.
$additional_info
{http_host} );
log_drek(
'info'
,
$additional_info
{http_method} .
' '
.
$additional_info
{http_status} .
' '
.
$additional_info
{http_url} );
log_drek(
'info'
,
'useragent: '
.
$additional_info
{http_ua} );
}
else
{
log_drek(
'info'
,
'App Proto: '
.
$additional_info
{app_proto} );
}
$file
->move_to(
$name
);
$json
->{cape_submit}{sha256} =
lc
( `sha256sum
$name
` );
chomp
(
$json
->{cape_submit}{sha256});
$json
->{cape_submit}{sha256} =~ s/[\ \t].+//;
log_drek(
'info'
,
'SHA256: '
.
$json
->{cape_submit}{sha256} );
$json
->{cape_submit}{sha1} =
lc
( `sha1sum
$name
` );
chomp
(
$json
->{cape_submit}{sha1});
$json
->{cape_submit}{sha1} =~ s/[\ \t].+//;
log_drek(
'info'
,
'SHA1: '
.
$json
->{cape_submit}{sha1} );
$json
->{cape_submit}{md5} =
lc
( `md5sum
$name
` );
chomp
(
$json
->{cape_submit}{md5});
$json
->{cape_submit}{md5} =~ s/[\ \t].+//;
log_drek(
'info'
,
'MD5: '
.
$json
->{cape_submit}{md5} );
my
$results
;
eval
{
$results
=
$cape_util
->submit(
items
=> [
$name
],
quiet
=> 1, ); };
if
($@) {
log_drek(
'err'
, $@ );
$c
->render(
text
=>
"Error... please see syslog\n"
,
status
=> 400, );
return
;
}
my
@submitted
=
keys
( %{
$results
} );
if
( !
defined
(
$submitted
[0] ) ) {
log_drek(
'err'
,
'Submitting "'
.
$name
.
'" failed'
);
$c
->render(
text
=>
"Submission failed\n"
,
status
=> 400, );
return
;
}
log_drek(
'info'
,
'Submitting "'
.
$name
.
'" submitted as '
.
$results
->{
$submitted
[0] } );
$c
->render(
text
=>
"Submitted as task ID "
.
$results
->{
$submitted
[0] } .
"\n"
,
status
=> 200, );
$json
->{cape_submit}{task} =
$results
->{
$submitted
[0] };
if
( !-d
$cape_util
->{config}->{_}->{incoming_json} ) {
log_drek(
'err'
,
'incoming_json directory, "'
.
$cape_util
->{config}->{_}->{incoming_json} .
'", does not exist'
);
return
;
}
my
$data_json
= encode_json(
$json
) .
"\n"
;
my
$data_json_file
=
$cape_util
->{config}->{_}->{incoming_json} .
'/'
.
$results
->{
$submitted
[0] } .
'.json'
;
eval
{ write_file(
$data_json_file
,
$data_json
); };
if
($@) {
log_drek(
'err'
,
'Failed to write submission data JSON out to "'
.
$data_json_file
.
'"... '
. $@ );
}
else
{
log_drek(
'info'
,
'Wrote submission data JSON out to "'
.
$data_json_file
.
'"'
);
}
return
;
}
app->start;