Malware detection with DNS RPZ and OSSEC

Building upon a sysadvent article I wrote at work, I’ve set up a dedicated Response Policy Zone using the freely available data files from the Malware Domain Blocklist. There are different ways to do this, but for this particular purpose I’ve imported the text file and generated a single zone file locally. BIND supports up to 32 RPZs, so in my config I’ve set this up as a separate zone, referenced as “malware”.

Below is the zone definition:

zone "malware" {
  type master;
  file "/etc/bind/db.malwaredomains";
};

 
Defining the “malware” zone as an RPZ (I have two response policy zones, one simply named rpz and now this one named malware):

options {
  response-policy { zone "rpz"; zone "malware"; };
};

 
Configure logging. The zones defined in the above response-policy {} setting fall under the rpz logging category.

logging {
  channel named-rpz {
    file "/var/log/bind/rpz.log" versions 3 size 250k;
    severity info;
  };
  category rpz {
  named-rpz;
  };
};

 
In the BIND log files, requests for domains in the malware zone are logged in the RPZ log file, suffixed with the zone reference, namely “malware”.

client 127.0.0.1#53547 (czgtgj.com): rpz QNAME Local-Data rewrite czgtgj.com via czgtgj.com.malware

 
After testing that attempts to reach malware sites are indeed logged by the DNS server, I configured OSSEC to tail BIND’s malware query log. For this I had to write a decoder and define logging rules in OSSEC, shown below. These could probably be drastically improved.

The end result is exactly as I wanted: If someone (or something) on my network is trying to reach a resource within a domain registered as affiliated with malware, OSSEC will react and alert by email, raise an alarm in your SIEM, or whatever else you want OSSEC to do.

From /var/ossec/etc/local_decoder.xml:

<decoder name="malware-dns">
  <prematch>^client </prematch>
</decoder>
<decoder name="malware-dns-lookup">
  <parent>malware-dns</parent>
  <regex offset="after_parent">^(\.+)#\d+ \((\.+)\): \.+.malware$</regex>
  <order>srcip, extra_data</order>
</decoder>

 
From /var/ossec/rules/malware_dns_rules.xml:

<group name="syslog,bind">
  <rule id="110201" level="0">
    <decoded_as>malware-dns</decoded_as>
    <description>Malware DNS group</description>
  </rule>
  
  <rule id="110202" level="8">
    <if_sid>110201</if_sid>
    <match>malware$</match>
    <description>Malware DNS lookup</description>
  </rule>
</group>

 
From /var/ossec/etc/ossec.conf:

<rules>
  [...]
  <include>malware_dns_rules.xml</include>
</rules>

 
Now, if something should reach out to a malware domain, I will get an email from my OSSEC server:

Received From: server->/var/log/bind/rpz.log
Rule: 110202 fired (level 8) -> "Malware DNS lookup"
Portion of the log(s):

client 127.0.0.1#52162 (czgtgj.com):
rpz QNAME Local-Data rewrite czgtgj.com via czgtgj.com.malware