道可道道尽道 發表於 2020-3-28 14:29:00

PHP中的变量覆盖漏洞

<h2 id="blogTitle0" style="font-weight: bold; color: rgba(255, 255, 255, 1); font-family: 微软雅黑, 宋体, 黑体, Arial; min-height: 25px; line-height: 25px; opacity: 0.8; background: rgba(0, 221, 221, 1); border-radius: 6px; padding: 8px; border: 1px dashed rgba(0, 221, 221, 1); margin: 18px 5px !important">&nbsp;简介</h2>
<p>今天利用周六整理了一下 php覆盖的漏洞</p>
<p>榆林学院的同学可以使用协会内部实验平台进行实验操作。</p>
<h2 id="blogTitle0" style="font-weight: bold; color: rgba(255, 255, 255, 1); font-family: 微软雅黑, 宋体, 黑体, Arial; min-height: 25px; line-height: 25px; opacity: 0.8; background: rgba(0, 221, 221, 1); border-radius: 6px; padding: 8px; border: 1px dashed rgba(0, 221, 221, 1); margin: 18px 5px !important">&nbsp;1.extract()变量覆盖</h2>
<p><span style="font-size: 14pt"><strong>1.extract()</strong></span></p>
<p>extract() 函数从数组中将变量导入到当前的符号表。</p>
<p>该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。</p>
<p>该函数返回成功设置的变量数目。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">extract</span>(<span style="color: rgba(0, 0, 255, 1)">array</span>,extract_rules,prefix)</pre>
</div>
<p>参考引用:https://www.runoob.com/php/func-array-extract.html</p>
<p><strong>eg:</strong></p>
<div class="cnblogs_code">
<pre>&lt;?<span style="color: rgba(0, 0, 0, 1)">php
</span><span style="color: rgba(0, 128, 128, 1)">extract</span>(<span style="color: rgba(128, 0, 128, 1)">$_GET</span><span style="color: rgba(0, 0, 0, 1)">);

</span><span style="color: rgba(0, 0, 255, 1)">echo</span> <span style="color: rgba(128, 0, 128, 1)">$name</span>.'&lt;br&gt;'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> <span style="color: rgba(128, 0, 128, 1)">$age</span>.'&lt;br&gt;'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> <span style="color: rgba(128, 0, 128, 1)">$phone</span>.'&lt;br&gt;'<span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">GET传参:?name=xiaohua&amp;age=22&amp;phone=112323123

