How to set up Dionaea Honeypot with Modern Honey Network and Slack alerts

In this tutorial I’m going to walk you through installing Modern Honey Network(MHN) and adding sensors, setting up a Dionaea honeypot, setting up the Dionaea SMB service, setting up Dionaea iHandlers, installing the MalwareCollectorSlack NodeJS server for Slack reporting, and configuring Dionaea to upload payloads to a custom location.

Beginners looking to get into malware analysis are often pointed towards Dionaea honeypot for collecting malware in the wild for analysis. Often installation is suggested to be done through the Modern Honey Network application. Unfortunately, the tutorials that exist online are incomplete, outdated, or just plain wrong and the automated Dionaea deployment though MHN installs a broken version of Dionaea. The Github issues of both the Dionaea and MHN projects are littered with people asking for assistance just getting the honeypot catching malware. After several days of troubleshooting I have a honeypot collecting malware and uploading data to MHN, and for fun I set up a little NodeJS server to alert me via Slack. Let’s get started!


-A DigitalOcean account – I will be using DigitalOcean throughout the tutorial. You can probably still follow along using other providers, but no guarantees.

PART 1 – Installing Modern Honey Network(MHN)

Head over to DigitalOcean and create a new Ubuntu 14.04 x64 Droplet at the $10/mo level. This is the cheapest level it can work on.

Access your new Droplet. Here’s a link to some stuff you should consider doing before moving forward.

First we need to update curl to version 7.50. Enter the following commands:

sudo apt-get build-dep curl

mkdir ~/curl
cd ~/curl
tar -xvjf curl-7.50.2.tar.bz2
cd curl-7.50.2

sudo make install
sudo ldconfig

Next we need to make sure Git is installed:

sudo apt-get install git -y

Now we install MHN. Make sure you understand that we are installing as root and the associated risks with this. Complete the MHN configuration when prompted and remember the email and password used here, you will log in with them later. Also make note of the IP and port you set up during configuration. It defaults to the web app running on port 80 and HoneyMap running on port 3000:

cd /opt/
sudo git clone
cd mhn/

Log into the MHN interface using the email and password you created during configuration. Along the top of the Dashboard there is a drop-down menu cnamed “Sensors”. Click the dropdown and select “Add Sensor”. Put “dionaea” in all three text fields and hit the “Create” button. You will see a UUID like my screenshot below:

Screenshot of MHN sensor UUID setup
Screenshot of MHN sensor UUID setup

Now we need to set up a user for the HPfeeds. Enter the following commands at the command prompt:


cd /opt/hpfeeds
source env/bin/activate
cd broker

PART 2 – Installing Dionaea Honeypot

Create another Ubuntu 14.04 droplet on DigitalOcean. The $5/mo level is fine. Here’s the link again for stuff you should do before moving forward. Like before we need to update curl. Here’s the commands again:

sudo apt-get build-dep curl

mkdir ~/curl
cd ~/curl
tar -xvjf curl-7.50.2.tar.bz2
cd curl-7.50.2

sudo make install
sudo ldconfig

Now install Dionaea Honeypot:

sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:honeynet/nightly
sudo apt-get update
sudo apt-get install dionaea

Next we need to set up the SMB service so we can actually capture some malware:

cd /opt/dionaea/etc/dionaea
sudo vim services-enabled/smb.yaml

Uncomment the Windows 7 section of smb.yaml and set os_type to 4. Here’s how my smb.yaml looks:

- name: smb 
    ## Generic setting ## 
    # 1:"Windows XP Service Pack 0/1", 
    # 2:"Windows XP Service Pack 2", 
    # 3:"Windows XP Service Pack 3", 
    # 4:"Windows 7 Service Pack 1", 
    # 5:"Linux Samba 4.3.11" 
    os_type: 4 
     # Additional config 
#    primary_domain: Test 
#    oem_domain_name: Test 
#    server_name: TEST-SERVER 
     ## Windows 7 ## 
    native_os: Windows 7 Professional 7600 
    native_lan_manager: Windows 7 Professional 6.1 
        comment: Remote Admin 
        path: C:\\Windows 
        type: disktree 
        coment: Default Share 
        path: C:\\ 
          - disktree 
          - special 
        comment: Remote IPC 
        type: ipc 
        comment: Microsoft XPS Document Writer 
        type: printq 
     ## Samba ## 
