2013-02-10 15 views
7

Ho un caso d'uso in cui consentiamo agli utenti di caricare file. Ora nel back-end java (controller che estrae il file dalla richiesta http e controlla), voglio rilevare se l'utente carica qualsiasi file eseguibile. Se carica, devo scartare quel file. L'ho cercato su Google ma non sono riuscito a trovare una soluzione soddisfacente. Alcune persone hanno suggerito di verificare l'estensione (.exe). Ma non sono sicuro di quanto lontano filtrerà i file exe. Voglio bloccare completamente i file eseguibili dal caricamento.Rileva un file eseguibile in java

Se qualcuno di voi ha trovato questo scenario o ha una soluzione al riguardo, per favore fatemelo sapere. Ti sarei grato.

Sarei più felice se potessi indicarmi qualsiasi implementazione JAVA o API Java o algoritmo che eseguono questo lavoro.

+0

Altri suggerimenti? – Rajeev

risposta

9

ho il sospetto che, a parte il metodo di verifica dell'estensione che hai già menzionato, non ci sarà modo di cogliere ogni possibile caso. I file eseguibili sono in definitiva sequenze di istruzioni della macchina che li rendono in gran parte indistinguibili da qualsiasi altro dato.

Nonostante ciò, tuttavia, è possibile cercare determinati tipi di di eseguibile. Per esempio:

  • Windows utilizza il formato Portable Executable, che dovrebbe sempre iniziare con la magia numero 4d5a (caratteri ASCII MZ) eseguibile
  • ELF formato utilizzato da Linux iniziare con 7f454c46
  • Java class files iniziano sempre con cafebabe (è esadecimale, non ASCII!).
  • Per quanto posso vedere, i file di Mach-O utilizzate da Mac-OSX hanno il magico numero di feedface (hex di nuovo)

Vi suggerisco di creare un FileInputStream o simili e leggere i primi byte del file, controllando questi numeri magici. Non rileva alcun file che contenga codice eseguibile, ma dovrebbe impedire l'autorizzazione dei file in questi formati eseguibili standard, che credo sia ciò che speravi.

Così, per esempio:

public static boolean isExecutable(File file) { 
    byte[] firstBytes = new byte[4]; 
    try { 
    FileInputStream input = new FileInputStream(file); 
    input.read(firstBytes); 

    // Check for Windows executable 
    if (firstBytes[0] == 0x4d && firstBytes[1] == 0x5a) { 
     return true; 
    } 
    return false; 
    } 
    catch (Exception e) { 
    e.printStackTrace(); 
    } 
} 

attenzione, inoltre, che è possibile ottenere un falso positivo, in cui si rifiuta un file che non era eseguibile. Non so quale tipo di file si intende caricare, quindi è necessario considerare la probabilità che ciò accada.

+0

grazie per il tuo suggerimento. Ho attraversato wiki e ho trovato il tipo di soluzioni simile. Di seguito sono riportati i wiki: http://www.csn.ul.ie/~caolan/publink/winresdump/winresdump/doc/pefile2.html Sarei davvero più felice, se puoi guidarmi come controllare le tre precedenti che hai citato in java – Rajeev

+0

Sì, ciò conferma quello che ho trovato: gli eseguibili di Windows iniziano sempre con ASCII 'MZ' (o hex' 4d5a'). Ho aggiornato la mia risposta per includere anche Mac OSX – jazzbassrob

+0

che ho aggiornato con un esempio di codice per Windows. Lo lascerò a te per capire come testare gli altri. Spero possa aiutare. – jazzbassrob

0

L'eseguibile di Windows inizia sempre con il numero magico MZ. Probabilmente potresti controllare per questo.

+0

Ho attraversato wiki e trovato sotto due wiki: http://www.delphidabbler.com/articles?article=8&part=1 http://stackoverflow.com/questions/2863683/how-to-find-if -a-file-is-an-exe Ma non così chiaro. Hanno suggerito di fare il tifo per PE ... ma hanno bisogno di maggiori informazioni su come controllare e attuare – Rajeev

0

Per quanto ho visto, l'approccio più comune è verificare l'estensione. Ad esempio, ho notato che i client di posta solitamente accettano di inviare un eseguibile se viene rinominato, ad es. per zip o qualche altra estensione.
Credo che ciò sembri adeguato poiché il problema di sicurezza è se l'utente esegue accidentalmente l'eseguibile. Rinominando il file in un'estensione sconosciuta/diversa l'utente non può accidentalmente farlo e quindi il pericolo è in qualche modo "mitigato"
Altrimenti viene in mente un modo per esaminare il contenuto del file per determinare se si dispone effettivamente di un eseguibile, I non so come fattibile/portatile/affidabile questo è

0

Date un'occhiata qui:

Is there a good way to determine if a file is executable in Java

sembra che questo comando può aiutare: java.io.File.canExecute()

+1

Sfortunatamente, questo determina solo se un file ha * permesso * di essere eseguito - non se contiene effettivamente codice eseguibile – jazzbassrob

+0

Come ha detto jazzbassrob, questo non aiuterà. Non è in grado di rilevare i dati eseguibili è lì nel file o non – Rajeev

+0

ho già passato attraverso il link che hai citato. Non è legato alla domanda, sto chiedendo esattamente ... – Rajeev

0

essere consapevoli del fatto che le finestre eseguibile non sono solo .exe file in modo controllando l'estensione non sarà sufficiente

Se si desidera qualcosa di avanzato e difficile da ingannare, è possibile utilizzare uno strumento di terze parti come File for Windows è una popolare strumento da riga di comando che è stato portato da Linux.

per esempio, se si desidera controllare qualche file program.exe

C:\file -b "program.exe" 

Il risultato sarà qualcosa di simile

PE32 executable for MS Windows <GUI> Intel 

È possibile eseguire questo strumento da un programma Java utilizza Runtime.getRuntime().exec()

Vedere this question per imparare come eseguire un programma da riga di comando e ottenere l'output in Java

È anche possibile controllare Apache Tika per ottenere il tipo di file dal suo contenuto

+0

Come posso farlo in java? – Rajeev

+0

Quali sono le dipendenze che è necessario aggiungere ... Sarà più utile a tutti se è possibile fornire un programma di esempio che rilevi i file eseguibili?Ringrazia anche a te se riesci a far luce sui negativi dell'utilizzo di questo metodo come casi limite per i quali può mancare o può trattare file normali come eseguibili. – Rajeev

+0

Non è necessario aggiungere nulla in Java (ad esempio, i jar), se si è in grado di eseguire il comando da 'cmd', è possibile chiamarlo direttamente da Java usando' getRuntime(). Exec() ' – iTech

Problemi correlati