【从零开始学CTF】4、PHP中的弱类型比较

【从零开始学CTF】4、PHP中的弱类型比较

大家好,我是H1TerHub的Rman,一直以来对网络安全十分感兴趣,今年在学校里成立H1TerHub战队,主打CTF的赛事。由于很多同学都是刚刚接触网络安全和CTF,于是就开了一些课,帮助他们入门和接触这个赛事。

于是乎就有把上课用的PPT编辑下分享给大家的想法。争取按照我们上课的进度,每周一更,希望能让更多的人了解这个比赛,也希望能跟大家共同交流学习。

本人也只是对CTF略有了解,文章也多改自网上各位师傅们的博客,当中也许会有错误,还望各位师傅指点。

0x00 强类型与弱类型

强类型

•所谓强类型(Strongly typed),顾名思义就是强制数据类型定义的语言。也就是说,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型。J

•ava、.NET、C++等都是强类型语言,在变量使用之前必须声明变量的类型和名称;且不经强制转换不允许两种不同类型的变量互相操作。


弱类型

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


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

•“==”和“===”都是用来比较两个数值是否相等的操作符。

•当比较的两个值都是相同类型时候“==”和“===”是相等的。

•1==1(两个int)1.0==1.0(两个float)‘H1TerHub’==’H1TerHub‘(两个字符串)

ATTENTION:在前后两个值的类型不一样的时候,‘==’会自动转换类型

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

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($Username) != md5($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)是比较两个字符串,如果str1<str2 则返回<0
如果str1大于str2返回>0 如果两者相等
返回0

例题


我们是不知道$password的值的,题目要求strcmp判断的接受的值和$password必需相等,strcmp传入的期望类型是字符串类型,如果传入的是个数组会怎么样呢?


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

payload:
password[]=xxx

Sha1函数的漏洞

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

•url/check.php?a[]=213
•If(sha1($_GET(‘a’))==0)
•echo ‘flag’;

•同样可以绕过。

1x03 Switch绕过

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


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的值是否等于
$key的值,但是$key的值我们不知道


这时我们构造一个和任意字符串返回为真的数组{“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才能生成验证码

Check.php 验证验证码

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

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

令reg为空字符串。

这时空字符串===NULL

达到绕过验证码



3x00 练习



来源:

galaxylab.org/php-%E5%B

mamicode.com/info-detai

blog.csdn.net/wy_97/art

cnblogs.com/Mrsm1th/p/6

编辑于 2017-10-21

文章被以下专栏收录