Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Proteccion de Licencia para Software .NET

Iniciado por TrOnTxU, 26 de Noviembre de 2010, 07:35:26 PM

« anterior - próximo »

TrOnTxU

Wenas.

Puede que hace unos años no me imaginara nunca haciendo esta pregunta, pero después de haber pasado por diferentes y variadas empresas (siempre que hicieran juegos, si es que eso se puede considerar variación XD), y haber visto lo que se cuece ...

El tema es que estoy desarrollando en casa un frame-work multiplataforma para PC y consolas next-gen (si, ya se que soy muy original). Basicamente se compone de una aplicacion/editor con soporte para plug-ins (de echo la mayoria de la funcionalidad está alojada en las .dll de los plugins) en C# (winforms/.NET), una serie de wrappers C++/CLR, y un player en C++ (bueno, uno para cada plataforma).

Mi problema ahora es como licenciarlo (entregar el software) y no arriesgarme a que me hagan la 3-14 (tb conocida en mi pueblo como: "la jugada fosca").

Para simplificarlo he decidido varias cosas:

* No distribuir el source de nada.
* Se podrian seguir desarrollando plug-ins para ampliar el editor.
* La "programación" seria completamente en script (de momento soporto Lua, aunque estoy pensando en integrar Python y Squirrell)
* El player siempre tiene la pantalla de splash, de modo que solo sirva de visualizador (tanto en el PC de desarrollo, como en la consola target)
* El editor no permita realizar el "empaquetado final" de los assets
* Para los masters o candidates versions que se deban enviar para checking a la compañia de la consola seria imprescindible que realizara yo la build final.
* El sistema de control de licencia solo esta instalado en el editor (desarrollarlo en C# es muchisimo más comodo).


El problema es que por mucho que le meto (y se me ocurre poner) al control de licencia:
* Guardado de datos sensibles encriptados
* Creación de Bulk Keys y License Keys
* Trial versions
* Caducidad de la licencia
* Control de cambio de fechas
* Verificación de licencia por servidor
* Grabacion y comprobacion de datos en registro de windows.

No me quito la sensacion que todo parece resumirse en que como alguien se salte el "if (LicenseManager.ChekValid())" que hay cuando arranca el editor todo esfuerzo es inutil.

He estado indagando en programas comerciales que te ofrecen soluciones en apariencia muy completas, pero a la hora de integrar (por los ejemplos que he visto) en tu programa es lo mismo, si alguien se salta el if ... hasta luego lucas.

He pensado en poner mas comprobaciones de licencia durante la ejecución de la aplicación, pero poca cosa más se me ocurre.

¿ Alguien está más familiarizado con esto?

Se que Vicente tiene idea (por no decir que es Dios) de todo el tema del .NET, el codigo que se produce al compilar, como decompilarlo, que si CLR, que si CLI, y todo eso que practicamente desconozco.
Mi pregunta tb seria como de facil es "reventar" una aplicacion de .NET para saltarse el if, o intentar trazar el comportamiento de la aplicacion, para descifrar  los algoritmos, claves y procedimientos del sistema de licencia. Sobretodo comparado con c++, porque tb habia pensado en hacer el sistema en c++ y ponerlo tanto en el player como en el editor (para lo que seguramente haria un wrapper C++/CLR y una bonita .dll).

Gracias de antemano a todos y un saludo.
Vicent: Linked-In  ***  ¡¡Ya tengo blog!!

Hechelion

#1
¿Es fácil reventar un simple IF?
Si, y da igual el lenguaje, reventar un if es lo primero que se aprende cuando te pones a aprender sobre estos temas, es como reventar la chapa de un auto (normal, no la de seguridad)

¿Es Fácil reconstruir un algoritmo mediante ingeniería inversa?
Nivel medio y depende de como lo implementes y la experiencia de la persona que trata de reventarlo.

Mi consejo, parte de la base que nada es 100% seguro y que si tu aplicación se vuelve conocida vas a tener decenas (por no decir cientos) de personas tratando de reventarla y tu solo eres uno, por lo cual no puedes entrar a competir para generar el último algoritmo contra piratería (y si lo logras, entonces olvídate del negocio de los videojuegos y dedícate a la seguridad informática que si logras un algoritmo así de seguro te vuelves millonario.)

La seguridad contra la pirateria es un tema de curva similar a la curva de oferta y demanda, a mayor demanda de un producto mayor probabilidad que alguien lo rompa, por lo cual debes determinar cuan seguro quieres que sea tu aplicación en base a tus proyecciones de ganancia, o sea, para llevar tu sueldo al banco no necesitas un camión de seguridad con guardias armados, acá es lo mismo.

Si tienes una aplicación cara, que sabes se va a vender, entonces no desarrolles ningún sistema de seguridad, compra algún desarrollo ya existente (si, los venden, y los mejores son las llaves por hardware).

Lo otro es hacer comprobaciones contra un servidor usando datos cifrados con llaves asincronas, hay excelentes algoritmos de codificación libres, donde si programas un buen sistema que cree claves fuertes vas a tener un sistema bien solido.

Por último, lo mejor es cifrar una una gran cantidad de datos o código que sea necesario para un paso del programa y que de preferencia sea obtenido al azar (esto es lo que hago yo), así, el que te quieren romper el trabajo les das tantos dolores de cabeza que le sea más fácil buscar otra aplicación que romper la tuya, como te decía antes, esto son dos curvas entre cuanto les interesa romper tu aplicación y cuanto trabajo les va a tomar.

Si hay dos aplicaciones que hacen más menos lo mismo y una es fácil de romper y la otra de solo ver el trabajo que hay que hacer ya te hace doler la cabeza, por lógica vas a romper y usar la que sea más fácil (Pero ten en mente que si hay alguien bueno que quiere romper tu sistema, a la larga lo va a conseguir)..


Si quieres aprender a programar sistemas anti-piratería, lo primero que tienes que hacer es aprender a romper programas.


Por último, y esto es consejo personal, cuando programas sistemas anti-pirateria, piensa siempre en tu cliente, tu programas para ellos, no para los piratas, si yo como cliente, tengo problemas para usar mi programa legal, ten por seguro que voy a terminar migrando y hablando mal del producto.

Edit:
Por cierto, no coloques sólo un punto de comprobación al inicio ni una sola función, tal como dices, debes agregar la comprobación en varias partes, por ejemplo, crear N objetos timer con tiempos aleatorios que comprueben la licencia o boten el programa. Y creas los objetos en diferentes etapas de tu aplicación.

TrOnTxU

#2
Muchas gracia por la explicación :)

