24/5/9 Web Code&phpstorm&代码审计

Fenglilinglegeluan 于 2024-05-09 发布 浏览量

题目:Web Code

image-20240509135324260

http://eci-2zede9gr1sd9rpm7qlo0.cloudeci1.ichunqiu.com/index.php?jpg=hei.jpg

1. url有文件包含,尝试读取index.php的源码。

  1. index.php源码:
PD9waHANCi8qKg0KICogQ3JlYXRlZCBieSBQaHBTdG9ybS4NCiAqIERhdGU6IDIwMTUvMTEvMTYNCiAqIFRpbWU6IDE6MzENCiAqLw0KaGVhZGVyKCdjb250ZW50LXR5cGU6dGV4dC9odG1sO2NoYXJzZXQ9dXRmLTgnKTsNCmlmKCEgaXNzZXQoJF9HRVRbJ2pwZyddKSkNCiAgICBoZWFkZXIoJ1JlZnJlc2g6MDt1cmw9Li9pbmRleC5waHA/anBnPWhlaS5qcGcnKTsNCiRmaWxlID0gJF9HRVRbJ2pwZyddOw0KZWNobyAnPHRpdGxlPmZpbGU6Jy4kZmlsZS4nPC90aXRsZT4nOw0KJGZpbGUgPSBwcmVnX3JlcGxhY2UoIi9bXmEtekEtWjAtOS5dKy8iLCIiLCAkZmlsZSk7DQokZmlsZSA9IHN0cl9yZXBsYWNlKCJjb25maWciLCJfIiwgJGZpbGUpOw0KJHR4dCA9IGJhc2U2NF9lbmNvZGUoZmlsZV9nZXRfY29udGVudHMoJGZpbGUpKTsNCg0KZWNobyAiPGltZyBzcmM9J2RhdGE6aW1hZ2UvZ2lmO2Jhc2U2NCwiLiR0eHQuIic+PC9pbWc+IjsNCg0KLyoNCiAqIENhbiB5b3UgZmluZCB0aGUgZmxhZyBmaWxlPw0KICoNCiAqLw0KDQo/Pg==
  1. 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?
 *
 */

?>

2. 发现是phpstorm,尝试读取默认文件 .idea/workspace.xml

image-20240509140115537

  1. 发现flag相关文件,fl3g_ichuqiu.php

3. 读取fl3g_ichuqiu.php源码

根据index.php源码的正则替换规则。

$file = preg_replace("/[^a-zA-Z0-9.]+/","", $file);
$file = str_replace("config","_", $file);

index.php?jpg=fl3g_ichuqiu.php

实际 _ 会被替换为空,所以要用config代替下划线。

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;//输入的字符串的每个字符替换成自身ascii+10对应的字符
    $rnd=random(4);
    $key=md5($rnd.$key);//系统提供的$key 拼接4个随机字符,再md5加密。
    $s=0;
    for($i=0;$i<strlen($txt);$i++){
        if($s == 32) $s = 0;
        $ttmp .= $txt[$i] ^ $key[++$s];//$txt和$key异或
    }
    return base64_encode($rnd.$ttmp);//拼接4个随机字符后base64编码
}
function decrypt($txt,$key){
    $txt=base64_decode($txt);//解码
    $rnd = substr($txt,0,4);//提取前4个字符,也就是加密阶段的$rnd
    $txt = substr($txt,4);//删去前4个的字符
    $key=md5($rnd.$key);//生成与加密阶段相同的$key

    $s=0;
    for($i=0;$i<strlen($txt);$i++){
        if($s == 32) $s = 0;
        $tmp .= $txt[$i]^$key[++$s];
    }//异或得到加密阶段替换成ascii+10对应字符的$txt
    for($i=0;$i<strlen($tmp);$i++){
        $tmp1 .= chr(ord($tmp[$i])-10);
    }//输入的字符串的每个字符替换成自身ascii-10对应的字符,也就是原$txt
    return $tmp1;
}
$username = decrypt($_COOKIE['user'],$key);
if ($username == 'system'){
    echo $flag;//如果cookie中user键的值经过decrypt解密后等于system,就输出flag。
}else{
    setcookie('user',encrypt('guest',$key));//设置cookie为guest加密后的值。
    echo "╮(╯▽╰)╭";
}
?>

通过分析代码,guest的值可以在浏览器中获取到。

image-20240509142633290

bWxrdhIeWUVO根据encrypt代码反向操作。

4. 开始求flag

  1. 先base64解密mlkvYEN

  2. 提取前4个字符mlkv为$rnd,并得到异或后的字符串。

    源代码: 
    $rnd=random(4);
    return base64_encode($rnd.$ttmp);
    
  3. guest替换成ascii+10对应的字符

    源代码: 
    $tmp .= chr(ord($txt[$i])+10);
    
  4. 第3步得到的字符与第2步得到的字符异或可以得到md5加密后的$key。

    源代码: 
    for($i=0;$i<strlen($txt);$i++){
            if($s == 32) $s = 0;
            $ttmp .= $txt[$i] ^ $key[++$s];//$txt和$key异或
        }
    $key=md5($rnd.$key);
    

    (ps:因为guest是5个字符,异或代码就循环了5次,只得到了$key的前5位。)

  5. 关键信息$rnd和$key都知道了。接下来构造一个字符串使他通过decrypt后返回system。

    1. system替换成ascii+10对应的字符

    2. 如4所说,guest生成的$key相比system生成$key要少一位。md5用 0123456789abcdef 补足一位给$key。

    3. 将前两步生成的字符串异或、拼接$rnd后进行base64编码得出想要的字典.

      源代码
          function encrypt($txt,$key){
          for($i=0;$i<strlen($txt);$i++){
              $tmp .= chr(ord($txt[$i])+10);
          }
          $txt = $tmp;//输入的字符串的每个字符替换成自身ascii+10对应的字符
          $rnd=random(4);
          $key=md5($rnd.$key);//系统提供的$key 拼接4个随机字符,再md5加密。
          $s=0;
          for($i=0;$i<strlen($txt);$i++){
              if($s == 32) $s = 0;
              $ttmp .= $txt[$i] ^ $key[++$s];//$txt和$key异或
          }
          return base64_encode($rnd.$ttmp);//拼接4个随机字符后base64编码
      }
      
  6. 放入burpsuite中跑一下。

    image-20240509151418016