php弱类型比较


0x00 强类型与弱类型

强类型

  • 所谓强类型(Strongly typed),顾名思义就是强制数据类型定义的语言。也就是说,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型。J
  • ava、.NET、C++等都是强类型语言,在变量使用之前必须声明变量的类型和名称;且不经强制转换不允许两种不同类型的变量互相操作。

弱类型

  • 对数据的类型要求并不严格,可以让数据类型互相转换。

1x00 PHP中“”和“=”的区别

  • “”和“=”都是用来比较两个数值是否相等的操作符。
  • 当比较的两个值都是相同类型时候“”和“=”是相等的。
  • 11(两个int)1.01.0(两个float)‘H1TerHub’==’H1TerHub‘(两个字符串)
  • ATTENTION:在前后两个值的类型不一样的时候,‘==’会自动转换类型

php弱类型比较 - 图1

一般看到“==”就可以关注是否存在弱类型比较

1x01 “==”类型转换的规则

  • 1、字符串和数字比较,字符串会被转换成数字。
  • “admin”==0(true)//admin被转换成数字,由于admin是字符串,转换失败,int(admin)=0,所以比较结果是true。
  • 2、混合字符串转换成数字,看字符串的第一个。
  • “1admin”==1 “2admin”==2
  • 3、字符串开头以xex开头,x代表数字。会被转换成科学计数法。
  • x*10^x的形式。

‘2e2’=2*10^2=200 “-2e2”=-2*10^2 “0e2”=0*10^2=0 “hh-2e2”=0 “1hh-2e2”=1

