PHP碰撞
PHP数组
php中有三种数组:
- 数值数组:带有数字 ID 键的数组
<?php
$a=arry("hhh",2,"lll");//自动分配ID键
$b[0]="hello";//人工分配ID键
$b[1]=3;
//for循环输出
- 关联数组:指定的键的数组,每个键关联一个值
<?php
$a=arry("yi"=>1,"er"=>2);
$a["san"]=3;
//foreach输出
- 多维数组:包含一个或多个数组的数组——套娃型
<?php
$a=arry(
arry(99,88),
arry(77)
)
$b=arry(
"hahah"=>arry("h","a")
)
//print_r输出
MD5碰撞
[^MD5]: 单向散列算法(英语:MD5 Message-Digest Algorithm)——是一种被广泛使用的密码散列函数,将数据(如一段文字)运算变为另一固定长度值,是散列算法的基础原理,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致
php中的md5默认返回32字节的结果,所以要得到16字节的需要使用字符串截取:
<?php $str = "hello world!"; echo "32byte-->",md5($str),"<br/>"; //为字符串计算摘要值 $md5Str = substr(md5($str),8,16);//获取16字节的摘要值 echo "16byte-->",$md5Str; ?>
因为32字节的字符串中间8-24字节与16字节加密的结果是相同的,所以在php中可以通过这一方式来获得16字节的摘要值
关于PHP弱类型
php中有==
和===
两种比较方法:
==
在比较时会将不同类型的变量或值转换为相同类型再进行比较——"1a"==1
,此处将1a转化为1——"a1"==0
,此处将a1转化为0"0e123456"=="0e234567"
相互比较的时候,会将0e
这类字符串识别为科学技术法的数字,0的无论多少次方都是零- 在php中当一个字符串被当作一个数值来取值时,如果该字符串没有包含
'.','e','E'
,并且其数值值在整形的范围之内时,该字符串被当作int来取值,其他所有情况下都被作为float来取值,而字符串的开始部分决定了它的值,如果字符串以合法的数值开始,则使用该数值,否则其值为0
===
在比较时直接比较类型是否相同,如果同类型,再比较值
MD5==绕过0e比较
<?php
$flag = "hhhh";
$a = $_GET['a'];
if ($a != 'QNKCDZO' && md5($a) == md5('QNKCDZO')) {
echo $flag;
}else{
echo("error");
}
上面这段代码中就是上述0e开头的所有字串都被认为是0,md5('QNKCDZO')
的结果是0e830400451993494058024219903391
,那么所有0e开头的md5串都可以满足上面的条件,常用的有:
240610708 --> 0e462097431906509019562988736854
s878926199a --> 0e545993274517709034328855841020
s155964671a --> 0e342768416822451524974117254469
s214587387a --> 0e848240448830537924465865611904
以下字符串进行两次md5后以0e开头
7r4lGXCH2Ksu2JNT3BYM
CbDLytmyGm2xQyaLNhWn
770hQgrBOjrcqftrlaZk
MD5===绕过数组比较
在php中的hash函数md5、sha1等处理中若传入一个数组的值,则会报错返回NULL
,而返回的值在类型和内容上都是相同的,所以可以用来绕过某些两边参数可控的场景
<?php
$flag='hhhh';
$a=$_GET['a'];
$b=$_GET['a'];
if(md5($a)===md5($b)){
echo $flag;
}else{
echo("error");
}
此时就可以传参为:?a[]=a&b[]=b,虽然会报错但是程序也会执行
md5===绕过(硬碰撞)
根据MD5的有限计算的特性可以得出,无论是32位还是16位,都一定会存在重复的编码,这种重复的例子就是硬碰撞
例如:
以上abc加密结果均为:ea8b4156874b91a4ef00c5ca3e4a4a34
,可以用来绕过特定的条件
例二:
a=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2
&b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2
NaN和INF
- NAN和INF,分别为非数字和无穷大,但是var_dump一下它们的数据类型是double
- 在md5函数处理它们的时候,是将其直接转换为字符串”NAN”和字符串”INF”使用的
- 它们与任何数据类型(除了true)做强类型或弱类型比较均为false,甚至
NAN===NAN
都是false,但md5('NaN')===md5('NaN')
为true
sha1碰撞
md5,sha1函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是相等的
sha1==0e绕过
10932435112: 0e07766915004133176347055865026311692244
aaroZmOk: 0e66507019969427134894567494305185566735
aaK1STfY: 0e76658526655756207688271159624026011393
aaO8zKZF: 0e89257456677279068558073954252716165668
aa3OFF9m: 0e36977786278517984959260394024281014729
0e1290633704: 0e19985187802402577070739524195726831799
PHP json
什么是json
- JSON (JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式,它基txt于ECMAScript(w3c制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据
- JSON的常规用途是从web服务器读取数据,然后在网页中显示这些数据
用法:
- Json_encode —— 对变量进行 JSON 编码
- json_decode —— 对 JSON 格式的字符串进行解码,转换为 PHP 变量
- json_last_error —— 返回最后发生的错误
几个栗子:
//将PHP数组转换为JSON格式数据
<?php
$a=array('a'=>1,'b'=>'hhhhh','c'=>99 ); //单双引号无所谓
echo json_encode($a);
//输出结果为:{"a":1,"b":"hhhhh","c":99}
//将PHP对象转换为JSON格式数据
<?php
class People{
public $name="";
public $age="";
public $birth="";
}
$b=new People();
$b->name="xiaoming";
$b->age=5;
$b->birth="buzhidao";
echo json_encode($b);
//输出结果为:{"name":"xiaoming","age":5,"birth":"buzhidao"}
//将JSON格式的字符串解码并转化为PHP变量
<?php
$c='{"a":1,"b":"11","c":99}';
var_dump(json_decode($c));
//运行结果为:object(stdClass)#2 (3) { ["a"]=> int(1) ["b"]=> string(2) "11" ["c"]=> int(99) }
//不可以用echo,会报错||使用JSON_UNESCAPED_UNICODE选项决定是否编码中文
//var_dump函数:用于输出变量的相关信息,函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值,数组将递归展开值,通过缩进显示其结构
json解码绕过
php在处理传入的json串时使用json_decode将其解码,进行比较时,可以利用字符串与0比较为真的特点绕过
<?php
$flag = 'hhhhhhhhhhhh';
$a = $_GET['a'];
$b = json_decode($a);
echo $b->abc;
var_dump($b->abc == $flag);
if ($b->abc == $flag) echo $flag;
else echo "error!!";
//当传入?a={"abc":0}时,输出flag
array_search绕过
函数的原型为:
mixed array_search ( mixed $needle , array $haystack [, bool $strict = false ] )
,其中$needle,$haystack
必需,$strict
可选 ,函数判断$haystack
中的值是存在$needle
,存在则返回该值的键值(数组的下标,例如该值在第一位返回0,第二位返回1),第三个参数默认为false,如果设置为true则会进行严格过滤(带类型的比较)
<?php
$a = array(0,1,2,3);
var_dump(array_search("a",$a));
var_dump(array_search("1a",$a));
var_dump(array_search("1a",$a,true));
?>
//输出结果为:int(0) int(1) int(2) bool(false)
php hash碰撞
- hash碰撞攻击就是构造恶意的数据是hash表退化为链表,每次插入数据都会遍历链表,消耗大量服务器资源,从而达到攻击目的
- php的数组就是利用hash表实现的,对于碰撞的数据,php采用双向链表解决方案,所以可以利用PHP的数组进行hash碰撞攻击