Skip to content

Commit a9353cf

Browse files
committed
4.4.2 release
1 parent 097e9a4 commit a9353cf

File tree

3 files changed

+156
-9
lines changed

3 files changed

+156
-9
lines changed

lib/Scot/Inbox/Config.pm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use Mojo::Util qw(decode);
3333
# S4INBOX_MSV_FILTER_DEFINITIONS... the filename holding the MSV filter definitions
3434
# S4INBOX_MSV_DBM_FILE ... the filename of the dbm file for msv deduplication
3535
# S4INBOX_SCOT_INPUT_QUEUE ... alertgroup, event, or dispatch
36-
# S4INBOX_MAIL_CLIENT_CLASS ... Scot::Inbox::Imap or Scot::Inbox::MSGraph
36+
# S4INBOX_MAIL_CLIENT_CLASS ... Scot::Inbox::Imap or Scot::Inbox::Msgraph
3737
# S4INBOX_TEST_MODE ... read inbox regardless of "unread" state and do not change read flags
3838
#
3939
# SECRETS

lib/Scot/Inbox/Processor.pm

Lines changed: 132 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ sub run ($self) {
7474
while (my $msg = $cursor->next) {
7575
$index++;
7676
$log->debug("[$target] processing message $index of $count");
77+
$log->debug("msg => ", {filter=>\&Dumper, value => $msg});
7778
if (! defined $msg) {
7879
$log->warn("[$target] undefined message encountered, skipping");
7980
next;
@@ -152,19 +153,26 @@ sub process_message ($self, $msg, $target) {
152153
return 1;
153154
}
154155

156+
$self->log->debug("Target is $target");
157+
155158
return $self->process_alert($msg) if ($target eq 'alertgroup');
156159
return $self->process_dispatch($msg) if ($target eq 'dispatch');
160+
return $self->process_vulnfeed($msg) if ($target eq 'vulnfeed' or $target eq "vuln_feed");
157161
return $self->process_event($msg) if ($target eq 'event');
158162

159163
}
160164

165+
sub processor_class ($self, $subject) {
166+
return "splunk" if $self->looks_like_splunk($subject);
167+
return "uba" if $self->looks_like_uba($subject);
168+
return "generic";
169+
}
170+
161171
sub process_alert ($self, $msg) {
162-
# 2 types of alerts, from splunk and generic
163172
my $subject = $msg->{subject};
164-
$self->log->debug("Looking at message $subject");
165-
my $json = ($self->looks_like_splunk($subject))
166-
? $self->process_splunk_alert($msg)
167-
: $self->process_generic_alert($msg);
173+
my $class = "process_".$self->processor_class($subject)."_alert";
174+
$self->log->debug("Looking at message $subject class $class");
175+
my $json = $self->$class($msg);
168176
$self->filter_msv($json) if $self->msv;
169177
my $status = $self->create_alertgroup($json);
170178
if ( $status > 0 ) {
@@ -185,6 +193,11 @@ sub looks_like_splunk ($self, $subject) {
185193
return undef;
186194
}
187195

196+
sub looks_like_uba ($self, $subject) {
197+
return 1 if ($subject =~ /Splunk UBA/i);
198+
return undef;
199+
}
200+
188201

189202
sub filter_msv ($self, $json) {
190203
# this function operates by side-effect
@@ -396,6 +409,40 @@ sub process_splunk_alert ($self, $msg) {
396409
return wantarray ? %json : \%json;
397410
}
398411

412+
sub process_uba_alert ($self, $msg) {
413+
$self->log->debug("Processing a UBA alert...");
414+
my ($html,
415+
$plain,
416+
$tree) = $self->preparse($msg);
417+
# return $alertname, $backlink, \%data;
418+
my ($alertname,
419+
$backlink,
420+
$columns,
421+
$data) = $self->get_uba_report_info($tree);
422+
my $alertschema = $self->build_alert_schema($columns);
423+
424+
my %json = (
425+
owner => 'scot-alerts',
426+
tlp => 'unset',
427+
view_count => 0,
428+
message_id => $msg->{message_id},
429+
subject => $msg->{subject},
430+
sources => [qw(email splunk)],
431+
tags => [],
432+
alerts => { data => $data },
433+
alert_schema => $alertschema,
434+
back_refs => $backlink,
435+
# additons to discuss with greg
436+
# (will delete in filter_schema after writing MSV log)
437+
columns => $columns, # to get column order from splunk
438+
links => [],
439+
search => $backlink,
440+
);
441+
$self->log->trace("built json ", {filter => \&Dumper, value => \%json});
442+
443+
return wantarray ? %json : \%json;
444+
}
445+
399446
sub build_alerts ($self, $alerts) {
400447
my @new = map { { data => $_ } } @$alerts;
401448
return \@new;
@@ -445,6 +492,57 @@ sub get_splunk_report_info ($self, $tree) {
445492
return $alertname, $search, \@tags;
446493
}
447494

495+
sub get_uba_report_info ($self, $tree) {
496+
my $alertname = "UBA parse error";
497+
my @tags = (qw(parse_error));
498+
my $backlink = 'parse_error';
499+
my %data = ();
500+
my @columns = ();
501+
502+
my $title_element = $tree->look_down('_tag', 'title');
503+
if ($title_element) {
504+
$alertname = $title_element->as_text;
505+
}
506+
507+
my $link_element = ($tree->look_down('_tag', 'a'))[0];
508+
if ($link_element) {
509+
$backlink = $link_element->attr('href');
510+
}
511+
512+
my $table = ($tree->look_down('_tag', 'table'))[0];
513+
my @rows = $table->look_down('_tag', 'tr');
514+
foreach my $row (@rows) {
515+
my ($col1, $col2) = $row->look_down('_tag', 'td');
516+
my $colname = $col1->as_text;
517+
push @columns, $colname;
518+
my $colval = $col2->as_text;
519+
$data{$colname} = $colval;
520+
}
521+
522+
# note: this is specified by Kyle Gonzales
523+
# Looking at the sample, however some of these could be missing
524+
525+
my $users_element = ($tree->look_down('_tag','ul'))[0];
526+
my @li_users = $users_element->look_down('_tag','li');
527+
foreach my $li (@li_users) {
528+
push @{$data{users}}, $li->as_text;
529+
}
530+
531+
my $devices_element = ($tree->look_down('_tag','ul'))[1];
532+
my @li_devices = $devices_element->look_down('_tag','li');
533+
foreach my $li (@li_devices) {
534+
push @{$data{devices}}, $li->as_text;
535+
}
536+
537+
my $domains_element = ($tree->look_down('_tag', 'ul'))[2];
538+
my @li_domains = $domains_element->look_down('_tag','li');
539+
foreach my $li (@li_domains) {
540+
push @{$data{domains}}, $li->as_text;
541+
}
542+
543+
return $alertname, $backlink, \%data;
544+
}
545+
448546
sub get_alert_results ($self, $tree, $alertname, $search) {
449547
my @results = ();
450548
my @columns = ();
@@ -592,6 +690,35 @@ sub process_dispatch ($self, $msg) {
592690
return 1;
593691
}
594692

693+
sub process_vulnfeed ($self, $msg) {
694+
$self->log->debug("Process a vulnfeed...");
695+
my ($html, $plain, $tree) = $self->preparse($msg);
696+
my $tlp = $self->find_tlp($plain);
697+
my $entry = $self->build_entry($tree, $tlp);
698+
699+
my %json = (
700+
vuln_feed => {
701+
subject => $msg->{subject},
702+
message_id => $msg->{message_id},
703+
owner => 'scot-vulnfeed',
704+
tags => $self->build_tags($msg),
705+
sources => $self->build_sources($msg),
706+
tlp => $tlp,
707+
},
708+
entry => $entry,
709+
);
710+
$self->log->debug("vulnfeed item = ", {filter=>\&Dumper, value=> \%json});
711+
my $resp = $self->scotapi->create_vulnfeed(\%json);
712+
713+
if (!defined $resp->{vuln_feed} || !defined $resp->{entry}) {
714+
$self->log->error("Error creating either dispatch or entry!");
715+
$self->log->error("resp = ",{filter =>\&Dumper, value => $resp});
716+
return;
717+
}
718+
return 1;
719+
}
720+
721+
595722
sub process_event ($self, $msg) {
596723
$self->log->debug("Processing a event...");
597724
my ($html, $plain, $tree) = $self->preparse($msg);
@@ -760,6 +887,3 @@ sub find_tlp ($self, $text) {
760887

761888
1;
762889

763-
764-
765-

lib/Scot/Inbox/ScotApi.pm

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,29 @@ sub create_dispatch ($self, $json) {
162162
};
163163
}
164164

165+
sub create_vulnfeed ($self, $json) {
166+
my $entry_text = delete $json->{entry};
167+
my $uri = $self->config->{uri_root}."/vuln_feed/";
168+
my $vulnfeed = decode_json $self->post($uri, $json);
169+
$self->log->debug("post returns: ",{filter =>\&Dumper, value => $vulnfeed});
170+
171+
if ( defined $vulnfeed and $vulnfeed->{id} > 0 ) {
172+
$self->log->debug("creating entry");
173+
my $entry = decode_json $self->create_entry("vuln_feed", $vulnfeed->{id}, $entry_text);
174+
$self->log->debug("entry = ",{filter=>\&Dumper, value => $entry});
175+
if ( defined $entry and $entry->{id} > 0 ) {
176+
return {
177+
vuln_feed => $vulnfeed,
178+
entry => $entry,
179+
};
180+
}
181+
}
182+
return {
183+
vulnfeed => undef,
184+
entry => undef,
185+
};
186+
}
187+
165188
sub create_event ($self, $json) {
166189
my $entry_text = delete $json->{entry};
167190
my $uri = $self->config->{uri_roo}."/entry/";

0 commit comments

Comments
 (0)