代码审计总结

0x00 前言

最近在锻炼自己的代码审计能力,所以准备总结一下审计的方法和技巧。

0x01 漏洞类型

  • sql注入
  • xss
  • 文件包含
  • 文件上传
  • 反序列化
  • csrf
  • ssrf
  • 代码执行

0x02 sql注入

基本sql注入

对于基本的sql注入的审计,可以通过$_GET,$_POST等传参追踪数据库操作,也可以通过select , delete , update,insert 数据库操作语句反追踪传参。

主要注意查看有无过滤,有没有转义,有没有参数化。

宽字节注入

在关键部分经过转义等操作也不是完全高枕无忧了,如果代码中存在一些utf-8、gbk、big5等编码的函数,就很有可能被传入一些字符吃掉反斜杠,如%df’ and ‘ 1=1’,由于反斜杠是%5c,%df%5c在编码处理时组成了“運”这种情况,使过滤功亏一篑,所以在这些存在编码的位置,要分析并测试会不会引起上述问题。

httpheader的参数

有些系统可能会将referer,X_Forwarded_For还有cookie等参数传入数据库,一般的防注入系统考虑了get和post的参数值,而忽略了这些值的检测,并且这些值都是用户可以控制的,所以也要关注一下。

二次注入

攻击payload首先被Web服务器上的应用存储,随后又在关键操作中被使用,这就是二次注入。虽然我们在第一次注入的时候做了足够的过滤,但是第一次构造出可能在第二次调用时触发的payload引发注入,所以在重复利用输入的值的位置需要额外注意。

文件名注入

php.ini中配置安全策略可以隔绝相当一部分的sql注入,比如magic_quote_gpc=on开启之后,能实现addslshes()和stripslashes()这两个函数的功能,但是这些功能不会过滤因为$_FILE,$_SERVER之类的值

有些cms会把文件名name的值保存在数据库里,但又没有对name进行过滤,可能会造成注入,所以在有对文件名处理的位置,除了考虑文件上传漏洞,也不要忘记分析一下产生sql注入的可能。

0x03 xss

反射型xss

反射型xss审计的时候基本的思路都一样,通过寻找可控没有过滤(或者可以绕过)的参数,通过echo等输出函数直接输出。寻找的一般思路就是寻找输出函数,再去根据函数寻找变量。一般的输出函数有这些:print , print_r , echo , printf , sprintf , die , var_dump ,var_export。

存储型

存储型xss审计和反射型xss审计时候思路差不多,不过存储型xss会在数据库中转一下,注意审计sql语句update ,insert更新和插入。

DOM

基于DOM的跨站脚本XSS:通过访问document.URL 或者document.location执行一些客户端逻辑的javascript代码。不依赖发送给服务器的数据。

审计DOM型XSS时,关注输入可以影响的document.URL等位置。

0x04 文件包含

PHP的文件包含可以直接执行包含文件的代码,包含的文件格式是不受限制的,只要能正常执行即可。

文件包含分为本地包含和远程包含。

远程文件包含

服务器的php配置中选项allow_url_fopen与allow_url_include为开启状态时,服务器会允许包含远程服务器上的文件,会产生远程文件包含的问题,所以面对这种问题,着重看是否打开了这两个配置选项。

如果非要用到远程文件,在include() ; include_once() ; require();require_once()等代码的位置,要将文件名限制为固定值,完全无法被用户控制。

本地文件包含

本地文件包含要查看的代码段和远程文件包含一样,主要查看
include() ; include_once() ; require();require_once()这四个函数的位置,要着重查看参数是否外部可控,尽量使其固定。

如果必须要求可控的话,查看是否经历了白名单验证文件名,或者通过函数过滤了危险的字符如“../”。

0x05 文件上传

文件上传漏洞需要审计的部分是上传函数

1
move_uploaded_file();

在这个函数周围,要查看是否后端检查,检查的是后缀,文件头,还是content-type。如果检查的是文件头和content-type,即

1
2
getimagesize()
mime_content_type()

等就会产生风险。
还要检查是黑名单过滤还是白名单过滤,如果是黑名单过滤,则要检查是否过滤全面了(大小写等)。

如果代码中没有将文件名整体重命名的函数,建议在这里加一个提升安全性。

除了代码中需要检查的部分,还要检查服务器的配置文件和php插件php-cgi等,以及服务器版本是否存在解析漏洞。

ps:文件上传这里,比起代码审计更好的方式是采取黑盒测试。

0x06 反序列化

php反序列化的审计,主要是查找 unserialize();函数的位置。

观察unserialize();函数的参数是否是用户可控的,如果可控就很容易被利用,再观察对传入参数的过滤函数检查情况。

0x07 csrf

csrf跨站请求伪造漏洞审计时主要查看在登陆后提交的代码部分,有没有通过token和referer对用户身份的合法性进行验证。还有整体有没有设置跨域权限。

0x08 ssrf

对于ssrf服务端请求伪造的审计,主要去找curl命令等接收远程请求的位置有没有过滤返回信息,验证远程服务器对请求的响应,查看有没有禁用不需要的协议。

0x09 代码、命令执行

首先来说一下命令执行,命令执行就是调用系统命令cmd或者应用指令bash,审计的时候去找会执行命令的函数:

1
2
3
4
5
6
7
system()
exec()
shell_exec()
passthru()
pcntl_exec()
popen()
proc_open()

然后查看这些位置有没有严格的过滤规则。

代码执行漏洞会将可执行代码放在webservice中执行,审计代码执行漏洞时,可以去寻找php中将字符串转换成代码并执行的函数,主要去搜索

1
2
3
4
5
6
eval()
asset()
preg_replace()
call_user_func()
call_user_func_array()
array_map()

然后查看这些位置有没有严格的过滤规则。

0x10 总结

上述这些漏洞的原理都基本写过一遍,大部分也做了复现,所以这里不再详细解释,只是整理一下审计过程中需要注意的位置,留作笔记。

顺便送上两张代码审计的思维导图

php代码审计导图:
https://github.com/echohun/tools/blob/master/%E5%AE%89%E5%85%A8%E6%80%9D%E7%BB%B4%E5%AF%BC%E5%9B%BE/PHP%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%84%91%E5%9B%BE.png

python代码审计导图:
https://github.com/echohun/tools/blob/master/%E5%AE%89%E5%85%A8%E6%80%9D%E7%BB%B4%E5%AF%BC%E5%9B%BE/Python%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%84%91%E5%9B%BE.jpg

代码审计的溢出导图:
https://github.com/echohun/tools/blob/master/%E5%AE%89%E5%85%A8%E6%80%9D%E7%BB%B4%E5%AF%BC%E5%9B%BE/%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E7%9A%84%E6%BA%A2%E5%87%BA%E8%84%91%E5%9B%BE.png

fork me on github