访问showImage.php

<?php

//$key = substr(md5('ctfshow'.rand()),3,8);
//flag in config.php
include('config.php');
if(isset($_GET['image'])){
    $image=$_GET['image'];
    $str = openssl_decrypt($image, 'bf-ecb', $key);
    if(file_exists($str)){
        header('content-type:image/gif');
        echo file_get_contents($str);
    }
}else{
    highlight_file(__FILE__);
}
?>

分析代码得到以下关键信息:

  • $key = substr(md5(‘ctfshow’.rand()),3,8);
  • flag in config.php
  • 想读取config.php的内容,需要知道$key的值

因为Z6Ilu83MIDw=是经过openssl_encrypt处理后的结果,所以可以利用它来爆破密钥。rand()函数的官方文档说明如下:

产生一个随机整数

如果没有提供可选参数 minmaxrand() 返回 0 到 getrandmax() 之间的伪随机整数。

经测试,最大为32767。(报错的话,php.ini去掉;extension=php_openssl.dll前面的;

<?php
for($i=0;$i<32767;$i++){
    $key = substr(md5('ctfshow'.$i),3,8);
    $image = "Z6Ilu83MIDw=";
    $str = openssl_decrypt($image, 'bf-ecb', $key);
    if(preg_match('/jpg|gif|png/',$str)){
        echo $i."<br>".$str;
        break;
    }
}
?>

运行后得到key值为27347。

接下来计算config.php加密后的值即可。

<?php
$rand = 27347;
$key = substr(md5('ctfshow'.$rand),3,8);
$image = "config.php";
$str = openssl_encrypt($image, 'bf-ecb', $key);
echo $str;
?>