Wednesday, February 15, 2017

Integrating OpenCanary & DShield

Being a volunteer for the SANS Internet Storm Center, I’m a big fan of the DShield service. I think that I’m feeding DShield with logs for eight or nine years now. In 2011, I wrote a Perl script to send my OSSEC firewall logs to DShield. This script has been running and pushing my logs every 30 mins for years. Later, DShield was extended to collect other logs: SSH credentials collected by honeypots (if you’ve a unused Raspberry Pi, there is a nice setup of a honeypot available). I’ve my own network of honeypots spread here and there on the Wild Internet, running Cowrie. But recently, I reconfigured all of them to use another type of honeypot: OpenCanary.

Why OpenCanary? Cowrie is a very nice honeypot which can emulate a fake vulnerable host, log commands executed by the attackers and also collect dropped files. Here is an example of Cowrie session replayed in Splunk:

Splunk Honeypot Session Replay

It’s nice to capture a lot of data but most of them (to not say “all of them”) are generated by bots. Honestly, I never detected a human attacker trying to abuse of my SSH honeypots. That’s why I decided to switch to OpenCanary. It does not record a detailed log as Cowrie but it is very modular and supports by default the following protocols:

  • FTP
  • HTTP
  • Proxy
  • MySQL
  • NTP
  • Portscan
  • RDP
  • Samba
  • SIP
  • SNMP
  • SSH
  • Telnet
  • TFTP
  • VNC

Writing extra modules is very easy, examples are provided. By default, OpenCanary is able to write logs to the console, a file, Syslog, a JSON feed over TCP or an HPFeed. There is no DShield support by default? Never mind, let’s add it.

As I said, OpenCanary is very modular and a new logging capability is just a new Python class in the module:

class DShieldHandler(logging.Handler):
    def __init__(self, dshield_userid, dshield_authkey, allowed_ports):
        self.dshield_userid = str(dshield_userid)
        self.dshield_authkey = str(dshield_authkey)
            # Extract the list of allowed ports
            self.allowed_ports = map(int, str(allowed_ports).split(','))
            # By default, report only port 22
            self.allowed_ports = [ 22 ]

    def emit(self, record):

The DShield logger needs three arguments in your opencanary.conf file:

"logger": {
    "class" : "PyLogger",
    "kwargs" : {
        "formatters": {
            "plain": {
                "format": "%(message)s"
        "handlers": {
            "dshield": {
                "class": "opencanary.logger.DShieldHandler",
                "dshield_userid": "xxxxxx",
                "dshield_authkey": "xxxxxxxx",
                "allowed_ports": "22,23"

The DShield UserID and authentication key are available in your DShield account. I added an ‘allowed_ports’ parameter that contains the list of interesting ports that will be reported to DShield (by default only SSH connections are reported). Now, I’m reporting many more connections attempts:

Daily Connections Report

Besides DShield, JSON logs are processed by my Splunk instance to generate interesting statistics:

OpenCanary Splunk Dashboard

A pull request has been submitted to the authors of OpenCanary to integrate my code. In the mean time, the code is available on my Github repository.

[The post Integrating OpenCanary & DShield has been first published on /dev/random]

from Xavier

No comments:

Post a Comment