PHP基本语法与弱类型的知识总结

这一周自己学习了PHP的基本语法和对PHP弱类型进行总结,下边就是我的分享。

一、PHP的基本语法

      PHP的基本语法,我自己主要是在 http://www.w3school.com.cn/php/index.asp  这个网站上学习的,里边介绍的非常详细。如果没有PHP基础的,可以去那个网站上学习。我主要是介绍PHP弱类型,以及对PHP弱类型的总结。

二、PHP弱类型的总结

    因为在ctf比赛中,PHP弱类型的题也出现不少,有必要学习PHP弱类型。所以自己也是在网上找一些PHP弱类型的知识。          

---
#<center> PHP弱类型总结与例题</center> #
在ctf比赛中,PHP弱类型的题也出现了不少,所以有必要去了解和和掌握这类型的题。自己也是总结了这几周做PHP弱类型的题以及在网上找的相关知识,来做一个整体的PHP弱类型总结。
# 0x01、PHP中"=="与"==="的符号比较

    <?php
    $a==$b;
    $a===$b;
    ?>

== 在进行比较时,先将字符串的类型转化为相同,再次进行比较

===在进行比较时,先判断两种字符的类型是否相等,再比较值是否相等  
如例题:

    <?php  
    if(isset($_GET['name']) and isset($_GET['password'])){
    if($_GET['name']==$_GET['password'])  
        echo '<p>Your password can not be your name!</p>';
    else if(sha1($_GET['name'])===sha1($_GET['password']))
    die('Flag:'.$flag);
    else  
        echo '<p>Invalid password.</p>';  
    }  
    else{
        echo '<p>Login first!</p>';
    ?>  

这就是一道典型的PHP弱类型的题,但需要有PHP基本的句法知识,此题还涉及到安全哈希加密算法sha1。下边我们对代码进行分析   

    isset() -- 来检测变量是否设置   

对name和password,我们可以让其类型为数组,但让数组里的数值不相等。 所以我们可以再这个网站.php后加上一个语句  

    ?name[]=a$password[]=b  

这样回车即可得到flag  

# 0x02、 数字和字符串或有数字的字符串,会转化成数值进行比较
PHP不会严格检验传入的变量,也可以将变量自由的转换类型  

例如:在$a=$b的比较中  

    $a=null;$b=false;//判断为真
    $a='';  $b=0;    //判断也为真  

详细比较,如下所示  

    <?php
    var_dump("justinlee"==0); //ture
    var_dump("1justinlee"==1);//ture
    var_dump("justinlee1"==1);//ture
    var_dump("justin1"==1);   //false
    var_dump("justinlee1"==0);//ture
    var_dump("0e12345"=="0e456789");//ture
    ?>
观察上面代码,"justinlee"==0 比较时,因为justinlee是字符串,会被强制转化为数值,而结果是0,就和0相等。"1justinlee"就会被转化为1,所以"1justinlee"==1就为ture。  

对"justinlee1"==1为ture和"justin1"==1为flase,这是为什么呢?原来是当一个字符串当作一个数值来取值时,其结果和类型如下:如果该字符串没有包含'.','e','E'时,并且其数值在整形的范围之内,该字符串被当作为int来取值,其他所有情况下都被作为float来取值,该字符串的开始部分决定了它的值,如果该字符串以合法的数值开始,则使用该数值。否则其值为0  

"0e12345"=="0e456789"在进行比较时,会将这类字符串识别为科学记数法,0的多少次方都是0,所以相等。  

# 0x03、MD5绕过

代码如下  

    <?php
    $md51==md5('QNKCDZO');
    $a=@$_GET['a'];
    $md5=@md5($a);
    if(isset($a)){
       if($a!='QNKCDZO'&&$md51 == $md52){
          echo"nctf{************}";}
       else{
          echo"false!!!";}
    }
    else{
        echo"please input a";}
    ?>  

这是一道md5绕过题,分析代码得,QNKCDZO是用MD5函数加密,然后赋值给md51,if后边是判断输入的a不等于QNKCDZO,而且md51=a。首先,对QNKCDZO加密,去浏览器搜索MD5函数,进行加密。加密后的结果如下所示

md5:0e83040045199349405802421990391  

可以看到加密后的结果是以0e开头的,而md5开头是0e的字符串 上边提到过,0e在比较的时候会将其视作为科学计数法,所以无论0e后面是什么,0的多少次方还是0  

所以去百度找以0e开头MD5的值,如下  

s878926199a  

0e545993274517709034328855841020  

s155964671a  

0e342768416822451524974117254469  

s214587387a  

0e848240448830537924465865611904  
 
随便从中找一个a值输入,此题便可得到flag值

# 0x04、strcmp漏洞绕过
如例题  

    <?php
    $password="***************"
    if(isset($_POST['password'])){
      if (strcmp($_POST['password'], $password) == 0) {
        echo "Right!!!login success";
        exit();    
        } else {
           echo "Wrong password..";}
    ?>  

分析代码得  
strcmp是比较两个字符串,如果str1<str2 则返回<0 如果str1大于str2返回>0 如果两者相等 返回0  
我们是不知道$password的值的,题目要求strcmp判断的接受的值和$password必需相等,strcmp传入的期望类型是字符串类型,如果传入的是个数组,它会如何比较呢?当传入password[]=xxxx时,因为函数接受不到不符合得类型,将出现错误,但是还是判断其相等。所以我们可以用password[]=xxxx进行绕过。  

# 0x05、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的值我们不知道,但是可以利用0=="justinlee"这种形式绕过

# 0x06、array_search is_array绕过  

代码如下:  
 
     <?php
      if(!is_array($_GET['test'])){exit();}
     $test=$_GET['test'];
     for($i=0;$i<count($test);$i++){
         if($test[$i]==="admin"){
             echo "error";
             exit();}
         $test[$i]=intval($test[$i]);}
     if(array_search("admin",$test)===0){
        echo "flag";}
     else{
        echo "false";
     }
     ?>  

分析代码,首先我们要了解array_search is_array的意思。  

php搜索数组中我们一般会用到array_search和is_array两个函数。array_search()和is_array()一样,在数组中查找一个键值。如果找到了该值,匹配元素的键名会被返回。如果没找到,则返回 false。

所以先判断传入的是不是数组,然后循环遍历数组中的每个值,并且数组中的每个值不能和admin相等,并且将每个值转化为int类型,再判断传入的数组是否有admin,有则返回flag。即payload test[]=0可以绕过。  

下面是array_search语法的介绍  

array_search(value,array,strict)  

value、array是参数,必需填写的,strict可选  函数判断array中的值是存在value,存在则返回该值的键值 第三个参数默认为false,如果设置为true则会进行严格过滤。  

    <?php
    $a=array(0,1);
    var_dump(array_search("admin",$a));//int(0)=>返回键值0
    var_dump(array_seach("1admin",$a));//int(1)==>返回键值1
    ?>
array_search函数类似于==,也就是$a=="admin",所以是$a=0。当然如果第三个参数为true则就不能绕过。

 
   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值