可能是这题的全网第一篇简中wp(

分析

按照惯例,先找flag在哪

在数据库,并且在admin用户同一条记录下。再分析一下功能,主要就四个

  • 根路由,查询输入的用户是否存在(app/blueprints/auth/routes.py)

  • /register,注册(app/blueprints/auth/routes.py)

  • /visit,分析功能后发现可以直接携带admin用户的token并请求任意路由(app/blueprints/bot/routes.py和app/utils/bot.py)

  • 带有profile字样的任意路由或其他路由,输出保存在数据库里的详细数据(app/blueprints/main/routes.py)

其中第四个功能的路由比较特殊

@main_bp.route('/<path:subpath>', methods=['GET'])

意思就是什么uri他都吃,再分析下面具体的实现代码

if re.match(r'.*^profile', subpath): # Django perfection
    ...
    ...
else:
    return jsonify({"error": "No match"}), 404

就可以得知,除了在其他代码里定义好的路由外,没有’profile’字样的uri最后都会被丢个No match

分析完功能,思路就很清晰了,应该就是想办法利用visit路由携带好的token去读profile。

但分析完后发现,虽然能请求profile,但上面这段代码很明显只能访问但不能回显携带的内容

所以要想个办法把请求的内容带出来。

我很少看题目附件里给的nginx配置文件,除非真的没有思路继续下去。而这题就正好是这种少数题目之一

看起来nginx在实现一种和CDN一样的效果,把前端访问过的静态文件存下来,如果在他的缓存路径里就直接读缓存,如果不在就把请求交给gunicorn做正常访问。

根据上面的分析也可以知道,很明显后端对/profile这个路由的访问处理并不是很严格,不管我访问什么稀奇古怪的路径,只要路径里带有profile就都会被判定为/profile。所以当我访问profile/1.css时,/profile的内容就会被缓存到profile/1.css里,我再正常地去访问profile/1.css就能够拿到/profile的内容。这种攻击方式被叫做缓存欺骗

实操

来看看具体题目,首先我想要访问/visit就需要有一个token。不过这个token是什么无所谓,只要有就行。所以需要先注册一个

接着拿去登陆,获取token(ip地址不一样别在意,就是拿平台靶场试的而已)

最后就可以拿去访问visit,出现下面字样说明访问成果

不过,完全一样的请求包也有可能在你访问后给你丢个invalid token,这种情况只要多发几次就行。原因不明,感觉像是HS256导致的某种神奇反应导致token间歇性不识别= =

最后正常访问即可