Por ahora solo tengo en mente un par de posibles clientes para un par de proyectos.
Asi que la aplicación no deberia ir de manos en manos, y seguramente serian los mismos clientes los que se asegurarian de que la aplicacion por la que pagan la licencia no sale a terceras personas que pudieran aprovecharse de algo que solo ellos deberian tener.

Asi que solo me preocupan los "clientes", que, como es habitual, si pueden pagar 10 en vez de 20 no se lo piensan, aunque esos 10 fueran a parar a alguien contratado para "modificar ilegalmente" el programa, en vez de al desarrollador original del software. Y que quede claro que siempre he defendido compartir código y el open source, pero depués de ver como diferentes empresas hacian grandes cantidades de dinero a costa del trabajo y esfuerzos de "asalariados", no tengo ninguna gana de lo que sigan haciendolo a la mia, puesto que aqui ya no cumplo el papel de "asalariado".

Mi intención (y espero que asi sea, o muy mal me irá) es que el "engine" en si, vaya creciendo y evolucionando en cuanto a plataformas destino y features, de manera que puedo controlar que sean "necesarias" ciertas actualizaciones, y que las versiones anteriores del software queden, por necesidad, obsoletas. Lo cual me puede ayudar a ir integrando un sistema de proteccion cada vez más complejo, o, al menos, ligeramente modificado, por si la versión anterior ya ha sido reventada.

Por supuesto no pienso dedicarme al software antipirateria ya que ni siquiera me considero experto en lo que hago (y eso que cada dia se me hace más dificil recordar cuantos años llevo ya en esto), asi que ni decir tengo de meterme en algo en lo que estoy completamente pez (ahora mismo no veo capaz ni de desbordar un buffer).