#    native_os: Windows 6.1 
#    native_lan_manager: Samba 4.3.11 
#    shares: 
#      admin: 
#        comment: Remote Admin 
#        path: \\home\\admin 
#        type: disktree 
#      share: 
#        coment: Default Share 
#        path: \\share 
#        type: disktree 
#      IPC$: 
#        comment: Remote IPC 
#        path: IPC Service 
#        type: ipc 
#      Printer: 
#        comment: Printer Drivers 
#        type: printq

The last thing we need to do is set up the hpfeed iHandler so incidents are reported to our MHN install:

sudo cp ihandlers-available/hpfeeds.yaml ihandlers-enabled/hpfeeds.yaml
sudo ihandlers-enabled/hpfeeds.yaml

Here’s what my hpfeeds.yaml looks like:

- name: hpfeeds 
    server: "IP of your server" 
    port: 10000 
    ident: "The UUID we set up when we added a sensor in MHN" 
    secret: "The SECRET you set up when we added the hpfeeds user" 
    # dynip_resolve: enable to lookup the sensor ip through a webservice 
    #dynip_resolve: ""

That should do it. Restart dionaea and you should almost immediately start seeing attacks roll in on MHN. Give it about an hour before you see payloads. Generally I get a few an hour, but sometimes nothing for multiple hours. If you want to test using Metasploit (ms10_061_spoolss) make sure your ISP is not filtering ports somewhere along the wire (apparently Comcast in my area filters 25, 139, and 445 on all traffic by default). I ended up having to install Metasploit on a DigitalOcean droplet to get around the issue.

sudo service dionaea restart

While I’m waiting I like to watch the attacks happen live in my console by tailing dionaea.log:

cd /opt/dionaea/var/dionaea
tail -f dionaea.log

part 3: Set up slack and slack logging

So now we are catching malware in the wild and reporting the attacks and payloads to an MHN Dashboard. Cool. I noticed two problems right away:

  1. I had no way of knowing when malware was collected without checking MHN or using SSH to check the dionaea server manually.
  2. The payloads were not transmitted to the MHN server. Great information about the payload is sent but not the actual malware itself.

To resolve these issues I put together a little NodeJS server to accept files from dionaea and to alert me via Slack in real time that malware has been collected. This final part of the walk-through will show you how to set up MalwareCollectorSlack and configure dionaea to send the actual malware to our server.

First head over to Slack and set up a team. Sign into your team and go to Apps and set up a Bot user. You will be given a token that we will be using later on. You should also set up three channels: logging, general, and json

Enter the following commands on the MHN server:

sudo apt-get install nodejs
sudo apt-get install npm
cd /opt
sudo git clone
cd MalwareCollectorSlack
sudo npm install
sudo mkdir uploads

Now we need to set an environment variable for the token that you got when you set up your Slack team. Instead of using an environmental variable you could just edit line 29 in server.js. I only did this step so I didn’t accidentally push my token to GitHub. You should also rename the Slack bot to your preferred name on line 30 in server.js:

SLACK_TOKEN=token received when Slack team was setup

Go ahead and set the notifications for each Slack channel to “all new messages” so we know when the data starts flowing.

I like to use “forever” to make sure that my script continues running and provide logging. Make sure to run sudo with the -E option if you used an ENV for the Slack token:

sudo npm install forever -g
sudo -E forever start -l forever.log -o out.log -e err.log --append server.js

Now we have to set up Dionaea to send data to our server:

cd /opt/dionaea/etc/dionaea/ihandlers-enabled
sudo vim submit_http.yaml

Here’s how your submit_http.yaml should look:

- name: submit_http 
      # the url to send the submission requests to 
      url: "http://IP.OF.YOUR.MHN.DROPLET:8080/" 
      # E-Mail (optional) 
      # email: ""                                                                               
      # username (optional)                                                                     
      # user:                                                                                   
      # password (optional)                                                                     
      # pass:

Next we need to set up log_json.yaml

sudo vim log_json.yaml

Here’s how your log_json.yaml should look

- name: log_json 
    # Uncomment next line to flatten object lists to work with ELK 
    # flat_data: true 
      - http://IP.OF.YOUR.MHN.DROPLET:8080/json 
      - file:///opt/dionaea/var/dionaea/dionaea.json

Now restart Dionaea