//结果:
// xiaohua
// 22
// 112323123</span>
?&gt;</pre>
</div>
<p><span style="font-size: 14pt"><strong>2.CTF中extract()导致的变量覆盖</strong></span></p>
<div class="cnblogs_code">
<pre>&lt;?<span style="color: rgba(0, 0, 0, 1)">php
</span><span style="color: rgba(128, 0, 128, 1)">$flag</span>='flag.php'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">extract</span>(<span style="color: rgba(128, 0, 128, 1)">$_GET)</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(<span style="color: rgba(0, 0, 255, 1)">isset</span>(<span style="color: rgba(128, 0, 128, 1)">$ceshi</span><span style="color: rgba(0, 0, 0, 1)">))
{
</span><span style="color: rgba(128, 0, 128, 1)">$content</span>=<span style="color: rgba(0, 128, 128, 1)">trim</span>(<span style="color: rgba(0, 128, 128, 1)">file_get_contents</span>(<span style="color: rgba(128, 0, 128, 1)">$flag</span><span style="color: rgba(0, 0, 0, 1)">));
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(<span style="color: rgba(128, 0, 128, 1)">$ceshi</span>==<span style="color: rgba(128, 0, 128, 1)">$content</span><span style="color: rgba(0, 0, 0, 1)">)
{
    </span><span style="color: rgba(0, 0, 255, 1)">echo</span>'flag{xxxxxxx}'<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
    </span><span style="color: rgba(0, 0, 255, 1)">echo</span>'Oh.no'<span style="color: rgba(0, 0, 0, 1)">;
}
}
</span>?&gt;</pre>
</div>
<p>我们大致分析是要求我们GET传参进去值会经过extract()函数&nbsp;下来会有两个if 第一个if判断 ceshi这个变量是否存在 存在则继续执行if里面的</p>
<p>使用file_get_contents()读取flag变量里面的文件传递给content变量 之后&nbsp;再进行判断传进来ceshi变量的值等不等于$content如果等于则打印出flag!</p>
<p>这里我们构造因为通过extract()函数我们传进的值会变成一个变量&nbsp; 例如我们GET传入 ceshi=1 则会存在$ceshi=1&nbsp; 所以我们构造GET传参pyaload:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 0, 128, 1)">GET传参payload:$ceshi</span>=&amp;<span style="color: rgba(128, 0, 128, 1)">$flag</span>=</pre>
</div>
<p>这样再程序中会有两个为空的变量而$flag=空 则覆盖了上面的$flag中的值 这样进行判断 都是空的所以为真则得到flag</p>
<p><strong><span style="font-size: 14pt">3.漏洞修复</span></strong></p>
<p><span style="font-size: 14px">不要使用。。。。<br>参考 官方文档 修改<em>extract_rules 里面的值为EXTR_SKIP&nbsp; eg:</em></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">extract</span>(<span style="color: rgba(128, 0, 128, 1)">$_GET</span>,EXTR_SKIP); </pre>
</div>
<p>&nbsp;</p>
<h2 id="blogTitle0" style="font-weight: bold; color: rgba(255, 255, 255, 1); font-family: 微软雅黑, 宋体, 黑体, Arial; min-height: 25px; line-height: 25px; opacity: 0.8; background: rgba(0, 221, 221, 1); border-radius: 6px; padding: 8px; border: 1px dashed rgba(0, 221, 221, 1); margin: 18px 5px !important">&nbsp;2.PHP动态变量覆盖</h2>
<p><span style="font-size: 18pt"><strong>1.动态变量覆盖</strong></span></p>
<p>PHP动态变量是指一个变量名的变量名可以动态的设置和使用,一个变量获取另一个变量的值作为这个变量的变量名。</p>
<div class="cnblogs_code">
<pre>&lt;?<span style="color: rgba(0, 0, 0, 1)">php
</span><span style="color: rgba(128, 0, 128, 1)">$bar</span>= "a"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$Foo</span>="Bar"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$World</span>="Foo"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$Hello</span>="world"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$a</span>="Hello"<span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">echo</span> <span style="color: rgba(128, 0, 128, 1)">$a</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">hello</span>
<span style="color: rgba(0, 0, 255, 1)">echo</span> $<span style="color: rgba(128, 0, 128, 1)">$a</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">world</span>
<span style="color: rgba(0, 0, 255, 1)">echo</span> $$<span style="color: rgba(128, 0, 128, 1)">$a</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">foo</span>
<span style="color: rgba(0, 0, 255, 1)">echo</span> $$$$<span style="color: rgba(128, 0, 128, 1)">$a</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Bar</span>
<span style="color: rgba(0, 0, 255, 1)">echo</span> $$$$$<span style="color: rgba(128, 0, 128, 1)">$a</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">a</span>
<span style="color: rgba(0, 0, 255, 1)">echo</span> $$$$$$<span style="color: rgba(128, 0, 128, 1)">$a</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">hello</span>
<span style="color: rgba(0, 0, 255, 1)">echo</span> $$$$$$$<span style="color: rgba(128, 0, 128, 1)">$a</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">world</span>

