0x00 前言
这片博文将简单的介绍我编写的 PHP 运行时漏洞检测系统 prvd 的检测逻辑, 以及该系统在实际测试中的效果。
0x01 基本知识
在这里我们先介绍几个常用的词语:
-
source数据来源点,可以是:
- 网络,例如常规的 Web 参数等
- 文件系统
- 数据库
- 等等其他用户可控或者间接可控的地方
-
filter数据过滤处理点,可以是:
-
编码解码,例如
base64_decode
等 -
常规字符串操作,例如
strtolower
等 -
安全过滤,例如
mysqli_escape_string
等 - 等等其他会更改字符串内容的地方
-
编码解码,例如
-
sink漏洞触发点,可以是:
-
操作文件相关行为,例如
file_put_content
等 -
操作网络相关函数,例如
curl
等 -
操作命令相关行为,例如
system
等 - 等等其他危险行为
-
操作文件相关行为,例如
有些地方既可以是 source 点,也可以是 sink 点,比如说 file_put_content
在参数可控的时候是 sink 点,因为返回的数据也是我们可控的,这里返回的数据也是 source 点。
0x02 xmark
我们先简单地介绍一下 xmark,这是一个 PHP7 扩展,能够直接使用 PHP 代码做到:
- 对字符串变量进行打标记
- Hook 绝大多数函数/类
- Hook 部分 opcode
基于 xmark 所提供的功能,即便是我们不熟悉 PHP 内部实现,我们也能够很简单的去实现:
- PHP RASP
- PHP 解密工具,例如 phpdecoder
- PHP 运行时漏洞检测
- …
因为 PHP 并不像 Python、Ruby 等其他语言可以很方便的 Hook 函数、类,所以我们开发了这么一个扩展来完成类似的功能。
实际上 xmark 这个项目有不少代码是直接拷贝 taint 的, 那为什么要改这样一个轮子呢?
- taint 的 source 点覆盖不全面,只对 GPC 进行标记
- taint 处理和漏洞相关的逻辑需要在 PHP 扩展中实现
这里我不打算花太多篇幅介绍 xmark 的实现,直接看代码更方便,更多关于 xmark 的信息可以点这里
0x03 prvd
前面说了基于 xmark 我们可以实现挺多好玩的事情, 这里我选择去完成一个 PHP 运行时漏洞检测系统,也就是 prvd 这个项目, 项目名也就是 PHP Runtime Vulnerability Detection 的缩写。
prvd 有两种模式,一种是 taint 模式, 另外一种是 payload 模式。taint 模式可以选择开启,payload 模式是一直都开启的。 这两种模式都依赖外部来解决执行路径的问题。
taint 模式
这种模式下 prvd 和 taint 一样,都是 source 打上一个标记,在某些 filter 中传递这个标记,然后在 sink 点检查对应的参数是否被打上标记。
比方说:
$_POST['cmd']
一开始就被我们打上了标记,在自赋值的时候将标记传递给了 $cmd1
, 在经历 strtolower
这个 filter 的时候继续将标记传递给了 $cmd2
, $cmd2
最后进入 sink 点 system
函数的时候被检测被打上了标记,从而确定是否可能存在问题。
taint 模式可以不需要输入特定的 payload 进行攻击就可能发现一些漏洞点,也不会污染数据,但是在 filter 中判断是否应该继续传递标记比较难处理, 有可能数据已经经过了很好的过滤,但是我们还是继续传递了标记,最终导致误报。也有可能数据处理不当,但我们已经去除了标记,最终导致漏报。
我们举个漏报的例子:
可控变量 $id
经过 mysqli_real_escape_string
的时候需不需清除其标记呢?
为了解决这种情况,我编写了另外一种 payload 模式。
payload 模式
有时候追踪执行流并没有什么用,整那么多玩意,还不如直接一把梭哈,直接把 payload 打过去,然后在 sink 点观测, 这就是我们的 payload 模式,这个模式的 prvd 可以归类为 IAST 的一种。
payload 模式相比 taint 模式,优点为:
- 误报率比 taint 模式低,使用 payload 模式,从技术上完全把误报率降低到 1% 以下
- 可以不关注 source 点和 filter 点,这样即使数据经历多次中转,最后经过 sink 点的漏洞,也有能力去检测,比如说多阶 SQL 注入的情况
缺点为:
- 漏报率可能会比 taint 模式下高,因为可能经过各种 filter 的时候就被 payload 就会拦截下来,也可能需要特定 payload 才能触发漏洞
- 需要特别关注 sink 点,在 sink 点中根据各种条件判断是否为漏洞
- 会污染数据
下面简单的介绍一下在 payload 模式下,各种漏洞的检测方法:
我知道上面的各种检测方式并不完美,每个漏洞的检测方法都有误报和漏报的情况,不过现阶段还是够用的,可以以后继续完善。
fuzzer
这里我使用 Python 写了一个比较简单的 fuzzer 放在项目 tools 目录下,目前也只是对每个 source 点增加一个 '"><xtanzi>./../xtanzi
这样的 payload
这个 fuzzer 的 DSN 地址为 http://admin:password@ip:9090/fuzz
这里也可以根据自己的情况,重新编写 fuzzer。
Sentry 漏洞展示
至此,我们还缺少一个漏洞上报的平台,我们希望这个平台能够:
- 良好的权限管理,拥有的 group、project 等功能
- 收集到漏洞触发时的请求信息
- 收集到漏洞触发时的堆栈信息
- 能够对多个同堆栈下的重复漏洞进行去重
- 能够一键提交 jira 以及 git issue
- 各种统计功能
- …
天啊,需求越来越多,我们的精力更多的被分配到了这个平台上了,请不要忘了我们本意是要做一个 PHP 运行时漏洞检测系统。 上报平台虽然重要,但不应该成为整套系统花费精力最多的部分,我们需要把时间放在漏洞检测这块。
这个时候我想起了 Sentry
Sentry is cross-platform application monitoring, with a focus on error reporting.
Sentry 本来是一个跨平台应用的异常报告系统,但在我们这套 PHP 运行时漏洞检测系统中被使用为漏洞上报平台了,理由是:
- 支持上面提到的需求
- 界面美观
- DRY
我们的 prvd 可以说是 Sentry 的一个检测漏洞的 Client,只不过 prvd 的功能不是报告异常,而是报告漏洞, 由于 Sentry 支持多种语言,所以我们不仅可以给 PHP 写这样一个 Client,还可以给 Python, Ruby 等其他语言写这样检测漏洞的 Client
0x04 实际例子
最后,我们拿 DedeCMS 作为测试例子,看看 prvd 的效果如何。
安装环境
首先在 dede/config.php
修改 csrf_check
函数让其直接返回 true,其次执行下面命令启动 fuzzer:
然后前往 Sentry 注册一个账号,或者自建一套 Sentry 服务
剩下的可以直接使用 docker
因为 taint 模式误报会比较多(taint 模式出来的漏洞在 Sentry 上会以蓝色标注),我也并不打算花时间去 review 详情,所以这里我只启用了 payload 模式。
检测过程
每个功能点都乱点一下,每个输入框都随便写写,尽量每个功能都能够瞎点瞎填覆盖到。
DedeCMS 相关漏洞
最后得出下面这些可疑的漏洞:
- dede_archives_do.php SQL 注入
- dede_article_add.php SQL 注入
- dede_article_keywords_make.php SQL 注入
- dede_article_test_same.php SQL 注入
- dede_pm.php SQL 注入
- dede_makehtml_rss_action.php SQL 注入
- dede_co_gather_start_action.php SQL 注入
- dede_co_export.php SQL 注入
- dede_co_do.php SQL 注入
- dede_content_batchup_action.php SQL 注入
- dede_makehtml_all.php SQL 注入
- dede_makehtml_archives_action.php SQL 注入
- dede_article_add.php 服务器端请求伪造
- dede_co_add.php 服务器端请求伪造
- …
虽然都只是后台的漏洞,但拿来做演示是最好不过了 :)
0x05 总结
上面简单的介绍了 prvd 的检测原理和使用过程。简单的说,prvd 就是一个半自动的 PHP 运行时漏洞检测系统, 在 taint 模式下,会尽可能显示可疑漏洞,方便熟悉安全的人员或者开发人员去 review 代码, 在 payload 模式下,即使不太了解安全的测试人员也能够检测出漏洞。
0x06 引用
- 上一篇:深入了解SQLMAP API
- 下一篇:如何构造基于浏览器的端口扫描器
猜你还喜欢
- 09-10PHP一些实用的自定义函数收集
- 12-06php 打包网站在线压缩为zip
- 08-03php 取出周一和周日的时间戳
- 09-10php入门教程
- 08-03PHP 数据类型
- 11-30浅谈PHP防注入
- 08-03PHP编程效率的20个要点
- 11-08PHP-Casbin: 支持ACL、RBAC、ABAC多种模型的PHP权限管理框架
- 04-08PHP开发规范
- 09-19浅谈PHP防注入
- 最新文章
- 随机文章
-
- 使用Burp拦截Flutter App与其后端的通信
- SRC漏洞挖掘实用技巧
- Javascript原型链攻击与防御
- 我如何通过Uber API接口劫持任意Uber注册账户
- Linux Sudo被曝漏洞,可导致用户以root权限运行命令
- Jenkins脏牛漏洞FRP内网提权
- ScoutSuite:一款针对云集群环境的安全审计工具
- 从宽字节注入认识PDO的原理和正确使用
- NDAY漏洞CVE-2017-11882新变异样本分析
- B2R2:一套针对二进制代码分析的实用算法、函数以及工具集
- 探究if条件语句引发的两个Web漏洞
- Apache Solr最新RCE漏洞分析
- 知名Web域名注册商披露数据泄露事件
- PHP-fpm 远程代码执行漏洞(CVE-2019-11043)分析
- 浅谈安全攻防场景下的安全检测
- Think CMF X任意内容包含漏洞分析复现
- 最后一个登录框引起的血案
- 十种注入技巧 | 通用性进程注入技巧研究
- 使用Burp拦截Flutter App与其后端的通信
- 存储型XSS的攻防:不想做开发的黑客不是好黑客
- 热门文章
-
- 九年专业安全团队承接渗透入侵维护服务
- Stuxnet纪录片-零日 Zero.Days (2016)【中文字幕】
- Emlog黑客站模板“Milw0rm”发布
- SQLMAP的注入命令以及使用方法
- 白帽故事汇:网络安全战士从来不是「男生」的专利
- 编辑器漏洞手册
- web安全之如何全面发现系统后台
- 常见Web源码泄露总结
- 深入理解JAVA反序列化漏洞
- cmseasy前台无需登录直接获取敏感数据的SQL注入(有POC证明)
- 网站后台登陆万能密码
- 黑客怎样简单入侵别人手机,黑客是如何入侵手机的?
- 黑麒麟2016渗透培训系列教程
- 破解emlog收费模板“Begin”
- 那些强悍的PHP一句话后门
- Android平台渗透测试套件zANTI v2.5发布(含详细说明)
- 渗透工具BackTrack与KaliLinux全套视频教程
- Python列为黑客应该学的四种编程语言之一 初学者该怎么学
- CVE-2017-11882漏洞复现和利用
- 恶意程序报告在线查询工具
- 文章标签
-