El tipo de aplicación que estoy realizando no creo que sea la indicada para un público extenso, y, en caso de que compañias más "importantes" quisieran utilizar mi producto, he de decir que me fio más de ellas (por irónico que parezca), que algunas de las más "pequeñas" que ahora mismo puedan estar interesadas en mi producto. Simplemente por el echo de que el dinero de las licencias "se la pela" literalmente.
Cuando he currado en una empresa "multinacional" o una empresa "grande" hemos tenido licencias legales de todo el software, incluso licencias de sobra guardadas en un cajón y cogiendo polvo. Más tarde he llegado a una empresa más "modesta" como Lead Programmer y me han tenido con un portatil basura durante dos o tres semanas (perdiendo tiempo de productividad) por no gastarse el dinero en un PC (entre otras muchas barbaridades).

Asi que lo que me preocupa, una vez más, es que alguien pueda gastarse dinero en saltarse el if, con tal de salirse con la suya y no pagar el mismo dinero o un poco más a mi, que al fin y al cabo, soy el que ha perdido montones de horas de sueño y vida social.

En cuanto al tema se los serials / bulk, las fechas de activación, etc lo he implementado como técnica disuasoria. Primero, es fácil de implementar, simplemente se basa en encryptar/desencryptar texto con la informacion de la licencia, comprobar las fechas y las features de la version activada.
Si alguien no versado en el tema ve los cuadros de dialogo y que no puede iniciar la aplicacion, puede frenarle la idea, antes incluso de intentar averiguar realmente como esta implementada la protección. Por supuesto, alguien que tenga idea tardaria 0'01 seg en reventarlo.

Como tengo mucho más que implementar de la parte funcional del software, no puedo dedicarle mucho más tiempo a esto, pero aun asi Hechelion me ha interesado mucho el tema de la protección que implementas tú cifrando parte del código necesario, si fueras tan amable de recomendarme un par de enlaces donde pueda intentar ilustrarme sobre el tema te estaria muy agracedio, más que nada por intentar mejorar un poco (solo lo suficiente) el sistema de protección.

Y por cierto, y ya que veo que estas muy puesto en el tema, también me suelo preguntar como se puede demostrar que una aplicación (pongamos un juego de ps3,  por ejemplo) ha sido realizado con tu sdk o engine. ¿Analizando los binarios para encontrar los patrones de tus librerias por ejemplo?
Es otra cosa que me ronda la cabeza, como ves últimamente me estoy volviendo un poco paranoico, XD

Bueno, muchas gracias de nuevo.
Adew!

EDIT:
en cuanto a crear varios timers me parece una idea estupenda, asi que voy a intentar ponerme con ello cuando antes,  :D thank you!
Por cierto, cuando hablas de no utilizar una única función, ¿te refieres que seria mejor tener varias funciones que hagan lo mismo o algo parecido y cada vez que "salta" un timer llamar a una de ellas?
Bien pensado tiene sentido que si averiguas la dirrecion de la funcion que hace el check, te seria, más o menos sencillo, buscar las zonas donde se llama a la misma direccion, ¿no?
Vicent: Linked-In  ***  ¡¡Ya tengo blog!!

Hechelion

#3
Ni experto ni entendido  :P , lo que pasa es que yo estuve (y estoy) en la misma situación que tu estás ahora, ya que me ha tocado programar muchos sistemas de gestión de datos para mi campo de trabajo y al igual que tú, no quería que la empresa se quedara funcionando con el programa demo de forma permanente y sin pagar o replicaran el sistema.

Así que me puse a averiguar que se podía hacer y la verdad, cuesta encontrar buena información, así que me puse a buscar lo contrario, ¿como romper programas?, de eso hay bastante información, sobre todo comunidades y foros que se dedican al tema, también participar en  foros de cifrado, etc.

Así fui aprendiendo algunas cosas y con eso en mente empecé a programar pensando en evitar las técnicas más comunes, por ejemplo, usar aplicaciones para "comprimir" (no recuerdo el termino técnico ahora) el .exe final, es completamente diferente buscar 2 bytes dentro de 2 MB sin tener ni idea de por donde comenzar, a buscar 2 bytes cerca de un texto en ASCII que dice "Su licencia no es valida".   Y cosas al estilo.

Personalmente divido la seguridad en 2, externa, que tiene que ver con todos los datos que rodean al programa, como licencia, datos, etc. E interna, que tiene que ver con el contenido del exe.

La interna es más simple, porque para editar un exe en hexadecimal se requiere por lo menos un poco de conocimiento, y conque compliques un poco el sistema (timer, varias funciones, etc) ya le colocas el tema cuesta arriba a la gran mayoría de los informáticos que tienen esas empresas y que podrían romper tu programa.