应用范例:

  • if (md5(php弱类型比较 - 图2%20!%3D%20md5(#card=math&code=Username%29%20%21%3D%20md5%28)password)) {$logined = false;}
  • 题目大意是要输入一个字符串和数字类型,并且他们的md5值相等,就可以成功执行下一步语句
  • 介绍一批md5开头是0e的字符串上文提到过,0e在比较的时候会将其视作为科学计数法,所以无论0e后面是什么,0的多少次方还是0md5(‘240610708’) == md5(‘QNKCDZO’)成功绕过!

0e开头的字符串

  • QNKCDZO
  • 0e830400451993494058024219903391
  • s878926199a
  • 0e545993274517709034328855841020
  • s155964671a
  • 0e342768416822451524974117254469
  • s214587387a
  • 0e848240448830537924465865611904
  • s214587387a
  • 0e848240448830537924465865611904
  • s878926199a
  • 0e545993274517709034328855841020
  • s1091221200a
  • 0e940624217856561557816327384675
  • s1885207154a
  • 0e509367213418206700842008763514

1x02 bool类型的true跟任意字符串可以弱类型相等

<?php If ( true=“H1TerHub”){ echo “success”; }

1x03 Strcmp函数的漏洞

  • Strcmp(str1, str2)是比较两个字符串,如果str10 如果两者相等返回0

例题

php弱类型比较 - 图3

我们是不知道php弱类型比较 - 图4password必需相等,strcmp传入的期望类型是字符串类型,如果传入的是个数组会怎么样呢?

我们传入password[]=xxx可以绕过是因为函数接受到了不符合的类型,将发生错误,函数返回值为0,所以判断相等

payload:password[]=xxx

Sha1函数的漏洞•与strcmp函数类似,sha1也有相同的漏洞。

  • url/check.php?a[]=213 •If(sha1($_GET(‘a’))==0) •echo ‘flag’;
  • 同样可以绕过。

1x03 Switch绕过

这个原理和之前的“==”相似

php弱类型比较 - 图5

1x04 json绕过

<?php if (isset($_POST['message'])) { $message = json_decode($_POST['message']); $key ="*********"; if ($message->key ==$key ) { echo "flag"; } else { echo "fail"; } } else{ echo "~~~~"; } ?>

输入一个json类型的字符串,json_decode函数解密成一个数组,判断数组中key的值是否等于php弱类型比较 - 图6key的值我们不知道

这时我们构造一个和任意字符串返回为真的数组{“key”:true}。即可绕过

payload=message={“key”,true}

1x05 array_search的漏洞

  • array_search() 函数与 in_array() 一样,在数组中查找一个键值。如果找到了该值,匹配元素的键名会被返回。如果没找到,则返回false。

<?php $a=array(1,4); var_dump(array_search("4admin",$a)); // int(0)=> 返回键值1 var_dump(array_search("1admin",$a)); // int(1) ==>返回键值0 ?>//这个和之前的类型转换类似,但是如果是array_search(“4admin”,$a,true),最后的“true”会禁止类型转换。

这个和之前的类型转换类似,但是如果是array_search(“4admin”,$a,true),最后的“true”会禁止类型转换。

2x00 弱类型比较产生漏洞的真实例子

这是一个登陆界面访问Index.php才能生成验证码

php弱类型比较 - 图7

php弱类型比较 - 图8

Check.php 验证验证码

php弱类型比较 - 图9

假如,check.php没有验证验证码是否允许为空,那么如果在我未访问index.php的情况下(或者删除phpsessid),$_session[‘authcode1’]===NULL

我直接在check.php 提交user=admin&pw=256&reg=

令reg为空字符串。

这时空字符串===NULL

达到绕过验证码

0x21数组key值溢出与MD5强比较

  1. **<?php**
  2. $six_number = $_POST['webp'];
  3. $a = $_POST['a'];
  4. $b = $_POST['b'];
  5. $c = $_POST['c'];
  6. if (md5($six_number) == 'e10adc3949ba59abbe56e057f20f883e' && md5($a) === md5($b) && $a !== $b)
  7. { if($array[++$c]=1)
  8. { if($array[]=1){ echo "nonono"; }
  9. else{ require_once 'flag.php';
  10. echo $flag; } } }
  11. **?>**

md5 e10adc3949ba59abbe56e057f20f883e 对应的明文是 123456,md5 相同而内容不同的话可以用数组绕过,即 a[]=1&b[]=2.

然而这个 if($array[]=1) 怎么绕过,咱两天里断断续续想着也没想出来……

最后比赛结束了才知道是数组 Key 整数溢出

在 php 中一个 array 包含键 key 和值 value,当给一个未指定 key 的 array 赋值时,会自动给当前 key 赋值为上一个使用过的 整数 key +1(一个整数),如果没有使用过的话则为 0.

假如之前的 key 是个字符或字符串,那新的下标也就是 0.

另外 php 的 ++ 除了会给整数 +1 外,还可以给字符 +1,倒是字符的 ++ 有亿点怪,比如 z-> aa, Z -> AA, 1Z -> 2A, Zaf -> Zag, 3adAZ -> 3adBA, etc.

这里就不研究了,也不是这题关键(喵喵懵了,感觉得看底层源码才知道

而这里的最大表示数是 2**63-1,即 9223372036854775807,然后因为 if($array[++$c]=1) 做了自增处理,咱把 c 设为 9223372036854775806,当 if($array[]=1) 赋值的时候就会造成溢出,报错且判断不为真,从而能够拿到 $flag.

0x21弱类型绕过序列化数据比较

http://ctf5.shiyanbar.com/10/web1/

天网系统

右击查看源代码

  1. <!-- $test=$_GET['username']; $test=md5($test); if($test=='0') -->

username中输入md5值为0e开头的字符串QNKCDZO

出现/user.php?fame=hjkleffifer

访问获得以下源码

  1. $unserialize_str = $_POST['password'];
  2. $data_unserialize = unserialize($unserialize_str);
  3. if($data_unserialize['user'] == '???' && $data_unserialize['pass']=='???'){
  4. print_r($flag);
  5. } 伟大的科学家php方言道:成也布尔,败也布尔。 回去吧骚年

从源码可以看出反序列化后存在php弱类型比较,可以通过true来进行绕过

  1. <?php
  2. $array = [
  3. "user" => true,
  4. "pass" => true,
  5. ];
  6. echo serialize($array);
  7. ?>

使用上述代码生成序列化字符串

  1. a:2:{s:4:"user";b:1;s:4:"pass";b:1;}

QNKCDZO填入username框中,将序列化字符串填入password框中,成功出现flag

1568989112589

php弱类型比较 - 图10

数组绕过strcmp函数

strcmp绕过 php >5.3

  1. <?php
  2. show_source(__FILE__);
  3. $password="***************";
  4. if(isset($_POST['password'])){
  5. if (strcmp($_POST['password'], $password) == 0) {
  6. echo "Right!!!login success";
  7. exit();
  8. } else {
  9. echo "Wrong password..";
  10. }
  11. }
  12. ?>

通过查看php手册可以看到

  1. strcmp ( string $str1 , string $str2 ) : int

如果 str1 小于str2 返回 < 0;如果 str1大于 str2返回 > 0;

如果两者相等,返回 0。

当php版本大于5.3时,strcmp函数传入字符串会爆出Warning错误,并且返回值为0

此时这里可以构造payload password[]=1

1568989770013

php弱类型比较 - 图11

数组绕过md5、sha1、base64_decode

利用情景

  1. <?php
  2. show_source(__FILE__);
  3. $tmp1 = $_POST['tmp1'];
  4. $tmp2 = $_POST['tmp2'];
  5. if(isset($tmp1) && isset($tmp2) && $tmp1 !== $tmp2 )
  6. {
  7. die("Error");
  8. }
  9. if(md5($tmp1)==md5($tmp2) && sha1($tmp1)==sha1($tmp2)&&base64_decode($tmp1) == base64_decode($tmp2))
  10. {
  11. echo "successful";
  12. }
  13. ?>

md5()sha1()base64_decode()只能处理传入的字符串数据,当传入数组后会报出Warning错误但是仍然会正常运行并返回值,当==左右两边都错误时,并且正常运行返回相同的值,就可以是判定条件成立。

1568991179209

php弱类型比较 - 图12

实际上这里换成===强类型判断结果也是一样的

1568991297615

php弱类型比较 - 图13

使用md5碰撞绕过强制类型转换后的强类型比较

  1. if((string)$_POST['param1']!==(string)$_POST['param2'] && md5($_POST['param1'])===md5($_POST['param2']))
  2. {
  3. die("success!);
  4. }

在强类型比较的基础上,把比较类型的转成字符串,这样数组绕过就不能用了,这里可以通过md5碰撞去生成两个字符串内容不同,md5相同的文件。

使用fastcoll工具来进行md5碰撞攻击

  1. fastcoll_v1.0.0.5.exe -p .\a.bin -o a1.bin a2.bin

用python来进行读取然后进行url编码

  1. #coding=utf-8
  2. import urllib.parse
  3. f1 = open("a1.bin","rb").read()
  4. f2 = open("a2.bin","rb").read()
  5. s1 = urllib.parse.quote(f1)
  6. s2 = urllib.parse.quote(f2)
  7. print(s1)
  8. print(s2)

1568994633570

php弱类型比较 - 图14

将其用post传参,成功绕过

1568994678783

php弱类型比较 - 图15

变量覆盖

我在变量覆盖第一题里面的WP中推荐了几篇关于变量覆盖的文章,同时如果对变量覆盖第一题有些遗忘的也可以看看我之前的那个文章:
CGCTF 变量覆盖第一题

这题还是比较简单的,直接上WP
我们进入环境之后发现没有东西, 还是老套路f12看源码,发现了php代码,进行代码审计:

$value){

php弱类型比较 - 图16%7B%0Aecho%20%24flag%3B%0A%7D%0A1%0A2%0A3%0A4%0A5%0A6%0A%E8%A6%81%E6%B1%82%24name%3D%22meizijiu233%22%E5%B0%B1%E5%8F%AF%E4%BB%A5%E8%8E%B7%E5%BE%97flag%EF%BC%8C%E4%BD%86%E6%98%AF%E6%88%91%E4%BB%AC%E5%B9%B6%E6%B2%A1%E6%9C%89%24name%E8%BF%99%E4%B8%AA%E5%8F%98%E9%87%8F%E3%80%82%E6%88%91%E4%BB%AC%E5%86%8D%E7%9C%8B%E7%9C%8B%E4%B8%8A%E9%9D%A2%E7%9A%84%EF%BC%8C%E6%98%AF%E4%B8%80%E4%B8%AA%E6%95%B0%E7%BB%84%E7%9A%84%E9%81%8D%E5%8E%86%E3%80%82%E4%BD%86%E6%98%AF%E4%B8%8D%E5%90%8C%E7%9A%84%E6%98%AF%EF%BC%8C%E4%BD%BF%E7%94%A8%E4%BA%86%E5%8F%AF%E5%8F%98%E5%8F%98%E9%87%8F%E3%80%82%E5%85%B3%E4%BA%8E%E5%8F%AF%E5%8F%98%E5%8F%98%E9%87%8F%EF%BC%8C%E6%88%91%E8%A7%89%E5%BE%97%E4%B8%BE%E4%B8%AA%E4%BE%8B%E5%AD%90%E5%B0%B1%E5%8F%AF%E4%BB%A5%E6%98%8E%E7%99%BD%E4%BA%86%EF%BC%9A%0A%0A%3C%3Fphp%0A%24name%3Dfeng%3B%0A%24%24name%3Dfeng1%3B%0Aprint%20%24name%3B%0Aprint%20%24%24name%3B%0Aprint%20%24feng%3B%0A%E7%BB%93%E6%9E%9C%E5%BA%94%E8%AF%A5%E6%98%AF%E8%BF%99%E6%A0%B7%EF%BC%9A%0Afeng%0Afeng1%0Afeng1%0A1%0A2%0A3%0A4%0A5%0A6%0A7%0A8%0A9%0A10%0A%E5%8F%AF%E5%8F%98%E5%8F%98%E9%87%8F%E5%8F%AF%E4%BB%A5%E7%90%86%E8%A7%A3%E6%88%90%24name%E6%98%AFfeng%EF%BC%8C%E5%89%8D%E9%9D%A2%E5%86%8D%E5%8A%A0%E4%B8%80%E4%B8%AA%24%E5%B0%B1%E7%9B%B8%E5%BD%93%E4%BA%8E%24feng%EF%BC%8C%E5%B0%B1%E6%98%AF%E6%8A%8A%E4%B8%80%E4%B8%AA%E5%8F%98%E9%87%8F%E7%9A%84%E5%80%BC%E4%BD%9C%E4%B8%BA%E6%96%B0%E7%9A%84%E5%8F%98%E9%87%8F%E7%9A%84%E5%8F%98%E9%87%8F%E5%90%8D%E3%80%82%E8%BF%99%E6%A0%B7%E6%9D%A5%E7%90%86%E8%A7%A3%E5%B0%B1%E5%8F%AF%E4%BB%A5%E4%BA%86%E3%80%82%0A%0A%E7%9F%A5%E9%81%93%E4%BA%86%E8%BF%99%E4%BA%9B%E7%9F%A5%E8%AF%86%E5%90%8E%EF%BC%8C%E6%88%91%E4%BB%AC%E6%9D%A5%E6%83%B3%E6%83%B3%E6%80%8E%E4%B9%88%E8%BF%9B%E8%A1%8C%E5%8F%98%E9%87%8F%E8%A6%86%E7%9B%96%E3%80%82%E5%9B%A0%E4%B8%BA%E6%9C%89%E4%BA%86%E5%8F%AF%E5%8F%98%E5%8F%98%E9%87%8F%EF%BC%8C%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E8%BF%99%E6%A0%B7%E6%9E%84%E9%80%A0%EF%BC%9A%0A%0A%3Fname%3Dmeizijiu233%0A1%0A%E8%BF%99%E6%A0%B7%E7%9A%84%E8%AF%9D%E5%9C%A8%24_GET%E4%B8%AD%E6%98%AF%E4%BB%A5name%3Ameizijiu233%E8%BF%99%E6%A0%B7%E7%9A%84%E9%94%AE%E5%80%BC%E5%AF%B9%E5%AD%98%E5%9C%A8%EF%BC%88%E8%BF%99%E6%A0%B7%E8%AF%B4%E5%8F%AF%E8%83%BD%E4%B8%8D%E5%A4%AA%E5%90%88%E9%80%82%EF%BC%8C%E5%BA%94%E8%AF%A5%E6%98%AF%24_GET%5B%E2%80%98name%E2%80%99%5D%E6%98%AFmeizijiu233%EF%BC%89%0A%E8%BF%99%E6%A0%B7%E7%9A%84%E8%AF%9D%EF%BC%8C%E4%B8%8A%E9%9D%A2%E7%9A%84%E4%BB%A3%E7%A0%81%E5%B0%B1%E5%8F%98%E6%88%90%E4%BA%86%E8%BF%99%E6%A0%B7%0A%24key%3Dname%2C%24value%3Dmeizijiu233%0A%24%24key%3D%24value%2C%E5%8F%98%E6%88%90%E4%BA%86%24name%3Dmeizijiu233%0A%E8%BF%99%E6%A0%B7%E6%9E%84%E9%80%A0%E4%B9%8B%E5%90%8Eget%E4%BC%A0%E9%80%92%E5%B0%B1%E5%8F%AF%E4%BB%A5%E6%88%90%E5%8A%9F%E8%8E%B7%E5%BE%97flag.%0A%E5%8E%9F%E6%96%87%E9%93%BE%E6%8E%A5%EF%BC%9A%5Bhttps%3A%2F%2Fblog.csdn.net%2Frfrder%2Farticle%2Fdetails%2F108466368%5D(https%3A%2F%2Fblog.csdn.net%2Frfrder%2Farticle%2Fdetails%2F108466368)%0A%0A!%5BUntitled%5D(php%25E5%25BC%25B1%25E7%25B1%25BB%25E5%259E%258B%25E6%25AF%2594%25E8%25BE%2583%25200a868bcbb12445e783f7b93d7573b5b3%2FUntitled.png)#card=math&code=key%20%3D%20%24value%3B%0A%7D%0Aif%28%24name%20%3D%3D%20%22meizijiu233%22%29%7B%0Aecho%20%24flag%3B%0A%7D%0A1%0A2%0A3%0A4%0A5%0A6%0A%E8%A6%81%E6%B1%82%24name%3D%22meizijiu233%22%E5%B0%B1%E5%8F%AF%E4%BB%A5%E8%8E%B7%E5%BE%97flag%EF%BC%8C%E4%BD%86%E6%98%AF%E6%88%91%E4%BB%AC%E5%B9%B6%E6%B2%A1%E6%9C%89%24name%E8%BF%99%E4%B8%AA%E5%8F%98%E9%87%8F%E3%80%82%E6%88%91%E4%BB%AC%E5%86%8D%E7%9C%8B%E7%9C%8B%E4%B8%8A%E9%9D%A2%E7%9A%84%EF%BC%8C%E6%98%AF%E4%B8%80%E4%B8%AA%E6%95%B0%E7%BB%84%E7%9A%84%E9%81%8D%E5%8E%86%E3%80%82%E4%BD%86%E6%98%AF%E4%B8%8D%E5%90%8C%E7%9A%84%E6%98%AF%EF%BC%8C%E4%BD%BF%E7%94%A8%E4%BA%86%E5%8F%AF%E5%8F%98%E5%8F%98%E9%87%8F%E3%80%82%E5%85%B3%E4%BA%8E%E5%8F%AF%E5%8F%98%E5%8F%98%E9%87%8F%EF%BC%8C%E6%88%91%E8%A7%89%E5%BE%97%E4%B8%BE%E4%B8%AA%E4%BE%8B%E5%AD%90%E5%B0%B1%E5%8F%AF%E4%BB%A5%E6%98%8E%E7%99%BD%E4%BA%86%EF%BC%9A%0A%0A%3C%3Fphp%0A%24name%3Dfeng%3B%0A%24%24name%3Dfeng1%3B%0Aprint%20%24name%3B%0Aprint%20%24%24name%3B%0Aprint%20%24feng%3B%0A%E7%BB%93%E6%9E%9C%E5%BA%94%E8%AF%A5%E6%98%AF%E8%BF%99%E6%A0%B7%EF%BC%9A%0Afeng%0Afeng1%0Afeng1%0A1%0A2%0A3%0A4%0A5%0A6%0A7%0A8%0A9%0A10%0A%E5%8F%AF%E5%8F%98%E5%8F%98%E9%87%8F%E5%8F%AF%E4%BB%A5%E7%90%86%E8%A7%A3%E6%88%90%24name%E6%98%AFfeng%EF%BC%8C%E5%89%8D%E9%9D%A2%E5%86%8D%E5%8A%A0%E4%B8%80%E4%B8%AA%24%E5%B0%B1%E7%9B%B8%E5%BD%93%E4%BA%8E%24feng%EF%BC%8C%E5%B0%B1%E6%98%AF%E6%8A%8A%E4%B8%80%E4%B8%AA%E5%8F%98%E9%87%8F%E7%9A%84%E5%80%BC%E4%BD%9C%E4%B8%BA%E6%96%B0%E7%9A%84%E5%8F%98%E9%87%8F%E7%9A%84%E5%8F%98%E9%87%8F%E5%90%8D%E3%80%82%E8%BF%99%E6%A0%B7%E6%9D%A5%E7%90%86%E8%A7%A3%E5%B0%B1%E5%8F%AF%E4%BB%A5%E4%BA%86%E3%80%82%0A%0A%E7%9F%A5%E9%81%93%E4%BA%86%E8%BF%99%E4%BA%9B%E7%9F%A5%E8%AF%86%E5%90%8E%EF%BC%8C%E6%88%91%E4%BB%AC%E6%9D%A5%E6%83%B3%E6%83%B3%E6%80%8E%E4%B9%88%E8%BF%9B%E8%A1%8C%E5%8F%98%E9%87%8F%E8%A6%86%E7%9B%96%E3%80%82%E5%9B%A0%E4%B8%BA%E6%9C%89%E4%BA%86%E5%8F%AF%E5%8F%98%E5%8F%98%E9%87%8F%EF%BC%8C%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E8%BF%99%E6%A0%B7%E6%9E%84%E9%80%A0%EF%BC%9A%0A%0A%3Fname%3Dmeizijiu233%0A1%0A%E8%BF%99%E6%A0%B7%E7%9A%84%E8%AF%9D%E5%9C%A8%24_GET%E4%B8%AD%E6%98%AF%E4%BB%A5name%3Ameizijiu233%E8%BF%99%E6%A0%B7%E7%9A%84%E9%94%AE%E5%80%BC%E5%AF%B9%E5%AD%98%E5%9C%A8%EF%BC%88%E8%BF%99%E6%A0%B7%E8%AF%B4%E5%8F%AF%E8%83%BD%E4%B8%8D%E5%A4%AA%E5%90%88%E9%80%82%EF%BC%8C%E5%BA%94%E8%AF%A5%E6%98%AF%24_GET%5B%E2%80%98name%E2%80%99%5D%E6%98%AFmeizijiu233%EF%BC%89%0A%E8%BF%99%E6%A0%B7%E7%9A%84%E8%AF%9D%EF%BC%8C%E4%B8%8A%E9%9D%A2%E7%9A%84%E4%BB%A3%E7%A0%81%E5%B0%B1%E5%8F%98%E6%88%90%E4%BA%86%E8%BF%99%E6%A0%B7%0A%24key%3Dname%2C%24value%3Dmeizijiu233%0A%24%24key%3D%24value%2C%E5%8F%98%E6%88%90%E4%BA%86%24name%3Dmeizijiu233%0A%E8%BF%99%E6%A0%B7%E6%9E%84%E9%80%A0%E4%B9%8B%E5%90%8Eget%E4%BC%A0%E9%80%92%E5%B0%B1%E5%8F%AF%E4%BB%A5%E6%88%90%E5%8A%9F%E8%8E%B7%E5%BE%97flag.%0A%E5%8E%9F%E6%96%87%E9%93%BE%E6%8E%A5%EF%BC%9A%5Bhttps%3A%2F%2Fblog.csdn.net%2Frfrder%2Farticle%2Fdetails%2F108466368%5D%28https%3A%2F%2Fblog.csdn.net%2Frfrder%2Farticle%2Fdetails%2F108466368%29%0A%0A%21%5BUntitled%5D%28php%25E5%25BC%25B1%25E7%25B1%25BB%25E5%259E%258B%25E6%25AF%2594%25E8%25BE%2583%25200a868bcbb12445e783f7b93d7573b5b3%2FUntitled.png%29)