找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 947|回复: 7

phpwind 7.5出现严重安全漏洞

[复制链接]

该用户从未签到

发表于 2010-3-31 00:09:40 | 显示全部楼层 |阅读模式
本帖最后由 Pledges 于 2010-3-31 00:16 编辑

来源:转载  发布时间:2010-1-11 0:39:45  

    近日,国内知名的社区PHPWIND又现严重漏洞,程序中有部分变量没有过滤导致任意包含本地文件,

从而可以执行任意PHP命令,官方针对这个漏洞已经做出了修补。

phpwind 7.5 Multiple Include Vulnerabilities  author: 80vulteam:

http://www.80vul.com一.api/class_base.php本地包含漏洞

1.描叙
api/class_base.php文件里callback函数里$mode变量没有过滤导致任意包含本地文件,

从而可以执行任意PHP命令.2. 具体分析api/class_base.php文件里:

  1.         function callback($mode, $method, $params) {
  2.                 if (!isset($this->classdb[$mode])) {
  3.                         if (!file_exists(R_P.'api/class_' . $mode . '.php')) {
  4.                                 return new ErrorMsg(API_MODE_NOT_EXISTS, "Class($mode) Not Exists");
  5.                         }
  6.                         require_once(R_P.'api/class_' . $mode . '.php'); //这里
  7.                         $this->classdb[$mode] = new $mode($this);
  8.                 }
  9.                 if (!method_exists($this->classdb[$mode], $method)) {
  10.                         return new ErrorMsg(API_METHOD_NOT_EXISTS, "Method($method of $mode) Not Exists");
  11.                 }
  12.                 !is_array($params) && $params = array();
  13.                 return @call_user_func_array(array(&$this->classdb[$mode], $method), $params);
  14.         }
复制代码
我们继续跟一下具体变量传递的过程. 上面的函数在run()里有调用:

  1.         function run($request) {
  2.                 $request = $this->strips($request);
  3.                 if (isset($request['type']) && $request['type'] == 'uc') {
  4.                         $this->type                = 'uc';
  5.                         $this->apikey        = $GLOBALS['uc_key'];//注意变量是该漏洞关键
  6.                 } else {
  7.                         $this->type                = 'app';
  8.                         $this->apikey        = $GLOBALS['db_siteownerid'];
  9.             $this->siteappkey = $GLOBALS['db_siteappkey'];
  10.                 }
  11.                 /***
  12.                 if ($this->type == 'app' && !$GLOBALS['o_appifopen']) {
  13.                         return new ErrorMsg(API_CLOSED, 'App Closed');
  14.                 }
  15.                 ***/
  16.                 ksort($request);
  17.                 reset($request);
  18.                 $arg = '';
  19.                 foreach ($request as $key => $value) {
  20.                         if ($value && $key != 'sig') {
  21.                                 $arg .= "$key=$value&";
  22.                         }
  23.                 }
  24.                 if (md5($arg . $this->apikey) != $request['sig']) {
  25. //注意这个判断,需要绕过它.上面的代码可以看的出来
  26. //$this->apikey        = $GLOBALS['uc_key'],和$request['sig']我们
  27. //都可以控制,那么很容易绕过它
  28.                         return new ErrorMsg(API_SIGN_ERROR, 'Error Sign');
  29.                 }
  30.                 $mode        = $request['mode']; //取$mode 没有过滤直接进入下面的callback()
  31.                 $method        = $request['method'];
  32.                 $params = isset($request['params']) ? unserialize($request['params']) : array();
  33.         if (isset($params['appthreads'])) {
  34.             if (PHP_VERSION < 5.2) {
  35.                 require_once(R_P.'api/class_json.php');
  36.                 $json = new Services_JSON(true);
  37.                 $params['appthreads'] = $json->decode(@gzuncompress($params['appthreads']));
  38.             } else {
  39.                 $params['appthreads'] = json_decode(@gzuncompress($params['appthreads']),true);
  40.             }
  41.         }
  42.                 if ($params && isset($request['charset'])) {
  43.                         $params = pwConvert($params, $this->charset, $request['charset']);
  44.                 }
  45.                 return $this->callback($mode, $method, $params); //调用callback ()
  46.         }
复制代码
我们继续看看run()函数的调用:在pw_api.php文件里:

  1. $api = new api_client();
  2. $response = $api->run($_POST + $_GET);//直接run了$_POST , $_GET提交的变量.
