xctf--web2

发布时间 2023-09-14 22:10:27作者: fan高

打开题目,源码如下:

可以看到提示,只需解出miwen即可。

首先分析一下题目中的一些函数:

  • strrev():反转字符串
<?php
echo strrve("abcd");
?>

输出为:dcba

  • strlen(string): 返回字符串的长度
  • substr(string, start, length):字符串截取
  • ord(string): 返回字符串首个字符的 ASCII 值
  • chr(): 从指定的 ASCII 值返回对应的字符
  • str_rot13() 函数对字符串执行 ROT13 编码(ROT13 编码把每一个字母在字母表中向前移动 13 个字母。数字和非字母字符保持不变。解码只需要再执行一次函数即可)
  • base64_encode(string): 使用 MIME base64 对数据进行编码

先看最后一段代码:

str_rot13(strrev(base64_encode($_)));

可以看到,这段代码先是把$_进行了base64编码,然后使用strrev进行反转,再用str_rot13()函数进行了一次编码。

那我们可以利用逆向思维,先使用str_rot13()函数进行一次解码,用strrev进行一次反转,然后再base64解密就可以得到$_字符串。

然后我们分析上面代码:

对于上面代码,可以先构造一个字符串然后看它的执行过程:

<?php
$str="abcdefg";
 function encode($str){
    $_o=strrev($str);
     echo '$_o:'.$_o."    ";
        
    for($_0=0;$_0<strlen($_o);$_0++){
       
        $_c=substr($_o,$_0,1);
        echo '$_c:'.$_c."    ";
        $__=ord($_c)+1;
        echo '$__:'.$__."    ";
        $_c=chr($__);
        echo '$_c:'.$_c."    ";
        $_=$_.$_c;
        echo '$_:'.$_."    ";
        
    } 
}
?>

输出的结果为:

$_o:gfedcba    
$_c:g    
$__:104    
$_c:h    
$_:h    

$_c:f    
$__:103    
$_c:g    
$_:hg    

$_c:e    
$__:102    
$_c:f    
$_:hgf    

$_c:d    
$__:101    
$_c:e    
$_:hgfe    

$_c:c    
$__:100    
$_c:d    
$_:hgfed    

$_c:b    
$__:99    
$_c:c    
$_:hgfedc    
$_c:a    
$__:98    
$_c:b    
$_:hgfedcb 

此时可以看出这段代码的执行过程。先对输入的字符串进行一次反转,然后从左到右依次选取字符,然后把字符的ASCII码加一输出 ,最后得到hgfedcb

如何还原呢?我们可以把最后得到的字符串与输入的字符串进行比较,首先是发现多了一个h并且少了一个a,并且整个字符串进行了反转。

那我们首先把字符串进行反转得到“bcdefgh”,然后再把每个字符的ASCII减一即可还原到输入字符串。

下面进行写代码:

<?php
$s=base64_decode(str_rot13(strrev("a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws")));
$s=strrev($s);
$d='';
for($i=0;$i<strlen($s);$i++){
    $a=substr($s,$i,1);
    $b=ord($a)-1;
    $c=chr($b);
    $d=$d.$c;
}
echo $d;
?>

得到flag。