百度杯CTF比赛 九月场(Code)

题目页面

百度杯CTF比赛 九月场(Code),攻防知识,第1张

查看url,有可能是文件包含,然后右键查看源代码,发现结果base64加密

百度杯CTF比赛 九月场(Code),攻防知识,第2张

尝试输入index.php,看看会不会被包含

百度杯CTF比赛 九月场(Code),攻防知识,第3张

发现成功包含了,然后用base64去解密,代码如下:

百度杯CTF比赛 九月场(Code),攻防知识,第4张

从代码的注释中发现了PhpStorm,所以怀疑是文件泄露

百度杯CTF比赛 九月场(Code),攻防知识,第5张

发现返回了页面,在页面中发现了其他php文件(fl3g_ichuqiu.php,index.php,config.php)

百度杯CTF比赛 九月场(Code),攻防知识,第6张

然后想这利用文件包含来包含fl3g_ichuqiu.php这个文件,可是因为index.php的正则不允许有任何的符号,但是他会把config转换为_这个符号所以构造这样的payload:fl3gconfigichuqiu.php

百度杯CTF比赛 九月场(Code),攻防知识,第7张

然后进行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){
	# 此循环用来把每个字符转换为ascii码然后+10然后在变成字符
    for($i=0;$i<strlen($txt);$i++){
        $tmp .= chr(ord($txt[$i])+10);
    }
    $txt = $tmp;
    # 获取4个随机字符
    $rnd=random(4);
    # 将4个随机支付与$key进行加密然后赋值给$key
    $key=md5($rnd.$key);
    $s=0;
    # 将$txt的每个字符与$key对应的字符进行加密。(如果$txt的长度是5,只会循环5次)
    for($i=0;$i<strlen($txt);$i++){
        if($s == 32) $s = 0;
        $ttmp .= $txt[$i] ^ $key[++$s];
    }
    # 将生成的随机字符与生成的加密字符进行拼接然后base64加密,并且将值返回
    return base64_encode($rnd.$ttmp);
}
function decrypt($txt,$key){
	# 先将输入进来的值进行解密
    $txt=base64_decode($txt);
    # 因为$txt是由随机字符和密文组合起来的
    # 所以前面4个字符是随机字符,$rnd取出随机字符
    $rnd = substr($txt,0,4);
    # $txt取出密文
    $txt = substr($txt,4);
    # 将随机字符与$key拼接,在进行md5加密
    $key=md5($rnd.$key);
    $s=0;
    # 因为加密进行了异或处理,因为异或是可逆的,
    # 所以$txt的每个字符与$key的每个字符进行异或就可以得到$tmp的值
    for($i=0;$i<strlen($txt);$i++){
        if($s == 32) $s = 0;
        $tmp .= $txt[$i]^$key[++$s];
    }
    # 因为加密的时候对每个字符的ascii码进行了+10的操作
    # 所以这里要将ascii码减10,在转换为字符
    for($i=0;$i<strlen($tmp);$i++){
        $tmp1 .= chr(ord($tmp[$i])-10);
    }
    return $tmp1;
}
# 对cookie里面的user这个值进行解密
$username = decrypt($_COOKIE['user'],$key);
# 如果解密的值是system则输出flag
if ($username == 'system'){
    echo $flag;
}else{
	# 如果解密的信息不是system,则设置user的cookie,为guest加密后的内容
    setcookie('user',encrypt('guest',$key));
    echo "╮(╯▽╰)╭";
}
?>

在这个代码中,我们需要知道$key前6位的值,因为system长度为6所以在循环加密的时候,只会循环6次,所以知道$key的前面6位就可以了。然后else那个语句guest是5个字符,因为他是5个字符,所以可以通过这个来获取5个密文,还剩下1个密文就可以拿到flag了。解密代码

#coding=utf-8
# 1-14行通过异或得$key的前面5个字符
guest = 'guest' # 对guest进行加密
txt = ''
# 对guest的每一个字符对应的ASCII码+10,然后转换对应字符
for i in range(len(guest)):
    txt += chr(ord(guest[i])+10)
# guest加密后的值,从cookie中获取
cookie_guest = "WFlSShVLCh8a"
# 因为加密的最后一步是加密base64加密所以这里要解密
cookie_guest = cookie_guest.decode('base64')
# 获取验证码,加密后的内容是由4位验证码和密文
rnd = cookie_guest[:4]
# 获取密文
ttmp = cookie_guest[4:]
key = ''
# 通过异或获得$key的前面5个字符
for i in range(len(guest)):
    key += chr(ord(ttmp[i]) ^ ord(txt[i]))
# 下面是对system进行加密
system = 'system'
txt1 = ''
# 将system的每一个字符对应的ASCII码+10,然后转换对应字符
for i in range(len(system)):
    txt1 += chr(ord(system[i])+10)
# 因为system是6位,需要6位的$key的内容,因为我们知道了$key的前面5个
# 所以这里用来爆破,这里是1-f的原因是因为md5加密后的内容是1-f
md5 = '0123456789abcdef'
new_key = ''
# 然后对system进行加密
for i in range(len(md5)):
	# 生成新的md5值
    new_key = key+md5[i]
    cookie_system=''
    for j in range(len(system)):
    	# 每个字符进行加密
        cookie_system += chr(ord(txt1[j]) ^ ord(new_key[j]))
    flag = rnd + cookie_system
    print(flag.encode('base64').strip())

然后把输出的值复制下来,然后用burp对cookie中的user进行爆破

百度杯CTF比赛 九月场(Code),攻防知识,第8张

转载请说明出处 内容投诉
九牛网 » 百度杯CTF比赛 九月场(Code)

发表评论

欢迎 访客 发表评论

定制开发服务!

技术支持 联系我们