PHP代码审计系列(一) 基础:方法、思路、流程

简介: PHP代码审计系列(一) 基础:方法、思路、流程

免责声明



本文仅用于技术讨论与学习,利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。

只供对已授权的目标使用测试,对未授权目标的测试作者不承担责任,均由使用本人自行承担。


文章正文

工具

Fotify|代码审计静态扫描工具,商业化静态代码扫描工具,误报率相对较低。

seay|源代码审计工具

PHPStorm|是PHP编程语言开发的集成环境。

chrome & burp & HackerBar 插件 & xdebug插件

Xcheck |Xcheck是一个由腾讯公司CSIG质量部代码安全检查团队自研的静态应用安全测试工具。Xcheck在基于成熟的污点分析技术与对抽象语法树的精准剖解上,通过巧妙优雅的实现来达到对污点的传递和跟踪的目的,更精准地发现隐藏在代码中的安全风险。同时赋予了Xcheck两大优势:快!低误报!


框架

确定目标是否使用的框架、MCV设计模式。

熟悉常见的框架:ThinkPHP、Laravel、Codeigniter、Yii等


MVC

既然是MVC框架的,那么我们真正关心的是其中的控制器(C),因为功能点大部分都在C上,我们能找到的大部分漏洞也都在C上


ThinkPHP

一般如果是审计基于框架的cms,我不会去看框架系统目录(对于TP框架就是ThinkPHP文件夹下的东西),第三方类库vendor也不会去先看,除非是在审计过程中流向了这些文件中,才会大概看一看,而重点在Application文件夹下做文章。

Laravel

目录怎么变,MVC架构的重点还是在Controllers里


无框架

先弄清目标的目录结构。

审计过程中需要关注几个点:(在我们后面开始审计的过程中,自己要注意这些地方,经常想一想)

1)函数集文件,通常命名包含function或者common等关键字,这些文件里面是一些公共的函数,提供其他文件统一调用,所以大多数文件都会在文件头部包含到其他文件。寻找这些文件一个非常好用的技巧就是去打开index.php或者一些功能性文件,在头部一般都能找到。

2)配置文件,通常命名中包括config关键字,配置文件包括web程序运行必须的功能性配置选项以及数据库等配置信息。从这个文件中可以了解程序的小部分功能,另外看这个文件的时候注意观察配置文件中参数值是单引号还是用双引号括起来,如果是双引号可能就存在代码执行的问题了。

3)安全过滤文件,安全过滤文件对代码审计至关重要,这关系到我们挖掘到的可以点能否直接利用,通常命名中带有filter、safe、check等关键字,这类文件主要是对参数进行过滤,大多数的应用其实会在参数的输入做一下addslashes()函数的过滤。

4)index文件,index是一个程序的入口,所以通常我们只要读一读index文件就可以大致了解整个程序的架构、运行的流程、包含到的文件,其中核心的文件有哪些。而不同目录的index文件也有不同的实现方式,建议最好将几个核心目录的index文件都通读一遍。


路由

以ThinkPHP为例,一般有几种形式:普通模式、PATHINFO模式、REWRITE模式、兼容模式

普通模式:

http://localhost/?m=home&c=user&a=login&var1=value1&var2=value2

pathinfo模式:

http://serverName/index.php(或者其他应用入口文件)/模块/控制器/操作/[参数名/参数值...]

REWRITE模式:

在PATHINFO的基础上去掉入口文件

http://serverName/模块/控制器/操作/[参数名/参数值...]

兼容模式:

http://servername/index.php?s=/index/Index/index

其中变量`s`的名称的可以配置的。

审计

流程

1、先全局总览:配置文件、路由等2、定向功能审计:黑盒(找到敏感功能)+白盒(定位到代码进行审计)3、敏感函数回溯

比较完整的审计流程:

先黑盒+白盒看敏感功能,再用自动化审计工具跑一遍并验证,最后再根据漏洞危险函数去回溯

常见漏洞类型审计(危险函数)

这里先仅列出函数,后面会详细展开

SQL注入

  1. 如果使用了框架,可以分辨一下框架名称以及版本,去搜索一下该版本的框架是否存在漏洞,如果存在再去cms中验证。
  2. 如果没有使用框架,则需要仔细的观察数据库函数,一般来说,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


宽字节注入

SET NAMES 'gbk' => set character_set_connection='gbk',character_set_results='gbk',character_set_client='gbk'

检索关键字

SET NAMES
2、character_set_client = gbk
3、mysql_set_charset('gbk')   //后面没有 mysql_real_escape_string函数

GPC

magic_quotes_gpc=on,会自动在GET、POST、COOKIE变量中的' 、"、 \、 NULL的前面加上反斜杠(\),但是在PHP5中magic_quotes_gpc并不会过滤$_SERVER变量,导致很多类似client-ip,referer一类的漏洞能够利用。PHP5.4取消这个参数。


