HoneyPot: Dionaea
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. 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. 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. 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:
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.
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:
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
Refer 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
The following values are available in the SDP definition.
{addrtype}
Address type. (IP4 or IP6)
{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 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.
Example:
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.
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.
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:
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.
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.