PHP立体安全:一网打尽攻击向量
所谓攻击向量,就是指黑传递有效负载或恶意结果而可以访问计算机或网络服务器的路径或方法。
PHP的安全并不只有危险函数,这只是冰山一角。本文将介绍PHP从汇编层面到框架层面直到标准层面的所有攻击向量。
攻击向量枚举图
PHP代码层面
介绍
危险函数是PHP代码层面的主要审计对象,它们通常有如下功能:
1.进行I/O操作
2.进行命令/代码执行
3.进行网络交互
4.进行数据库交互
实际上这些功能都是开发所不可缺少的,功能设计本身没有问题,只是被滥用了。
实例-preg_replace的e参数
这是thinkphp2.x的一个历史漏洞,存在于/ThinkPHP/Lib/Think/Util/Dispatcher.class.php// $depr是取得的操作系统目录分隔符,可以认为等效如下形式$depr='\/';...$paths = explode($depr,trim($_SERVER['PATH_INFO'],'/'));...$res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));(向右滑动、查看更多)
构造特定路由访问即可控制反向引用2处的值,又因为这里是双引号可以解析变量,利用PHP复杂变量进行命令执行.
例如/any_1/any_2/any_3/${phpinfo()}即可触发代码执行。(为了直观,省略了一些对路由机制的处理,实际上前几个any位置会被丢弃)
攻击向量分析
在PHP代码层面,本质上就是利用PHP已有的一些敏感功能,无论是phar反序列化,或者是file_put_content文件操作函数,还是call_user_function之类的回调函数,本身都是没有问题的,只是被恶意滥用,达到了开发者预期之外的效果。
PHP实现层面
介绍
PHP官方提供了PHP的C语言源码,可以在php/php-src: The PHP Interpreter (github.com)下载到源码,方便查看PHP函数的C语言实现。悠悠这里调试的PHP源码是分支PHP-5.6版本。
在PHP实现层面,C语言的业务逻辑缺陷外显成一个又一个的PHP的小trick,包括open_basedir的软链接绕过、is_file触发phar反序列化等等。
实例-strip_tags实现缺陷$str = strip_tags($str, '<audio>');//本意是设置白名单只允许标签audio存在// 但是可以任意位置加斜杠,不影响audio白名单,这是一个底层trick// 例如<a/udio href=``》会变成<a udio href=''>,再配合javascript伪协议触发xss(向右滑动、查看更多)
这一trick成因来自于底层的C语言实现,我们来看一下。
关键代码如下
while (i < len) {switch (c) {case'\0':break;case'<': ...if (state == 0) { ... } elseif (state == 1) { depth++; }break; ...case'>':if (depth) { depth--;break; } ...if (allow) {if (tp - tbuf >= PHP_TAG_BUF_SIZE) { pos = tp - tbuf; tbuf = erealloc(tbuf, (tp - tbuf) + PHP_TAG_BUF_SIZE + 1); tp = tbuf + pos; } *(tp++) = '>'; *tp='\0';if (php_tag_find(tbuf, tp-tbuf, allow)) {memcpy(rp, tbuf, tp-tbuf); rp += tp-tbuf; } tp = tbuf; }break;(向右滑动、查看更多)
发现此时只是在内存开辟空间,没有进行白名单处理。跳到php_tag_find函数。
while (!done) {switch (c) {case'<': *(n++) = c;break;case'>': done =1;break;default:if (!isspace((int)c)) {if (state == 0) { state=1; }// 这个地方就是trick出现的原因if (c != '/') { *(n++) = c; } } else {if (state == 1) done=1; }break; } c = tolower(*(++t)); } *(n++) = '>'; *n = '\0';if (strstr(set, norm)) { done=1; } else { done=0; } efree(norm);return done;
我们可以看到,c等于"/"时不被计数,而它的位置并没有限定,导致trick诞生。
攻击向量分析
这种攻击向量中,PHP代码层面并不是危险函数,甚至是用于过滤的安全函数,但是底层实现逻辑与官方文档原意并不完全相同,导致非预期行为引发漏洞。实际上,PHP的大量trick都来源于此,即使开发者小心翼翼的按照官方文档进行开发,充分考虑安全因素,仍然可能生产不安全的代码。
PHP汇编层面和扩展层面
介绍
即使PHP的代码层面毫无问题,C语言实现层面完美无瑕,仍然可能存在攻击向量。那就是二进制安全,在汇编层面具有漏洞。
实例-htmlspecialchars()缓冲区溢出
bug编号: 60965
PHP版本: 5.4
bug描述: 40个字节以上长实体将导致缓冲区溢出。
<?php
echo htmlspecialchars('
"""""""""""""""""""""""""""""""""""""""""""""
',ENT_QUOTES, 'UTF-8', false), "\n";
在这个实例中,攻击向量变得非常隐秘,它不是PHP使用者的问题,也不是PHP开发者的问题,而是二进制层面的漏洞。
实例-不安全的.so扩展
这是一个自定义的恶意扩展,修改php.ini,增加extension=youyou.so启用之后,就可以调用system(),通过原先不存在的函数获得权限等,自定义的函数当然是不会被waf拦截的。
这里演示的是.so作为后门的用途,但实际上很多扩展本来不是作为后门,只是开发功能时留下了二进制层面的漏洞,被加以滥用了而已。
攻击向量分析
这一层面防不胜防,与代码层面的缺陷可以由个人用户自行修补不同,汇编和扩展层面寻常开发者不能自己修补,所以危害巨大,容易成为突破口。
C特性、操作系统层面
介绍
PHP语言毕竟底层是C语言,在毫不设防的情况下,C语言的特性就会保留且暴露出来。
实例-CVE-2015-2348
操作系统在识别字符串时,认为\0字符是一个字符串的结束符号。PHP源码的ext/standard/basic_functions.c中对长度的安全检查受限于C语言特性失效。php版本<=5.4.39 、5.5.0-5.5.23、5.6.0-5.6.7时存在。
move_uploaded_file($_FILES['file']['tmp_name'],"/tmp/youyou.php\x00.png")(向右滑动、查看更多)
攻击向量分析
C语言特性为安全过滤等操作带来了不便,好在PHP官方对此积极修复,实际上PHP8.0在以windows作为服务器环境时仍然存在大量类似的安全缺陷,例如>转为.问题。
PHP框架层面
介绍
现代框架一般由model,controller,view,router,middle部分组成,其中model包括与数据库的交互脚本,controller包括对业务逻辑的具体实现,view是前端的视图,router控制访问的请求的处理器行驶路由权限,middle作为中间件完成各种过滤功能。框架本身提供了更多更新的功能,可能会被开发者滥用。
实例-CodeIgniter框架sql缓存滥用
CI框架的model层已经封装了result()方法来获取数据库查询得到的数据,这其中经过大量复杂的解耦,我们直接看重点,省略部分过程,看到主要功能类。通过result找到它的具体逻辑result_object()
找一下这个类的属性来源。
继续看它的用途。
也就是说结果早就出来了储存在某个属性里....
我们惊奇的发现,这里优化性能时把数据库查询的缓存运用ORM技术经过反序列化存在了一个文件里。这是一个奇特的框架功能,但是由于写入控制的很
好,本身没有安全问题。
写入逻辑不可控,只是功能比较奇特,但是不能利用。不过,如果遇到一个这样的控制器。
由于这里没有对..进行过滤,存在一个目录穿越漏洞,虽然在别处控制了目录权限限制/var/html/www目录执行,但是可以借助框架的那个特殊功能触发反序列化构造利用链条扩大攻击面。
攻击向量分析框架的大量功能构建在PHP代码层面之上,它们本身可能是安全的,但是却可以作为新的"自定义"函数与业务逻辑捧出火花产生安全问题,是不容忽视的攻击向量来源。
PHP标准层面
介绍
web技术有许许多多的技术标准例如GraphQ、Jwt等等,它们的设计都是为了满足某种开发需求,但是在具体实现的时候可能会出现一些问题。
实例-OAtuh2.0实现缺陷
这是OAuth官网写的OAuth2.0技术标准脉络。
正如官方所说,OAuth2.0的作用是供用户授权访问第三方应用。涉及权限的问题,就是敏感的问题。
TheOAuth 2.0 authorization framework enables a third-partyapplicationto obtain limited access to an HTTP servic(向右滑动、查看更多)
这是微软对OAtuth授权代码授予的说明图。
这是微软对OAtuh隐式授权流的说明图。
我们可以发现,授权代码授予方式与隐式授权流的不同在于使用场景有无后端,前者是拥有后端,所以发送了the app's cilent_id,后者没有后端,没有提供这一信息。
如果采用了错误的实现方式,让前者在OAuth服务器上把acess token与cilent_id绑定,根据不同的client_id确定了可访问资源的范围,后者如果也是用的相同实现方式,相当于为none的client_id绑定了所有acess token,没有清晰的拥有者,同时对应了多个资源,就会出现问题。
采用错误实现的时候,我们可以通过正常操作获取acess token,然后等待它更新token,通过重放的方式修改图中的hidden sign改变获取资源的范围,绕过身份认证。
正确的实现方式应该是把acess token和资源绑定,有clent_id则连带绑定,没有则忽略。
攻击向量分析
PHP标准层面的漏洞是致命的,因为标准设计是为了解决某些开发上的问题,而具体实现时开发者可能不会考虑其安全性的问题,某种具有缺陷的实现思路一旦传播开来就会产生大面积的安全缺陷。尤其是标准设计本身具有难度,开发者难以察觉问题所在。RSA标准曾经使用过一种圆锥曲线密钥,后来发现存在数学上的缺陷,但是高明的开发者也不可能发现标准本身具有这种问题,可是不怀好意的人利用它却不是一件难事。
总结
PHP的安全是立体的、多维度的安全,从宏观到微观有各种各样的攻击面。本文枚举了PHP所有可能的攻击向量,虽然所举实例并不丰富,但是足够经典,如有不足还望指正。
精彩推荐
相关文章
-
犹记得,据2001年7月的PHP官方文档描述,"PHP是有史以来最好的语言,没有之一。它快速,非常强大,而且免费。"不过,随着时间的迭代,不少开发者发现所谓世界上最好的语言PHP,虽然能极大地提升性能,但是其功能不够完善最终导致PHP开始走上了下坡路,对此,你怎么看? 作者|ItaloBaeza 译者|孙薇,责编|屠
-
作者|OscarMerida译者|弯月 出品|CSDN(ID:CSDNnews)PHP是一门有趣的编程语言。语言与利用语言构建的程序通常属于两种设计理念。这里我指的不是瀑布式或敏捷之类的软件开发生命周期,而是软件管理的基本思想。有人将这些思想称为"正确的方式"以及"WorseisBetter"。 PHP包含一些奇怪的
-
作者|Brent 译者|张兰月 这篇文章不在于解决关于PHP的那个永恒话题,而是想让你了解,PHP在这些年的进展以及那些值得关注的特性与发展现状。 之前,有一篇非常流行的博客文章是"PHP:那些糟糕的设计",第一次读到这篇博客的时候,我正在一个非常破旧的地方工作,处理着许多PHP遗留项目。这篇博客对我触动很深,我开
-
点击上方"程序员软件库",选择"星标" 第一时间关注软件资讯干货!作者|ClementBrian译者|弯月 出品|CSDN(ID:CSDNnews)万物有开始就有结束。而如今PHP也步入了暮年。在这个时代,长盛不衰的唯一方法就是无可取代。一门技术如非必不可少,就会被慢慢遗忘。PHP不仅可有可无,而且会加剧开发工作的复
-
晓查乾明发自凹非寺 这些结果之中,不乏有2016年、2018年的结果,说PHP已经过时了。 现已2019年,这个曾经自称为"世界上最好的语言"PHP,情况如何? 一位名叫Brent的程序员小哥,写了一篇博客文章,介绍了PHP在2019年的情况。 他说,现在的PHP每年都会积极开发新版本,从2004年发布PHP5以来性
-
来源:OSC-王练 随着上周PHP7.3Alpha3的发布,意味着PHP7.3即将进入特性冻结阶段,不再有新的功能添加,后续的Beta和RC版本将主要进行修复,直到11月29日发布正式版本。 从目前的更新说明来看,PHP7.3并不是一个主打新特性的版本,包含更多的是Bug修复。PHP7.3删除了对BeOS的支持,改进
-
作者|BENJAMES 译者|Arvin,责编|夕颜 出品|CSDN(ID:CSDNnews)1995年6月,拉斯穆斯·勒多夫(RasmusLerdorf)在Usenet小组中发布了一则如下公告。公告至今还在,随时可以阅读。 公告: 正式发布个人主页工具(PHP工具)1.0版本。这些工具是一组用C编写的小巧紧凑的cg
-
1、所有应聘人员要求:人品要正、心术要正,能力不够可以培养,但人品不能缺失。 2、处于快速上升期的米宅有能力、也有信心给加盟的朋友们提供更好的发展空间、更好的工作环境、更好的未来回报。 3、所有岗位工资标准:行业中等偏上,不敢追求太高,但绝不能低于行业平均水平。 工作地点:郑东新区CBD、地铁口 额外回报:优秀人员有股
-
从PHP8.0之后,我参与PHP开源就少了,从而博客也写的少了,不少朋友来问,所以觉得有必要用一篇文章说明下近况。 总的来说,本职工作发生了一些变化,导致工作上的事情,牵扯了太多的精力,从而没有办法有太多的精力投入PHP开源工作中。 而关于,工作的变化,我稍微介绍下: 0x01 从2018年开始,我的主要工作基本上就是
-
选自Medium 作者:VladimirGoncharov 机器之心编译 参与:HuiyuanZhuo、思源、刘晓坤 作者VladimirGoncharov平常主要关注与研究两个主题:PHP和ServerAdministration(服务器管理)。在过去的半年中,作者利用空闲时间探索PHP与OpenCV的结合,并借此调