题目:Web Code
http://eci-2zede9gr1sd9rpm7qlo0.cloudeci1.ichunqiu.com/index.php?jpg=hei.jpg
1. url有文件包含,尝试读取index.php的源码。
- index.php源码:
PD9waHANCi8qKg0KICogQ3JlYXRlZCBieSBQaHBTdG9ybS4NCiAqIERhdGU6IDIwMTUvMTEvMTYNCiAqIFRpbWU6IDE6MzENCiAqLw0KaGVhZGVyKCdjb250ZW50LXR5cGU6dGV4dC9odG1sO2NoYXJzZXQ9dXRmLTgnKTsNCmlmKCEgaXNzZXQoJF9HRVRbJ2pwZyddKSkNCiAgICBoZWFkZXIoJ1JlZnJlc2g6MDt1cmw9Li9pbmRleC5waHA/anBnPWhlaS5qcGcnKTsNCiRmaWxlID0gJF9HRVRbJ2pwZyddOw0KZWNobyAnPHRpdGxlPmZpbGU6Jy4kZmlsZS4nPC90aXRsZT4nOw0KJGZpbGUgPSBwcmVnX3JlcGxhY2UoIi9bXmEtekEtWjAtOS5dKy8iLCIiLCAkZmlsZSk7DQokZmlsZSA9IHN0cl9yZXBsYWNlKCJjb25maWciLCJfIiwgJGZpbGUpOw0KJHR4dCA9IGJhc2U2NF9lbmNvZGUoZmlsZV9nZXRfY29udGVudHMoJGZpbGUpKTsNCg0KZWNobyAiPGltZyBzcmM9J2RhdGE6aW1hZ2UvZ2lmO2Jhc2U2NCwiLiR0eHQuIic+PC9pbWc+IjsNCg0KLyoNCiAqIENhbiB5b3UgZmluZCB0aGUgZmxhZyBmaWxlPw0KICoNCiAqLw0KDQo/Pg==
- 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
- 发现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的值可以在浏览器中获取到。
bWxrdhIeWUVO
根据encrypt代码反向操作。
4. 开始求flag
-
先base64解密
mlkvYEN
-
提取前4个字符
mlkv
为$rnd,并得到异或后的字符串。源代码: $rnd=random(4); return base64_encode($rnd.$ttmp);
-
将
guest
替换成ascii+10对应的字符源代码: $tmp .= chr(ord($txt[$i])+10);
-
第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位。)
-
关键信息$rnd和$key都知道了。接下来构造一个字符串使他通过decrypt后返回system。
-
将
system
替换成ascii+10对应的字符 -
如4所说,guest生成的$key相比system生成$key要少一位。md5用 0123456789abcdef 补足一位给$key。
-
将前两步生成的字符串异或、拼接$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编码 }
-
-
放入burpsuite中跑一下。