复制代码
上面的分析是逆行分析了整个漏洞变量提交的过程,其实我们这个漏洞还包含一次编码与
解码的问:require_once(R_P.'api/class_' . $mode . '.php');这个需要绕过魔术引号才可以
包含容易文件.我们注意看run()的第一句        

  1. $request = $this->strips($request);

  2. strips() //的代码:

  3.         function strips($param) {
  4.                 if (is_array($param)) {
  5.                         foreach ($param as $key => $value) {
  6.                                 $param[$key] = $this->strips($value);
  7.                         }
  8.                 } else {
  9.                         $param = stripslashes($param);
  10. //变量直接使用了stripslashes,那么我们可以直接绕过魔术引号了 :)
  11.                 }
  12.                 return $param;
  13.         }
复制代码
3.POC/EXP  缺4.FIX由于漏洞信息的外泄,官方针对这个漏洞已经做出了修补:
http://www.phpwind.net/read-htm-tid-914851.html具体代码:

  1. require_once Pcv(R_P.'api/class_' . $mode . '.php');

  2. function Pcv($filename,$ifcheck=1){
  3.         $tmpname = strtolower($filename);
  4.         $tmparray = array(' http://',"\0"); //过滤了http:// \0 意思是不让远程 不让截断
  5.         $ifcheck && $tmparray[] = '..';    //过滤了.. 意思是不让转跳目录
  6.         if (str_replace($tmparray,'',$tmpname)!=$tmpname) {
  7.                 exit('Forbidden');
  8.         }
  9.         return $filename;
  10. }
复制代码

从Pcv()可以看出来phpwind的补丁风格是很猥琐的,单从这个pcv来看 还有很多的逻辑问题,
比如http://这个过滤很搞笑,人家就不可以用ftp://? ...二.apps/share/index.php远程包含漏洞1.

描叙apps/share/index.php 里$route和$basePath变量没有初始化,导致远程包含或者本地包含
php文件,导致执行任意php代码2.具体分析


  1. <?php
  2. if ($route == "share") {
  3.         require_once $basePath . '/action/m_share.php';
  4. } elseif ($route == "sharelink") {
  5.         require_once $basePath . '/action/m_sharelink.php';
  6. }
  7. ?>
复制代码
这个漏洞好象不太需要分析!!!! 我建议写这个代码的人应该扣除年终奖...
3.POC/EXP    缺
4.FIX已经在这个补丁的同时'修补'了http://www.phpwind.net/read-htm-tid-914851.html

  1. <?php
  2. !function_exists('readover') && exit('Forbidden');
  3. if ($route == "share") {
  4.         require_once $basePath . '/action/m_share.php';
  5. } elseif ($route == "sharelink") {
  6.         require_once $basePath . '/action/m_sharelink.php';
  7. }
  8. ?>
复制代码

三.apps/groups/index.php远程包含漏洞1.描叙apps/groups/index.php
里$route和$basePath变量没有初始化,导致远程包含或者本地包含php文件,导致执行
任意php代码
2.具体分析

  1. <?phpif ($route == "groups") {require_once $basePath . '/action/m_groups.php';} elseif ($route == "group") {require_once $basePath . '/action/m_group.php';} elseif ($route == "galbum") {require_once $basePath . '/action/m_galbum.php';}
复制代码

这个漏洞好象不太需要分析!!!! 我建议写这个代码的人应该扣除年终奖...3.POC/EXP   
缺4.FIX已经在这个补丁的同时'修补'了http://www.phpwind.net/read-htm-tid-914851.html

  1. <?php
  2. !function_exists('readover') && exit('Forbidden');
  3. if ($route == "groups") {
  4. require_once $basePath . '/action/m_groups.php';
  5. } elseif ($route == "group") {
  6. require_once $basePath . '/action/m_group.php';
  7. } elseif ($route == "galbum") {
  8. require_once $basePath . '/action/m_galbum.php';
  9. }
  10. ?>
复制代码

该用户从未签到

发表于 2010-3-31 00:33:37 | 显示全部楼层
黑客强势插入

该用户从未签到

发表于 2010-3-31 00:58:59 | 显示全部楼层
看不懂强势围观.

该用户从未签到

发表于 2010-3-31 10:09:37 | 显示全部楼层
LZ你要把本版块往IT新闻版块发展?

该用户从未签到

发表于 2010-3-31 11:45:18 | 显示全部楼层
强势断后···

该用户从未签到

发表于 2010-3-31 12:11:19 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

该用户从未签到

发表于 2010-3-31 12:45:33 | 显示全部楼层
强势垫底

该用户从未签到

发表于 2010-5-23 06:36:35 | 显示全部楼层
强势回帖
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表