“ 摆烂很久,发一发笔记吧”
# 01 背景
aiohttp 是一个基于异步IO的Python库,专门用于处理HTTP请求和响应,是Python中一个强大的异步HTTP框架,支持异步编写HTTP请求处理逻辑,包括文件上传、WebSocket连接等。可同时支持客户端使用和服务端使用。
这个如果仅用在客户端,就和常见的requests库差别不大,就大材小用了。所以很多时候会用在服务器端,例如Web服务器,由于HTTP连接就是IO操作,因此可以利用其协程特性来异步编程,实现多用户的高并发支持。
影响版本:
aiohttp >= 1.0.5, < 3.9.2
根据官方的说明,这个漏洞也是发生在用作web服务的这种场景下产生的。当aiohttp在静态资源解析的时候,如果配置了follow_symlinks这个参数为True,可能会导致系统上的任意文件的未授权读取。
所以前置条件就是以下两条:
-
使用 aiohttp 作为 Web 服务器并启用静态资源解析
-
follow_symlinks
设置为True
# 02 漏洞原理
其实漏洞的原理官方已经说的很清楚了。
总结一下就是,在使用aiohttp作为Web服务器并配置静态路由时,需要为静态文件设定存放的根路径。其中有个选项follow_symlinks
会跟随符号链接来访问静态文件,可用于决定是否跟随访问到静态根目录之外的符号链接。
当follow_symlinks
设置为True
时,不会检查给定文件路径是否在根目录内。
# 03 环境
这里我们结合描述就可以写一个简单的demo测试环境:
from aiohttp import web
app = web.Application()
app.router.add_routes([
web.static("/static", "static/", follow_symlinks=True),
])
if __name__ == '__main__':
web.run_app(app, host='0.0.0.0', port=8888)
这里可以通过黑盒思维下,直接试一下穿越路径,其实就能有结果
# 04 patch浅析
patch官方也直接给出了,很清楚,都省的找了。通过查看patch的位置,我们可以看到在两个点进行了修复。但经过实际的测试,漏洞的位置实际为aiohttp.web_urldispatcher.StaticResource._handle里面。
这里发送poc请求后,可以看到获得如下参数,一个是Request对象一个是self对象。Request可以看到就是一个描述发送的请求的对象。
self这里就会获取到之前配置的follow_symlinks
值。
整个流程不复杂,到这里会判断self中的follow_symlinks 是否设置为True,是的话就会跳过这里的判断。直接往下
如果设置为False,或者没有这个参数的话,就会通过filepath.relative_to(self._directory)
去检查当前的文件的绝对路径是不是以server的设置的静态目录为开头,不是的话就直接异常报错。比如:
然后来到这里,filepath已经被处理为了一个绝对路径:
-
首先会判断这里的
filepath
是不是表示一个目录,如果是,就会将目录的索引以HTML格式返回。但还要经过一个校验,如果没有配置show_index这个参数的话,默认就403了。
-
然后会判断这里的
filepath
是不是一个文件,如果是个文件,就返回了文件内容的Response。
# 05 修复
最后,做的修复前面也提到过
1. 先是把filepath转为了相对路径:
filepath 是一个已解析的绝对路径,而 unresolved_path 是一个未解析的相对路径
2. 然后是强制检查抛异常:
没修复前,如果 follow_symlinks 没有的话,就会检查到当前的文件不在server的设置的静态目录下,也就是穿越后的路径是不是以当前静态资源的绝对路径开头,不是这里就抛异常了,不会往下进行。
修复后相当于就相当于强制触发了这个检查。
本演示仅用于学习和研究,请在实验环境中运行,请勿用于其他任何非法用途,否则后果自负!
-------- 快上车就完事了 --------
hijackY∣来一起共同成长
识别二维码,快上车就完事了
也可 赞赏 转发 在看↘
原文始发于微信公众号(hijackY):aiohttp路径穿越(CVE-2024-23334)复现与分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论