php代码审计备忘录

php代码审计实施要点

代码\审计工具

工具 介绍
seay源代码审计系统 免费的,支持5.4一下版本代码审计,不要太依赖自动审计,能发现太少
Fortify SCA 商业化工具,需要破解,需要规则库
Rips 老工具,使用前要看支持情况,好处是linux下可以使用
burp suite 验证漏洞工具

总体来说fortify审计结果更加精准,如果对自己没信心,更多依赖fortify

PHP测试环境搭建

使用phpstudy8.0,可快速完成PHP环境搭建

PHP代码调试

代码审计中调试是最重要的技能之一。php调试方式有很多,如果仅仅是为了做安全性测试查看变量值,可以使用echo输出到浏览器,或者使用seay工具自带的代码调试功能,php自带的调试功能对我们来说使用较少,且php代码调试较为简单,不在过多描述

代码审计思路

php代码审计通常有三种思路

  1. 检查敏感函数的参数,然后回溯变量,判断变量是否可控并且没有严格过滤
  2. 找出哪些代码文件接收外部传入的参数,然后跟踪变量传递过程,观察是否有变量传递到高危的函数里,或者传递过程是否存在有代码逻辑漏洞的地方
  3. 直接挖掘功能点漏洞,可以通过正则搜索自己关心的功能的高危函数

sql注入

由于开发者编码的时候对用户输入未进行过滤且把用户输入直接拼接在SQL查询语句中导致数据泄露,或使攻击夺取网站管理权限,甚至服务器沦陷。形成条件:

1.对用户输入不进行过滤
2.动态构造SQL语句,后端编码时把用户输入的数据直接拼接在SQL语句中

sql注入需要关注的关键字

select from 数据库查询
mysql_connect 数据库连接
mysql_query 数据库请求
mysql_fech_row 数据库请求
update,insert,delete 增删改
urldecode、rawurldecode 二次urldecode注入函数,比如我们提交id=1%2527,webserver第一次解析式id=1%27,urldecode第二次解析就会变成id=1‘.造成单引号引入引发注入

示例:

#略

防范手段

使用intval()、mysql_real_escape_string()、addslashes()等函数过滤用户的一切输入
magic_quotes_gpc PHP4.3以前可以在任何配置文件代码中开启
magic_quotes_runtime PHP4.3以前可以在任何配置文件代码中开启
PDO prepare php<5.3.6版本使用此函数依然存在宽字节注入,产生条件需要配合set names “gbk”

XSS漏洞

挖掘XSS漏洞关键在于寻找没有被过滤的的参数,且这些参数传入到输出函数

xss输出函数关键字

扫描二维码关注公众号,回复: 15269114 查看本文章
print 输出字符串
print_r 打印变量
echo 输出一个或多个字符串
var_dump 打印变量的相关信息
var_export 输出或返回变量中的字符串
die 函数输出一条消息,并退出当前脚本
printf
sprintf

防范手段

htmlspecialchars() 用于转义处理在页面上显示的文本
htmlentities() 用于转义处理在页面上显示的文本。
strip_tags() 过滤掉输入、输出里面的恶意标签。
urlencode() 函数 用于输出处理字符型参数带入页面链接中。
intval() 函数 用于处理数值型参数输出页面中。

CSRF审计

CSRF需要了解项目大致代码结构,找出和后台及核心模块相关的功能代码,然后查看是否有缺失token referer相关验证代码,然后黑盒判断不需要token和referer可以请求和返回同样的数据,则判断可能存在CSRF漏洞

  1. 后台功能模块:管理后台/会员中心/添加用户等。
  2. 被引用的核心文件里面有没有验证token和referer相关的代码
  3. 没带token:可以直接请求这个页面。
  4. 没带referer:返回相同的数据

防御手段

服务器端:
  1、One-Time Tokens
  2、增加验证码
3、新增Samesite属性

samesite属性介绍

如果SamesiteCookie被设置为Strict,浏览器在任何跨域请求中都不会携带Cookie,新标签重新打开也不携带,所以说CSRF攻击基本没有机会。
如果SamesiteCookie被设置为Lax,那么其他网站通过页面跳转过来的时候可以使用Cookie,可以保障外域连接打开页面时用户的登录状态。但相应的,其安全性也比较低。
SamesiteCookie目前有一个致命的缺陷:不支持子域。例如,种在topic.a.com下的Cookie,并不能使用a.com下种植的SamesiteCookie。这就导致了当我们网站有多个子域名时,不能使用SamesiteCookie在主域名存储用户登录信息。每个子域名都需要用户重新登录一次。
总之,SamesiteCookie是一个可能替代同源验证的方案,但目前还并不成熟,其应用场景有待观望。

