Quanto è sicura la mia applicazione?

0

Ho creato una piccola applicazione in .NET che funge da loader per le mie altre applicazioni.

Essenzialmente, una volta aperta, questa app otterrà un elenco di applicazioni disponibili e, quando viene selezionata un'opzione, scarica la versione più recente dell'applicazione in memoria e la apre.

L'applicazione stessa è offuscata (anche se dubito che sia importante) e fa quanto segue:

  1. Passa a una posizione HTTP hard-coded
  2. Scarica una stringa codificata in base 64 di un messaggio crittografato AES-256 contenente l'elenco delle applicazioni disponibili, i relativi percorsi, le dipendenze e la chiave di decrittografia.
  3. Una volta selezionata un'applicazione, scarica il file binario crittografato (e tutte le dipendenze) elencate nella configurazione, il tutto in memoria
  4. Un set base di semplici funzioni di manipolazione delle stringhe viene eseguito sulla chiave di decrittografia trovata nella configurazione e viene generato SecureString
  5. Questa chiave viene quindi utilizzata per decodificare AES e quindi caricare l'applicazione (ancora una volta, tutto in memoria).
  6. La chiave viene immediatamente impostata per lo smaltimento

Preoccupazioni per la sicurezza

  • Credo che il punto di ingresso principale sia l'applicazione stessa. Credo che, sebbene offuscato, può essere comunque facilmente analizzato.

    • Puoi proteggerti da questo?
  • Usando Fiddler / WireShark o altre applicazioni, si può facilmente determinare da dove viene letta la configurazione, e si può eventualmente impostare una risposta, quindi per le chiamate future, l'app verrà alimentata con lo stesso risultato (senza recuperarla effettivamente da la posizione prevista).

    • C'è un modo per verificare che sia stato scaricato dalla destinazione prevista?
  • Il fatto che la chiave per decodificare i file binari possa essere recuperata da un insieme di funzioni di manipolazione delle stringhe, penso possa essere facilmente riprodotta, se l'applicazione è decodificata.

    • Suggerisci un altro modo di gestire la chiave specifica dell'applicazione?
  • Quanto è facile / probabile salvare lo stato di un'applicazione in esecuzione in memoria in modo che possa essere riutilizzato senza passare attraverso l'applicazione loader ?

  • Quali altre preoccupazioni prenderesti in considerazione?

Informazioni aggiuntive

L'applicazione controlla attualmente se un proxy è attualmente registrato con il sistema e tenta di recuperarlo bypassando il proxy, tuttavia a me sembra un hack piuttosto che una funzione di sicurezza.

    
posta Zuiq Pazu 20.03.2015 - 11:33
fonte

1 risposta

1

Da quanto hai descritto, non è affatto sicuro, per un sacco di motivi. I primi due sono:

  • Stai scaricando i dati su HTTP. Anche se AES fornisce riservatezza, non fornisce l'autenticità o l'integrità del messaggio.
  • Stai utilizzando le chiavi codificate. Tirarli fuori sarebbe banale, anche con l'offuscamento. Ciò significherebbe che potrei MitM il tuo traffico e inviare binari arbitrari per assumere il controllo del sistema.
  • Stai facendo affidamento sull'offuscamento del processo per la sicurezza, che è in violazione del principio di Kerckhoffs .

La buona notizia è che è un modo corretto per farlo, con crittografia asimmetrica:

  • Genera una coppia di chiavi RSA.
  • Archivia i componenti chiave pubblica all'interno dell'applicazione.
  • Hash gli assembly sul lato server e firma l'hash con la chiave privata RSA.
  • Consegna l'hash e gli assembly firmati su HTTPS alla tua applicazione.
  • Hash il file binario scaricato, quindi utilizza la chiave pubblica per verificare l'hash rispetto alla firma.
  • Se la firma corrisponde, puoi usare i binari in sicurezza.

Puoi fare tutto questo con RSACryptoServiceProvider . Raccomando di usare SHA256 per i tuoi hash. Raccomando anche di controllare il nome sicuro dei file binari anche dopo aver verificato la loro autenticità, solo per motivi di tranquillità: puoi estenderlo ulteriormente utilizzando Strong Name Signing.

Una routine di verifica molto semplice potrebbe essere simile a questa:

bool VerifySignature(byte[] file, byte[] signature)
{
    using (var rsa = new RSACryptoServiceProvider())
    {
        rsa.ImportCspBlob(PublicKey);
        return rsa.VerifyData(file, CryptoConfig.MapNameToOID("SHA256"), signature);
    }
}

Dove PublicKey è una matrice di byte contenente i dati esportati da rsa.ExportCspBlob(false) sull'istanza RSA che ha generato la coppia di chiavi.

    
risposta data 20.03.2015 - 11:46
fonte

Leggi altre domande sui tag