php特性
preg_match()
数组绕过
preg_match()只能处理字符串,当传入的subject是数组时,会返回false
1 | if(preg_match("/[0-9]/", $num)){ |
payload:
num[]=1
最大回溯次数绕过
PHP 为了防止正则表达式的拒绝服务攻击(reDOS),给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit
回溯次数上限默认是 100 万。如果回溯次数超过了 100 万,preg_match 将不再返回非 1 和 0,而是 false。
intval()
字符绕过
intval()而言,如果参数是字符串,,则返回字符串中第一个不是数字的字符之前的数字串所代表的整数值。如果字符串第一个是‘-’,则从第二个开始算起。
1 | if($num==="4476"){ |
payload:
1 | num=4476a |
科学计数法
intval() int 函数如果base为0,则var中存在字母的话遇到字母就停止读取,但遇到e,会表示科学计数法
1 | if($num==4476){ |
payload:
1 | num=4476e1 |
进制转换
0bxx:二进制
0xxx:八进制
0Xxx:十六进制
1 | if($num==4476){ |
payload:
1 | num=010574 //八进制,php会自动识别进制 |
小数点绕过
1 | if($num==="4476"){ |
进制转换绕过不可行了,只能通过小数点,使得intval()转变为int()
strpos
1 | strpos() - 查找字符串在另一字符串中第一次出现的位置(区分大小写) |
md5
科学计数法绕过
md5()遇到公式,会先进行运算,再对运算结果计算md5
由于0和任何数相乘都等于0,所以0e开头的任何数,其md5都是相同的
比如 md5(‘0e1234’),会先运算成 md5(0),再计算MD5值。
补充:
0e是科学计数法,大小写等价,即 0e 和 0E 的结果相同。
科学记数法是一种记数的方法。把一个数表示成a与10的n次幂相乘的形式。
格式为:aEb=a×10^b,即a乘以10的b次幂。
绕过思路1:遇到弱比较(md5(a)==md5(b))时,可以使用0e绕过,即将a和b赋值为0e开头的数
0e绕过还有一种变体,如果某个字符串是0e开头的,在比较时,php也会先把它计算为0,在参与比较。
绕过思路2:遇到弱比较(md5(a)==0),可以传入QNKCDZO等绕过
一些MD5值为0e开头的字符串:
1 | QNKCDZO => 0e830400451993494058024219903391 |
数组类型(数组绕过)
md5()不能处理数组,数组都会返回NULL,同时会报一个warning,不影响执行
绕过思路:遇到强比较(a===b)时,可以使用数组绕过。GET传参时,以 a[]=1&b[]=2
这种形式传递数组。
1 | $a = array(1,2,3); |
算数运算配合自动类型转换
md5()遇到算数符时,会先运算,再计算结果的md5值
所以,当字符串与数字类型运算时,会将字符串转换成数字类型再参与运算,最后计算运算结果的MD5值
数值类型
虽然 md5() 要求传入字符串,但传入整数或小数也不会报错;数字相同时,数值型和字符串的计算结果是相同的。
MD5值相等的字符串
1 | $Param1="\x4d\xc9\x68\xff\x0e\xe3\x5c\x20\x95\x72\xd4\x77\x7b\x72\x15\x87\xd3\x6f\xa7\xb2\x1b\xdc\x56\xb7\x4a\x3d\xc0\x78\x3e\x7b\x95\x18\xaf\xbf\xa2\x00\xa8\x28\x4b\xf3\x6e\x8e\x4b\x55\xb3\x5f\x42\x75\x93\xd8\x49\x67\x6d\xa0\xd1\x55\x5d\x83\x60\xfb\x5f\x07\xfe\xa2"; |
$a==md5($a)
0e215962017
的 MD5 值也是由 0e 开头,在 PHP 弱类型比较中相等
file_put_contents()
PHP: file_put_contents - Manual
- 该函数访问文件时,遵循以下规则:
- 如果设置了 FILE_USE_INCLUDE_PATH,那么将检查 filename 副本的内置路径
- 如果文件不存在,将创建一个文件
- 打开文件
- 如果设置了 LOCK_EX,那么将锁定文件
- 如果设置了 FILE_APPEND,那么将移至文件末尾。否则,将会清除文件的内容
- 向文件中写入数据
- 关闭文件并对所有文件解锁
- 如果成功,该函数将返回写入文件中的字符数。如果失败,则返回 False。
1 | int file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] ) |
in_array()
in_array()函数搜索数组中是否存在指定的值
1 | in_array(needle,haystack, type) |
优先级
符号
&&,||> = > and,or
get/post
http协议默认先以get方式获取数据,无论以哪种方式发起的,总是get方式优先,即通过get方式获取到了数据就不会再去通过post方式获取
is_numeric
is_numeric(mixed $value
): bool
检查指定的变量是否为数字或数字字符串
highlight_file
highlight_file(string $filename
, bool $return
= false
): string|bool
使用 PHP 内置的语法高亮器所定义的颜色,打印输出或者返回 filename
文件中语法高亮版本的代码。
1 | filename |
欲高亮文件的路径。
1 | return |
设置该参数为 true
使函数返回高亮后的代码。
如果 return
设置为 **true
**,高亮后的代码不会被打印输出,而是以字符串的形式返回。高亮成功返回 **true
**,否则返回 **false
**。
eval()
eval — 把字符串作为PHP代码执行
ReflectionClass反射类
获取类的信息,并实例化对象
1 | <?php |
call_user_func
call_user_func — 把第一个参数作为回调函数调用
call_user_func(callable $callback
, mixed ...$args
): mixed
第一个参数 callback
是被调用的回调函数,其余参数是回调函数的参数。
callback
将被调用的回调函数(callable)。
args
0个或以上的参数,被传入回调函数。
hex2bin()
hex2bin(string $string
): string|false
转换十六进制字符串为二进制字符串。
php 伪协议
配合file_put_contents(v3,str);(在需要使用base64转换时);
1 | v3=php://filter/write=convert.base64-decode/resource=1.php&str=...... |
当ban掉base64时,我们可以使用
1 | php://filter/resource=flag.php |
is_file()
判断是否为文件
php协议绕过
highlight_file()可以识别php伪协议,而is_file()不能识别
/proc/self/root
在linux中/proc/self/root是指向根目录的 也就是说,如果在命令行中输入 ls /proc/self/root,其实显示的内容是根目录下的,多次重复后可绕过is_file
php版本
当 php 版本⼩于 8 时,GET 请求的参数名含有 . ,会被转为 _ ,但是如果参数名中有 [ ,这个 [ 会被直接转为 _ ,但是后⾯如果有 . ,这个 . 就不会被转为 _ 。
ctype_alpha
ctype_alpha(mixed $text
): bool
检测提供的 string 类型的 text
里面的所有字符是否都是字母。在标准的 C
语言区域设置中,字母仅仅是指 [A-Za-z]
,并且如果 $text 是单个字符,则 ctype_alpha() 等同于 (ctype_upper($text) || ctype_lower($text))
,但是在其他语言中有些字母既不视为大写也不视为小写。
用小数可以绕过
php原生类
https://blog.csdn.net/unexpectedthing/article/details/121780909
MAC地址
/sys/class/net/eth0/address