文件包含漏洞

文件包含分为本地文件包含与远程文件包含,文件包含漏洞大多出现在模块加载、模板加载以及cache调用的地方,比如传入模块参数,另外就是直接搜索include()等函数回溯变量看看是否可控

函数 说明
include()
include_once()
require()
require_once()

文件读取/下载漏洞

前提条件:在读取文件的时候,将被读取文件设置为变量,通过动态变量来引入需要读取的文件时,用户对变量的值可控

关键字:file_get_contents()、highlight_file()、fopen()、readfile()、fread()、fgetss()、parse_ini_file()、show_sorce()、file()

文件上传漏洞

直接搜索move_uploaded_file(),再去看调用这个函数的代码是否有上传格式校验措辞,以及校验措施是否可以绕过即可

关键字:move_uploaded_file()

任意文件删除漏洞

在删除文件的时候,将被删除文件设置为变量,通过动态变量来引入需要删除的文件时,用户对变量的值可控

关键字:unlink()

任意文件写入漏洞

在写入文件的时候,将被写入文件内容设置为变量,通过动态变量来引入需要写入的文件时,用户对变量的值可控而

关键字:fwrite(),file_put_contents()

代码命令执行漏洞

web 应用代码中,允许接收用户输入一段代码,之后在 web 应用服务器上执行这段代码,并返回给用户。由于用户可以自定义输入一段代码,在服务器上执行,所以恶意用户可以写一个远程控制木马,直接获取服务器控制权限,所有服务器上的资源都会被恶意用户获取和修改,甚至可以直接控制数据库

关键字:

1、eval
2、assert
3、preg_replace
4、create_function
5、array_map
6、call_user_func
7、call_user_func_array
8、array_filter
9、usort
10、uasort

命令执行漏洞

代码执行漏洞指的是可以执行PHP脚本代码,命令执行漏洞指的是可以执行系统或者应用指令,直接在代码里搜索相关函数,然后判断变量是否可控即可

关键字:

system();
exec();
passthru();
shell_exec();
popen();
proc_open();
pcntl_exec();

变量覆盖漏洞

是变量覆盖指的是用我们自定义的参数值替换程序原有的变量值,通常来说,单独的变量覆盖漏洞很难有利用价值,需要和其他漏洞结合起来才能完成攻击。通过搜索$$符号去挖掘相关漏洞,搜索extract(),parse_str()以及import_request_variables()函数,追溯变量是否可控等。

$$使用不当

也就是PHP动态变量,是指一个变量名的变量名可以动态的设置和使用,一个变量获取另一个变量的值作为这个变量的变量名。

extract() 函数从数组中将变量导入到当前的符号表。也就是将数组展开,键名作为变量名,元素值为变量值。在下列案例中,a为变量名,test为变量值

parse_str()变量覆盖

import_request_variables()该函数的第二个参数用于设置注册变量的前缀,若当第二个参数未进行设置,将会出现覆盖全局变量的情况
在这里插入图片描述
在这里插入图片描述

越权漏洞

越权漏洞是指应用在检查授权时存在纰漏,使得攻击者在获得低权限用户账户后,利用一些方式绕过权限检查,访问或者操作其他用户或者更高权限。越权漏洞的成因主要是因为开发人员在对数据进行增、删、改、查询时对客户端请求的数据过分相信而遗漏了权限的判定。越权访问漏洞主要分为水平越权访问和垂直越权访问。

代码分析
在代码中可以看到,出现了POST[id],大家都知道POST过来的数据,用户都是可控的,这就意味着POST任意的ID,进而导致别人的用户被修改,系统首先接受了POST[id]的值,在经过过滤,赋值给clean_user_id,然后直接把clean_user_id带入到SQL语句中执行,并没有判断这个id是不是当前的,因此我们可以提交POST数据,通过控制id参数,来访问访问其他用户(图挂了)。

反序列化漏洞

序列化-serialize():
把对象转换为字节序列的过程称为对象的序列化

反序列化-unserialize():
把字节序列恢复为对象的过程称为对象的反序列化

反序列化对象中存在魔术方法,而且魔术方法中的代码可以被控制,漏洞根据不同的代码可以导致各种攻击。

反序列化漏洞的本质是:unserialize函数的变量可控,php文件中存在可利用的类,类中有魔术方法。
魔术方法(关键字):
_construc(),_destruct(),_call(),_callStatic(),_get(),_set(),_isset(),_unset(),_sleep(),_wakeup(),_toString(),_invoke(),_set_state(),_clone(),_debuginfo()

