变量转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(string)TRUE //returns "1"
(string)FALSE //returns ""

echo TRUE; //prints "1"
echo FALSE; //prints nothing!

$string='12345.678';
$boolean=!!$string; //prints bool(true)

var_dump($val = "0" + "123"); //prints int(123)

$arr = array();
var_dump($arr>"zzz"); //prints bool(true)

var_dump('0e123'=='0e456');

//指数转整数
var_dump((int)6e6); //int(6000000)
var_dump((int)'6e6'); //int(6)

归纳一下

true对于1 flase对应0

string对应bool的true(除了”0”和空字符串,其余全都是true)

字符串进行相加减能够得到整数 再利用一个chr就能够拿到字符,然后就可以写shell

数组永远比字符串大

0e开头后面全是数字的字符串会被当作科学计数法 0的多少次幂 都是0

危险函数

intval floatval

获取变量的整数值

语法

1
intval ( mixed $var [, int $base = 10 ] ) : int

通过使用指定的进制 base 转换(默认是十进制),返回变量 varinteger 数值。 intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。

参数

1
2
3
4
5
6
7
8
var 要转换成整数的值

base 转换所使用的进制
Note:
如果 base 是 0,通过检测 var 的格式来决定使用的进制:
如果字符串包括了 "0x" (或 "0X") 的前缀,使用 16 进制 (hex);否则,
如果字符串以 "0" 开始,使用 8 进制(octal);否则,
将使用 10 进制 (decimal)。

返回值

成功时返回 var 的 integer 值,失败时返回 0。 空的 array 返回 0,非空的 array 返回 1。字符串的返回值不确定,遵守字符串转整数规则

最大的值取决于操作系统。 32 位系统最大带符号的 integer 范围是 -2147483648 到 2147483647。举例,在这样的系统上, intval(‘1000000000000’) 会返回 2147483647。64 位系统上,最大带符号的 integer 值是 9223372036854775807。

demo

遇到无法解析的字符时,就返回 其实就是一个字符串转整数

1
2
3
4
5
6
7
8
9
10
intval('1')  ==>1
floatval('1') ==>1
<====分界线====>
intval('0x1')==>0 //0x1被判断为字符串
intval(null)==>0
intval('0x2222')==>0 //同样被判断为字符串
intval('0x2222'+1)==>8739 //这里先是一个表达式的计算,把返回结果给了 intval函数

floatval('1/2') ==>1 // /被判断为非法字符
floatval('1 2') ==>1

md5

0e弱比较绕过 数组绕过

in_array

在 PHP 手册中, in_array() 函数的解释是 bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] ) , 如果 strict 参数没有提供,那么 in_array 就会使用松散比较来判断 $needle 是否在 $haystack 中。当 strict 的值为 true 时, in_array() 会比较 needls 的类型和 haystack 中的类型是否相同。

1
2
3
4
5
<?php
$array=[0,1,2,'3'];
var_dump(in_array('abc', $array)); //true
var_dump(in_array('1bc', $array)); //true
?>

switch

如果 switch() 是数字类型的 case 的判断时,switch 会将其中的参数转换为 int 类型

1
2
3
4
5
6
7
8
9
10
<?php
$i ="2abc";
switch ($i) {
case 0:
case 1:
case 2:
echo "i is less than 3 but not negative";
break;
case 3: echo "i is 3";}
?>

is_numric

判断是否为数字,不仅仅是十进制数字,利用弱类型,将数字后面加上空格或者任意一个字符即可绕过。 is_numeric 检测的时候会自动过滤掉前面的 ‘ ‘, ‘\t’, ‘\n’, ‘\r’, ‘\v’, ‘\f’ 等字符,但是不会过滤 ‘\0’,如果这些字符出现在字符串尾,也不会过滤,而是返回 false

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
$a = '1';
$b = '1a';
$c = '1 ';
var_dump(is_numeric($a));//true
var_dump(is_numeric($b));//false
var_dump(is_numeric($c));//false
echo is_numeric(233333); // 1
echo is_numeric('233333'); // 1
echo is_numeric(0x233333); // 1
echo is_numeric('0x233333'); // 1
echo is_numeric('9e9'); // 1
echo is_numeric('233333abc'); // 0
var_dump(is_numeric("\01")); // false
var_dump(is_numeric(" 1")); // true
var_dump(is_numeric("\t1")); // true
var_dump(is_numeric("\f1")); // true
var_dump(is_numeric("\f\f1")); // true
var_dump(is_numeric("1\f")); // false
?>

补充

16进制绕过

1
2
0xccccccccc == 54975581388
3735929054==deadc0de;

strstr

查找字符串的首次出现 大小写敏感

1
2
3
4
<?php
var_dump(strstr('phpinfo','PHP'));
//输出
bool(false)

strcmp

strcmp() 函数在 PHP 官方手册中的描述是 int strcmp ( string $str1 , string $str2 ),需要给 strcmp() 传递 2 个 string 类型的参数。如果 str1 小于 str2,返回 -1,相等返回 0,否则返回 1。strcmp() 函数比较字符串的本质是将两个变量转换为 ASCII,然后进行减法运算,然后根据运算结果来决定返回值。 并且区分大小写

传入非字符串(和版本有关)

1
2
3
strcmp("foo", array()) => NULL + PHP Warning
strcmp("foo", new stdClass) => NULL + PHP Warning
strcmp(function(){}, "") => NULL + PHP Warning

strpos

查找字符串首次出现的位置,返回结果和弱比较一起使用就会出现问题,字符串的索引位置从0开始,

1
2
3
4
5
6
7
<?php
$mystring = 'abc';
$findme = 'a';
$pos = strpos($mystring, $findme);
if($pos!=flase){
echo "success"
}

二次编码绕过

1
2
3
4
5
6
7
8
9
10
11
<?php
$x = $_GET['x']; //?x=file:///var/www/html/readme.%2570hp
$pos = strpos($x,"php");
if($pos){
exit("denied");
}
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,"$x");
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$result = curl_exec($ch);
echo $result;

chr

chr()会自动对参数进行256取余

ord

上面这两个函数,默认取第一个字符进行处理

数组绕过

数组可以绕过很多用来判断字符串的函数

strlen() 5.2版本

strcmp()

preg_match()

可变变量

见可变变量学习