情人节约宝妹攻略
       
      
    
   
  
  安全宝在情人节前出了一个网络安全闯关游戏,题目还是比较简单的。
Q1、世界上先有男人还是先有女人? 答案是“男人”。
Q2、世界上为什么先有男人? 答案是“先生”。
Q3、请从本页面找到密码并输入。 查看网页源码,可以看到一段源码:
1 2 3 4 5 6 7 8 9 <div  class ="page page-3 invisible" >     <div  class ="dp c dp-4-1" > </div >      <div  class ="password-form dp c" >          <input  type ="text"  class ="text"  name =""  value =""  id ="password1" />          <a  href ="javascript:;"  class ="form-button h"  onclick ="checkPassword(this)" > </a >      </div >      <div  class ="dp c dp-logo" > </div >  </div > 
可见,输入密码后点击按钮会调用checkPassword函数,在源码里可以看到网页引用了一个index.js文件:
1 <script  src ="js/index.js"  type ="text/javascript" > </script > 
访问该文件,里面有一段被混淆的js代码:
1 (function (b,a,c,d )function (e )".page" ).filter(".page-" +e).show().siblings().hide()};b.checkPassword=function (f )var  e=c(f).prev().val();if (e=="wo ai anquanbao" ){showPage(4 )}else {c(f).prev().val("" ).focus()}}})(window ,document ,window .jQuery); 
格式化一下js代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 (function (b, a, c, d )      b.showPage = function (e )          c(".page" ).filter(".page-"  + e).show().siblings().hide()     };     b.checkPassword = function (f )          var  e = c(f).prev().val();         if  (e == "wo ai anquanbao" ) {             showPage(4 )         } else  {             c(f).prev().val("" ).focus()         }     } })(window , document , window .jQuery); 
可见,checkPassword函数会判断输入的密码是否为"wo ai anquanbao",是的话就调用showPage(4)函数显示第4个问题。
Q4、在这里我用.htaccess限制了访问所有图片,来找找约会地点吧。 
图片里提示了"yuehui.png",访问http://yuebaomei.com/yuehui.png,发现访问不了。http://yuebaomei.com/show.php?p=dGlzaGkucG5n,打开是上面那张图片。show.php就是用来显示图片的脚本,参数p的值"dGlzaGkucG5n"看起来像base64编码,解码结果为"tishi.png"。
也就是说,参数p的值是图片名的base64编码,那么"yuehui.png"的base64编码为"eXVlaHVpLnBuZw=="。http://yuebaomei.com/show.php?p=eXVlaHVpLnBuZw==,成功得到了约会地点:
要拿终极大奖的话可以继续答题。
Q5、在这里宝妹有三个问题,任选其一做对就有终极大奖哦。 
A、我没安卓手机,不好调试。 
B、我对SQL注入不太熟悉。 
C、所以只能选择PHP了。 
 
选择PHP代码审计,可以看到一段PHP代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <?php $flag  = "THIS IS FLAG" ;if  ("POST"  == $_SERVER ['REQUEST_METHOD' ]){     $password  = $_POST ['password' ];     if  (0  >= preg_match('/^[[:graph:]]{12,}$/' , $password ))     {         echo  'Wrong Format' ;         exit ;     }     while  (TRUE )     {         $reg  = '/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/' ;         if  (6  > preg_match_all($reg , $password , $arr ))             break ;         $c  = 0 ;         $ps  = array ('punct' , 'digit' , 'upper' , 'lower' );         foreach  ($ps  as  $pt )         {             if  (preg_match("/[[:$pt :]]+/" , $password ))                 $c  += 1 ;         }         if  ($c  < 3 ) break ;         if  ("42"  == $password ) echo  $flag ;         else  echo  'Wrong password' ;         exit ;     } } ?> 
Google一下,可以找到正则表达式里一些单词代表的含义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 [:graph:]     #打印字符,不包括空格 [:punct:]     #打印字符,匹配任何标点符号 [:digit:]     #匹配任何数字 [:upper:]     #匹配任何大写字母 [:lower:]     #匹配任何小写字母 [:alnum:]     #字母和数字 [:alpha:]     #字母 [:ascii:]     #0-127的ascii字符 [:blank:]     #空格和制表符 [:cntrl:]     #控制字符 [:print:]     #打印字符,包括空格 [:space:]     #空白字符(比/s多个垂直指标) [:word:]      #单词字符(/w) [:xdigit:]    #匹配任何16进制数字 
从代码可以看出password必须符合以下条件:
1 2 3 4 5 6 7 8 9 if  (0  >= preg_match('/^[[:graph:]]{12,}$/' , $password )){     echo  'Wrong Format' ;     exit ;  } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $reg  = '/([[:punct:]]+[[:digit:]]+[[:upper:]]+[[:lower:]]+)/' ;if  (6  > preg_match_all($reg , $password , $arr ))    break ; 
1 2 3 4 5 6 7 8 9 10 11 12 $c  = 0 ;$ps  = array ('punct' , 'digit' , 'upper' , 'lower' );foreach  ($ps  as  $pt ){     if  (preg_match("/[[:$pt :]]+/" , $password ))         $c  += 1 ; } if  ($c  < 3 ) break ;
1 2 3 4 5 6 if  ("42"  == $password ) echo  $flag ;else  echo  'Wrong password' ;
既然密码必须等于"42",那么就和上面密码长度必须大于等于12位矛盾了,所以密码应该是在和"42"做比较的时候被转成了数字。"0.42E+2"表示0.42 * 10^2 = 42。"0.42E+2"刚好被各种字符分割成6部分,但是长度小于12,只需要补0就行了。"0.4200000E+2"。
输入后成功通关了:
暂时还不知道奖品是什么,期待中……