当前位置:首页 » 编程语言 » php源码审计

php源码审计

发布时间: 2025-03-09 06:41:17

A. [红日安全]代码审计Day2 - filter_var函数缺陷

本文由红日安全成员:七月火 编写,如有不当,还望斧正。

前言

大家好,我们是红日安全-代码审计小组。最近我们小组正在做一个php代码审计的项目,供大家学习交流,我们给这个项目起了一个名字叫PHP-Audit-Labs。现在大家所看到的系列文章,属于项目第一阶段的内容,本阶段的内容题目均来自PHP SECURITY CALENDAR 2017。对于每一道题目,我们均给出对应的分析,并结合实际CMS进行解说。在文章的最后,我们还会留一道CTF题目,供大家练习,希望大家喜欢。下面是第二篇代码审计文章:

Day 2 - Twig

题目叫做Twig,代码如下:

漏洞解析

这一关题目实际上用的是PHP的一个模板引擎Twig,本题考察XSS(跨站脚本攻击)漏洞。虽然题目代码分别用了escape和filter_var两个过滤方法,但是还是可以被攻击者绕过。在上图第8行中,程序使用Twig模板引擎定义的escape过滤器来过滤link,而实际上这里的escape过滤器,是用PHP内置函数htmlspecialchars来实现的,具体可以点击这里了解escape过滤器,htmlspecialchars函数定义如下:

