¿Qué tan segura es mi aplicación?

0

He creado una pequeña aplicación en .NET que sirve como loader para mis otras aplicaciones.

Esencialmente, cuando se abre, esta aplicación obtendrá una lista de las aplicaciones disponibles, y cuando se selecciona una opción, descarga la última versión de la aplicación en la memoria y la abre.

La aplicación en sí misma está ofuscada (aunque dudo que eso importe) y hace lo siguiente:

  1. Navega a una ubicación HTTP codificada de forma rígida
  2. Descarga una cadena codificada en base 64 de un mensaje cifrado AES-256 que contiene la lista de aplicaciones disponibles, sus rutas, dependencias y clave de descifrado.
  3. Una vez que se selecciona una aplicación, descarga el archivo binario cifrado (y las dependencias) que figuran en la configuración, todo en la memoria
  4. Se realiza un conjunto básico de funciones simples de manipulación de cadenas en la clave de descifrado que se encuentra en la configuración y se genera un SecureString
  5. Esta clave se usa para descifrar AES y luego cargar la aplicación (una vez más, todo en la memoria).
  6. La clave se establece inmediatamente para su eliminación

Problemas de seguridad

  • Creo que el punto de entrada principal es la propia aplicación. Creo que, aunque ofuscado, se puede analizar fácilmente de todos modos.

    • ¿Puedes protegerte contra esto?
  • Al usar Fiddler / WireShark u otras aplicaciones, uno puede determinar fácilmente de dónde se está leyendo la configuración, y posiblemente puede configurar una respuesta, por lo que para futuras llamadas, la aplicación se alimentará con el mismo resultado (sin realmente recuperarlo). la ubicación prevista).

    • ¿Existe alguna forma de verificar que se haya descargado del destino deseado?
  • El hecho de que la clave para descifrar los archivos binarios pueda recuperarse mediante un conjunto de funciones de manipulación de cadenas, creo que se puede reproducir fácilmente, si la aplicación tiene ingeniería inversa.

    • ¿Sugiere otra forma de tratar con la clave específica de la aplicación?
  • ¿Qué tan fácil / probable es guardar el estado de una aplicación que se ejecuta en la memoria para que pueda reutilizarse sin pasar por la aplicación loader ?

  • ¿Qué otras preocupaciones consideraría?

Información adicional

La aplicación actualmente verifica si un proxy está registrado actualmente en el sistema e intenta recuperarlo sin pasar por el proxy, sin embargo, para mí esto suena como un hack en lugar de una característica de seguridad.

    
pregunta Zuiq Pazu 20.03.2015 - 11:33
fuente

1 respuesta

1

Por lo que describió, no es seguro en absoluto, por varias razones. Los dos primeros son:

  • Estás descargando datos a través de HTTP. Incluso si AES proporciona confidencialidad, no proporciona autenticidad o integridad del mensaje.
  • Estás usando claves codificadas. Sacarlas sería trivial, incluso con ofuscación. Esto significaría que podría mitigar su tráfico y enviar archivos binarios arbitrarios para asumir el control del sistema.
  • Confía en la ofuscación del proceso de seguridad, que viola el principio de Kerckhoffs .

La buena noticia es que hay una forma adecuada de hacer esto, con criptografía asimétrica:

  • Genera un par de claves RSA.
  • Almacene los componentes de la clave pública dentro de su aplicación.
  • Hash los ensamblajes en el lado del servidor y firme ese hash con la clave privada RSA.
  • Envíe el hash y los ensamblados firmados a través de HTTPS a su aplicación.
  • Hash el binario descargado, luego use la clave pública para verificar el hash contra la firma.
  • Si la firma coincide, es seguro usar los binarios.

Puedes hacer todo esto con RSACryptoServiceProvider . Recomiendo usar SHA256 para sus hashes. También recomiendo verificar el nombre seguro de los binarios incluso después de que hayas verificado su autenticidad, solo para tu tranquilidad, puedes extender esto más usando la Firma de nombre fuerte.

Una rutina de verificación realmente simple podría tener este aspecto:

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

Donde PublicKey es una matriz de bytes que contiene los datos exportados por rsa.ExportCspBlob(false) en la instancia RSA que generó su par de claves.

    
respondido por el Polynomial 20.03.2015 - 11:46
fuente

Lea otras preguntas en las etiquetas