php代码审计
sql注入
来自 梅子酒师傅的 《对PHP类CMS审计的一点总结》
如果使用了框架,可以分辨一下框架名称以及版本,去搜索一下该版本的框架是否存在漏洞,如果存在再去cms中验证。因为本篇文章主要讲我自己在cms审计上的一些经验,因此不多深入框架的审计部分。
如果没有使用框架,则需要仔细的观察数据库函数,一般来说,cms是将select、insert等函数进行了封装的,比如$db->table(‘test’)->where(“name=admin”)便是 select * from test where name=admin这种格式,而此时若是发现cms使用的是过滤+拼接,那么很有可能会出现问题,而如果使用了PDO,则继续跟进涉及到table,order by等字段的拼接去,因为这些字段是无法使用PDO的。
审计要素:
参数是否用户可控
是否使用了预编译
那么首先,如果没有使用框架封装的sql语句,那么全局搜索insert、select等sql语句关键词,然后定位到具体的语句,然后查看里面有没有拼接的变量,回溯可不可控。如果可控并且存在字符串拼接,很有可能就存在漏洞。
使用了框架的就是搜索的关键词不一样,还是得看是否存在字符串拼接,可不可控。
即使使用了预编译,但是如果在预编译之前字符串拼接了,那照样没有鸟用,该注入还是能注入。
下面提供一般我会搜索的关键词(框架的根据你审计项目的框架的手册,自行搜索。)师傅们有想补充的也可以补充。
insert
create
delete
update
order by
group by
where
from
limit
desc
asc
union
select
6.2.2. xss漏洞
审计要素
是否存在全局参数过滤器,过滤规则是否符合安全要求,是否存在需过滤和不需过滤两种输出,页面是否控制恰当。
输出时是否进行编码(HTML、JS等)。
前端是否采用了Angularjs、React、vue.js等具有XSS防护功能的前端框架进行数据输出。
这个的话,我就不会关键词搜了,我就是会在寻找其他漏洞的过程中,注意有没有直接把输入原样输出的地方,也没有特别关注这一块。
如果想特意挖掘这一块,可以
查看是否配置了全局的拦截器、过滤器。检查数据输出函数,例如常用的输出函数有print、print_r、echo、printf、sprintf、die、var_dump、var_export。
6.2.3. CSRF漏洞
与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。
审计要素
是否在表单处存在随机token。
是否存在敏感操作的表单。
CSRF主要利用场景实际上是一些越权的操作,或者一些敏感功能存在的地方,例如管理后台、会员中心等地方。我们可以尝试搜索表单位置,查看是否会生成随机token,在查看后端代码中是否会先验证这部分的token。如果没有验证token,再进一步看看是否有refer的相关验证,如果没有,那么就存在CSRF的问题。
可以尝试全局搜索
csrf-token
csrf_token
csrftoken
csrf
下面是一个更新密码的操作,假设构造一个链接为 http://127.0.0.1/index.php?password_new=password&password_conf=password&Change=Change#的链接,直接发送给受害者点击,那么当前情况下,可以直接修改受害者的密码,因为没有进行任何的验证措施。当然一般代码不会这么写,只是拿DVWA的CSRF举个例子。
6.2.4. SSRF漏洞
ssrf是利用存在缺陷的web应用作为代理攻击远程和本地的服务器。常见的方式如下:
1.可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务的banner信息;
2.攻击运行在内网或本地的应用程序(比如溢出);
3.对内网web应用进行指纹识别,通过访问默认文件实现;
4.攻击内外网的web应用,主要是使用get参数就可以实现的攻击(比如struts2,sqli等);
5.利用file协议读取本地文件等。
审计要素:
是否存在可以产生SSRF漏洞的函数。
是否存在内网ip地址正则过滤,且正则是否严谨。
是否存在限制请求的方式只能为HTTP或者HTTPS。
当然PHP底下经常可能会出现SSRF漏洞的主要有几个函数,它们分别是file_get_contents()、fsockopen()、curl_exec()、get_headers()。通过全文关键函数搜索,在看是否限制了访问端口,访问协议,内网ip地址等。
利用file://、http/https:// 、dict://、gopher://协议去搞内网。
列一下,我经常搜索的关键词
file_get_contents
fsockopen
curl_exec
get_headers
fopen
readfile
注意
一般情况下PHP不会开启fopen的gopher wrapper
file_get_contents的gopher协议不能URL编码
file_get_contents关于Gopher的302跳转会出现bug,导致利用失败
curl/libcurl 7.43 上gopher协议存在bug(%00截断) 经测试7.49 可用
curl_exec() //默认不跟踪跳转,
file_get_contents() // file_get_contents支持 php://input协议
各种绕过,我就不在这说了。
6.2.5. XML外部实体注入
审计要素
参数是否用户可控
是否libxml版本为2.9.0以上
是否禁用了外部实体
这个一般我关注的少,仅仅是搜索“DOMDocument”,“SimpleXMLElement”和“simplexml_load_string”等关键词,分析下是否存在参数拼接的XML字符串,或未做限制的批量解析方法。对参数进行回溯,判断其是否用户可控。
差不多就没啥了。
6.2.6. 文件包含漏洞
审计要素
参数是否用户可控
是否存在include,require,include_once, require_once等函数。
文件包含算是拿shell最快的方法了,所以一般要重点关注。
无非是include,require,include_once, require_once这四个函数,全局搜索这四个函数,一个一个去看,去回溯,查看变量可不可控。
6.2.7. 文件上传漏洞
审计要素
是否检查了上传文件的文件类型
是否限制了文件上传路径
是否对文件进行了重命名
文件大小是否限制
是否返回了文件路径或文件路径很好猜测
有的项目,会对文件上传下载进行分装,所以可以全局搜索有关upload、file的函数,看看是不是封装了
function upload
function file
如果封装了,那么就看这些封装好的函数,有没有上面提到的审计要素的漏洞。
如果没封装,一般是move_uploaded_file这个函数,全局搜索,这个函数,回溯查看这些漏洞存不存在。(白盒黑盒一起搞比较好。)
6.2.8. 变量覆盖
审计要素
是否存在造成变量覆盖的函数,例如:extract()、parse_str()、import_request_variables和$$等。
是否存在可以完整利用的攻击链。
一般就这几个函数和关键词
extract
parse_str
import_request_variables
mb_parse_str
$$
不过还有个特殊的配置,也可能造成变量覆盖
下面的部分来自mi1k7ea师傅PHP变量覆盖漏洞
register_globals全局变量覆盖
php.ini中有一项为register_globals,即注册全局变量,当register_globals=On时,传递过来的值会被直接的注册为全局变量直接使用,而register_globals=Off时,我们需要到特定的数组里去得到它。
注意:register_globals已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。
当register_globals=On,变量未被初始化且能够用户所控制时,就会存在变量覆盖漏洞:
“;
if ($a) {
echo “Hacked!”;
}
?>
通过GET和POST方式输入变量a的值:
当然,也可以从COOKIE中输入:
6.2.9. 代码执行漏洞
审计要素
php.ini文件中的disable_function是否有禁用函数。
是否存在代码执行的敏感函数。
是否输入变量可控。
全局搜索下面的关键词,回溯参数可不可控。
eval
asser
preg_replace
create_function
array_map
call_user_func
call_user_func_array
array_filter
usort
uasort
$a($b)(动态函数)
6.2.10. 命令执行漏洞
审计要素
参数是否用户可控
是否配置了全局过滤器,过滤规则是否符合安全规范
是否所有的命令执行参数都经过了过滤器,或受白名单限制
全局搜索下面的关键词,回溯参数可不可控。
exec
passthru
proc_open
shell_exec
system
pcntl_exec
popen
“(被反引号包裹的变量也可以执行)
6.2.11. 任意文件下载/下载漏洞审计
审计要素
是否存在../、.、..\等特殊字符过滤。
参数是否用户可控
是否配置了相对路径或者绝对路径。
查询这些关键词,查看变量是否可控,是否有过滤
fgets
fgetss
file_get_contents
readfile
parse_ini_file
highlight_file
file
fopen
readfile
fread
Tip:前两天遇到个,过滤了config/database.php这样的正则匹配,还过滤了..,目的是防止目录穿越,读取服务器其他目录的文件,可是没过滤一个.
这样我使用config/./database.php绕过了正则,照样把敏感文件读取出来了。。。
6.2.12. 任意文件删除
和上面的下载一样
搜索的关键词变了
rmdir
unlink
6.2.13. 任意文件写入
还是一样,关键词为
copy
file_put_contents
fwrite
6.2.14. 会话认证漏洞
会话认证漏洞实际上涉及的方面比较广,如cookie、session、sso、oauth等,当然这个漏洞比较常见是在cookie上,服务端直接取用cookie中的数据而没有校验,其次是cookie加密数据在可预测的情况下。
审计要素
是否cookie中的加密数据可预测。
是否cookie中的数据可预测。
服务端是否只依赖cookie来判断用户身份。
全局去寻找cookie生成的逻辑,判断是否可预测,判断用户身份是否只依赖cookie,而不是随机的,比如
鉴权是只通过cookie中的userid来判断,如果我遍历userid,可以达到登录绕过或越权的目地。
6.2.15. 反序列化漏洞
一般实际审计的时候,项目中见的比较少,框架中见的比较多。
全局搜索serialize。看看存不存在可控变量。
很早之前写过这个系列的小结
序列化(一)利用-phar-拓展-php-反序列化漏洞攻击面
序列化(二)session反序列化
序列化(三)原生类反序列化
0x07 参考
对PHP类CMS审计的一点总结
http://www.oriole.fun/index.php/archives/69/
PHP变量覆盖漏洞小结
还有狼组wiki中的文章
0x08 总结
这篇文章,就是自己总结下审计的流程,或许有很多不足、缺漏,希望师傅们谅解及指正。
审计是一件很难一概而论的事情,有时会很枯燥,看代码看的头疼,但自己找到0day的感觉,是非常不一样的,加油吧,师傅们。
原文地址
https://www.chuanpuyun.com/article/5966.html