PHP代码审计技巧
编译方式
1 | 和Java和.NET不同,PHP并不存在手动编译的过程,开发人员只要提供PHP源代码 |
协议使用
php://input
介绍
1 | php://input是一个可以访问请求的原始数据的只读流。 |
使用时需要结合file_get_contents函数
1 | 变量 = file_get_contents("php://input") |
缺点
1 | 无法读取Content-Type为multipart/form-data的POST数据 |
函数使用
@符号
1 | @符号是PHP的错误控制操作符,在函数的前面添加@符号时,将不会回显报错信息 |
可变函数
1 | PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号() |
1 | 可变函数可以用来实现包括回调函数,函数表在内的一些用途 |
include()
文件包含时如果发生报错,仍会执行脚本
如果需要包含一个文件时,可用越级符号跳到上一级文件
1 | /index.php?file=index.php../../windows/win.ini |
include_once()
如果文件的代码已经被包含了,就不会再包含
将会优先查询一次已加载的文件列表确认是否存在
require()
文件包含是如果发生报错,会停止执行脚本
require_once()
如果文件的代码已经被包含了,就不会再包含
将会优先查询一次已加载的文件列表确认是否存在
assert()
断言函数自PHP 8删除,可以传入一个字符串用于执行php代码
如果需要执行多个php代码时,可使用or关键字
1 | assert('phpinfo() or system("ls")') |
preg_replace()
传入的模式形参$pattern
中存在/e
时,就会将第二个参数$replacement
作为PHP代码执行
第三个参数$subject
得保证符合$pattern
的要求才能执行命令
1 | preg_replace("/abc/e",PHP代码,"abcd") |
变量使用
全局变量
1 | $_GET |
$http_raw_post_data
介绍
1 | 是PHP内置的一个全局变量,在PHP无法识别的Content-Type时,将POST的数据原样填入该变量中 |
使用条件
1 | php.ini中设置 always_ppulate_raw_post_data = on |
使用
1 | 通过赋值给其他变量,或者是直接获取该变量的内容即可操作POST的数据内容 |
缺点
1 | 无法读取Content-Type为multipart/form-data的POST数据 |
逻辑特性
0e MD5
1 | s878926199a 0e545993274517709034328855841020 |
科学计数法
使用科学计数法时,$a的值为9e9,可使以下if语句为真(值很大且位数小)
1 | intval($a) > 1000000 && strlen($a) <= 3 |
短标签绕过
如果php
无法使用时,可以采用短标签
1 | <?=代码;?> |
数组传输
如果要在GET或POST直接传输一个一维数组
1 | 数组名[]=值1&数组名[]=值2 |
如果要在GET或POST直接传输一个二维数组
1 | 数组名['键1']=值1&数组名['键2']=值2 |
如果是要传入空数组时
1 | 数组名[]= |
array_search()绕过
对于一个数值型的数组,如果需要匹配的内容为字符串时,首先会将需要匹配的字符串转换为数字0
之后在数组中匹配的就是0,返回对应的下标或者键
is_numeric()绕过
1 | is_numeric函数对于空字符%00,无论是%00放在前后都可以判断为非数值,而%20空格字符只能放在数值后。 |
1 | 可使用数字的十六进制绕过,需要在前面添加0X |
1 | 先将一个数字添加一个字符a,然后将其用引号引起来。 |
json_decode
如果值为数字,且需要让其解释为字符串时,必须使用引号括起来
当传入的键值对中值为数组类型时,需要使用[]中括号引起来,而不是花括号
getReailFileType
当文件的头部含有GIF89a时(GIF必须大写),可以绕过该函数检测
漏洞
PHP 5.5.9 数组整数溢出,重排序
当数组为九位16机制数时,会溢出,等同于重新排序,16的8次方即4294967296在逻辑上等同于下标0;
1 | stuff[4294967296]=admin&stuff[1]=user |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 狐狸小镇!