?&gt; </pre>
</div>
<p>&nbsp;</p>
<p><span style="font-size: 14pt"><strong>CTF中的动态变量覆盖</strong></span></p>
<p>https://www.cnblogs.com/xhds/p/12586928.html&nbsp; CTF中的动态变量覆盖</p>
<p>&nbsp;</p>
<p><span style="font-size: 14pt"><strong>3.漏洞修复</strong></span></p>
<p><span style="font-size: 14px">避免使用这个</span></p>
<h2 id="blogTitle0" style="font-weight: bold; color: rgba(255, 255, 255, 1); font-family: 微软雅黑, 宋体, 黑体, Arial; min-height: 25px; line-height: 25px; opacity: 0.8; background: rgba(0, 221, 221, 1); border-radius: 6px; padding: 8px; border: 1px dashed rgba(0, 221, 221, 1); margin: 18px 5px !important">&nbsp;3.parse_str()变量覆盖</h2>
<p><strong><span style="font-size: 14pt">1.parse_str()</span></strong></p>
<p>parse_str() 函数把查询字符串解析到变量中。</p>
<p><span style="font-size: 14px">注释:<span style="background-color: rgba(255, 255, 255, 1); color: rgba(255, 0, 0, 1)"><strong>如果未设置 array 参数,由该函数设置的变量将覆盖已存在的同名变量。</strong></span></span></p>
<p><span style="font-size: 14px">注释:php.ini 文件中的 magic_quotes_gpc 设置影响该函数的输出。如果已启用,那么在 parse_str() 解析之前,变量会被 addslashes() 转换。</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">parse_str</span>(<span style="color: rgba(0, 0, 255, 1)">string</span>,<span style="color: rgba(0, 0, 255, 1)">array</span>)</pre>
</div>
<p>参考引用:https://www.runoob.com/php/func-string-parse-str.html</p>
<p><strong>eg:</strong></p>
<div class="cnblogs_code">
<pre>&lt;?<span style="color: rgba(0, 0, 0, 1)">php
</span><span style="color: rgba(0, 128, 128, 1)">parse_str</span>("name=xiaohua&amp;age=22"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> <span style="color: rgba(128, 0, 128, 1)">$name</span>."&lt;br&gt;"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> <span style="color: rgba(128, 0, 128, 1)">$age</span><span style="color: rgba(0, 0, 0, 1)">;
</span>?&gt;
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">xiaohua
//22</span></pre>
</div>
<p>&nbsp;</p>
<p><span style="font-size: 14pt"><strong>2.CTF中parse_str()导致的变量覆盖</strong></span></p>
<div class="cnblogs_code">
<pre>&lt;?<span style="color: rgba(0, 0, 0, 1)">php
</span><span style="color: rgba(0, 128, 128, 1)">error_reporting</span>(0<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(128, 0, 128, 1)">$flag</span>="flag{xiaohua-2020}"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">empty</span>(<span style="color: rgba(128, 0, 128, 1)">$_GET</span>['id'<span style="color: rgba(0, 0, 0, 1)">])) {
   </span><span style="color: rgba(0, 128, 128, 1)">show_source</span>(<span style="color: rgba(255, 0, 255, 1)">__FILE__</span><span style="color: rgba(0, 0, 0, 1)">);
   </span><span style="color: rgba(0, 0, 255, 1)">die</span><span style="color: rgba(0, 0, 0, 1)">();
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(128, 0, 128, 1)">$a</span> = "www.xiaohua.com"<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(128, 0, 128, 1)">$id</span> = <span style="color: rgba(128, 0, 128, 1)">$_GET</span>['id'<span style="color: rgba(0, 0, 0, 1)">];
    @</span><span style="color: rgba(0, 128, 128, 1)">parse_str</span>(<span style="color: rgba(128, 0, 128, 1)">$id</span>);<span style="color: rgba(0, 128, 0, 1)">//
</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(128, 0, 128, 1)">$a</span> != 'QNKCDZO' &amp;&amp; <span style="color: rgba(0, 128, 128, 1)">md5</span>(<span style="color: rgba(128, 0, 128, 1)">$a</span>) == <span style="color: rgba(0, 128, 128, 1)">md5</span>('QNKCDZO'<span style="color: rgba(0, 0, 0, 1)">)) {
       </span><span style="color: rgba(0, 0, 255, 1)">echo</span> <span style="color: rgba(128, 0, 128, 1)">$flag</span><span style="color: rgba(0, 0, 0, 1)">;
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">exit</span>("no no"<span style="color: rgba(0, 0, 0, 1)">);
}
}
</span>?&gt; </pre>
</div>
<p>&nbsp;</p>
<p>分析代码 判断GET传入的id值是否为空为空的话输出源码终止程序,否则的话则接收id值 经过parse_str() 然后呢if判断 $a 的值要不等于QNKCDZO</p>
<p>但$a的md5值要等于QNKCDZO这里可以采用Hash比较缺陷&nbsp;来解决这一步 下来就是传入变量覆盖$a的值&nbsp; 因为有parse_str所以我们可以构造payload:</p>
<div class="cnblogs_code">
<pre>payload:http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">127.0.0.1/test.php?id=a=s878926199a </span></pre>
</div>
<p>&nbsp;</p>
<p><span style="font-size: 14pt"><strong>3.漏洞修复</strong></span></p>
<p>为了防止变量覆盖,尽量使用指定输出变量方式</p>
<h2 id="blogTitle0" style="font-weight: bold; color: rgba(255, 255, 255, 1); font-family: 微软雅黑, 宋体, 黑体, Arial; min-height: 25px; line-height: 25px; opacity: 0.8; background: rgba(0, 221, 221, 1); border-radius: 6px; padding: 8px; border: 1px dashed rgba(0, 221, 221, 1); margin: 18px 5px !important">&nbsp;4.import_request_variables()变量覆盖</h2>
<p><strong><span style="font-size: 14pt">1.&nbsp;<span class="refname">import_request_variables()</span></span></strong></p>
<p><span style="font-size: 14px"><span class="refname">(PHP 4 &gt;= 4.1.0, PHP 5 &lt; 5.4.0)</span></span></p>
<p>&nbsp;<span class="refname">import_request_variables&nbsp;—&nbsp;<span class="dc-title">将 GET/POST/Cookie 变量导入到全局作用域中</span></span></p>
<p><span class="refname"><span class="dc-title">将 GET/POST/Cookie 变量导入到全局作用域中。如果你禁止了&nbsp;register_globals,但又想用到一些全局变量,那么此函数就很有用。</span></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">import_request_variables</span> ( <span style="color: rgba(0, 0, 255, 1)">string</span> <span style="color: rgba(128, 0, 128, 1)">$types</span> [, <span style="color: rgba(0, 0, 255, 1)">string</span> <span style="color: rgba(128, 0, 128, 1)">$prefix</span> ] ) : bool</pre>
</div>
<p>参考引用:https://www.php.net/manual/zh/function.import-request-variables.php</p>
<p>&nbsp;</p>
<p><span style="font-size: 14pt"><strong>2.CTF中import_request_variables()导致的变量覆盖</strong></span></p>
<div class="cnblogs_code">
<pre>&lt;?<span style="color: rgba(0, 0, 0, 1)">php
</span><span style="color: rgba(128, 0, 128, 1)">$num</span>=0<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">include 'flag.php';</span>
<span style="color: rgba(0, 128, 128, 1)">import_request_variables</span>('gp'); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">导入get和post中变量</span>

