Open source software security

Using and Extending Kojoney SSH Honeypot

30 November -0001

Kojoney (http://kojoney.sourceforge.net/) is a wonderful low interaction SSH honeypot written in Python. Honeypots are systems that are set up in a deliberately vulnerable state in order to capture and observe intruder behaviour. For more information about honeypots see the excellent HoneyNet Project (http://www.honeynet.org/). There are many reasons to run a honeypot, but for the purposes of this discussion we will assume that you want to run a honeypot to observe post compromise behavior in order to fingerprint patterns. This is useful because you can use fingerprints to set up alerting or protective mechanisms that can detect compromise quickly and aid in response. For instance, running a honeypot you might discover that most attackers, after compromising an apache web server, attempt to write a file into the /tmp directory. You can use this information to set up monitoring of the /tmp directory, and alert administrators whenever apache writes new files into /tmp. This can tip off systems administrators to a possible compromise, by alerting them that there is behavior occurring on their system that typically corresponds to post compromise attacker behavior.

Honeypots can be generally divided into two categories: low interaction and high interaction. A high interaction honeypot is a complete system stack, set up on either a real or virtual appliance. The high interaction honeypot is a real system for all intents and purposes and provides intruders with all the capabilities and tools that a real system would have. High interaction honeypots can be a wonderful source of information about attackers, but they carry a high risk as well. There are significant legal ramifications to running a high interaction honeypot that should be carefully considered before installing or running one. You need to think very carefully about your deployment so you don't end up providing a platform from which an attacker could compromise other systems.

A low interaction honeypot is a software system that simulates a real system or service. What differentiates a low interaction honeypot is generally the environment and tools provided for an attacker to interact with. The disadvantage of a low interaction honeypot is that they are easier for an attacker to detect and because they offer fewer tools for the attacker to interact with they do not provide as much data about attack patterns. The main advantages of low interaction honypots is that they provide a much more controlled environment. This allows you to carefully craft the environment in which an attacker can operate so as to prevent them from them from doing harm to the host system or other systems. A low interaction honeypot safely provides a sandbox, where attacker behavior can be observed without exposing further systems to compromise.

Kojoney is a low interaction SSH honeypot. It is written in Python and based on the Twisted and Conch libraries that provide SSH server and TCP/IP support. Kojoney sets up a very real SSH server on your host machine, but when an attacker authenticates to Kojoney they are trapped in the honeypot rather than passed on to a shell. This means that after an attacker logs in they can only interact with Kojoney, not the actual host system. Kojoney can be configured with any number of user accounts and password that it will allow to successfully authenticate. Kojoney will record attempts to authenticate, including failed login attempts, and monitor attacker IP and accounts tested.

Once logged in an attacker can issue a strictly limited subset of commands to which Kojoney will respond with pre-defined text. The two notable exceptions to this rule are the curl and wget command. When an attacker issues either of these commands Kojoney will actually fetch the files requested, downloading them into a specific directory for artifact analysis. The attacker is never able to actually see or interact with files retrieved in this way, however. The downloads are safely locked away so that administrators can look at them, but attackers cannot use them.

Installing Kojoney

Installing Kojoney is relatively straightforward. Be sure to have all the prerequisite libraries and packages listed on the Kojoney homepage before beginning installation. These consist of OpenSSL, Python, Bash or Sh, and Perl. You'll also need development tools like GCC andy Python development libraries installed. Once you have these prerequisites installed simply download the latest version of kojoney, unpack it with:

# tar -xvzf kojoney-XXX.tar.gz

Once everything is unpacked you can use the INSTALL.sh script to actually install kojoney.

# cd kojoney
# chmod u+x INSTALL.sh
# ./INSTALL.sh

Next hit the 'Enter' key to view the license agreement, then type 'yes' and hit Enter to agree to it. This will begin the installation procedure. Note any errors as these may point to missing required packages. If installation fails you'll need to uninstall using the uninstall script before attempting to re-install:

# ./UNINSTALL.sh
# ./INSTALL.sh

During the install you should answer 'yes' when asked if you want Kojoney to start at boot time. This will install useful service management scripts in /etc/init.d so you can easily start and stop Kojoney. Once the install script completes you're Kojoney installaion will be ready to go. The main Kojoney files are located in /etc/kojoney and /usr/share/kojoney.

Running Kojoney

Before starting Kojoney you should be sure that you don't have an SSH service already listening on port 22. If you're already running an SSH server, it's best to move it to an alternate port such as 2222. You can modify the port that OpenSSH listens on by editing the /etc/sshd/conf/sshd_config file and restarting the service. You should also be sure to allow incoming TCP port 22 connections to your Kojoney host. If your firewall is blocking attackers then they'll never have a chance to interact with Kojoney.

To start Kojoney it's easiest to simply use the init script like so:

# /etc/init.d/kojoney start

To check if Kojoney is running you can either use:

# /etc/init.d/kojoney status

or

# ps aux | grep kojoney

and look for Kojoney in the output. Once you're sure Kojoney is running you can log in and test out the installation. To do this simply SSH to localhost port 22 as the user 'admin' and try logging in using the password 'admin' like so:

# ssh admin@localhost

Try to issue a few commands and log out using the 'exit' command. You'll quickly notice that there are some severe limitations in the number of commands that you can actually utilize with Kojoney. Kojoney also doesn't handle backspace characters, so if you munge a command and try and use backspace to correct it Kojoney won't interpret the command properly. Similarly Kojoney doesn't handle the up arrow key, which is commonly used to scroll through the command history.

Viewing Downloads

Files downloaded through Kojoney by attackers are written by default in /var/log/kojoney. This location is defined in the coret_config.py file in /usr/share/kojoney. The location is defined by the DOWNLOAD_REAL_DIR variable. You can optionally configure Kojoney to not download files by setting the DOWNLOAD_REAL_FILE variable to "False". Downloaded files have their filenames prefaced with "http__" making them easy to spot. Note that as far as I know Kojoney doesn't do any throttling or limiting, so it could theoretically be possible to cause a denial of service (DoS) condition by downloading large files and filling up the Kojoney host's disk space.

Generating Reports

Kojoney comes with two binaries, kojreport and kojreport-filter, that can be used to generate reports of the connections attempts, files downloaded, and commands issued in kojoney. The easiest way to observe these reports is to simply run the kojreport command like so:

# /usr/share/kojoney/kojreport /var/log/honeypot.log 0 0 1

You can view full options for the kojreport command at http://kojoney.sourceforge.net/kojreport.html and the kojreport-filter command (which is useful for targeted reports) at http://kojoney.sourceforge.net/kojreport-filter.html. You'll find a lot of useful information in the reports but if you keep Kojoney up and running for any significant time you'll need to sift through the data and pull subsets of the kojoney log for reporting. Scheduling a daily report is the easiest way to get timely information out of your Kojoney installation. You can use the following script scheduled in your system's crontab to do this. Special thanks to Andrew Rosborough for providing this script:

#!/bin/sh
# This script will send a daily honeypot report to the configured email address
DATE=`date '+%Y/%m/%d' --date='1 day ago'`
# email subject
SUBJECT="Kojoney Daily Report"
# email to
EMAIL="root@localhost"
# email message
EMAILMESSAGE="/usr/share/kojoney/report.txt"
# generate report
/usr/share/kojoney/kojreport-filter /var/log/honeypot.log $DATE 0 0 1 > $EMAILMESSAGE
# send email using /bin/mail
/usr/bin/mutt -s "$SUBJECT" "$EMAIL" < $EMAILMESSAGE

Scheduled daily this will send a summary of Kojoney activity to the root account. This helps keep tabs on Kojoney activity in a convenient format.

Extending Kojoney

After using Kojoney for a while I became curious as to whether or not it's functionality could be extended. Kojoney's major limitation is the limited command set that it recognizes. Most commands simply result in a "permission denied" error which is cause for immediate suspicion, especially when an attacker thinks they have logged in as root. Luckily, it is pretty simple to tinker with Kojoney to get it to respond to custom commands in a manner of your choosing. The two key files to modify are /usr/share/kojoney/coret_honey.py and /usr/share/kojoney/coret_fake.py. The coret_fake.py file contains the output of most commands that Kojoney provides. One quick thing you'll notice is that the timestamps on the output for the "ls" command are woefully out of date. It's worth updating these and perhaps customizing them. Once you've adjusted the built in command output to suit your needs you'll probably also want to add support for new commands.

To add support for a new commands, say the "uptime" and "ps" commands, which are not supported by default in Kojoney simply edit the coret_fake.py file. Add the following lines to the end of the file:

FAKE_UPTIME = " 10:35:11 up 43 days, 17 min,  2 users,  load average: 0.08, 0.05, 0.04"
FAKE_PS = ("  PID TTY          TIME CMD",
"25304 pts/1    00:00:00 bash",
"28018 pts/1    00:00:00 ps"
)

You can adjust the values to whatever you see fit. Now that you have the output strings edit the coret_honey.py file, look for the portion of the file that reads:

    retvalue = 1
    print "COMMAND IS : " + data
    transport.write('\r\n')

    if uname_re.match(data):
        transport.write(FAKE_OS)
    elif ls_re.match(data):
        for line in FAKE_LS:
            transport.write(line + '\r\n')
    elif data == "exit":
        transport.loseConnection()
    elif data == "w":
        for line in FAKE_W:
            transport.write(line + '\r\n')

Insert our new commands into this porting on coret_honey.py like so:

    retvalue = 1
    print "COMMAND IS : " + data
    transport.write('\r\n')

    if uname_re.match(data):
        transport.write(FAKE_OS)
    elif ls_re.match(data):
        for line in FAKE_LS:
            transport.write(line + '\r\n')
    elif data == "ps":
        for line in FAKE_PLAIN_PS:
            transport.write(line + '\r\n')
    elif data == "uptime":
        transport.write(FAKE_UPTIME)
    elif data == "exit":
        transport.loseConnection()
    elif data == "w":
        for line in FAKE_W:
            transport.write(line + '\r\n')

Once this is done suppport is enabled for the new commands! Simply restart Kojoney using:

# /etc/init.d/kojoney stop
# /etc/init.d/kojoney start

And log in to test out the new command output. You can use this method to add support to any number of new commands. I have found that it's a good idea to review the Kojoney logs daily and pick out commands attackers have used that are not supported and write in support for them. This allows you to incrementally increase the interactivity of your low interaction honeypot to suite the demands of attackers.

One thing that Kojoney doesn't do very well is simulate the directory tree. I have yet to figure out an elegant way to handle this by modifying the Kojoney code. It would be nice to set up some elaborate array in a config file and use that to allow attackers to change directories and look at individual files. Kojoney will also not let attackers "write" files into the existing structure which can be a telltale sign that attackers are in a honeypot.

Conclusions

Kojoney is a wonderful low interaction honeypot that can provide useful intelligence to almost any organization. By extending Kojoney you can easily increase it's "interactivity" to make it more like a high interaction honeypot while retaining the safety of utilizing a low interaction honeypot. Because Kojoney is written in Python it's easy to look through the codebase and understand what is going on under the hood. Although Kojoney hasn't been updated in a while it is still extremely valuable and probably worth looking into, and contributing back to the project.