Dionaea is meant to be a nepenthes successor, embedding python as scripting language, using libemu to detect shellcodes, supporting ipv6 and tls
How it works
dionaea intention is to trap malware exploiting
vulnerabilities exposed by services offerd to a network, the
ultimate goal is gaining a copy of the malware.
Security
As Software is likely to have bugs, bugs in software offering
network services can be exploitable, and dionaea is software
offering network services, it is likely dionaea has
exploitable bugs.
Of course we try to avoid it, but if nobody would fail when trying hard, we would not need software such as dionaea.
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.
Of course we try to avoid it, but if nobody would fail when trying hard, we would not need software such as dionaea.
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.
Network Connectivity
Given the softwares intented 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.
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.
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.
Protocols
Network services speak a certain language, this language is
called protocol.
When we started deploying honeypots, you could trap worms just by opening a single port, and wait for them to connect and send you an 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 and interaction.
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 procotol, dionaea implements the protocols in python. There is 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.
When we started deploying honeypots, you could trap worms just by opening a single port, and wait for them to connect and send you an 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 and interaction.
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 procotol, dionaea implements the protocols in python. There is 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.
SMB
The main protocol offerd by dionaea is SMB. SMB has a decent
history of remote exploitable bugs, and is a very popular
target for worms. dionaeas SMB implementation makes use of an
python3 adapted version of scapy. As scapys own version of
SMB was pretty limited, almost everything but the Field
declarations had to be rewritten. The SMB emulation written
for dionaea is used by the mwcollectd low interaction
honeypot too.
Besides the known attacks on SMB dionaea supports uploading files to smb shares.
Adding new DCE remote procedure calls is a good start to get into dionaea code, you can use:
to identify potential usefull targets of unknown dcerpc calls using the data you gathered and stored in your logsql database. Patches are appreciated.
Besides the known attacks on SMB dionaea supports uploading files to smb shares.
Adding new DCE remote procedure calls is a good start to get into dionaea code, you can use:
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 usefull targets of unknown dcerpc calls using the data you gathered and stored in your logsql database. Patches are appreciated.
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.
For https, the self-signed ssl certificate is created at startup.
ftp
Dionaea provives 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.
tftp
Written to test the udp connection code, dionaea provides a
tftp server on port 69, which can serve files. Even though
there were vulnerabilities in tftp services, I'm yet to see
an automated attack on tftp services.
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:
Patches would be appreciated.
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 onRefer to the blog for more information.
Patches would be appreciated.
MySQL
This module implements the MySQL wire stream protocol - backed up by
sqlite as database. Please refer to 2011-05-15
Extending Dionaea for more information.
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. 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 for 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.
- 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 SDP
- sdp
- The value to use as SDP
- {addrtype}
- Address type. (IP4 or IP6)
- {unicast_address}
- RTP address
- {audio_port}
- Dionaea audio port.
- {video_port}
- Dionaea video port.
- [audio_port]...content...[/audio_port]
- The content is only available in the output if the audio_port value is set.
- [video_port]...content...[/video_port]
- The content is only available in the output if the video_port value is set.
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]
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.
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.
dionaea can http/POST the file to several services like CWSandbox, Norman Sandbox or VirusTotal.
Logging
Getting a copy of the malware is cool, getting an overview of
the attacks run on your sensor is priceless.
dionaea can write information to a text file, but be aware, dionaeas logging to text files is rather chatty, really chatty, and you do not want to look at the information, if you are not debugging the software or writing some new feature for it.
Of course, you can appy filters to the logging, to limit it to different facilities or levels, but in general you do not want to work with text files.
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 he wants to get informed about, the pathes are matched in a glob like fashion. Therefore logging information using an ihandler is superior to text logging, you get the information you are looking for, and can write it to a format you choose yourself. 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:
dionaea can write information to a text file, but be aware, dionaeas logging to text files is rather chatty, really chatty, and you do not want to look at the information, if you are not debugging the software or writing some new feature for it.
Of course, you can appy filters to the logging, to limit it to different facilities or levels, but in general you do not want to work with text files.
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 he wants to get informed about, the pathes are matched in a glob like fashion. Therefore logging information using an ihandler is superior to text logging, you get the information you are looking for, and can write it to a format you choose yourself. 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:
Additional to local logging, dionaea can send a contionous stream of its attacks to a xmpp server, which allows creating a distributed setup of sensors with high detail of information for each attack.
Refer to logxmpp and pg_backend for more information about distributed setups using xmpp.
- 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
Additional to local logging, dionaea can send a contionous stream of its attacks to a xmpp server, which allows creating a distributed setup of sensors with high detail of information for each attack.
Refer to logxmpp and pg_backend for more information about distributed setups using xmpp.
Development
dionaea 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 subscribe to RSS updates and submit bugs or patches.Compiling & Installation
Requirements
- libev >=4.04, schmorp.de
- libglib >=2.20
- libssl, openssl.org
- liblcfg, liblcfg.carnivore.it
- libemu, libemu.carnivore.it
- python >=3.2, python.org
-
- sqlite >=3.3.6 sqlite.org
- readline >=3 cnswww.cns.cwru.edu
- cython >0.14.1, cython.org
- libudns, corpit.ru
- libcurl >=7.18, curl.haxx.se
- libpcap >=1.1.1, tcpdump.org
- libnl from git, infradead.org (optional)
- libgc >=6.8, hp.com (optional)
Ubuntu
Some packages are provided by the apt-tree, so you don't have to install everything from sourceaptitude install libudns-dev libglib2.0-dev libssl-dev libcurl4-openssl-dev \ libreadline-dev libsqlite3-dev python-dev \ libtool automake autoconf build-essential \ subversion git-core \ flex bison \ pkg-config
tar xfz ...
The remaining dependencies have to be installed from source, we will install all dependencies to /opt/dionaea here, so make sure the directory exists, and you are allowed to write it.libglib (debian <= etch)
If your lack a recent glib, better update your operating system.liblcfg (all)
git clone git://git.carnivore.it/liblcfg.git liblcfg cd liblcfg/code autoreconf -vi ./configure --prefix=/opt/dionaea make install cd .. cd ..
libemu (all)
git clone git://git.carnivore.it/libemu.git libemu cd libemu autoreconf -vi ./configure --prefix=/opt/dionaea make install cd ..
libnl (linux && optional)
git clone git://git.kernel.org/pub/scm/libs/netlink/libnl.git cd libnl autoreconf -vi export LDFLAGS=-Wl,-rpath,/opt/dionaea/lib ./configure --prefix=/opt/dionaea make make install cd ..
libev (all)
wget dist.schmorp.de/libev/libev-4.04.tar.gz tar xfz libev-4.04.tar.gz cd libev-4.04 ./configure --prefix=/opt/dionaea make install cd ..
Python 3.2
Before installing Python, we will install required dependenciesreadline
Should be available for every distribution.sqlite > 3.3
Should be available for every distribution. If your distributions sqlite version is < 3.3 and does not support triggers, you are doomed, please let me know, I'll write about how broken pythons build scripts are, and document how to to compile it with a user- provided - more recent - sqlite version.Python
wget www.python.org/ftp/python/3.2.2/Python-3.2.2.tgz tar xfz Python-3.2.2.tgz cd Python-3.2.2/ ./configure --enable-shared --prefix=/opt/dionaea --with-computed-gotos \ --enable-ipv6 LDFLAGS="-Wl,-rpath=/opt/dionaea/lib/ -L/usr/lib/x86_64-linux-gnu/" make make install
Cython (all)
We have to use cython >= 0.15 as previous releases do not support Python3.2 __hash__'s Py_Hash_type for x86.wget cython.org/release/Cython-0.15.tar.gz tar xfz Cython-0.15.tar.gz cd Cython-0.15 /opt/dionaea/bin/python3 setup.py install cd ..
udns (!ubuntu)
udns does not use autotools to build.wget www.corpit.ru/mjt/udns/old/udns_0.0.9.tar.gz tar xfz udns_0.0.9.tar.gz cd udns-0.0.9/ ./configure make sharedThere is no make install, so we copy the header to our include directory.
cp udns.h /opt/dionaea/include/and the lib to our library directory.
cp *.so* /opt/dionaea/lib/ cd /opt/dionaea/lib ln -s libudns.so.0 libudns.so cd - cd ..
libcurl (all)
Grabbing curl from your distributions maintainer should work, if you run a decent distribution. If not consider upgrading your operating system.libpcap (most)
To honor the effort, we rely on libpcap 1.1.1. Most distros ship older versions, therefore it is likely you have to install it from source.wget www.tcpdump.org/release/libpcap-1.1.1.tar.gz tar xfz libpcap-1.1.1.tar.gz cd libpcap-1.1.1 ./configure --prefix=/opt/dionaea make make install cd ..
OpenSSL (optional)
WARNING: doing this, requires *all* dependencies to be compiled using the same ssl version, so you have to link curl and python to your own openssl build tooIf you experience problems with tls connections, install your OpenSSL >= 0.9.8l/1.0.0-beta2, or fall back to cvs for now.
cvs -d anonymous@cvs.openssl.org:/openssl-cvs co openssl cd openssl ./Configure shared --prefix=/opt/dionaea linux-x86_64 make SHARED_LDFLAGS=-Wl,-rpath,/opt/dionaea/lib make install
Compiling dionaea
git clone git://git.carnivore.it/dionaea.git dionaeathen ..
cd dionaea autoreconf -vi ./configure --with-lcfg-include=/opt/dionaea/include/ \ --with-lcfg-lib=/opt/dionaea/lib/ \ --with-python=/opt/dionaea/bin/python3.2 \ --with-cython-dir=/opt/dionaea/bin \ --with-udns-include=/opt/dionaea/include/ \ --with-udns-lib=/opt/dionaea/lib/ \ --with-emu-include=/opt/dionaea/include/ \ --with-emu-lib=/opt/dionaea/lib/ \ --with-gc-include=/usr/include/gc \ --with-ev-include=/opt/dionaea/include \ --with-ev-lib=/opt/dionaea/lib \ --with-nl-include=/opt/dionaea/include \ --with-nl-lib=/opt/dionaea/lib/ \ --with-curl-config=/usr/bin/ \ --with-pcap-include=/opt/dionaea/include \ --with-pcap-lib=/opt/dionaea/lib/ make make install
Update dionaea
Most updates boil down to a
git pull; make clean installBut, you always want to make sure your config file is up to date, you can use
/opt/dionaea/etc/dionaea# diff dionaea.conf dionaea.conf.dist
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.
- Ubuntu Lucid - weekly git snapshots
- Debian - not really packages, just a guide how to create packages
- Arch Linux - build scripts, compile from source, uses git
- Slackware - build scripts, compile from source, uses git
Running dionaea
The software has some flags you can provide at startup, the
-h flags shows the help, the -H includes the default values.
-c, --config=FILE use FILE as configuration file Default value/behaviour: /opt/dionaea/etc/dionaea.conf -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: /opt/dionaea examples: # dionaea -l all,-debug -L '*' # dionaea -l all,-debug -L 'con*,py*' # dionaea -u nobody -g nogroup -r /opt/dionaea/ -w /opt/dionaea -p /opt/dionaea/var/dionaea.pid
Configuration - dionaea.conf
If you want to change the software, it is really important to
understand how it works, therefore please take the time to
how it works.
dionaea.conf is the main configuration file, the file controls consists of sections for:
downloads specify where to store downloaded malware.
bistreams specify where to store bi-directional streams, these are pretty useful when debugging, as they allow to replay an attack on ip-level, without messing with pcap&tcpreplay, which never worked for me.
submit specifies where to send files to via http or ftp, you can define a new section within submit if you want to add your own service.
listen sets the addresses dionaea will listen to. The default is all addresses it can find, this mode is call getifaddrs, but you can set it to manual and specify a single address if you want to limit it.
modules is the most powerfull section, as it specifies the modules to load, and the options for each module.
The subsections 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.
dionaea.conf is the main configuration file, the file controls consists of sections for:
- logging
- processors
- downloads
- bistreams
- submit
- listen
- modules
logging
The logging section controls ... logging, you
can specify log domains and loglevel for different
logfiles.
As dionaea is pretty ... verbose, it is useful to rotate the logfiles using logrotate.
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.As dionaea is pretty ... verbose, it is useful to rotate the logfiles using logrotate.
# logrotate requires dionaea to be started with a pidfile # in this case -p /opt/dionaea/var/run/dionaea.pid # adjust the path to your needs /opt/dionaea/var/log/dionaea*.log { notifempty missingok rotate 28 daily delaycompress compress create 660 root root dateext postrotate kill -HUP `cat /opt/dionaea/var/run/dionaea.pid` endscript }/etc/logrotate.d/dionaea
downloads specify where to store downloaded malware.
bistreams specify where to store bi-directional streams, these are pretty useful when debugging, as they allow to replay an attack on ip-level, without messing with pcap&tcpreplay, which never worked for me.
submit specifies where to send files to via http or ftp, you can define a new section within submit if you want to add your own service.
listen sets the addresses dionaea will listen to. The default is all addresses it can find, this mode is call getifaddrs, but you can set it to manual and specify a single address if you want to limit it.
modules is the most powerfull section, as it specifies the modules to load, and the options for each module.
The subsections 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.
modules
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.
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.
python
The python module allows using the python interpreter in
dionaea, and allows controlling some scripts dionaea uses
logsql
This section controls the logging to the sqlite
database.
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.
To query the logsql database, I recommend looking at the readlogsqltree.py script, for visualisation the gnuplotsql script.
The blog on logsql:
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 /opt/dionaea/var/dionaea -R
To query the logsql database, I recommend looking at the readlogsqltree.py script, for visualisation the 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
want to use logxmpp, make sure to enable logxmpp in the ihandler
section.
Using logxmpp allows you to share your new collected files with other sensors anonymously.
The blog on logxmpp:
Using logxmpp allows you to 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
p0f
Not enabled by default, but recommend: the p0f service,
enable 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 attackers operating system,
and you can look them up from the sqlite database, even the
rejected connections.
If you face problems, here are some hints.
If you face problems, here are some hints.
nfq
The python nfq script is the counterpart to the nfq module.
While the nfq module interacts with the kernel, the nfq
python script takes care of the required steps to start a new
service on the ports.
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.
As dionaea can not predict which protocol will be spoken on unknown ports, neither implement the protocol by itself, it will connect the attacking host on the same port, and use the attackers server side protocol implementation to reply to the client requests of the attacker therefore dionaea can end up re?exploiting the attackers machine, just by sending him the exploit he sent us.
The technique is a brainchild of Tillmann Werner, who used it within his honeytrap 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
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:
If you have dionaea running on your NAT router, I recommend something like:
Using something like:
Even if you add an exemption for ssh like:
As it is easy to avoid this, I recommend sticking with the recommendation.
Besides the already mention 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).
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.
As dionaea can not predict which protocol will be spoken on unknown ports, neither implement the protocol by itself, it will connect the attacking host on the same port, and use the attackers server side protocol implementation to reply to the client requests of the attacker therefore dionaea can end up re?exploiting the attackers machine, just by sending him the exploit he sent us.
The technique is a brainchild of Tillmann Werner, who used it within his honeytrap 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 worst case you'd end up with offering 64k services per ip scanned. By default you'd run out of fds at about 870 services offerd, 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 condition fails, we do not spawn a new service, and let nfqeueu 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 as 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 his SYN.
I prefer NF_DROP, as port scanners such as nmap tend to limit their scanning speed, once they notice packets get lost.
-
recursive-self-connecting
Assume some shellcode or download instructions makes dionaea to- 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 - ....
- ....
Therefore dionaea checks if the remote host connecting a nfq mirror is a local address using 'getifaddrs' and drops local connections.
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 5Explanation:
- ACCEPT all 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 NFQUEUEExplanation:
- ACCEPT all connections to existing services in mangle::PREROUTING
- MARK all 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 5will enqueue all SYN packets to the NFQUEUE, once you stop dionaea you will not even be able to connect to your ssh daemon.
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 NFQUEUEdionaea 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 mention 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).
ihandlers
ihandlers section is used to specify which
ihandlers get started by ihandlers.py . You do not want to
miss p0f and logsql.
services
services controls which services will get started
by services.py
Utils
Dionaea ships with some utils, as 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 - 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.
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.
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': ['', '