php特性总结下
4.变量覆盖:
在PHP中,符号表(Symbol Table)是一个内部数据结构,用于跟踪当前脚本中定义的变量和它们的值。在PHP脚本执行期间,符号表记录了所有已经声明的变量及其对应的值,并且可以动态地添加、修改和删除这些变量。
extract:
PHP extract() 函数用于将数组中的键作为变量名,将对应的值作为变量值导入到当前程序的符号表中
extract()导入变量名和值时,如果原来已经存在相同的变量名,那么旧的值会被数组中同名的健对应的值替换掉
<?php |
在小皮上面测试,可以看到,本来hobby的值为play,可以是我们通过get方式传入一个同名变量,使值为study,play就会被study覆盖
parse_str:
解析字符串,如果字符串中含有类似a=b字符串,就会把$a=b导入到符号表中,可能会覆盖已有变量的值
<?php |
$$:
举个栗子:
|
foreach遍历$GET
数组,如果get传同名变量?a=10,在$$key=$value
中,会先解析$key
为a,然后就会变为$a=10
,从而覆盖掉原来a的值(在show上面有个关于这个的题,可以去看看)
5.import_request_variables:
这个函数会把 GET/POST/Cookie 变量导入到全局作用域中,如果程序中已经有同名变量,会造成覆盖
5.is_file&&require_once
|
可以直接用compress.zlib://flag.php读取文件,还学到了一个方法,不断重复/proc/self/root使得is_file返回false,简单来说就是这个函数在解析文件路径时是递归调用的,又因为/proc/self是符号链接,所以要不断递归解析到对应的文件路径,要用符号链接,这个递归层数是有限制的,最高为40,**所以只要/proc/self/root重复超过40次即可,**payload:
file=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.php |
require_once或include_once都是只包含一次文件的的,也可以尝试用这个绕过
6.is_numeric&trim:
is_numeric是检测传入参数字符串是否是数字,但是在php5中传入符合进制数字的字符串也会返回true,如
var_dump(is_numeric("0x123")); |
在php5中都返回true,但在php7都会返回false
而且is_numeric
有一些特殊字符是会忽略的的,如%0C(\f) %2B(+) - . %20(空)
,数字字符串里带上这些会true
trim函数也不会清除\f
,即%0C
7.转换变量字符
php的变量只允许数字字母和下划线组成,通过get或post传的变量中如果有非法字符会被自动转化为_
,但是这种转化只会发生一次,如果变量名中有两个非法字符,只会转化第一个
但是特殊符号不能放开头,而且居然不会转化{}
,经过测试,通过get或post传会被转化_
的字符有%20 . + [
这四个字符
8.$_SERVER[‘argv’]
使用$_SERVER['argv']
这个参数需要 php.ini中register_argc_argv=on(默认为off),这个配置开启时,通过web服务传递的参数可以被解析为命令行参数,存放在$_SERVER[‘argv’]中,这如:
|
可以看到,argc存放的是参数个数,argv数组存放了所有的参数,而且各个参数之间通过 + 分割,当然放$_GET
和$_POST
数组的参数还是按 & 分割的
举个栗子(show的真题):
<?php |
首先是变量字符转换,要正常传CTF_SHOW.COM,需要传CTF[SHOW.COM,提前让php转化非法字符
其次是如何让$fl0g===”flag_give_me”,尤其在!isset($_GET[‘fl0g’]的情况下
这时就可以利用$a=$_SERVER[‘argv’],get传?$fl0g=flag_give_me,那么就是a就是f l 0 g = f l a g g i v e m e 这个字符串,把 c 赋值为 a s s e r t 把这个字符串当作 p h p 代码执行,就能把 fl0g=flag_give_me这个字符串,把c赋值为assert把这个字符串当作php代码执行,就能把fl0g=flag_give_me这个字符串,把c赋值为assert把这个字符串当作php代码执行,就能把fl0g导入进来,拿到flag,payload:
get: ?$fl0g=flag_give_me |
9.gettext&get_defind_vars:
php的gettext()
函数就是返回你传入的参数,什么也不干,安装了gettext拓展后,使用 _() 就相当于 gettext() 这个别名在php5成功能使用
get_defind_vars
可以获取当前定义的变量和一些超全局变量,这个函数在无参数rce时也常用
举个栗子(show):
<?php |
其他:
=优先于 & |:
举个栗子:
在$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);,由于赋值预算比其他运算优先级高,所以v0先被is_numeric($v1)赋值了,后面的不会影响v0的值 |
json_decode:
php处理json会自动解析unicode编码,但是8进制或16进制无法处理,因此可以用来绕过黑名单