sudo service dionaea restart

If you turned on Slack notifications you should be getting alerts every few seconds from the /json channel. With a little luck within a few minutes you should see a “Malware Collected” message and the MD5 hash of the captured malware in the /general channel.

Part 4: payload uploads

The final two things we need to do are add a script to upload the samples to our server and edit to call our script whenever Dionaea collects malware.

We are going to need to install pip3 and download the Python3 requests library:

sudo apt-get install python3-pip
sudo pip3 install requests

Now we need to create the custom script and place it where Dionaea can find it:

cd /opt/dionaea/lib/dionaea/python/dionaea
sudo vim

Here’s how the script looks:

import requests 
def CustomUploader(n): 
        url = 'http://IP.OF.YOUR.MHN.DROPLET:8080/upload' 
        files = {'file':open(n, 'rb')} 
        r =, files=files)

Now we need to edit to call our script. We will back up the old just in case:

sudo cp
sudo vim

Here’s how your script should look. The only things added were an import of our script and the call to that you can see inside the “Custom File Uploaders” comment block:

#*                               Dionaea 
#*                           - catches bugs - 
#* Copyright (C) 2009  Paul Baecher & Markus Koetter 
#* This program is free software; you can redistribute it and/or 
#* modify it under the terms of the GNU General Public License 
#* as published by the Free Software Foundation; either version 2 
#* of the License, or (at your option) any later version. 
#* This program is distributed in the hope that it will be useful, 
#* but WITHOUT ANY WARRANTY; without even the implied warranty of 
#* GNU General Public License for more details. 
#* You should have received a copy of the GNU General Public License 
#* along with this program; if not, write to the Free Software 
#* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. 
#*             contact 
from dionaea import IHandlerLoader 
from dionaea.core import ihandler, incident, g_dionaea 
from dionaea.exception import LoaderError 
from dionaea.util import md5file 
import os 
import logging 
import sys 

from CustomUploader import CustomUploader 

logger = logging.getLogger('store') 
class StoreHandlerLoader(IHandlerLoader): 
    name = "store" 
    def start(cls, config=None): 
            return storehandler("", config=config) 
        except LoaderError as e: 
            logger.error(e.msg, *e.args) 
            return None 
class storehandler(ihandler): 
    def __init__(self, path, config=None): 
        logger.debug("%s ready!" % (self.__class__.__name__)) 
        ihandler.__init__(self, path) 
        dionaea_config = g_dionaea.config().get("dionaea") 
        self.download_dir = dionaea_config.get("download.dir") 
        if self.download_dir is None: 
            raise LoaderError("Setting download.dir not configured") 
            if not os.path.isdir(self.download_dir): 
                raise LoaderError("'%s' is not a directory", self.download_dir) 
            if not os.access(self.download_dir, os.W_OK): 
                raise LoaderError("Not allowed to create files in the '%s' directory", self.dow
    def handle_incident(self, icd): 
        logger.debug("storing file") 
        p = icd.path 
        # ToDo: use sha1 or sha256 
        md5 = md5file(p) 
        # ToDo: use sys.path.join() 
        n = os.path.join(self.download_dir, md5) 
        i = incident("") 
        i.file = n 
        i.url = icd.url 
        if hasattr(icd, 'con'): 
            i.con = icd.con 
        i.md5hash = md5 
            i = incident("") 
            logger.debug("file %s already existed" % md5) 
        except OSError: 
            logger.debug("saving new file %s to %s" % (md5, n)) 
  , n) 
            i = incident("") 
        #     call the script and place the script being called in 
        #     /opt/dionaea/lib/dionaea/python/dionaea 
                logger.debug("Upload complete via CustomUploader") 
        except BaseException as e: 
                logger.debug("There was a problem uploading via CustomerUploader: " + str(e)) 
        i.file = n 
        if hasattr(icd, 'con'): 
            i.con = icd.con 
        i.url = icd.url 
        i.md5hash = md5

Restart Dionaea so it picks up the changes

sudo service dionaea restart

And there you have it. When you get a slack alert that says “Binary Posted” in the /logging channel go take a look at /opt/MalwareCollector/uploads and the malware should be waiting there for you.

In my next article I walk through setting up an Dionaea honeypot to avoid Nmap service detection.

If you have any issues or questions please leave a comment below or find me on Twitter @TheJBAnderson