Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #! /usr/bin/perl
- #
- # Script written to pull IP data from openIOC and search Splunk.
- #
- use strict;
- use warnings;
- $|=1;
- use LWP::UserAgent;
- use XML::LibXML;
- my %splunk_id;
- my @SPLUNK_SERVERS = ("internal.splunk.com:8089"); # set this to your splunk server(s)
- my $ioc_dir = "/tmp/iocfiles"; # Set to your IOC files location
- $splunk_id{'username'} = q/USERNAME/; # Splunk Username
- $splunk_id{'password'} = q/PASSWORD/; # Splunk Password
- $splunk_id{'data_type'} = "csv";
- sub splunk_login {
- my %BROWSER_PARAMS;
- $BROWSER_PARAMS{'username'}= $_[0];
- $BROWSER_PARAMS{'password'} = $_[1];
- my $base_url = "https://".$_[2];
- my $browser = LWP::UserAgent->new;
- my $response = $browser->post($base_url."/servicesNS/".$BROWSER_PARAMS{'username'}."/search/auth/login/", \%BROWSER_PARAMS);
- my $auth_key = "Login Error (".$response->content.")";
- if ($response->content =~ /<sessionKey>(.*?)<\/sessionKey>/){$auth_key = $1;};
- return $auth_key;
- }
- sub splunk_search {
- my %BROWSER_PARAMS;
- $BROWSER_PARAMS{'search'} = $_[0];
- my $browser = LWP::UserAgent->new;
- my $base_url = "https://".$_[1];
- $browser->default_header('Authorization' => "Splunk ".$_[2]);
- my $response = $browser->post($base_url."/servicesNS/".$_[3]."/search/search/jobs", \%BROWSER_PARAMS);
- my $search_id = "Error";
- if ($response->content =~ /<sid>(.*?)<\/sid>/){$search_id = $1;};
- return $search_id;
- }
- sub splunk_status {
- my $base_url = "https://".$_[1];
- my $browser = LWP::UserAgent->new;
- $browser->default_header('Authorization' => "Splunk ".$_[2]);
- my $response = $browser->get($base_url."/servicesNS/".$_[3]."/search/search/jobs/".$_[0]);
- if($response->code() != 200){die "Check error (".$response->code().")\n";}
- return $response->content;
- }
- sub splunk_get_data {
- my $base_url = "https://".$_[1];
- my $browser = LWP::UserAgent->new;
- $browser->default_header('Authorization' => "Splunk ".$_[2]);
- my $response = $browser->get($base_url."/servicesNS/".$_[3]."/search/search/jobs/".$_[0]."/results?output_mode=".$_[4]);
- if($response->content){return $response->content;}else{return "NULL";}
- }
- sub xml_dispatchState {
- my $dom = XML::LibXML->load_xml(string => $_[0]);
- my @CONTENT = $dom->getElementsByTagName("s:key");
- for(my $j=0;$j<@CONTENT;$j++){
- my @TYPE_INFO = $CONTENT[$j]->getAttributeNode("name");
- foreach my $type_info (@TYPE_INFO){
- if ($type_info->nodeValue eq "dispatchState"){return $CONTENT[$j]->textContent;}
- }
- }
- return;
- }
- sub ioc_get_ip {
- my %BAD_IP_LIST;
- my $parser = XML::LibXML->new();
- my $dom = $parser->parse_file($_[0]."/".$_[1]);
- my @CONTENT = $dom->getElementsByTagName("ns0:Content");
- for(my $j=0;$j<@CONTENT;$j++){
- my @TYPE_INFO = $CONTENT[$j]->getAttributeNode("type");
- foreach my $type_info (@TYPE_INFO){
- if ($type_info->nodeValue eq $_[2]){$BAD_IP_LIST{$CONTENT[$j]->textContent} = $_[1];}
- }
- }
- return \%BAD_IP_LIST;
- }
- sub craft_search{
- my $search_string = "sourcetype != \"audittrail\" ";
- my $search_suffix = "";
- if ($_[0] eq 'IP'){
- my $BAD_IP_REF = $_[1];
- foreach my $k (keys %$BAD_IP_REF){
- # Ignore IP's in private address space
- if (!($k =~ /^10\./)){$search_suffix .= $k." OR ";}
- }
- $search_string = $search_string.$search_suffix;
- $search_string =~ s/OR\s+$/\| stats count\(src_ip\) AS \"Hit Count\" by src_ip \, dst_ip | rename src_ip AS \"Source IP\"\, dst_ip AS \"Destination IP\"/;
- }
- return $search_string;
- }
- opendir(DIR, $ioc_dir) or die "Can't open $ioc_dir: $!";
- my @FILES = readdir DIR;
- closedir DIR;
- my %BAD_IP; # Hash containing bad IP's
- foreach my $file (@FILES){
- if ($file =~ m/\.ioc$/){
- my $tmp_ip_hash = ioc_get_ip($ioc_dir, $file, "IP");
- foreach my $ip_val (keys %$tmp_ip_hash){$BAD_IP{$ip_val}++;}
- }
- }
- my $search_string = craft_search('IP', \%BAD_IP);
- my $stop_tm = time(); my $start_tm = $stop_tm-(60*60);
- my $search = 'search earliest='.$start_tm.' latest='.$stop_tm.' '.$search_string;
- print "\n$search\n\n";
- my %SPLUNK_AUTH;
- foreach my $splunk_server (@SPLUNK_SERVERS){
- my $session_key = splunk_login($splunk_id{'username'}, $splunk_id{'password'}, $splunk_server);
- if ($session_key ne "Login Error"){$SPLUNK_AUTH{$splunk_server} = $session_key;}
- }
- if (!((keys %SPLUNK_AUTH) >= 1)){die "Splunk login error\n";}
- my %SEARCH_ID;
- while(my ($server, $sessionkey) = each %SPLUNK_AUTH ) {
- $SEARCH_ID{$server} = splunk_search( $search, $server, $sessionkey, $splunk_id{'username'});
- }
- my ($j, $n) = (1, 1);
- while ($j){
- while ( my ($server, $searchid) = each %SEARCH_ID ) {
- my $current_status = xml_dispatchState(splunk_status($searchid, $server, $SPLUNK_AUTH{$server}, $splunk_id{'username'}));
- print $current_status."...\t\r";
- if ($current_status eq "DONE"){
- my $results = splunk_get_data($searchid, $server, $SPLUNK_AUTH{$server}, $splunk_id{'username'}, $splunk_id{'data_type'});
- if ($results ne "NULL"){
- print "\n".$results."\n\n";
- }else{
- print "\nSearch complete.... No baddies found!\n\n";
- }
- delete($SEARCH_ID{$server});
- }
- }
- if (keys %SEARCH_ID){for (my $sleep=0;$sleep<5;$sleep++){$n++;sleep 1;}}else{$j=0;}
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement