
从前端解决下载无后缀文件出现后缀的问题.txt

发现bug.txt
最近我们的新生训练赛就要开始了,题目陆陆续续到了测试阶段,对于pwn题,
一些简单题就只需要提供一个binary文件,没有后缀,下载下来就能直接打。结果上传一看,
限制了文件类型。好不容易能上传任意文件了,下载下来却发现多了一个.txt
后缀。
ELF怎么可能有后缀呢?检查http响应,没有问题:
1 | 200 OK |
然而实际下载的文件却变成了shellcode.txt
。
于是我跑到我自己的网站上,
有一个putenv
文件,尝试下载,http响应是这样的:
1 | 200 OK |
下载下来是没有后缀名的。这不是都正确声明Content-Disposition
了吗,
为什么还是不能下载无后缀名的文件呢?
尝试复现.txt
尝试修改自己的python服务,使响应和平台的一致,并没有任何效果。既不是因为Content-Type
,
又不是因为Content-Disposition
,真正的原因是什么呢?
硬调chromium.txt
为了深入理解其中发生了什么,只能调试浏览器了,看看下载文件中发生了什么。由于chromium 是开源的,可以就着源码,拿符号对着看。问题是,浏览器这么多进程,怎么调试呢? 阅读官方的调试指南, 里面提到可以关闭沙箱,并限制renderer进程,然而这仍然不够,还需要搭配上gdb调试的一些设置, 它们是:
1 | set breakpoint always-inserted on |
这样就能让所有进程同时运行,同时将断点下在所有进程中,并且监控所有进程。
那么方法有了,调试什么函数呢?直接使用copilot读取仓库并寻找下载时指定文件名的函数,
定位到了net::GenerateFileNameImpl
函数,然后直接跟到GetSuggestedFilenameImpl
,
其中的重要内容大致是
1 | std::u16string GetSuggestedFilenameImpl( |
接着我们使用gdb -x stub -args /usr/lib/chromium/chromium --no-sandbox --single-process
启动浏览器调试,把断点下在net::GenerateFileNameImpl
,下载调试符号,让浏览器跑起来。
启动完成以后尝试下载一下文件,观察到此时进入调试态,注意寄存器的状态是什么样的。
虽然Arch提供了chromium的调试符号包,但是调试符号中只有函数名,这意味着我们没有源码可以看,只能盲调。
通过pwndbg的nextcall
命令,可以很方便地观察调用了哪些函数,就着源码看也还行。
例如以下是下载我网站上文件时寄存器的状态,根据源码,rdx是指向Content-Disposition
的字符串,
rsi是指向url的字符串,r9是指向mime_type的字符串,即application/octet-stream
。
接下来不断使用nextcall
去找我们感兴趣的函数,以此侧面观察控制流(记得在
GetSuggestedFilenameImpl
步入)。在这里我们就能观察到解析了Content-Disposition
。
之后调用了net::EnsureSafeExtension
函数,把参数对应过去,mime_type是空字符串,
后缀名被Content-Disposition
强制指定了,因此没有添加后缀名。(#L32)
接着看看平台上下载文件的例子,首先观察mime_type是text/plain
,而且链接前面是blob
,
并且没有Content-Disposition
头的信息。
继续执行,直接到了EnsureSafeExtension
的地方,此时我们发现走了另一个分支(
!is_name_from_content_disposition
),阅读源码可知在这里由于传入的mime_type是text/plain
,
因此后续发现prefered extension是.txt
,导致被强制加上了.txt后缀。(#L34)
在chromium查找扩展名的过程中,由于application/octet-stream
是“通用二进制数据”,
因此检查直接返回了,不要求后缀名。
错误设置的下载方式
原先平台上下载方式是把请求响应包在blob里,然后模拟链接点击下载, mime_type是在链接中设置的,查阅 Mozilla HTTP 文档 发现需要在blob中设置才行。

修复这个小bug
给blob加上mime_type就行。
1 |
|
参考
- 标题: 从前端解决下载无后缀文件出现后缀的问题.txt
- 作者: RocketDev
- 创建于 : 2025-08-31 21:14:00
- 更新于 : 2025-08-31 23:22:00
- 链接: https://rocketma.dev/2025/08/31/discard.txt/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。