前言:
此文中的PHP特性,都是博主在CTF题目以及渗透实战中所遇到的,可能有疏漏或不对的地方,还望各位大佬多多指出,感谢!
1、intval():
格式:intval (var, base)
- base: 可选,无则十进制
- 如果 base 是 0,通过检测 var 参数的格式来决定使用的进制(0开头8进制,0x开头16进制)
一些特性:
1、获取变量的整数值
例如 4.2取4
2、传入的字符串存在字母时,只会取字母前面的数字
例如 6e123 取6
3、函数里面有运算式,会把e正确识别为科学计数法符号,并进行运算
例如 intval(1e1+1) = 11
4、在没有运算式时,只会取e前面的数字,并不会把e看做科学计数法符号
参考2
5、在传入的参数非数字字符时,一律返回0
例如:
intval('a')==0 intval('.')==0intval('/')==0
0与字符串进行弱比较返回值为true,详细请看下文松散比较表格
6、非空数组返回1,空数组返回0
2、__wakeup() :
在反序列化之后立即被调用
将变量数改为大于真实变量数即可绕过
3、strcmp() :
格式:strcmp(str1,str2)
该函数返回值:
- 0 - 如果两个字符串相等
- <0 - 如果 string1 小于 string2
- >0 - 如果 string1 大于 string2
strcmp比较的是字符串类型,如果强行传入其他类型参数,会出错,出错后返回值0,正是利用这点进行绕过
例如:传入数组类型 str1[]=666
只有PHP5.3有此漏洞
4、assert():
会把读到的字符串当做PHP执行,末尾不需要引号
5、eval():
会把读到的字符串当做PHP执行,末尾要有引号
6、include():
文件包含漏洞,会执行读到的PHP源码
特性:即使路径中的头目录不存在,也可以正确执行包含目标文件
例如: hint.php?/../../../flag.php
hint.php?这个目录不存在,但仍能够往上跳转4级目录,去包含flag.php
常见的文件包含函数还有:
include_once( )
功能与 Include()相同,区别在于当重复调用同一文件时,程序只调用一次
require( )
require()与 include()的区别在于 require()执行如果发生错误,函数会输出
错误信息,并终止脚本的运行。
require_once( )
功能与 require()相同,区别在于当重复调用同一文件时,程序只调用一次。
7、readfile():
读取一个文件,并写入到输出缓冲
特性:即使路径中的头目录不存在,也可以正确读取目标文件
例如: hint.php?/../../../flag.php
和include相似
8、call_user_func():
回调函数,call_user_func(a,b,...) a为要执行的函数名,剩下的都为a的参数,可以没有
返回值为将参数带入a函数的执行结果
但该函数还可以接受数组来调用类中的静态方法
例如: call_user_func($array); 调用classname这个类里的sya_hello方法 array[0]=$classname 类名 array[1]=say_hello say_hello()静态方法
9、trim():
该函数会移除变量中的
- "\0" - NULL
- "\t" - 制表符
- "\n" - 换行
- "\x0B" - 垂直制表符
- "\r" - 回车
- " " - 空格
但不会移除 \f 换页符,ASCII值为12 url编码为%0c
10、is_number():
判断变量是否为纯数字,但变量开头有非打印字符(如\f \n)仍会识别为数字
11、extract():
将数组变量中的键和键值转化为变量名和变量,如果有冲突,则覆盖已有的变量
例子: <?php $a = "Original"; $my_array = array("a" => "Cat","b" => "Dog", "c" => "Horse"); extract($my_array); echo "\$a = $a; \$b = $b; \$c = $c"; ?> // $a=Cat;$b=Dog;$c=Horse
12、parse_str():
函数把查询字符串(例如这种:name=Peter&age=43)解析到变量中
格式: parse_str(string,array)
array可选(规定存储变量的数组名称,该参数指示变量存储到数组中)
如果不设置array参数,将会覆盖同名变量
例如: <?php parse_str("name=Peter&age=43"); echo $name."<br>"; echo $age; ?> // Peter 43
13、get_defined_vars():
返回由所有已定义变量所组成的数组
可配合 var_dump使用
14、gettext():
gettext() 函数的工作原理是,在翻译前,需要使用 gettext() 函数将要翻译的文本字符串标记为可翻译字符串,然后环境中是什么语言,就会输出相应语言的翻译,该函数可用于凑数
_()是gettext()的拓展函数在开启相关设定后,_("666")等价于gettext("666")
<?php echo gettext(666); //输出 666 echo "\n"; echo _("666"); //输出 666 ?>
15、匿名函数(create_function):
php里默认命名空间是\,所有原生函数和类都在这个命名空间中
调用该函数需要前面加斜杠 /create_function()
该函数内部构造类似于
function fT(,$a) { echo "test".$a; }
该函数不需要第一个参数,并可添加第二个参数,可用于构造闭合
该函数自PHP 7.2起已经弃用
16、$_SERVER['argv']:
$_SERVER['argv']: 1、cli模式(命令行)下 第一个参数$_SERVER['argv'][0]是脚本名,其余的是传递给脚本的参数 2、web网页模式下 在web页模式下必须在php.ini开启register_argc_argv配置项 设置register_argc_argv = On(默认是Off),重启服务,$_SERVER[‘argv’]才会有效果 这时候的$_SERVER[‘argv’][0] = $_SERVER[‘QUERY_STRING’] 此变量为URL问号后面的所有值 $argv,$argc在web模式下不适用
17、哈希函数:
哈希函数(sha1,md5等),无法处理数组,若处理,会返回NULL,可用于===强比较
18、命令执行函数:
有回显:
system()
passthru()
无回显:
exec()
shell_exec() 或者`` 反引号
无回显函数需要添加echo 输出 exec只返回最后一行内容 ,shell_exec()返回完整内容
在题目中如果没有echo的话,需要利用curl来实现flag.php的外带
19、全局变量:
$GLOBALS所有已定义的变量都在此变量数组里存储
var_dump($GLOBALS) 可查看所有的变量信息
20、自增绕过:
payload:
code=$=(/.);$=$[''!=''];$%ff=%2b%2b$;$%ff=%2b%2b$.$%ff;$%2b%2b;$%2b%2b;$%ff.=%2b%2b$;$%ff.=%2b%2b$;$=.$%ff;$$_;&=system&__=cat /flag
21、违规变量名:
PHP变量名由数字字母下划线组成,GET或POST方式传进去的变量名,会自动将空格 + . [转换为_
有一种特殊情况,GET或POST方式传参时,变量名中的 [ 也会被替换为_,但其后的字符就不再进行替换了
如 CTF[SHOW.COM = CTF_SHOW.COM
22、无法处理数组的函数:
md5() 返回NULL sha1() 返回NULL preg_match() 返回false intval() 非空数组返回1,空数组返回0 stripos() 返回NULL strcmp() 返回0
23、命令运算:
php里数字可以和命令可以进行运算,且不影响运行结果
并且也可以使用位运算符 |,或三目运算符
24、加减乘除运算符:
<?php $v1=1; $v2=3; $v3=-phpinfo();+ (url编码) $code = eval("return $v1$v3$v2;"); echo "$v1$v3$v2 = ".$code; ?>
25、 位运算符:
<?php $v1=1; $v2=3; $v3=|phpinfo();| (url编码) $code = eval("return $v1$v3$v2;"); echo "$v1$v3$v2 = ".$code; ?>
26、三目运算符:
<?php $v1=1; $v2=?phpinfo():; $v3=1; eval("return $v1$v2$v3;'"); >
27、PHP代码表示方式:
1、正常写法xml格式
<?php echo '1111'; ?>
2、短标签
<? echo '1111'; ?> <?= //相当于<? echo ?>
需要 php.ini 配置文件中的指令 short_open_tag 打开后才可用,或者在 PHP 编译时加入了 --enable-short-tags 选项。自 PHP5.4 起,短格式的 echo 标记 <?= 总会被识别并且合法,而不管 short_open_tag 的设置是什么
3、asp风格写法
<% echo '1111'; %>
(注意:这种写法在php配置中默认关闭了的,如果要正常输出,需要配置php.ini文件。在配置文件中找到asp_tags=off ,将off改为on。改动配置文件后需要重启apache。)但是在php7之后被移除了
4、长标签风格
<script language="php"> </script> 在php7之后被移除了
28、松散比较: