<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>葡萄树 On The Road --- 我只是一个会操作计算机的民工 &#187; PHPWind</title>
	<atom:link href="http://www.am82.com/houzan/archives/tag/phpwind/feed" rel="self" type="application/rss+xml" />
	<link>http://www.am82.com/houzan</link>
	<description>我的时光，停在了你的角落...~</description>
	<lastBuildDate>Tue, 07 Sep 2010 02:08:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>PHPWind 7.5 多处包含漏洞</title>
		<link>http://www.am82.com/houzan/archives/3585</link>
		<comments>http://www.am82.com/houzan/archives/3585#comments</comments>
		<pubDate>Mon, 11 Jan 2010 01:30:41 +0000</pubDate>
		<dc:creator>假装纯情</dc:creator>
				<category><![CDATA[php技术]]></category>
		<category><![CDATA[技术专题]]></category>
		<category><![CDATA[PHPWind]]></category>
		<category><![CDATA[漏洞]]></category>

		<guid isPermaLink="false">http://www.am82.com/houzan/?p=3585</guid>
		<description><![CDATA[作者: 80vul

一.api/class_base.php本地包含漏洞

1.描叙

  api/class_base.php文件里callback函数里$mode变量没有过滤导致任意包含本地文件,从而可以执行任意PHP命令.

2. 具体分析

api/class_base.php文件里.......]]></description>
			<content:encoded><![CDATA[<p>作者: <a href="http://www.80vul.com/" target="_blank">80vul</a></p>
<p>一.api/class_base.php本地包含漏洞</p>
<p>1.描叙</p>
<p>api/class_base.php文件里callback函数里$mode变量没有过滤导致任意包含本地文件,从而可以执行任意PHP命令.</p>
<p>2. 具体分析</p>
<p>api/class_base.php文件里:</p>
<p><code> function callback($mode, $method, $params) {<br />
if (!isset($this-&gt;classdb[$mode])) {<br />
if (!file_exists(R_P.'api/class_' . $mode . '.php')) {<br />
return new ErrorMsg(API_MODE_NOT_EXISTS, "Class($mode) Not Exists");<br />
}<br />
require_once(R_P.'api/class_' . $mode . '.php'); //这里<br />
$this-&gt;classdb[$mode] = new $mode($this);<br />
}<br />
if (!method_exists($this-&gt;classdb[$mode], $method)) {<br />
return new ErrorMsg(API_METHOD_NOT_EXISTS, "Method($method of $mode) Not Exists");<br />
}<br />
!is_array($params) &amp;&amp; $params = array();<br />
return @call_user_func_array(array(&amp;$this-&gt;classdb[$mode], $method), $params);<br />
}<br />
</code><br />
我们继续跟一下具体变量传递的过程. 上面的函数在run()里有调用:</p>
<p><code> function run($request) {<br />
$request = $this-&gt;strips($request);<br />
if (isset($request['type']) &amp;&amp; $request['type'] == 'uc') {<br />
$this-&gt;type  = 'uc';<br />
$this-&gt;apikey = $GLOBALS['uc_key'];//注意这个变量也是该漏洞的关键<br />
} else {<br />
$this-&gt;type  = 'app';<br />
$this-&gt;apikey = $GLOBALS['db_siteownerid'];<br />
$this-&gt;siteappkey = $GLOBALS['db_siteappkey'];<br />
}<br />
/***<br />
if ($this-&gt;type == 'app' &amp;&amp; !$GLOBALS['o_appifopen']) {<br />
return new ErrorMsg(API_CLOSED, 'App Closed');<br />
}<br />
***/<br />
ksort($request);<br />
reset($request);<br />
$arg = '';<br />
foreach ($request as $key =&gt; $value) {<br />
if ($value &amp;&amp; $key != 'sig') {<br />
$arg .= "$key=$value&amp;";<br />
}<br />
}<br />
if (md5($arg . $this-&gt;apikey) != $request['sig']) { //注意这个判断,需要绕过它.上面的代码可以看的出来$this-&gt;apikey = $GLOBALS['uc_key'],和$request['sig']我们<br />
//都可以控制,那么很容易绕过它<br />
return new ErrorMsg(API_SIGN_ERROR, 'Error Sign');<br />
}<br />
$mode = $request['mode']; //取$mode 没有过滤直接进入下面的callback()<br />
$method = $request['method'];<br />
$params = isset($request['params']) ? unserialize($request['params']) : array();<br />
if (isset($params['appthreads'])) {<br />
if (PHP_VERSION &lt; 5.2) {                 require_once(R_P.'api/class_json.php');                 $json = new Services_JSON(true);                 $params['appthreads'] = $json-&gt;decode(@gzuncompress($params['appthreads']));<br />
} else {<br />
$params['appthreads'] = json_decode(@gzuncompress($params['appthreads']),true);<br />
}<br />
}<br />
if ($params &amp;&amp; isset($request['charset'])) {<br />
$params = pwConvert($params, $this-&gt;charset, $request['charset']);<br />
}<br />
return $this-&gt;callback($mode, $method, $params); //调用callback ()<br />
}<br />
</code><br />
我们继续看看run()函数的调用:</p>
<p>在pw_api.php文件里:</p>
<p><code>$api = new api_client();<br />
$response = $api-&gt;run($_POST + $_GET);//直接run了$_POST , $_GET提交的变量.</code></p>
<p>上面的分析是逆行分析了整个漏洞变量提交的过程,其实我们这个漏洞还包含一次编码与解码的问:require_once(R_P.&#8217;api/class_&#8217; . $mode . &#8216;.php&#8217;);这个需要绕过魔术引号才可以<br />
包含容易文件.我们注意看run()的第一句</p>
<p><code>$request = $this-&gt;strips($request);</code></p>
<p>strips()的代码:</p>
<p><code>function strips($param) {<br />
if (is_array($param)) {<br />
foreach ($param as $key =&gt; $value) {<br />
$param[$key] = $this-&gt;strips($value);<br />
}<br />
} else {<br />
$param = stripslashes($param); //变量直接使用了stripslashes,那么我们可以直接绕过魔术引号了 :)<br />
}<br />
return $param;<br />
}<br />
</code><br />
3.POC/EXP</p>
<p>缺</p>
<p>4.FIX</p>
<p>由于漏洞信息的外泄,官方针对这个漏洞已经做出了修补:</p>
<p>http://www.phpwind.net/read-htm-tid-914851.html</p>
<p>具体代码:</p>
<p><code>require_once Pcv(R_P.'api/class_' . $mode . '.php');</code></p>
<p><code> </code></p>
<p><code>function Pcv($filename,$ifcheck=1){<br />
$tmpname = strtolower($filename);<br />
$tmparray = array(' http://',"\0"); //过滤了http:// \0 意思是不让远程 不让截断<br />
$ifcheck &amp;&amp; $tmparray[] = '..';    //过滤了.. 意思是不让转跳目录<br />
if (str_replace($tmparray,'',$tmpname)!=$tmpname) {<br />
exit('Forbidden');<br />
}<br />
return $filename;<br />
}<br />
</code><br />
从Pcv()可以看出来phpwind的补丁风格是很猥琐的,单从这个pcv来看 还有很多的逻辑问题,比如http://这个过滤很搞笑,人家就不可以用ftp://? &#8230;</p>
<p>二.apps/share/index.php远程包含漏洞</p>
<p>1.描叙</p>
<p>apps/share/index.php 里$route和$basePath变量没有初始化,导致远程包含或者本地包含php文件,导致执行任意php代码</p>
<p>2.具体分析</p>
<p>这个漏洞好象不太需要分析!!!! 我建议写这个代码的人应该扣除年终奖&#8230;</p>
<p>3.POC/EXP</p>
<p>缺</p>
<p>4.FIX</p>
<p>已经在这个补丁的同时&#8217;修补&#8217;了</p>
<p>http://www.phpwind.net/read-htm-tid-914851.html</p>
<p>三.apps/groups/index.php远程包含漏洞</p>
<p>1.描叙</p>
<p>apps/groups/index.php 里$route和$basePath变量没有初始化,导致远程包含或者本地包含php文件,导致执行任意php代码</p>
<p>2.具体分析</p>
<p><code>if ($route == "groups") {<br />
require_once $basePath . '/action/m_groups.php';<br />
} elseif ($route == "group") {<br />
require_once $basePath . '/action/m_group.php';<br />
} elseif ($route == "galbum") {<br />
require_once $basePath . '/action/m_galbum.php';<br />
}<br />
</code></p>
<p>这个漏洞好象不太需要分析!!!! 我建议写这个代码的人应该扣除年终奖&#8230;</p>
<p>3.POC/EXP</p>
<p>缺</p>
<p>4.FIX</p>
<p>已经在这个补丁的同时&#8217;修补&#8217;了</p>
<p>http://www.phpwind.net/read-htm-tid-914851.html</p>
]]></content:encoded>
			<wfw:commentRss>http://www.am82.com/houzan/archives/3585/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