Considero que lo más difícil es un un buen sistema externo, porque lo más fácil es hacer una instalación legal pero haciendo un seguimiento de cada paso del programa (que archivos abre, que llamados hizo al registro, etc) y luego con un poco de ingenio es fácil copiar y pegar los archivos que creaste o los registros y así replicar el programa en otro PC, la mejor opción son las llaves de hardware, lo más simple es obteniendo el serial de un USB o de un HDD y usando ese valor para encryptar/desencritar otro dato.

¿Por qué hablo de usar esos valores para encriptar y no sólo como una comparación?
Como te decía antes, saltar una comparación es simple, pero si el dato es parte del algoritmo, entonces complicas bastante la situación, porque para poder recuperar un dato critico para tu programa, si o si, necesitas tener la clave, no importa cuantos if puedas modificar, si no tienes la clave no vas a poder recuperar el dato y sin ese dato tu programa no corre.
Modificar el programa se hace mucho más complicado, porque está obligado a entender lo que programaste para poder romperlo, o obtener la clave rompiendo el cifrado, pero en el mercado hay excelentes algoritmos asíncronos que con una buena clave hacer que romper el cifrado sea una tarea titanica.



Sobre tu pregunta, la verdad, por lo que sé, creo que lo mejor que puedes hacer es firmar el producto de tu aplicación, si por ejemplo, es un editor de imágenes, puedes agregar una marca de agua o una cabecera, si tu producto es un archivo en binario es más simple, ya que agregas una cabecera o una cola con la firma de tu aplicación. Probar que determinado patrón es tuyo, no es tarea fácil, en cambio, no hay ninguna forma de ambigüedad as  explicar un "Desarrollado por TrOnTxU editor" en medio del archivo. Por ejemplo, si creas una página HTML con el word y la miras en un editor hexadecimal, veras que se agregan líneas que indican que esa página fue creada con el Office.

TrOnTxU

#4
Hola,
siguiendo el consejo de Hechelion estoy investigando la forma de "romper" yo mismo la protección de mi software para poder mejorarla.

