PHP常见函数漏洞

本文列举了在CTF和渗透测试中遇到的PHP特性,包括intval()的进制转换、__wakeup()在反序列化后的调用、strcmp()的字符串比较漏洞、assert()与eval()的代码执行、文件包含函数的安全隐患等,还讨论了各种函数的潜在安全问题和利用方式。
摘要由CSDN通过智能技术生成

目录

前言:

1、intval():

一些特性:

2、__wakeup() :

3、strcmp() :

4、assert():

5、eval():

6、include():

7、readfile():

8、call_user_func():

9、trim():

10、is_number():

11、extract():

12、parse_str():

13、get_defined_vars():

14、gettext():

15、匿名函数(create_function):

16、$_SERVER['argv']:

17、哈希函数:

18、命令执行函数:

有回显:

无回显:

19、全局变量:

20、自增绕过:

21、违规变量名:

22、无法处理数组的函数:

23、命令运算:

        24、加减乘除运算符:

        25、 位运算符:

        26、三目运算符:

27、PHP代码表示方式:

1、正常写法xml格式

2、短标签

3、asp风格写法

4、长标签风格

28、松散比较:


前言:

此文中的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、松散比较:

04ac74dbffdf4e78b8c6edaea7527189.png

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Elitewa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值