$ binwalk -e xx.bin
3.1.1 漏洞位置(unpfs.py)
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:
# 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)# 漏洞位置
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)
Python 3.10.1 (tags/v3.10.1:2cd268a, Dec 6 2021, 19:10:37) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> os.path.join("/tmp","../etc/passwd")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>> import os
>>> os.path.join("/tmp","../etc/passwd")
'/tmp/../etc/passwd'
3.1.2 漏洞修复
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)
+ outfile_path = os.path.abspath(os.path.join(out_dir, entry.fname))
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:
3.2 CVE-2023-0591
3.2.1 漏洞位置(ubireader/ubifs/outpu.py)
def extract_files(ubifs, out_path, perms=False):
inode = inodes[dent_node.inum]
dent_path = os.path.join(path, dent_node.name)#漏洞位置
if dent_node.type == UBIFS_ITYPE_DIR:
try:
if not os.path.exists(dent_path):
3.2.2 漏洞修复
- target_path = os.path.join(os.getcwd(), target, path)
+ target_path = os.path.realpath(os.path.join(os.getcwd(), target, path))
+ if not is_safe_path(target, target_path):
+ print(f"Path traversal attempt to {target_path}, discarding.")
+ continue
3.3 CVE-2023-0592
3.3.1 漏洞位置(src/scripts/jefferson)
target_path = os.path.join(os.getcwd(), target, path)
if not is_safe_path(target, target_path):
print(f"Path traversal attempt to {target_path}, discarding.")
continue
for inode in dirent.inodes:
try:
if stat.S_ISDIR(inode.mode):
3.3.2 漏洞修复
- target_path = os.path.join(os.getcwd(), target, path)
+ target_path = os.path.realpath(os.path.join(os.getcwd(), target, path))
if not is_safe_path(target, target_path):
print(f"Path traversal attempt to {target_path}, discarding.")
continue
for inode in dirent.inodes:
try:
if stat.S_ISDIR(inode.mode):
import binwalk.core.plugin
import os
import shutil
class EvilExtractor(binwalk.core.plugin.Plugin):
def init(self):
os.system("nc -lvp 56643")
原文始发于微信公众号(山石网科安全技术研究院):Binwalk 任意代码执行漏洞原理分析