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!
Requirements
-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 wget http://curl.haxx.se/download/curl-7.50.2.tar.bz2 tar -xvjf curl-7.50.2.tar.bz2 cd curl-7.50.2 ./configure make 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 https://github.com/threatstream/mhn.git
UPDATE 6/12/2018: Thanks to @comhack on Twitter for pointing out that the mhn install script is broken. The issue was caused by HurricanLabs removing their Github repo. Lucky for us, it was forked! You need to edit the mhn/scripts/install_hpfeeds.sh script. Change Line 70 from:
pip install -e git+https://github.com/HurricaneLabs/pyev.git#egg=pyev
to:
pip install -e git+https://github.com/couozu/pyev.git#egg=pyev
You should be able to install MHN without any issues now.
cd mhn/ ./install.sh
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:

Now we need to set up a user for the HPfeeds. Enter the following commands at the command prompt:
IDENT=<YOUR UUID THAT WAS GENERATED LAST STEP> SECRET=<CHOOSE A RANDOM STRING OF LETTERS AND NUMBERS OR PHRASE> PUBLISH_CHANNELS="dionaea.connections,dionaea.capture,mwbinary.dionaea.sensorunique,dionaea.caputres,dionaea.capture.anon" SUBSCRIBE_CHANNELS="" cd /opt/hpfeeds source env/bin/activate cd broker python add_user.py "$IDENT" "$SECRET" "$PUBLISH_CHANNELS" "$SUBSCRIBE_CHANNELS"
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 wget http://curl.haxx.se/download/curl-7.50.2.tar.bz2 tar -xvjf curl-7.50.2.tar.bz2 cd curl-7.50.2 ./configure make 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 config: ## 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 shares: ADMIN$: comment: Remote Admin path: C:\\Windows type: disktree C$: coment: Default Share path: C:\\ type: - disktree - special IPC$: comment: Remote IPC type: ipc Printer: 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 config: 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: "http://hpfriends.honeycloud.net/ip"
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:
- I had no way of knowing when malware was collected without checking MHN or using SSH to check the dionaea server manually.
- 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 https://github.com/JBAnderson/MalwareCollectorSlack 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 export SLACK_TOKEN
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 config: # 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 config: # Uncomment next line to flatten object lists to work with ELK # flat_data: true handlers: - 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 store.py 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 CustomUploader.py
Here’s how the script looks:
# CustomUploader.py import requests def CustomUploader(n): url = 'http://IP.OF.YOUR.MHN.DROPLET:8080/upload' files = {'file':open(n, 'rb')} r = requests.post(url, files=files)
Now we need to edit store.py to call our script. We will back up the old store.py just in case:
sudo cp store.py store.py.BAK sudo vim store.py
Here’s how your store.py script should look. The only things added were an import of our script and the call to CustomUploader.py 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 #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #* 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 nepenthesdev@gmail.com #* #*******************************************************************************/ 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 sys.path.append('/opt/dionaea/lib/dionaea/python/dionaea') from CustomUploader import CustomUploader logger = logging.getLogger('store') logger.setLevel(logging.DEBUG) class StoreHandlerLoader(IHandlerLoader): name = "store" @classmethod def start(cls, config=None): try: return storehandler("dionaea.download.complete", 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") else: 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 nload_dir) 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("dionaea.download.complete.hash") i.file = n i.url = icd.url if hasattr(icd, 'con'): i.con = icd.con i.md5hash = md5 i.report() try: os.stat(n) i = incident("dionaea.download.complete.again") logger.debug("file %s already existed" % md5) except OSError: logger.debug("saving new file %s to %s" % (md5, n)) os.link(p, n) i = incident("dionaea.download.complete.unique") #---------------------------------------------------- # CUSTOM FILE UPLOADERS GO HERE # call the script and place the script being called in # /opt/dionaea/lib/dionaea/python/dionaea try: CustomUploader(n) 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 i.report()
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