如果服务器能够接收我们反序列化过的字符串、并且未经过滤的把其中的变量直接放进如下这些魔术方法里面的话,就会容易造成反序列化漏洞:

__construct():当一个对象创建时被调用;

destruct():当一个对象销毁时被调用;

__toString():当一个对象被当作一个字符串使用;

sleep() :在对象在被序列化之前运行;
__wakeup():将在序列化之后立即被调用。

XML注入漏洞

XML注入漏洞是指XML外部实体注入漏洞,又名XXE漏洞。XXE(XML External Entity),在应用程序解析XML输入时,当允许引用外部实体时,可以构造恶意内容导致读取任意文件或SSRF、端口探测、DoS拒绝服务攻击、执行系统命令、攻击内部网站等

关键字:simplexml_load_string() #此函数在高版本中已修复,但低版本中还存在此问题

PHP运行环境安全检查

运行环境安全顾名思义,就是检查配置项,检查启动权限等(这属于加固范畴),这里仅仅说下配置项安全

配置项 描述
open_basedir 使用open_basedir选项能够控制PHP脚本只能访问指定的目录,这样能够避免PHP脚本访问不应该访问的文件,一定程度上限制了phpshell的危害,一般设置为只能访问网站目录。open_basedir = D:/usr/www
allow_url_fopen 此选项可通过 URL 形式的 fopen 封装协议使得可以访问 URL 对象例如文件。默认的封装协议提供用 ftp 和 http协议来访问远程文件,PHP中allow_url_fopen默认开启,若应用服务不需要用到远程读取操作,建议关闭。allow_url_fopen = Off
allow_url_include 此选项允许有以下功能使用URL识别的fopen封装:包括,includeinclude_oncerequirerequire_once**。此设置要求allow_url_fopen选项要开启。从PHP5.2开始allow_url_include默认关闭。allow_url_include = Off
safe_mode_exec_dir 此选项能控制 PHP可调用的外部命令的目录,如果 PHP 程序中有调用外部命令,那么指定外部命令的目录,能控制程序的风险。若需要执行某些程序,可指向单独的目录,将执行程序拷贝到目录中即可。建议不要执行任何程序,直接指向网页目录。safe_mode_exec_dir = D:/phpstudy/www
magic_quote_gpc 此选项开启后自动实现addslshes()和stripslashes()这两个函数的功能。会对每一个通过GET、POST、COOKIE方式传递的变量自动转换。但无法对数值类型过滤,所以当开启此选项后,建议对数值类型变量使用intval函数强制转换。magic_quotes_gpc=On,PS:magic_quotes_gpc在PHP5.4之后版本被移除
register_globals 此选项开启后PHP中提交的变量,包括使用POST或者GET提交的变量,都将自动注册为全局变量,能够直接访问,这是对服务器非常不安全。建议关闭。register_globals = Off
safe_mode 此选项被开启后,可控制PHP高危函数,比如system。同时会把很多文件操作函数进行权限控制。建议开启。safe_mode = On PS:在php5.3以上版本,safe_mode被弃用,在php5.4以上版本,则将此特性完全去除了。
session_use_trans_sid 此选项被开启后,可控制PHP高危函数,比如system。同时会把很多文件操作函数进行权限控制。建议开启。safe_mode = On PS:在php5.3以上版本,safe_mode被弃用,在php5.4以上版本,则将此特性完全去除了。
display_errors 此选项开启后,PHP 将输出所有的错误或警告信息,攻击者能利用这些信息获取 web 根路径等敏感信息建议关闭活限制错误信息显示级别。关闭错误信息提示:display_errors = Off限制错误信息显示级别(只显示警告以上的错误信息):error_reporting = E_WARNING & E_ERROR
expose_php 此选项开启后,那么由 PHP 解释器生成的每个响应都会包含主机系统上所安装的 PHP 版本。了解到远程服务器上运行的 PHP 版本后,攻击者就能针对系统枚举已知的盗取手段,从而大大增加成功发动攻击的机会。建议关闭。expose_php = Off
disable_functions 此选项开启后,可将不需要使用到的高危函数禁止,提高安全性。disable_functions = phpinfo,exec,system,passthru,popen,pclose,shell_exec,proc_open,dl,curl_exec,multi_exec,chmod,gzinflate,set_time_limit
log_errors 开启此选项后会把错误信息记录下来,便于查找服务器运行的原因 log_errors = On设置错误日志存放目录,建议将PHP和Apache错误日志存放同一目录下error_log =D:/usr/local/apache2/logs/php_error.log

PHP代码编写规范检查

待补充

猜你喜欢

转载自blog.csdn.net/u014247926/article/details/127117877