Incorporating Virustotal Data to Elasticsearch

Now that we’re collecting logs from various sources including Sysmon, we have access to file hash information. A while back I came across this SANS article on incorporating Virustotal to Elasticsarch here. The article is from 2015 when Elasticsearch was still in version 1.5, the creator was Jason Kendall and the github project is posted here. Unfortunately I have tried to get this working on Logstash version 5.x without success; Therefore, I stayed with version 2.3.4. My test environment was running Elasticsaerch version 2.3.4 as well as Logstash 2.3.4 in which the Virustotal plug-in did work!

Since my environment is on Elasticsearch version 5.x, I ended up creating a small VM with Logstash 2.3.4 and setup the virustotal plugin here, the data is still going to my current server so I’m happy with that.

Prerequisites:

  • Logstash 2.3.4 or earlier
  • Git  (yum install git)
  • Ruby Gem
  • Nano (my preferred text editor)
  • Sign up for a Virustotal public API https://www.virustotal.com

Step 1: Install Ruby On Rails

sudo yum install ruby

Say Yes to the promt

sudo yum install gcc g++ make automake autoconf curl-devel openssl-devel zlib-devel httpd-devel apr-devel apr-util-devel sqlite-devel
sudo yum install ruby-rdoc ruby-devel

Install Ruby Gems & Update

sudo yum install rubygems
gem update –system

Step 2: Install Virustotal Plug-in

cd /tmp
git clone https://github.com/coolacid/logstash-filter-virustotal.git
cd logstash-filter-virustotal

Since this script was written for versions prior to 2.0, we’re going to edit the .gemspec file.

 nano /tmp/logstash-filter-virustotal/logstash-filter-virustotal.gemspec

Edit the following, and change it to <3.0.0 or whatever version you choose.
s.add_runtime_dependency logstash-core, >= 1.4.0, < 2.0.0

Save it (CTRL-O) and exit.
let’s continue with the installation.

gem build logstash-filter-virustotal.gemspec 
cd /opt/logstash
bin/plugin install /tmp/logstash-filter-virustotal/logstash-filter-virustotal-0.1.1.gem

Note: you might get a warning message of “fatal: Not a git repository (or any of the parent directories): .git” which you may ignore.

You may now restart logstash.

Lastly, confirm that your Virustotal plugin is part of the logstash plugins.
under /opt/logstash run the following:

bin/plugin list

You should see logstash-filter-virustotal listed

Done!

Now let’s configure Logstash to lookup file hashes that are being generated from Sysmon.

In my use case I’m only looking focusing on EventID 15 in Sysmon
Event ID 15: FileCreateStreamHash

My Logstash configuration does the following:

  • Only looks at Event ID 15 and Hash field.
  • Focuses on the highlighted information from Virustotal. (Note: when the file queries Virustotal, the Anti-virus list will also be populated; therefore, my logstash configuration will automatically remove that information).

 

Here’s my logstash configuration for Virustotal. (Note: I”m using NXlog to send the logs from my Windows system to Logstash.

#Winlogs Input
input {
  tcp {
    port => 5044
    type => "winlogs"
    codec => json
  }
}

#Sysmon Logs

# Sysmon remove Sha256= from field FileStream

filter {
if [type] == "winlogs" {
  if [Channel] == "Microsoft-Windows-Sysmon/Operational" and [EventID] == 15 {
  mutate {
    gsub => ["Hash", "SHA256=", ""]
  }
  }
}
}


# Sysmon virustotal check

filter {
if [type] == "winlogs" {
  if [Channel] == "Microsoft-Windows-Sysmon/Operational" and [EventID] == 15 
  and ([TargetFilename] =~ /(?i)\.(doc|zip|exe)/ ) {
  virustotal {
            apikey => 'MyApiKeyFromVirustotal'
            field => '[Hash]'
            lookup_type => 'hash'
            target => 'virustotal'
  }
  }
}
}

#Removes Virustotal AV Vendor Info
filter {
if [type] == "winlogs" {
  if [Channel] == "Microsoft-Windows-Sysmon/Operational" and [EventID] == 15 {
   mutate { remove_field => ["[virustotal][scans]"]}
  }
}
}

output {
if [type] == "winlogs" {
  elasticsearch { 
     hosts => ["http://MyElasticsearch5servers:9200"]
     index => "logstash-virustotal-%{+YYYY.MM.dd}"
 }
}
}

Update: 07-06-2017 – Logstash configuration to receive from Winlogbeat

input {
  beats {
    port => ##
	tags => [ "winlogbeat" ]
  }
}


#Drops non-hash files
filter {
if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational" and [event_id] == 15
  and [event_data][Hash] == "Unknown" {
    drop { }
  }
}

# Sysmon remove Sha256= from field FileStream

filter {
if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational" and [event_id] == 15 {
  mutate {
    gsub => ["[event_data][Hash]", "SHA256=", ""]
  }
  }

}

filter {
if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational" and [event_id] == 15 and ([event_data][TargetFilename] =~ /(?i)\.(doc|zip|exe)/ ) {
 virustotal {
           apikey => 'YourVirusTotalAPIKey'
           field => '[event_data][Hash]'
           lookup_type => 'hash'
           target => 'virustotal'
 }
 }
}


output {
if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational" and [event_id] == 15 {
   gelf {
      host => ["Your2.xLogstashserver"]
	  port => ##
   }
}
}

output {
if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational" and [event_id] == 15  {
  elasticsearch { 
     hosts => ["http://YourElasticsearchnode:9200"]
     index => "logstash-virustotal%{+YYYY.MM.dd}"
 }
}
}

 

Finally, here’s a sample log of Putty.exe without the unnecessary anti-virus vendor information.

Here’s a sample dashboard of Elasticsearch, which makes it easy to sort by high number of positives.

One last thing. Virustotal limits you to  the following if you have a public key:

Privileges public key
Request rate 4 requests/minute
Daily quota 5760 requests/day
Monthly quota 178560 requests/month
Status Key enabled

Therefore please ensure that you are not abusing the daily limit; otherwise, you might need to upgrade to a Private API.

Here’s a sample of my current API Consumption:

Thanks for reading.

 

0 0 votes
Article Rating
Subscribe
Notify of
guest
1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
ghost
ghost
4 years ago

can we get a updated conf I am unable to use this in winlogbeat 7.0.0