<span style="color: rgba(0, 0, 255, 1)">if</span>(<span style="color: rgba(128, 0, 128, 1)">$num</span>=="xiaohua"<span style="color: rgba(0, 0, 0, 1)">){
    </span><span style="color: rgba(0, 0, 255, 1)">echo</span> 'flag{ xiaohua-2020-3-28}'<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> echo $flag.php;</span>
}<span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
    </span><span style="color: rgba(0, 0, 255, 1)">echo</span> "NO!"<span style="color: rgba(0, 0, 0, 1)">;
}
</span>?&gt;

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">payload:http://127.0.0.1/test.php?num=xiaohua
//flag{ xiaohua-2020-3-28} </span></pre>
</div>
<p><span style="font-size: 14pt"><strong>3.漏洞修复</strong></span></p>
<p>尽量不要使用....</p>
<h2 id="blogTitle0" style="font-weight: bold; color: rgba(255, 255, 255, 1); font-family: 微软雅黑, 宋体, 黑体, Arial; min-height: 25px; line-height: 25px; opacity: 0.8; background: rgba(0, 221, 221, 1); border-radius: 6px; padding: 8px; border: 1px dashed rgba(0, 221, 221, 1); margin: 18px 5px !important">&nbsp;5.PHP全局变量覆盖</h2>
<p><strong><span style="font-size: 14pt">1.register_globals</span></strong></p>
<p>当register_globals全局变量设置开启时,传递过来的值会被直接注册为全局变量而使用,这会造成全局变量覆盖</p>
<p>在PHP5.3之前 默认开启 PHP5.3默认关闭&nbsp; PHP5.6及5.7已经被移除</p>
<p>&nbsp;</p>
<p><span style="font-size: 14pt"><strong>2.CTF中全局变量覆盖</strong></span></p>
<p><span style="font-size: 14px">测试环境:php5.2.17</span></p>
<div class="cnblogs_code">
<pre>&lt;?<span style="color: rgba(0, 0, 0, 1)">php
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(128, 0, 128, 1)">$num</span><span style="color: rgba(0, 0, 0, 1)">){
   </span><span style="color: rgba(0, 0, 255, 1)">echo</span> "flag{xiaohua-2020-3-28}"<span style="color: rgba(0, 0, 0, 1)">;
}
</span>?&gt;
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">payload:http://127.0.0.1/test.php?num=1
//flag{xiaohua-2020-3-28}</span></pre>
</div>
<p>&nbsp;</p>
<p><span style="font-size: 14pt"><strong>3.漏洞修复</strong></span></p>
<p>关闭register_globals=off 或者使用5.6以上版本。。</p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/xhds/p/12587249.html
頁: [1]
查看完整版本: PHP中的变量覆盖漏洞