php代码审计
前言
官方文档:php.net
php官方文档是非常详情,好用的,在遇到不清楚作用的函数时可以进行查询
白盒测试做代码审计最主要的知识是要去了解一个漏洞应该有哪些防御方式,因为大部分的漏洞都是因为修复没有做的全面,或者修复没有考虑到一些情况导致漏洞。
MVC:
C:分发处理请求网站的逻辑
M:处理和数据库相关的操作
V:显示给用户的内容
代码审计流程
正向查找流程
a. 从入口点函数出发(如index.php)
b. 找到控制器,理解URL派发规则(URL具体映射到哪个具体的代码里)
c. 跟踪控制器调用,以理解代码为目标进行源代码阅读
d. 最终在阅读代码的过程和尝试中,可能发现漏洞
本质:程序员疏忽或逻辑问题导致漏洞
特点:
- 复杂:需要极其了解目标源码的功能与框架
- 跳跃性大:涉及M/V/C/Service/Dao等多个层面
- 漏洞的组合:通常是多个漏洞的组合,很可能存在逻辑相关的漏洞
反向查找流程
a. 通过危险函数,回溯可能存在的漏洞
1. 查找可控变量
2. 传递的过程中触发漏洞
特点:
- 与上下文无关
- 危险函数,调用即漏洞
代码审计工具功能大多就是这个原理
双向查找流程(手动审计主要方式)
- 略读代码,了解框架(正向流程,如:网站都有哪些功能,什么样的架构如mvc:它的m在哪v,c在哪,用了什么模板引擎,是否用了orm(如果使用了ORM那么sql注入就很少了,如果没用是手工写的sql语句,可以关注是否存在sql漏洞)等...)
- 是否有全局过滤机制
- 有:是否可以绕过
- 可以:寻找漏洞触发点(反向查找流程,找危险函数)
- 不可以:寻找没有过滤的变量
- 没有:那么就看它具体是如何处理的,具体代码具体分析
- 有处理:寻找遗漏的处理点(如忘记处理的地方或者处理不太正确的地方)
- 完全没有处理:可以挖成筛子(很少)
- 有:是否可以绕过
3.找到了漏洞点,漏洞利用是否有坑
根源:理解程序执行过程,找寻危险逻辑
特点:
高效:如挖隧道,双向开工,时间减半(不需要去完全理解网站内部原理和函数作用)
知识面广:需要同时掌握正向,反向挖掘技巧,并进行结合
以及所有正向,反向的优点
SQL注入漏洞挖掘技巧
PHP+mysql链接方式有:
mysql(废弃,但老的仍然有)
mysqli
PDO
sql注入常见过滤方法:
intval: 把用户输入的数字后面的所有不是数字的都过滤掉
addslashes: 把 ' 前加\转义掉
mysql_real_escape: 和第二个类似,但会考虑用户输入和mysql的编码,避免像宽字节注入问题
mysqli_escape_string / mysqli_real_escape_string / mysqli::escape_string (和mysqli搭配使用,和前面的功能类似)和他们的差别是会主动加引号包裹
PDO: quote
参数化查询
常见注入过滤绕过方法:
intval:不知道
addslashes / mysql_real_escape
1.宽字节注入
2.数字型sql语句
3.寻找字符串转换函数(传入编码好的字符绕过过滤,在后面被转换成sql语句)
urldecode
base64_decode
iconv
json_decode
stripshasles
simple_xml_loadstring
例如:传入id被过滤但后面有一处代码是解码base64,所以我们可以传入 ' 的base64编码绕过
<?php
$id = addslashes($_GET['id']);
....
$id = base64_decode($id);
....
$sql = "select * from flag where id = '$id'";
?>
mysqli::escape_string // PDO::quote
1.宽字节注入
参数化查询
1.寻找非sql值的位置
开发者容易遗漏得输入点
-
HTTP头
a. X-Forwarded-For
b. User-Agent
c. Referer
-
PHP_SELF(访问的页面url名,但用户可控)
-
REQUEST_URI(用户请求得完整路径)
-
文件名 $_FILES[][name]
-
php://input (post穿进去得内容)
引入单引号(转义符)的方法('号被过滤,看后面有没有可以引入的地方)
stripslashes
base64_decode
urldecode
substr
iconv
str_replace('0','',$sql)
xml
json_encode
任意文件操作
PHP上传的文件会被保存在$_FILES下
PHP文件操作函数汇总
- 文件包含
- include/require/include_once/require_once/spl_autoload
- 文件读取
- file_get_contents/fread/readfile/file/ highlight_file/show_source
- 文件写入
- file_put_contents/fwrite/mkdir/fputs
- 文件删除
- unlink/rmdir
- 文件上传
- move_uploaded_file/copy/rename
文件上传漏洞
文件上传流程:
-
检查文件大小,后缀,类型
-
检查文件内容(如文件头,尾等)
-
提取文件后缀
-
生成新文件名
-
将上传临时文件拷贝到新文件名位置
文件上传逻辑常见错误
- 只检查文件类型不检查文件后缀
- 文件后缀黑名单有遗漏
- 使用原始文件名,导致\0截断(一般没有了)
- 前端检验
文件包含漏洞
首先明确一点,文件包含漏洞不等于文件读取漏洞
危害:文件读取 / 代码执行
常见位置:模板文件名(切换模板)
语言文件名(切换语言)
常见利用:
要寻找可被包含利用的文件:上传文件,临时文件,Session文件,日志文件
后缀无法控制的情况:\0截断,协议利用
PHP5.3.4+ 对包含\0的文件操作函数进行了限制,基本上没有了
案例:
Metinfo 5.3.10版本Getshell漏洞
可控制的部分:include $file . '.php';
http协议利用:http://xxxx.com/1.php (远程文件包含,一般不开设置不能用)
PHP协议利用:zip/phar
制作2.php的压缩包 -> 2.zip -> 改后缀为 -> 2.jpg
在服务器中上传2.jpg文件
再利用:zip://var/www/upload/head/2.jpg#2.php (#意思是访问zip内部的子文件->2.php)
文件删除漏洞
危害:
删除服务器任意文件,DOS服务器
删除安装锁文件,导致目标环境可被重新安装
重新安装 -》任意重置管理员密码
案例
上传新头像会把老头像自动删除,但可以把删除老图像的地址换成别的造成任意文件删除
命令执行
命令执行指的是执行系统命令 (ls)
可以在这个网站查询复制命令的意思
代码执行指的是PHP的代码执行
本质:用户输入无过滤,拼接到了系统命令中
PHP命令执行函数:
- system
- passthru
- exec
- shell_exec
- popen (常见的就是上面这5种)
- proc_open
- pcntl_exec
- dl
要像命令执行很难,要先学会如何正确防御命令注入,才能分辨出哪些没有正确处理
防御PHP命令注入漏洞:
PHP中只能使用escapeshellcmd和escapeshellatg进行命令参数的过滤
- 先区分这2个函数:
escapeshellcmd
escapeshellatg
escapeshellatg没问题但escapeshellatg是只能限制逃逸不出单引号'但有些命令的不常用参数是可以任意命令执行
- 要把用户的输入放在值里
如果把输入直接是键值对可能会造成漏洞
grep {$query}
有一些命令的不常用参数可能会导致一些意外比。直接使用 | 等命令跳出前面的命令实现命令执行
修复:
grep -i {$query}
grep -- {$query}
XML实体注入漏洞
PHP XML解析函数
simplexml_load_file
simplexml_load_string
SimpleXMLElement
DOMDocument
xml_parse
如果发现有这几个函数的地方,基本上可以确定百分之80有xml实体注入
libxml_disable_entity_loader(true)来禁用掉外部实体的加载,就不存在xml实体注入
PHP中XXE漏洞逐渐减少,到现在的版本里几乎已经绝迹了,因为PHP XML操作依赖libxml库
但在libxml2.9.0+默认是关闭了xml外部实体解析开关的,可以顺势挖一下也比较简单
方法:暴力搜索就行,查看有没有xml解析函数,再看禁没禁止外部加载
无输出点的xxe漏洞:有时候可能存在xxe漏洞但并不会在页面中显示,要利用到blind-xxe
Blind XXE原理:
利用XML外部实体功能读取文件
利用XML外部实体功能发送HTTP请求
利用HTTP协议传递文件内容
前端漏洞:
建议代码审计不去主要找这种漏洞,进行黑盒测试就能挖到的漏洞,在代码审计过程中没必要太注重
百盒测试中可以关注前端漏洞类型:
XSS漏洞
CSRF漏洞
Jsonp劫持漏洞(前面三个关注多)
URL跳转漏洞(不多)
点击劫持漏洞(不多)
xss
在白盒测试中寻找XSS漏洞:
常见防护方法:
htmlspecialchars()把用户输入转义成html实体字符(这时候是绝对没有xss的)
strip_tags() 从字符中去除HTML和PHP标记
自动化FUZZ -》寻找输出函数(危险函数)
富文本XSS挖掘
什么是富文本:本质就是html,网站给你一个有很多功能的输入框
为什么出现富文本xss:
前面2种防护方法要么就是转义掉要么就是直接去除掉,但在一些写文章,或者发帖的需要提交html富文本,如果使用前面的方法那么提交的就不是富文本了,会影响业务。
常见富文本过滤方法:
会使用富文本的xss过滤器:把用户输入的恶意标签,属性去掉
黑名单(很难过滤掉该过滤的标签属性)
白名单
CSRF
在白盒测试中寻找CSRF漏洞:
检查Referer(来自于当前域名,可信域名,才会执行)
(可以看正则匹配全面吗,比如正则匹配xxx.nte后缀的域名,那么可以注册个cxxx.nte域名绕过)
检查Token
(寻找跨域漏洞,要去跨域请求某一个网站内容的时候需要先去请求这个网站有没有crossdomain.xml,
要根据这里面配置的信息来认证是否允许用户去发送一个跨站的请求)
Flash
Jsonp
CORS 黑盒测试就可以找到这三个
Jsonp劫持漏洞
在白盒测试中寻找Jsonp劫持漏洞:
Jsonp介绍:Jsonp是 json 的一种"使用模式" 可以让网页从别的域名(网站)那获取资料,即跨域读取数据;
它利用的是script标签的 src 属性不受同源策略影响的特性,使网页可以得到从其他来源动态产生的 json 数据,因此可以用来实现跨域读取数据。
更通俗的说法:JSONP 就是利用