Lo primero que he encontrado es el Reflector y el FileDisassembler. Con el que puedes ver e incluso trazar en el visual studio cualquier .NET, .exe o .dll, a nivel de código fuente (C# en este caso). Lo único que no se todavia como hacer es modificar el ensamblado, pero darme un dia más que esto parece (y ojala me equivoque) que coser y cantar  >:(

Si no seria muy complicado sustituir un "jne" por un "je" en ensamblador ni te cuento como de facil es leer o trazar el codigo fuente C# y encontrar lo que buscas, sobretodo si se trata de modificar un par de comparaciones.

Lo primero que tengo en mente es utilizar ofuscadores de código, ya lo utilizaba bastante cuando haciamos juegos de moviles en java, e incluso a veces desensamblabamos el propio código ofuscado, ya que algunos parches para algun movil especifico como meter una llamada a un clase unica de ese modelo, sin tener la libreria y cosas de ese estilo.
La verdad es que funcionan de una forma muy parecida a los que utilizaba para java, pero con la diferencia aquel código ofuscado y decompilado, raramente podia compilarse de nuevo otra vez como java, y tenias que modificar y "reconstruir" parte del código, y si no estabas muy relacionado el byte-code de java, puede que no supierascomo hacerlo o las pasaras canutas (como yo).
Esto parece, sin embargo, y a mi pesar, mucho más fácil  :grrr:

Tambien he leido que hay una manera de que visual studio encripte tus dlls, y que solo con una clave puedas decriptarla, pero una vez el usuario final tenga la clave, no se que le impediria utilizar reflector, por ejemplo.

Por último, el tema de comprimir o encriptar parte del código ... no se me ocurre como, no se si el código CLI o como se llame se puede encriptar/comprimir, y luego hacer el procedimiento inverso y ejecutarlo.
Lo único que posiblemente se pueda hacer, o pueda funcionar, es tener código "crítico" para la ejecución del programa en C# en un archivo encriptado y en tiempo de ejecución desencriptarlo y compilarlo / ejecutarlo JIT. Pero no se donde meter la clave, si la pongo en código se puede trazar, si la pongo el registro tambien, si la pongo en un archivo por supuesto, y si la encripto necesito otra clave para desencriptarla (nananana, arrrrggg!)  |:|


La verdad es que me asusta bastante esta "desproteción" del software, que para mi parece demasiado flagrante, y aunque sé que todos los lenguajes se pueden "crackear" esto me parece excesivo. El coste de la versatilidad y potencia de la reflexión en .NET aqui parece una de las mayores amenazas para la seguridad de tu producto.
Pero bueno, tengo la mayor parte de la funcionalidad del editor en C#, y la verdad es que me ha costado menos de la mitad que si la tuviera que haber hecho en C++, asi que no voy a cambiar a estas alturas de lenguaje.

Si alguien puesto en .NET me pudiera tranquilizar (aunque solo fueran un par de mentiras piadosas) quizás acabará antes de "rallarme" con todo este tema, y vuelva al código de funcionalidad del programa. (please)


Bueno, un saludo y gracias.

EDIT: otra cosa que estoy pensando es realizar crc o hash de los assemblies que contienen la proteccion, y comprobarlos en otras partes del programa, o utilizar el resultado como clave asimetrica para encriptar algo, todavia estoy cociendo la idea. No es un obstaculo insuperable, pero puede dar bastantes dolores de cabeza al que intente modificar un assembly. ¿alguna opinión al respecto?
Vicent: Linked-In  ***  ¡¡Ya tengo blog!!

fjfnaranjo

IMHO

Mi consejo es, por extremadamente simplificante que te suene, el siguiente:

1: Dota a tu código fuente de varias maneras de identificarse a si mismo como el framework de origen de cualquier aplicación que se realice con él (una pantalla con el logo del fw al principio, marcas en el código que se puedan descifrar con una clave asimétrica, etc..).

2: Simplifica hasta el absurdo el sistema de validación de la licencia: número de serie + server de autentificación debería ser suficiente, pero no obligues al usuario de tu fw estár conectado constantemente a Internet.

3: Especifica todo con detalles y cuidado en la licencia, para que nadie pueda hacer uso de tu fw sin remunerarte.

Y ya. Con eso vas a cubrir lo suficiente la aplicación.

Cualquier cracker en condiciones, va a romper cualquier sistema que uses, es sólo cuestión de tiempo. Así que no gastes tu tiempo en inventar un super sistema de seguridad. Es mejor invertir en desarrollar una licencia de uso que te proteja e incluir un control de licencias mínimo. Con esto te aseguras dos cosas:

1: No dar por culo al usuario legítimo.

2: Si alguien se hace muy rico con tu producto, lo puedes atacar legalmente y las va a pagar.

No te preocupes por la cantidad de "piratería" esporádica que puedas tener. Al final la mayoría de gente que usa la aplicación pirata no van a publicar con ella.

Empresas como Autodesk o Microsoft no ganan pasta persiguiendo al artista/programador que usa ilegalmente su software. Para ellos es hasta provechoso que esto ocurra, porque se da difusión al producto. Luego, la empresa de turno que use ese software donde este artista/programador trabajen, es la que te va a aportar beneficios.

Cuantos más individuales se sientan cómodos y conozcan tu producto, más clientes potenciales legales y con recursos vas a tener ;)
fjfnaranjo.com - Creating entertainment - Creando entretenimiento
fjfnaranjo [4t] gm4il [d0t] c0m (mail y msn)

TrOnTxU

Gracias por los aportes, opiniones y consejos  :)

Pues después de unos cuantos repasos, es como me temia. He aprendido a trazar el código fuente c# a partir del .exe o de una .dll y a modificar las instruciones IL en menos de un dia :(
Me cuesta 0,2segs crackear mi sistema de protección conforme lo tengo ahora. Asi que algo si que me voy a poner las pilas.

La verdad es que es demasiado fácil.

He pensado un par de cosillas y ya van tomando forma, pero la primera y más importante es evitar a toda costa que se modifiquen los assemblies, asi que a "hashear" y a encryptar que toca.

Ya iré contando avances.
Gracias de nuevo.
Vicent: Linked-In  ***  ¡¡Ya tengo blog!!

Vicente

Estoy de vacaciones, si me mandas un privado a la vuelta miro esto, sino se me olvidara entre los miles de cosas que tendre pendientes :S






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.