htmlspecialchars:(PHP 4, PHP 5, PHP 7) 功能:将特殊字符转换为HTML实体 定义:string htmlspecialchars(string$string,[int$flags = ENT_COMPAT | ENT_HTML401,[string$encoding = ini_get("default_charset"),[bool$double_encode = TRUE]])

第二处过滤在第17行,这里用了filter_var函数来过滤nextSlide变量,且用了FILTER_VALIDATE_URL过滤器来判断是否是一个合法的url,具体的filter_var定义如下:

filter_var:(PHP 5 >= 5.2.0, PHP 7) 功能:使用特定的过滤器过滤一个变量定义:mixed filter_var(mixed$variable,[int$filter = FILTER_DEFAULT,[mixed$options]])

针对这两处的过滤,我们可以考虑使用javascript伪协议来绕过。为了让大家更好理解,请看下面的demo代码:
我们使用payload:?url=javascript://comment%0aalert(1),可以执行alert函数:
实际上,这里的//在JavaScript中表示单行注释,所以后面的内容均为注释,那为什么会执行alert函数呢?那是因为我们这里用了字符%0a,该字符为换行符,所以alert语句与注释符//就不在同一行,就能执行。当然,这里我们要对%百分号编码成%25,因为程序将浏览器发来的payload:javascript://comment%250aalert(1)先解码成:javascript://comment%0aalert(1)存储在变量$url中(上图第二行代码),然后用户点击a标签链接就会触发alert函数。
实例分析

本次实例分析,我们选取的是Anchor 0.9.2版本,在该版本中,当用户访问一个不存在的URL链接时,程序会调用404模板,而这个模板则存在XSS漏洞,具体代码如下:

该代码在themes\default\404.php中,看第4行code标签中的current_url函数,我们可在anchor\functions\helpers.php文件中,看到current_url函数是由Uri类的current方法实现的,具体代码如下:
我们跟进到Uri类,在system\uri.php文件中,我们发现这里调用了static::detect方法(statci::是在PHP5.3版本之后引入的延迟静态绑定写法)。
在current方法下面,我们就可以找到detect方法,该方法会获取$_SERVER数组中的'REQUEST_URI'、'PATH_INFO'、'ORIG_PATH_INFO'三个键的值(下图第3-4行代码),如果存在其中的某一个键,并且符合filter_var($uri, FILTER_SANITIZE_URL)和parse_url($uri, PHP_URL_PATH),则直接将$uri传入static::format方法(下图第10-14行代码),具体代码如下:
我们跟进static::format方法,可以发现程序过滤了三次(下图第3-7行),但是都没有针对XSS攻击进行过滤,只是为了获取用户访问的文件名,具体代码如下:
由于没有针对XSS攻击进行过滤,导致攻击十分容易,我们来看看XSS攻击具体是如何进行的。
漏洞利用

我们构造payload如下:http://localhost/anchor/index.php/。根据上面的分析,当我们访问这个并不存在的链接时,程序会调用404模板页面,然后调用current_url函数来获取当前用户访问的文件名,也就是最后一个/符号后面的内容,所以最终payload里的部分会嵌入到 标签中,造成XSS攻击,效果图如下:

修复建议

这对XSS漏洞,我们最好就是过滤关键词,将特殊字符进行HTML实体编码替换,这里给出的修复代码为Dedecms中防御XSS的方法,大家可以在uploads/include/helpers/filter.helper.php路径下找到对应代码,具体防护代码如下:

结语

看完了上述分析,不知道大家是否对filter_var函数绕过有了更加深入的理解,文中用到的CMS可以从这里下载,当然文中若有不当之处,还望各位斧正。如果你对我们的项目感兴趣,欢迎发送邮件到[email protected]联系我们。Day2的分析文章就到这里,我们最后留了一道CTF题目给大家练手,题目如下:

题解我们会阶段性放出,如果大家有什么好的解法,可以在文章底下留言,祝大家玩的愉快!

相关文章

Anchor CMS 0.9.2: XSS

B. PHP代码审计-sprintf函数中的安全问题

在PHP代码审计中,对sprintf函数的安全问题进行探讨。sprintf与vsprintf相似,都是用于格式化字符串输出,但vsprintf在传参时使用数组,其余行为与sprintf相同。需要注意的是,sprintf具有自动类型转换功能。当格式与输入数据类型不匹配时,sprintf会自动截断输入。这就导致程序员可能忽视对特定格式的强制类型转换,使潜在危险的payload得以保留,最终可能引发安全问题,如WordPress SQL注入漏洞。

sprintf的format参数包含百分号%、美元符号$和单引号'。百分号用于识别格式模式的开始,后面的数字对应参数输入数据;美元符号和单引号开启padding模式,使用$'后的字符填充;长度参数规定输入数据长度,不足时使用填充字符;类型参数s表示字符串,d表示整数。在使用单引号时,为了正确处理字符串中的单引号,需要进行转义。

在不加$的情况下,单引号会被吞噬,无法正常带入参数。当同时存在$和单引号时,理解为开启padding模式,单引号被吞掉,导致单引号逃逸。使用$'两个字符的模式会吞掉单引号后面的两个字符,同样引发单引号溢出问题。

另一个值得关注的细节是,尽管%y格式无明确规定,但在sprintf中使用%y并不会报错,而是输出空值。这使得利用这一特性吞噬反转义符成为可能。

总结,除了宽字节问题和substr问题,了解如何通过格式化字符串吞噬单引号的技巧对于安全审计工作至关重要。在CMS系统不断成熟、数据库操作日趋规范的背景下,这些安全问题的识别和防范对于确保系统的安全性具有重要意义。

热点内容
安全的加密 发布:2025-03-09 19:53:25 浏览:56
python怎么注释多行 发布:2025-03-09 19:28:15 浏览:427
sql转换函数to 发布:2025-03-09 19:18:03 浏览:636
sql查询的艺术 发布:2025-03-09 19:17:30 浏览:899
怎么在服务器上修改ip 发布:2025-03-09 19:17:21 浏览:868
linux限制连接数 发布:2025-03-09 19:17:21 浏览:186
水密码洗面奶怎么样 发布:2025-03-09 19:16:01 浏览:645
合金弹头加密版 发布:2025-03-09 19:11:49 浏览:723
房屋解压手续流程 发布:2025-03-09 18:56:50 浏览:1001
怎么切换python版本 发布:2025-03-09 18:52:43 浏览:556