首页
社区
课程
招聘
[原创]Binwalk命令执行漏洞复现-CVE-2022-4510
发表于: 2023-2-8 19:56 13333

[原创]Binwalk命令执行漏洞复现-CVE-2022-4510

2023-2-8 19:56
13333

偶然间看见了binwalk的这个漏洞,这个工具知名度不必多说了,所以我去查看了我环境中的binwalk的版本
图片描述
版本2.2.1刚好符合漏洞区间2.12b-2.3.3,所以决定自己去亲自复现一下这个漏洞

参考:https://onekey.com/blog/security-advisory-remote-command-execution-in-binwalk/
https://mp.weixin.qq.com/s/gZp87CAeuM1eC91kA8Cqeg
在漏洞介绍中,binwalk 的PFS文件的提取器存在着路径穿越漏洞,从而造成远程代码执行
所以我们去binwalk的路径下搜索一下pfs文件
图片描述
看到出现了这个俩个相关文件路径,在后续的查看中这俩个是相同的文件,所以我选择了/src/binwalk/plugins/unpfs.py 进行查看
部分代码如下:

问题就出现在"os.path.join"这个函数之中

os.path.join函数从后往前去进行拼接 其中碰到第一个”/“这个字符后会将前面全部抛弃,而如果碰到了"/" 或者 "../"这样的字符则会将前面的路径全部保留,其中"/"比"./”或者"../"的优先级高,大体意思如下

图片描述
所以"os.path.join"拼接后的路径并不能完全解析文件的后续路径,即使unpfs.py代码中有着路径穿越的检查,所以这里存在着漏洞

当确定存在路径穿越漏洞后,常规的利用思路是覆盖ssh文件或者其它的重要文件
但是作者想要不依赖环境去获得权限
这就不得不提到了binwalk的一种特性,它在运行的时候会加载所有的插件去保证文件的提取,同时binwalk运行用户自定义插件,且开放了插件的api,详情如下:
https://github.com/ReFirmLabs/binwalk/wiki/Creating-Custom-Plugins#plugin-activation
我们可以通过python编写自定义插件,然后将其放入到“$HOME/.config/binwalk/plugins/”路径中,这样在后续的运行中binwalk就会加载我们的程序,
因为是python编写,所有我们就可以去进行多种操作,手写socket啊,或者使用os.system查看敏感文件什么的
这里官方提供了poc:
https://github.com/ReFirmLabs/binwalk/pull/617

我们可以根据官方的文件头去进行自定义poc
编写好反弹shel的poc后我们用winhex将文件头复制到前面
图片描述
文件头内容如下:

别忘了修改一下文件的大小也就是c100处
图片描述
然后将其改名为poc.pfs并且压缩一下,
然后进入主目录下我们去使用binwalk去运行poc.zip这个压缩文件
可以看到在binwalk的插件目录下我们成功写入了自定义的脚本
图片描述
同时成功的反弹了shell
截图如下:
图片描述

def extractor(self, fname):
     fname = os.path.abspath(fname)
     out_dir = binwalk.core.common.unique_file_name(os.path.join(os.path.dirname(fname), "pfs-root"))
 
     try:
         with PFS(fname) as fs: //重复读取pfs文件内容
             # The end of PFS meta data is the start of the actual data
             data = binwalk.core.common.BlockFile(fname, 'rb')
             data.seek(fs.get_end_of_meta_data())
             for entry in fs.entries():
                 outfile_path = os.path.join(out_dir, entry.fname)//将压缩包中的路径拼接到out_dir路径中 binwalk根据这个路径去进行响应路径文件填写
                 if not outfile_path.startswith(out_dir):
                     binwalk.core.common.warning("Unpfs extractor detected directory traversal attempt for file: '%s'. Refusing to extract." % outfile_path)
                 else:
                     self._create_dir_from_fname(outfile_path)
                     outfile = binwalk.core.common.BlockFile(outfile_path, 'wb')
                     outfile.write(data.read(entry.fsize))
                     outfile.close()
             data.close()
def extractor(self, fname):
     fname = os.path.abspath(fname)
     out_dir = binwalk.core.common.unique_file_name(os.path.join(os.path.dirname(fname), "pfs-root"))
 
     try:
         with PFS(fname) as fs: //重复读取pfs文件内容
             # The end of PFS meta data is the start of the actual data
             data = binwalk.core.common.BlockFile(fname, 'rb')
             data.seek(fs.get_end_of_meta_data())
             for entry in fs.entries():
                 outfile_path = os.path.join(out_dir, entry.fname)//将压缩包中的路径拼接到out_dir路径中 binwalk根据这个路径去进行响应路径文件填写
                 if not outfile_path.startswith(out_dir):
                     binwalk.core.common.warning("Unpfs extractor detected directory traversal attempt for file: '%s'. Refusing to extract." % outfile_path)

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2023-2-8 20:03 被庄周恋蝶恋花编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//