LOADING...

dadada~

loading

PHP碰撞


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位,都一定会存在重复的编码,这种重复的例子就是硬碰撞

例如:

  • ?a=
  • &b=
  • &c=
  • (太长了所以给收成超链接了)

以上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服务器读取数据,然后在网页中显示这些数据

用法:

  1. Json_encode —— 对变量进行 JSON 编码
  2. json_decode —— 对 JSON 格式的字符串进行解码,转换为 PHP 变量
  3. 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碰撞

大佬文章

大佬文章+1

  • hash碰撞攻击就是构造恶意的数据是hash表退化为链表,每次插入数据都会遍历链表,消耗大量服务器资源,从而达到攻击目的
  • php的数组就是利用hash表实现的,对于碰撞的数据,php采用双向链表解决方案,所以可以利用PHP的数组进行hash碰撞攻击