Un eseguibile binario deve avere componenti critici di testo semplice?

7

Quando le aziende eseguono il pacchetto di eseguibili binari, vengono spesso crittografati, compressi, codificati e altrimenti creati in modo che il tuo pigro hacker non possa semplicemente aprire il programma in Notepad ++ e vedere il codice.

In tutti quelli che ho guardato, tuttavia, ognuno di essi ha componenti di codice critici che non sono criptati, non compressi e leggibili. Qui sembra che la metodologia sia più "sicurezza per offuscamento" creando nomi di variabili senza senso e tentando di rendere il codice difficile da capire. Ma resta il fatto che è lì in chiaro per essere decifrato.

È questo per necessità? Stavo pensando che potrebbe avere essere in questo modo in modo che il sistema operativo abbia qualcosa di sensato da eseguire (che poi ha istruzioni per decomprimere / decodificare ulteriormente il resto dell'eseguibile), ma non lo so abbastanza per essere sicuro. O c'è un modo per creare effettivamente un intero file eseguibile senza avere alcun componente leggibile dall'uomo?

    
posta asteri 07.02.2013 - 18:36
fonte

5 risposte

8

In definitiva, la CPU esegue il codice. E la CPU si aspetta istruzioni in "testo chiaro". Potresti immaginare un codice applicativo in cui una piccola parte iniziale dell'eseguibile prima decodifica il resto del codice, ma questo ha diversi problemi:

  • Questo impone a tutto il codice di passare alla RAM invece di rimanere su disco e di essere caricato su richiesta, implicando un maggiore consumo di RAM e tempi di avvio più lunghi.
  • Quella routine di "decrittografia" deve, necessariamente, non essere crittografata.
  • La routine di decifrazione conosce tutto ciò che è necessario per decrittografare il resto del codice, in modo che possa essere decompilato ed emulato dall'hacker; non è realmente "decifrazione" poiché non c'è chiave (o, equivalentemente, la chiave è incorporata nella routine, che l'attaccante ha sotto le sue mani).

Sperimentalmente, questo tipo di crittografia non ostacola molto gli aggressori, quindi la saggezza generale è che "non vale lo sforzo". Salvo sei in uno scenario molto specifico in cui l '"attaccante" è un automa senza cervello che può essere ingannato da questi metodi di nascondino: è il caso del virus, dove l'"attaccante" è il software antivirus.

Il codice realmente crittografato è possibile se la CPU sta eseguendo la decodifica stessa, internamente, con alcune chiavi di gestione. Questo è quello che succede in una console PS3, per esempio.

    
risposta data 07.02.2013 - 19:06
fonte
3

Stai parlando di due componenti diversi. Uno è il loader , che non è leggibile dall'uomo ma deve essere leggibile dalla macchina (quindi non crittografato) per poter essere eseguito. E questo ha in questo modo, come dici tu: altrimenti otterrai una porzione di dati non eseguibili.

Potrebbero essere presenti anche molti altri "componenti di testo in chiaro" come copyright, manifest, informazioni sui file, e così via, che sono leggibili dall'uomo ma non sono sensibili - cioè, lo sviluppatore non poteva Non importa se sei in grado di leggere il suo nome. In realtà probabilmente preferisce in questo modo.

Il caricatore esegue diverse operazioni di controllo dell'integrità, controllo del debugger e cosa no, quindi decrittografa il file eseguibile "vero" in memoria.

La misura in cui l'eseguibile è crittografato dipende dal caso d'uso. Ad esempio, il file binario potrebbe mantenere solo crittografate alcune routine critiche che hanno a che fare con la protezione dalla copia, la personalizzazione o il branding; in modo che tu possa aprire il file con un editor binario e vedere tutte le risorse, le stringhe, i cursori, ecc. come il giorno.

Oppure potrebbe essere crittografato con uno standard "binario-agnostico-così-io-voglio-cifrare-tutto-eseguibile" / codificatore, nel qual caso vedrai in chiaro le stringhe che appartengono a codice decryptor , ma non quelli dell'eseguibile originale. Ovviamente, i decodificatori vengono spesso ulteriormente offuscati per rendere più difficile per il proprio hacker medio riconoscere il codificatore e ottenere il decryptor adatto (più diffuso è il crittografo, più è probabile che esista).

    
risposta data 07.02.2013 - 18:56
fonte
1

Ad un certo punto un eseguibile deve apparire come un eseguibile, altrimenti il sistema non saprà cosa fare con esso. Questo di solito comporta un'intestazione che ne indica un eseguibile (ad esempio l'intestazione MZ in un EXE di Windows), così come alcune strutture contenenti puntatori a vari riferimenti come il punto di partenza per l'esecuzione, seguiti da un blob di dati binari che è il corpo eseguibile del file.

Un sacco di volte ci sono anche i metadati ad esso associati che il sistema operativo utilizza come firme dell'autenticode e attributi come editore, versione, ecc.

Al minimo, ha bisogno di quei bit di intestazione e del corpo dell'eseguibile. Quel corpo eseguibile avrebbe bisogno di un numero sufficiente di codice in chiaro per eseguire il meccanismo di decrittografia / decompressione, quindi inserire il nuovo codice per l'esecuzione.

    
risposta data 07.02.2013 - 18:53
fonte
1

Il modo in cui un eseguibile viene compilato e ciò che è visibile al suo interno varia un po 'a seconda della piattaforma e del linguaggio di programmazione coinvolto. I portons "criptati codificati" non sono realmente criptati e criptati. Sono solo dati non testuali. È un codice macchina, che viene eseguito dal sistema operativo.

Ad esempio, su Windows ... Se sei riuscito a mettere le mani su un file .dll creato in .NET, uno comparato in VB6, uno comparato in C ++ probabilmente troverai una grande differenza in quanto "normale" testo "è visibile se lo apri nel blocco note.

I file .dll .NET o .exe non sono realmente compilati in codice macchina, sono compilati in MSIL - una forma di bytecode che viene compilata come codice macchina dal runtime .NET. Il bytecode Java funziona allo stesso modo. Ci sono informazioni che sono molto facili da decompilare, e per qualcuno che sa leggere bytecode o msil, non è affatto un errore.

I file C ++, d'altra parte, sono compilati in codice macchina e sono molto meno difficili da leggere (se non del tutto) aprendo in Blocco note.

In altre parole, non ha nulla a che fare con la crittografia o la codifica, ha a che fare con il modo in cui il file è pronto per essere letto e eseguito dal PC.

Quando si tratta del testo semplice nei file, sei corretto. Sembra un rischio per la sicurezza, ma come è stato sottolineato dozzine di volte su StackOverflow, non è davvero possibile impedire alle persone di decompilare / esaminare il codice, in particolare se fatto in un linguaggio come .NET o Java. Devi presumere che il tuo codice sia completamente aperto a una persona esperta. ( Come mi è stato fatto notare quando ho fatto una domanda su come proteggere i dati sensibili in una finestra app costruita con .NET )

Per quanto riguarda ciò che informaiton viene visualizzato, questo è praticamente determinato dal compilatore e dagli strumenti utilizzati per creare l'exe.

    
risposta data 07.02.2013 - 18:56
fonte
0

Ci sono alcune cose diverse che accadono qui. Ci sono due modi principali in cui il codice può essere eseguito su un computer. La maggior parte dei programmi (applicazioni native) sono compilati in base al cosiddetto codice macchina. È un insieme di istruzioni non umano leggibile che deve essere elaborato dalla CPU. Questo codice macchina può includere dati che dovrebbero essere caricati in memoria come parte dell'esecuzione. Questo è il motivo per cui alcune stringhe di testo normale sono visibili all'interno dell'eseguibile. Si tratta semplicemente di elementi di dati che verranno caricati in un indirizzo di memoria a cui verrà indirizzato il codice macchina illeggibile. Il loro punto è puramente per la visualizzazione all'utente e / o utilizzare come costanti per il confronto delle stringhe. In realtà non sono istruzioni su cui funziona il computer.

Tale codice macchina può essere eseguito attraverso un disassemblatore, tuttavia il codice che ne risulta è spesso molto difficile da leggere ed è completamente non documentato. Quindi, è estremamente raro che qualsiasi protezione aggiuntiva venga messa su un eseguibile di questo tipo perché non è realmente necessario e poiché il codice deve essere in grado di essere letto dalla CPU alla fine, qualcuno che voleva sapere cosa stava succedendo poteva semplicemente guarda le istruzioni così come sono decodificate da inviare al compilatore.

L'altro tipo di programma principale sono le lingue che utilizzano un interprete, VM o runtime per eseguire il loro comportamento. Lingue come PHP, Java e .Net (C #, VB) rientrano in questa categoria. Dal momento che non si compongono effettivamente al codice macchina, possono essere "decompilati" molto più facilmente e ottenere qualcosa che è molto più vicino al codice originale. Per rendere questo processo più complicato, esiste una tecnica nota come offuscamento del codice. Non è crittografia, ma piuttosto, semplicemente rimuovendo gli identificatori che renderebbero più facile per qualcuno dire cosa sta succedendo e possibili alterazioni dei percorsi del codice per rendere più difficile l'interpretazione del codice al codice sorgente originale.

Esistono alcune piattaforme che tentano di consentire l'esecuzione di codice crittografato utilizzando un segmento di codice nativo che gestisce la decrittografia in modo che il codice effettivo utilizzato dal runtime sia disponibile solo immediatamente prima e durante l'uso, ma tali sistemi sono raramente usato a causa del sovraccarico che introducono.

Se si vedono stringhe di testo normale in un'immagine eseguibile, è quasi garantito che le stringhe siano caricate in memoria come dati poiché se l'eseguibile è stato compresso o crittografato, le stringhe non sarebbero visibili neanche.

    
risposta data 07.02.2013 - 19:51
fonte

Leggi altre domande sui tag