0%

php弱类型

弱类型与强类型

通常语言有强类型和弱类型两种,强类型指的是强制数据类型的语言,就是说,一个变量一旦被定义了某个类型,如果不经过强制类型转换,这个变量就一直是这个类型,在变量使用之前必须声明变量的类型和名称,且不经强制转换不允许两种不同类型的变量互相操作。而弱类型语言,不会检查变量类型,可以随时的转换变量类型。

在php中

1
2
$x=1;
$x="string";//随意转换变量类型

但在C语言中任何变量都要先定义变量类型,再进行赋值。

比较操作符

在编程中类型转换是不可避免的一个事情,比如说网络编程中get方法或者post方法传入一个需要转换成int的值,再比如说变量间进行比较的时候,需要将变量进行转换,鉴于php是自动进行类型转换,所以会引发很多意想不到的问题。

php有两种比较方式,一种是“= =” 一种是“= = =”这两种都可以比较两个数字的大小,但是有很明显的区别。

“= =”:会把两端变量类型转换成相同的,在进行比较。

“= = =”:会先判断两端变量类型是否相同,在进行比较。

类型转换问题

php中最常见的就是string 转int,或者int转string。

一般有两种方法,一是强制类型转换(string)$xstrval($x),(int)$xintval($X),二是根据运算符自动转换。

例如

1
2
3
4
5
6
$a=123;var_dump($a); //int(123)
var_dump($a + "123"); //int(246)
var_dump($a . "123"); //string(6) "123123"
var_dump($a =="123a1"); //bool(true)
var_dump($a == "123e1"); //bool(false)
var_dump($a == "12.3e1"); //bool(true)

如果是运算符则会自动转换成数值再进行计算,如果是字符串运算符则转换成字符串再计算

如果是“==”,则会把字符串转换成数值,根据官方文档如果该字符串没有包含’.’,’e’,’E’并且其数值值在整形的范围之内,该字符串被当作int来取值,其他所有情况下都被作为float来取值,该字符串的开始部分决定了它的值,如果该字符串以合法的数值开始,则使用该数值,否则其值为0。

hash绕过

hash1.php

1
2
3
4
5
6
$flag = "{This_is_a_test!!!!}"; //假设flag的值不可见
$int =0; //为$int赋值 使其满足if的条件
if($flag !== $int && md5($flag) == $int) //注意"!==" 先判断类型
echo "correct\n";
else
echo "incorrect\n";

为$int赋何值,才能满足条件?

先看下面几个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$flag1 = "{You_can't_see_me}";
$flag2 = "{You_can't_see}";
$flag3 = "{You_can't_se}";

var_dump(md5($flag1)); //string(32) "dc39eb7c561e8753d2ce41cb2e1f798b"
var_dump(intval(md5($flag1))); //int(0)

var_dump(md5($flag2)); //string(32) "2e2e029620ec42eb68bc24e88d35b027"
var_dump(intval(md5($flag2))); //int(200)

var_dump(md5($flag3)); //string(32) "58a39a758897868896d56904481fb4a0"
var_dump(intval(md5($flag3))); //int(58)

var_dump("1e1q" == 10); //bool(true)
var_dump("1eq" == 1); //bool(true)

不难看出,不论$flag的值是什么,md5函数都会返回32位的16进制数,利用转换漏洞,可以轻松爆破,从而绕过。但如果e后面有比较长的纯数字字符那么就别想着爆破了(概率较小)。

1
2
3
4
5
6
7
8
$flag = "{This_is_a_test!!!!}"; //假设flag的值不可见
$i=0;
$j=intval(md5($flag));
while($i!=$j)
{
$i++;
}
echo $i; //721

json绕过

JSON 是一种轻量级的数据格式,他基于 javascript 语法的子集,即数组和对象表示。由于使用的是 javascript 语法,因此JSON 定义可以包含在javascript 文件中,对其的访问无需通过基于 XML 的语言来额外解析 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
if (isset($_POST['message'])) {
$message = json_decode($_POST['message']);
$key ="abc";
if ($message->key == $key) {
echo "flag";
}
else {
echo "fail";
}
}
else{
echo "~~~~";
}
?>

输入一个数组进行json解码,如果解码后的message与key值相同,会得到flag,主要思想还是弱类型进行绕过,我们不知道key值是什么,但是我们知道一件事就是它肯定是字符串,这样就可以了,上文讲过,两个等号时会转化成同一类型再进行比较,直接构造一个数值就可以相等了。最终payload message={“key”:0}。 如果$key中的字符串开头并不是字母,则需要我们去爆破。

参考文章

-------------本文结束感谢您的阅读-------------