php代码审计入门(一)——基础篇

环境准备:


  • phpstudy + pikachu
  • sublime text 3
    辅助插件:Package Control(用于安装其他插件)、CTags(用于建立索引)、phpfmt(格式化php代码)、ConvertToUTF8
    Build System:php7.0+(确保能正常执行php语句)

项目地址:https://github.com/universal-ctags/ctags
需把ctags.exe放入到 SystemRoot 下:C:\Windows

建立索引:

  • sublime text:打开侧边栏,右键点击 打开文件夹 ,选择部署在 phpstudy 下的 pikachu 目录
  • 右键点击pikachu,选择CTags:Build Tags,至此建立索引完成。

定位函数及引用处:

  • 对于pikachu目录下的任一php文件,我们找到任一调用函数,右键选择Navigate to Definition,即可导航到定义函数处。
  • 或者直接把光标停放在该函数,即可查看所以定义函数及引用函数的位置

审计方法与步骤:


  • 审计前的准备,把握网站结构

浏览源码文件夹,了解该程序的大致目录

  • 入口文件

index.php、admin.php文件一般是整个程序的入门,详细读一下index文件就可以知道程序的架构、运行流程、包含哪些配置文件,包含哪些过滤文件及安全过滤文件,了解程序的业务逻辑。

  • 配置文件

一般文件名类似config.php,可能会记录数据库的相关信息及程序的相关信息。注意查看数据库的编码,如果是gbk且数据库为mysql,则可能存在宽字节注入。如果变量的值用双引号,则可能存在双引号解析代码执行的问题

  • 过滤功能

通过详读公共函数文件和安全过滤文件,清晰掌握用户输入的数据的过滤规则(哪些被过滤、哪些无过滤、在哪些被过滤、过滤规则是什么、能否绕过过滤的数据、过滤的方式是替换还是正则、是否设置了GPC、有没有使用addslasher()处理等)

审计方法:
  • 通读全文法:

一般是企业对自身产品的审计。对于小型应用,源代码相较少,咱们也可以读一读。

  • 敏感函数参数回溯法:

最高效、最常用的方法。
大多数漏洞的产生是因为函数的使用不当导致的。我们只要找到这样的一些使用不当的函数,就可以快速挖掘想要的漏洞。

或者我们可以配合一些自动化审计工具,比如 Seay源代码审计系统,主要利用正则匹配一些高危函数、关键函数以及敏感关键字,但是可能会有很多误报

然后我们具体分析敏感函数的上下文,追踪参数源头,尝试控制可控的参数变量。

  • 定向功能分析法:

根据程序的业务逻辑来审计。
首先是用浏览器逐个访问浏览,看看这套程序有哪些功能。根据功能点推测可能存在的漏洞
常见功能漏洞:(包括但不局限于)

程序初始安装、站点信息泄露、文件上传/管理、登录认证/权限管理、数据库备份恢复、找回密码、验证码等等

常见重要配置:


启用全局变量:

register_globals = off

这个设置的作用是关闭自动注册的全局变量

在设置为On的时候,php会将$_POST$_GET$_COOKIE$_ENV$_SESSION数组中的$key=>$value直接注册为变量,比如$_POST['username']就会被注册为$username

存在以下风险:

不知道变量是哪里来的,不方便别人阅读代码
变量之间相互覆盖,引起不必要的麻烦

短标签:
我之前看过一篇文章,大概内容是利用短标签来绕过waf达到文件上传的目的,虽然最后好像没有成功

short_open_tag = On

这个设置决定了是否允许PHP代码开始标志的缩写形式:

本指令也会影响到缩写形式: ,它和: 等价,使用此指令需要 short_open_tag 的值为Onmou
注意:PHP 5.4.0起,总是可用的

安全模式:

safe_mode = off

php的安全模式能够控制一些php中的函数,比如system(),同时把很多文件操作函数进行了权限控制,它会比较执行脚本UID(用户ID)和脚本尝试访问的文件的UID,以此作为限制机制的基础。
默认情况下,php.ini是没有打开安全模式的
本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0起移除

安全模式下执行程序主目录:

safe_mode_exec_dir = /var/www/html

如果php启用了安全模式,system等其他可执行程序将拒绝启动不在此目录中的程序,使用/作为目录分隔符

禁用危险类/函数:

disable_classes、disable_functions

禁用某些类和函数,以逗号作为分隔,且只能在php.ini中设置

文件上传和目录权限:

file_uploads = On  # 允许HTTP文件上传
upload_max_filesize = 100M  #  文件上传大小限制
upload_tmp_dir =  # 上传临时文件保存的目录,需要可写,如果不设置,则采用系统临时目录:/tmp、C:\Windows\Temp

用户访问目录限制:

# .号代表当前目录
open_basedir= .:/tmp/

Linux以:进行分隔,Windows则是以;作为分隔符
该选项能够控制PHP脚本只能访问指定的目录,能在一定程度上限制php shell的危害,一般设置为php脚本所在的目录和/tmp/目录,能够一定程度上防止php木马跨站运行

错误信息:

display_error = On

是否将错误信息作为输出的一部分,在进行调试的时候我们可以设置为On,等上线以后,处于生产模式,建议改为OFF,以免暴露信息

error_reporting = E_ALL

这个变量的作用是将错误级别设置为最高,可以显示所以的问题,方便排错。推荐使用 E_ALL 或者 E_STRICT,即所有级别

错误日志:

# 错误日志的位置,必须对Web用户可写入,如果不定义则默认写入到Web服务器的错误日志中
error_log = 
# 建议将错误日志输出到文件,而不是直接输出到前端
log_errors = on
# 错误日志管理信息的最大长度,设为0时表示无限长度
log_errors_max_len = 1024

关闭PHP版本信息在http头中的泄漏:

expose_php = Off

魔术引号:

magic_quotes_gpc = On
magic_quotes_runtime = Off

为GPC(Get/Post/Cookie)操作设置 magic_quotes 状态,当magic_quotes 为 on,所有的'"NULL 被一个反斜杠自动转义
注意:本特性自 PHP 5.3.0 起废用并将自 PHP 5.4.0 起移除(因效率问题)

远程文件相关:

allow_url_fopen=On  # 是否允许打开远程桌面

本选项激活了URL形式的fopen 封装协议使得可以访问URL对象。默认的封装协议提供使用ftp和http协议来访问远程文件,一些拓展库例如zlib可能会注册更多的封装协议

allow_url_include=Off  # 是否允许包含远程文件

本选项激活允许 includeinclude_oncerequirerequire_once等函数使用URL形式的fopen封装协议,导致能够可以远程包含文件

你可能感兴趣的:(php代码审计入门(一)——基础篇)