二次urldecode注入

我们提交参数到web服务器,web服务器会自动解码一次。1%2527 解码两次=》1'

检索关键字:

urldecode

rawurldecode


XSS

审计要素


  • 是否存在全局参数过滤器,过滤规则是否符合安全要求,是否存在需过滤和不需过滤两种输出,页面是否控制恰当。
  • 输出时是否进行编码(HTML、JS等)。
  • 前端是否采用了Angularjs、React、vue.js等具有XSS防护功能的前端框架进行数据输出

寻找带有参数的输出函数,然后根据输出函数对输出内容回溯输入参数,观察有没有经过过滤常用的输出函数:

print、print_r、echo、printf、sprintf、die、var_dump、var_export

CSRF

先黑盒:打开几个有非静态操作的页面,抓包看看有没有token,如果没有token的话,再直接请求这个页面,不带referer再白盒:读代码的时候看看几个核心文件里面有没有验证token和referer相关的代码

可以尝试全局搜索

csrf-token
csrf_token
csrftoken
csrf

SSRF


审计要素:

  • 是否存在可以产生SSRF漏洞的函数。
  • 是否存在内网ip地址正则过滤,且正则是否严谨。
  • 是否存在限制请求的方式只能为HTTP或者HTTPS。


通过全文关键函数搜索,再看是否限制了访问端口,访问协议,内网ip地址等。

关键词:


file_get_contents

fsockopen

curl_exec

get_headers

fopen

readfile


文件包含漏洞

文件包含算是拿shell最快的方法了,所以一般要重点关注。

大多数出现在模块加载、模板加载以及cache调用的地方先跟踪一下程序运行流程,看看里面模块加载时包含的文件是否可控,另外就是直接搜索


关键词:


include、include_once、require、require_once

回溯看看有没有可控的变量


文件读取(下载)漏洞


先黑盒看看功能点对应的文件,再去读文件搜索文件读取函数,回溯看看有没有直接或者间接控制的变量:


关键词:


file_get_contents()  

highlight_file()  

fopen()  

readfile()  

fread()  

fgetss()  

fgets()  

parse_ini_file()  

show_source()  

file()  

文件包含函数include等


文件上传


审计要素


  • 是否检查了上传文件的文件类型
  • 是否限制了文件上传路径
  • 是否对文件进行了重命名
  • 文件大小是否限制
  • 是否返回了文件路径或文件路径很好猜测


有的项目,会对文件上传下载进行分装,所以可以全局搜索有关upload、file的函数,看看是不是封装了


function uploadfunction file


如果封装了,那么就看这些封装好的函数,有没有上面提到的审计要素的漏洞。

如果没封装,一般是move_uploaded_file这个函数,全局搜索这个函数,回溯查看这些漏洞存不存在。(白盒黑盒一起搞比较好。)


文件删除


可以先去找相应的功能点,直接黑盒测试一下看能不能删除某个文件,如果删除不了,再去执行流程去追提交的文件名参数的传递过程。

unlink

rmdir

代码执行


审计要素


  • php.ini文件中的disable_function是否有禁用函数。
  • 是否存在代码执行的敏感函数。
  • 是否输入变量可控。

关键词:


eval()、assert()、preg_replace()、create_function()、array_map()、call_user_func()、call_user_func_array()、array_filter、 usort()、动态函数


命令执行


审计要素

  • 参数是否用户可控
  • 是否配置了全局过滤器,过滤规则是否符合安全规范
  • 是否所有的命令执行参数都经过了过滤器,或受白名单限制

关键词:


exec()、passthru()、system()、 shell_exec()、popen()、反引号`、proc_open()、pcntl_exec()


变量覆盖


变量覆盖漏洞通常要结合应用其他功能代码来实现完整攻击,所以挖掘一个可用的变量覆盖漏洞不仅仅要考虑的是能够实现变量覆盖,还要考虑后面的代码能不能让这个漏洞利用起来。要挖可用的变量覆盖漏洞,一定要看漏洞代码行之前存在哪些变量可用覆盖并且有被使用到。extract()parse_str() 这两个函数比较好挖掘,直接检索关键字,然后回溯import_request_variables()函数则相当于开了全局变量注册,这时候只要找哪些变量没有初始化并且操作之前没有赋值的,然后就去提交这个变量作为参数。PHP4-5.4.0 才有该函数。$$ 变量覆盖,经典代码:


以上代码,可以用从G P C获得的 '参数=值',来覆盖之前的所有变量

XXE


关键函数


SimpleXMLElement

simplexml_load_string

loadxml


直接搜索  回溯 


逻辑漏洞


通读功能点源码。值得关注的点是程序是否可以重复安装、修改密码处是否可越权修改其他用户密码、找回密码验证码是否可暴力破解以及修改其他用户密码、cookie是否可预测或者说cookie验证是否可绕过等。

危险函数:  php黑魔法


in_array : 在比较之前会自动做类型转换


is_numeric:任何参数做16进制编码传入,会直接通过(true)


双等于(==):弱等于,判断之前会先做变量类型转换


$_REQUEST获取变量,进行过滤,可能存在绕过:GET方式传危险数据,POST方式传正常数据,$REQUEST默认获取的是POST方式传入的数据。所有如果存在类似,**$GET传入的参数,通过$_REQUEST进行过滤**,就可能存在问题

相关文章
|
1月前
|
SQL 安全 PHP
PHP开发中防止SQL注入的方法,包括使用参数化查询、对用户输入进行过滤和验证、使用安全的框架和库等,旨在帮助开发者有效应对SQL注入这一常见安全威胁,保障应用安全
本文深入探讨了PHP开发中防止SQL注入的方法,包括使用参数化查询、对用户输入进行过滤和验证、使用安全的框架和库等,旨在帮助开发者有效应对SQL注入这一常见安全威胁,保障应用安全。
59 4
|
1月前
|
JSON PHP 数据格式
PHP解析配置文件的常用方法
INI文件是最常见的配置文件格式之一。
51 12
|
3月前
|
Java PHP 数据安全/隐私保护
PHP 面向对象,构造函数,析构函数,继承,方法的重写,接口抽象类,static,final,this,parent,self的异同和作用
本文详细介绍了PHP面向对象编程的一系列核心概念和用法,包括构造函数、析构函数、继承、方法重写、访问控制、接口、抽象类、静态成员、final关键字、以及this、self、parent这三个关键字的异同和作用。通过具体示例代码,展示了如何在PHP中使用这些面向对象的特性,以及它们在实际开发中的应用。
PHP 面向对象,构造函数,析构函数,继承,方法的重写,接口抽象类,static,final,this,parent,self的异同和作用
|
3月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入探索与实践在软件开发的广袤天地中,PHP以其独特的魅力和强大的功能,成为无数开发者手中的得力工具。而在这条充满挑战与机遇的征途上,设计模式犹如一盏明灯,指引着我们穿越代码的迷雾,编写出更加高效、灵活且易于维护的程序。今天,就让我们聚焦于设计模式中的璀璨明珠——策略模式,深入探讨其在PHP中的实现方法及其实际应用价值。
策略模式,这一设计模式的核心在于它为软件设计带来了一种全新的视角和方法。它允许我们在运行时根据不同情况选择最适合的解决方案,从而极大地提高了程序的灵活性和可扩展性。在PHP这门广泛应用的编程语言中,策略模式同样大放异彩,为开发者们提供了丰富的创作空间。本文将从策略模式的基本概念入手,逐步深入到PHP中的实现细节,并通过一个具体的实例来展示其在实际项目中的应用效果。我们还将探讨策略模式的优势以及在实际应用中可能遇到的挑战和解决方案,为PHP开发者提供一份宝贵的参考。
|
3月前
|
PHP UED 开发者
PHP中处理异常的现代方法
【9月更文挑战第26天】在PHP的世界里,异常处理是代码健壮性的守护神。本文将深入浅出地探讨如何在PHP项目中优雅地处理异常,从而避免程序崩溃并提升用户体验。
|
3月前
|
IDE 安全 网络安全
Xdebug 在不同版本的 PHP 中配置方法有什么不同?
Xdebug 在不同版本的 PHP 中配置方法有什么不同?
231 4
|
4月前
|
PHP 开发工具 git
【Azure 应用服务】在 App Service for Windows 中自定义 PHP 版本的方法
【Azure 应用服务】在 App Service for Windows 中自定义 PHP 版本的方法
|
3月前
|
PHP 开发者
PHP中的魔法方法
本文将介绍PHP中的一些特殊方法,这些方法以双下划线(__)开头,被称为魔术方法或魔法方法。这些方法在特定情况下会自动调用,例如当尝试访问未定义的属性或调用未定义的方法时。本文将详细讲解几个常用的魔术方法,以及如何在实际应用中使用它们来增强PHP代码的可读性和健壮性。
35 0
|
4月前
|
JSON PHP Apache
[GFCTF 2021]Baby_Web(CVE-2021-41773) 从一道题入门PHP代码审计 (保姆级)
[GFCTF 2021]Baby_Web(CVE-2021-41773) 从一道题入门PHP代码审计 (保姆级)
43 1
|
4月前
|
Java 应用服务中间件 PHP
PHP——调用java文件中的方法
PHP——调用java文件中的方法
61 0
PHP——调用java文件中的方法