访问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()函数的官方文档说明如下:
产生一个随机整数
如果没有提供可选参数
min和max,rand() 返回 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;
?>