TE: Insomni'hack 2016 Teaser - Smartcat (Web 50pts)

We are given a debug interface at http://smartcat.insomnihack.ch/cgi-bin/index.cgi. Cat lovers would probably love this:

Given only an input textfield, the first thing that an attacker would do is to attempt inputs in the textfield. When I gave it an input "hihi", I got the following:


The error message is a giveaway. It tells us that the web server is running the command "ping -c 1 hihi". Does this mean that we can maliciously inject any command into the textfield? Let's try the input "localhost; ls" and see if we get a listing of the current directory.


We get the error message "Bad character in dest". It seems like we had entered some blacklisted characters. After some tries, I realized that both special characters - the space and the semi-colon - are blacklisted. I also realized that they accept the textfield input via GET parameters in the URL. The parameter name can be seen in the source code of the web page:


Since the semi-colon is blacklisted, the other alternative to end a command is the newline character. To specify this in the url, we use its hex encoding '%0A'. Now we try http://smartcat.insomnihack.ch/cgi-bin/index.cgi?dest=localhost%0Als.


Sweet! We got a listing of the current directory! Now we can use the same technique to display the current directory's hierarchy using the tool "find".


The final step is to view the contents of the flag file. However, since the space character is blacklisted, the command isn't as simple as "cat ./there/is/your/flag/or/maybe/not/what/do/you/think/really/please/tell/me/seriously/though/here/is/the/flag". Fortunately, the program "cat" also takes in inputs from STDIN. Therefore, we can use input redirection to specify the filepath of the flag. We use the command "cat<./there/is/your/flag/or/maybe/not/what/do/you/think/really/please/tell/me/seriously/though/here/is/the/flag" and we get:


Hurray, we get the flag! But that is not the end. I decided to also view the source code of the web page (using the URL http://smartcat.insomnihack.ch/cgi-bin/index.cgi?dest=localhost%0Acat%3Cindex.cgi) to see the vulnerable code:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/usr/bin/env python

import cgi, subprocess, os

headers = ["mod_cassette_is_back/0.1","format-me-i-im-famous","dirbuster.will.not.help.you","solve_me_already"]

print "X-Powered-By: %s" % headers[os.getpid()%4] 
print "Content-type: text/html"
print

print """
<html>

<head><title>Can I haz Smart Cat ???</title></head>

<body>

  <h3> Smart Cat debugging interface </h3>
"""

blacklist = " $;&|({`\t"
results = ""
form = cgi.FieldStorage()
dest = form.getvalue("dest", "127.0.0.1")
for badchar in blacklist:
 if badchar in dest:
  results = "Bad character %s in dest" % badchar
  break

if "%n" in dest:
 results = "Segmentation fault"

if not results:
 try:
  results = subprocess.check_output("ping -c 1 "+dest, shell=True)
 except:
  results = "Error running " + "ping -c 1 "+dest


print """

  <form method="post" action="index.cgi">
    <p>Ping destination: <input type="text" name="dest"/></p>
  </form>

  <p>Ping results:</p><br/>
  <pre>%s</pre>

  <img src="../img/cat.jpg"/>

</body>

</html>
""" % cgi.escape(results)

It turns out that they first run our input through the blacklist, which comprises special characters such as the space, dollar sign, semi-colon, ampersand, pipe, round bracket, curly bracket, back-tick and tab. Therefore, our initial attempt at using the space character and the semi-colon failed. However, they did not blacklist the newline character.

Subsequently, they prepend our input to the string "ping -c 1 " and executes it in a subprocess, with shell enabled. This is a known security hazard and it is even boxed in red on Python's web documentation:


The vulnerability is further elaborated below:

Essentially, the use of shell=True allows shell injection (what we did above) to take place. The use of a blacklist helps to mitigate the vulnerability but a clever attacker may still be able to find ways around it.


Moral of the Story:

Avoid the arbitrary execution of user inputs, especially in shell. If such an operation is absolutely necessary, make sure that the user input is sanitized before it is executed and/or the environment is sandboxed (e.g. using chroot).

Comments