MegaVision es un sistema propietario desarrollado por MRV dedicado a la gestión de elementos de RED, basado en SNMP por TCP, Network Management System (NMS), provee administración y control de elementos gestionados por CORBA o SNMP. Es común ver este tipo de sistemas de administración en empresas como NEXTEL, ALCATEL o Radiomovil Dipsa (TELCEL), por este sistema se pagan licencias de un costo considerable. Con el se lleva un control de los elementos de RED como radioantenas y equipos de telecomunicaciones específicas como switch’s de red asi como de storage por FC.
Las licencias para acceder a todas las funcionalidades disponibles, como es de esperarse y ya mencione anteriormente son muy costosas, por lo tanto, la seguridad con la cual se desarrollan estas aplicaciones de uso específico se podría pensar, es muy elevada y de estándares sumamente rígidos, su impacto en las empresas es demasiado alto, sin embargo como vamos a ver en el siguiente tutorial, descubriremos que esto es totalmente falso.
Primero obtendremos la versión trial de 30 días disponible en:
ftp://ftp.mrv.com/pub/software/megavision/MVPro30daysTrial.exe
Trataremos ahora de ver que información podemos obtener con el PEiD:
Pues lejos de la información natural de inicio de memoria para el programa particular no logramos obtener nada mas. Cargamos el programa en OllyDbg (el nombre del ejecutable es: lan4ms.exe) y comenzaremos a debuggear de manera normal tratando de buscar la primera caja de error, cuando cargamos el programa en OllyDbg esta es la pantalla inicial:
Ahora al ejecutarlo buscaremos la primera pantalla de error:
Como se puede observar de manera inicial, obtenemos un cuadro de dialogo que nos indica que el password de acceso al sistema es incorrecto, primero brincaremos este cuadro, para posteriormente poder ingresar al combo que permite capturar el serial de la licencia. Hay que tener bien en claro que este primer password NO ES LA ACTIVACION de la aplicación, sino solo la validación inicial para poder ingresar al cuadro de activación del producto.
Ahora bien, el siguiente paso es buscar la cadena con la leyenda «Invalid Password» buscamos en todas las cadenas referenciadas (all referenced text strings) y vamos a ese fragmento de código:
.
.
.
004B5CBF . 83C4 10 ADD ESP,10
004B5CC2 . 8B85 D4FEFFFF MOV EAX,DWORD PTR SS:[EBP-12C]
004B5CC8 . 8B48 34 MOV ECX,DWORD PTR DS:[EAX+34]
004B5CCB . 51 PUSH ECX ; /s2
004B5CCC . 8D95 ECFEFFFF LEA EDX,DWORD PTR SS:[EBP-114] ; |
004B5CD2 . 52 PUSH EDX ; |s1
004B5CD3 . E8 C4120A00 CALL <JMP.&MSVCR80.strcmp> ; \strcmp
004B5CD8 . 83C4 08 ADD ESP,8
004B5CDB . 85C0 TEST EAX,EAX
004B5CDD 74 17 JE SHORT lan4ms.004B5CF6
004B5CDF . 6A 00 PUSH 0 ; /Arg2 = 00000000
004B5CE1 . 68 880F5800 PUSH lan4ms.00580F88 ; |Arg1 = 00580F88 ASCII «Invalid password!»
004B5CE6 . 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+8] ; |
004B5CE9 . E8 32C3F9FF CALL lan4ms.00452020 ; \lan4ms.00452020
004B5CEE . 83C8 FF OR EAX,FFFFFFFF
004B5CF1 . E9 88000000 JMP lan4ms.004B5D7E
004B5CF6 > 8B85 D4FEFFFF MOV EAX,DWORD PTR SS:[EBP-12C]
004B5CFC . A3 8CDA5A00 MOV DWORD PTR DS:[5ADA8C],EAX
004B5D01 . 8B85 D4FEFFFF MOV EAX,DWORD PTR SS:[EBP-12C]
004B5D07 . 8B48 04 MOV ECX,DWORD PTR DS:[EAX+4]
004B5D0A . 83E9 01 SUB ECX,1
004B5D0D . 894D EC MOV DWORD PTR SS:[EBP-14],ECX
004B5D10 . EB 05 JMP SHORT lan4ms.004B5D17
004B5D12 >^E9 1BFFFFFF JMP lan4ms.004B5C32
004B5D17 > 0FBE85 DFFEFFF>MOVSX EAX,BYTE PTR SS:[EBP-121]
004B5D1E . 85C0 TEST EAX,EAX
004B5D20 . 75 14 JNZ SHORT lan4ms.004B5D36
004B5D22 . 6A 00 PUSH 0 ; /Arg2 = 00000000
004B5D24 . 68 740F5800 PUSH lan4ms.00580F74 ; |Arg1 = 00580F74 ASCII «Unknown User Name!»
004B5D29 . 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+8] ; |
004B5D2C . E8 EFC2F9FF CALL lan4ms.00452020 ; \lan4ms.00452020
004B5D31 . 83C8 FF OR EAX,FFFFFFFF
004B5D34 . EB 48 JMP SHORT lan4ms.004B5D7E
004B5D36 > 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14]
004B5D39 . 83C0 01 ADD EAX,1
004B5D3C . A3 30DA5A00 MOV DWORD PTR DS:[5ADA30],EAX
.
.
.
La dirección 004B5CE1 es la encargada de invocar el cuadro de diálogo y la instrucción ubicada en la dirección 004B5CDD es la que realiza la validación del password, el cual previamente obtiene directamente desde la base de datos, la instrucción que cambiaremos para saltar la validación es la siguiente:
004B5CDD 74 17 JE SHORT lan4ms.004B5CF6
la cual quedará de la siguiente manera:
004B5CDD 75 17 JNZ SHORT lan4ms.004B5CF6
La volvemos a ensamblar y para comprobar la efectividad del salto obligado pondremos un BreakPoint en la siguiente dirección:
004B5D1E y ejecutaremos instrucción por instrucción presionando F7.
Con esto brincamos la primera validación y llegamos a la parte de la inserción de la licencia:
Cuando se ingresa un password incorrecto, el programa arroja el siguiente error:
El procedimiento normal para encontrar la validación de la licencia, consiste en buscar este texto de error en todas las referencias de cadenas contenidas en el programa, sin embargo esto no dará resultado, debido a que la leyenda de error, se extrae directamente del stack en tiempo de ejecución. Esta es una medida de seguridad que los programadores implementaron para evitar que durante el debugging no se pueda localizar de manera satisfactoria el fragmento de código o módulo que describe la validación de la licencia. Esto si bien complica nuestro trabajo no lo hace imposible. Analizando el funcionamiento del programa resulta complicado tratar de adivinar el modulo de validación, así que comenzaremos a debuggear desde que se introduce la supuesta licencia en el cuadro de dialogo. Para esto buscaremos por nombre en el actual módulo (Control + N) el método correspondiente a GetDigTextA, colocamos un BreakPoint en esta instrucción
Names in lan4ms, item 820
Address=0056CFD0
Section=.rdata
Type=Import (Known)
Name=USER32.GetDlgItemTextA
y debuggeamos paso a paso.
Aquí debemos ser pacientes y debuggear paso a paso, instrucción por instrución hasta notar algo que nos indique donde se encuentra el modulo de validación de licencias, como se puede observar lo primero que ocurre luego de la lectura de cada carácter ingresado al TextBox, se valida la fecha de descarga del paquete de instalación (Installer) que no exceda los 30 días, aparentemente no ocurre nada interesante, sin embargo al revisar el stack se puede observar el mensaje de error que resulta después de una validación con respuesta de fallo:
Si bajamos y recorremos el stack podemos ver, que quien origina ese mensaje es el modulo MSVCR80 así que vamos en el desensamblador a dicho módulo y colocamos un Breakpoint en la instrucción mas inmediata que nos proporcione una buena posición de lectura:
0012DFC8 0012DFA8
0012DFCC 00CB8008
0012DFD0 0012E9EC
0012DFD4 78138CED MSVCR80.78138CED
0012DFD8 7A89623C
0012DFDC 00000002
0012DFE0 78134C58 RETURN to MSVCR80.78134C58 from MSVCR80.78138CD9
0012DFE4 00000001
0012DFE8 00CAAC28
0012DFEC 00CA9D30
0012DFF0 005AB7A8 lan4ms.005AB7A8
Una vez colocados aqui debuggeamos de nuevo con mucha paciencia, luego de ver con mucho detenimiento el comportamiento del programa localizamos un RET el cual devuelve el control después de unas estructuras de validación:
.
.
.
78144A99 C3 RETN
78144A9A CC INT3
78144A9B CC INT3
78144A9C CC INT3
78144A9D CC INT3
78144A9E CC INT3
78144A9F CC INT3
78144AA0 > 8B5424 04 MOV EDX,DWORD PTR SS:[ESP+4]
78144AA4 8B4C24 08 MOV ECX,DWORD PTR SS:[ESP+8]
78144AA8 F7C2 03000000 TEST EDX,3
78144AAE 75 3C JNZ SHORT MSVCR80.78144AEC
78144AB0 8B02 MOV EAX,DWORD PTR DS:[EDX]
78144AB2 3A01 CMP AL,BYTE PTR DS:[ECX]
78144AB4 75 2E JNZ SHORT MSVCR80.78144AE4
78144AB6 0AC0 OR AL,AL
78144AB8 74 26 JE SHORT MSVCR80.78144AE0
78144ABA 3A61 01 CMP AH,BYTE PTR DS:[ECX+1]
78144ABD 75 25 JNZ SHORT MSVCR80.78144AE4
78144ABF 0AE4 OR AH,AH
78144AC1 74 1D JE SHORT MSVCR80.78144AE0
78144AC3 C1E8 10 SHR EAX,10
78144AC6 3A41 02 CMP AL,BYTE PTR DS:[ECX+2]
78144AC9 75 19 JNZ SHORT MSVCR80.78144AE4
78144ACB 0AC0 OR AL,AL
.
.
.
Es aquí donde luego de varios ciclos, siempre devuelve el control, en este punto se valida la versión y se generan hash’s interesantes y de los cuales no se necesita tener gran experiencia para deducir que donde existen hash’s, existen contraseñas e involucran métodos de validación; colocamos un BreakPoint en
78144AA8 F7C2 03000000 TEST EDX,3
Volvemos a ejecutar paso a paso y nos encontramos con los hash en cuestión:
Si somos observadores, se puede ver con claridad como el algoritmo de cifrado para el licenciamiento toma como llave privada o semilla la IP de nuestro equipo, como podemos ver en la parte alta del acumulador que es precisamente donde se obtiene y almacena la IP casi en todo momento.También es visible el diccionario de datos que muy posiblemente se utiliza para realizar el cifrado:
.
.
.
00512F8C |. BE A0D45800 MOV ESI,lan4ms.0058D4A0 ; ASCII «poDhemotoAvn%fRTBNHFGWdLK<>?MFcdGFRtYUga[]P01567824hfderCDuserLOMsertNmServNjKLOPKaswertbvsegodniavsebuDETHOROshoHTR6TREQpmzxmNcVFERhgakj<>?:98765$#@*hjgqwe#^&%542@hgqwerNEOCHENJHhochetsaVeritHGFDKLJMNBGJHfagbvxcsde$#@()*&^56TrfxcVFREVvg»…
00512F91 |. 8DBD 90FEFFFF LEA EDI,DWORD PTR SS:[EBP-170]
00512F97 |. F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS>
00512F99 |. 66:A5 MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI]
00512F9B |. A4 MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
00512F9C |. B9 44000000 MOV ECX,44
00512FA1 |. BE 88D35800 MOV ESI,lan4ms.0058D388 ; ASCII «Abhyr56$3vfKLOPhjuTRQAJmKhnGFDRTfghkO92K6%34$!hjkasdorterPoostorogneyPogaluistaNadeush%er410865#*netNIKakixptobelovTAKCHTOnBUdemrewqusfrtbp7&8*#nefacFDRTVerteMNEchtotozdewqasdnechisto908f5%$fd21SWERhoroshenkoenacgfhalo984%$*poverteETONEj»…
.
.
.
El cual esta contenido en el módulo inicial (lan4ms) y es invocado desde el actual. La IP del equipo como ya lo mencione antes, juega un papel muy importante en el cifrado de la licencia, si quisieramos hacer el keygen para este software deberíamos poner especial cuidado en el siguiente fragmento de código:
Ahora tenemos la traza completa del programa, presionamos F9 para evitarnos debugear paso a paso, pues finalmente tenemos el BreakPoint en un punto estratégico, ahora analicemos la pila y los nuestros registros EAX, ECX y EDX, en EDX se encuentra el password erróneo y en los demás registros se encuentran el serial de la licencia:
como se muestra en la imágen el contenido de nuestros registros es el siguiente:
EAX 0012E9A0 ASCII «7HZ$NWQ77**7»
ECX 0012E9A0 ASCII «7HZ$NWQ77**7»
EDX 00CCDD68 ASCII «jesusssss»
EBX 001578C8
ESP 0012E738
EBP 0012E9D8
ESI 005AB7A8 lan4ms.005AB7A8
EDI 00D0AB30
EIP 78144AA8 MSVCR80.78144AA8
C 0 ES 0023 32bit 0(FFFFFFFF)
P 1 CS 001B 32bit 0(FFFFFFFF)
A 0 SS 0023 32bit 0(FFFFFFFF)
Z 0 DS 0023 32bit 0(FFFFFFFF)
S 0 FS 003B 32bit 7FFDD000(FFF)
T 0 GS 0000 NULL
D 0
O 0 LastErr ERROR_SUCCESS (00000000)
EFL 00000206 (NO,NB,NE,A,NS,PE,GE,G)
ST0 empty +UNORM 0002 0000000C 00000000
ST1 empty -UNORM FA68 00000000 F649F9A4
ST2 empty 5.2740113353076364920e-2157
ST3 empty -UNORM FBB4 00000200 00050006
ST4 empty -3.2319180689861794800e-3439
ST5 empty -3.8526553087286295760e+4501
ST6 empty -NAN FFFF BF998A90 BF98F7E0
ST7 empty 1.2497930472981881780e-3031
3 2 1 0 E S P U O Z D I
FST 0020 Cond 0 0 0 0 Err 0 0 1 0 0 0 0 0 (GT)
FCW 027F Prec NEAR,53 Mask 1 1 1 1 1 1
El contenido de nuestra pila es:
.
.
0012E730 00429A59 lan4ms.00429A59
0012E734 0012E9A0 ASCII «7HZ$NWQ77**7»
0012E738 00429A69 RETURN to lan4ms.00429A69 from <JMP.&MSVCR80.strcmp>
0012E73C 00CCDD68 ASCII «jesusssss»
0012E740 0012E9A0 ASCII «7HZ$NWQ77**7»
.
.
Y finalmente el fragmento de código en el desensamblador que se encarga de realizar la validación se muestra a continuación:
.
.
78144AA0 > 8B5424 04 MOV EDX,DWORD PTR SS:[ESP+4]
78144AA4 8B4C24 08 MOV ECX,DWORD PTR SS:[ESP+8]
78144AA8 F7C2 03000000 TEST EDX,3
78144AAE 75 3C JNZ SHORT MSVCR80.78144AEC
78144AB0 8B02 MOV EAX,DWORD PTR DS:[EDX]
78144AB2 3A01 CMP AL,BYTE PTR DS:[ECX]
78144AB4 75 2E JNZ SHORT MSVCR80.78144AE4
78144AB6 0AC0 OR AL,AL
78144AB8 74 26 JE SHORT MSVCR80.78144AE0
78144ABA 3A61 01 CMP AH,BYTE PTR DS:[ECX+1]
78144ABD 75 25 JNZ SHORT MSVCR80.78144AE4
78144ABF 0AE4 OR AH,AH
78144AC1 74 1D JE SHORT MSVCR80.78144AE0
78144AC3 C1E8 10 SHR EAX,10
78144AC6 3A41 02 CMP AL,BYTE PTR DS:[ECX+2]
78144AC9 75 19 JNZ SHORT MSVCR80.78144AE4
78144ACB 0AC0 OR AL,AL
78144ACD 74 11 JE SHORT MSVCR80.78144AE0
.
.
Ahora finalmente sabemos que para la IP de este equipo la cual es 192.168.1.78 el serial de la licencia es 7HZ$NWQ77**7. Probemos introduciendo este serial en el programa para asegurarnos si estamos en lo correcto:
Listo, el programa se encuentra disponible con todas sus funciones, para obtener el keygen de esta aplicación basta con debuggear la parte de la generación de hash, sin embargo esto es mas engorroso y sale del objetivo primordial de este tutorial: crackear aplicaciones de uso sumamente especifico.
Existe un bucle, el cual se encuentra en nuestro BreakPoint principal (78144AA8 F7C2 03000000 TEST EDX,3) que valida 6 veces la versión y cada vez que lo hace obtiene un serial diferente de los cuales los siguientes son validos para licenciar el software como FULL PRO y Enterprise Edition:
Password :iLG:vSG:?OL Full Edition
Password MM^>JJDQ^^Q Full Edition
Password 7HZ$NWQ77**7 Enterprise Edition
Hay que ser cuidadosos para identificar estos seriales, pues se generan al culminar la validación de la versión y antes de comenzar con el siguiente loop en los registros EAX y ECX.
Tratando de realizar el keygen me he percatado de que estas empresas desarrolladoras de software especifico generan strings muy largos que usan como hash o números semillas de algoritmos hexadecimales para cifrar sus seriales tanto EMC como MRV utilizan cadenas del estilo:
0012EABC |0058B7A8 ¨·X. ASCII «JHYTREDCxsERtgFer1928374%$#@GFDrtqFVBNm<>V,.?:LKFAqwdTYGJ^%$#*(@!1982373645gFDSJKLkUYTGb81GtrEWsxALHgVGYHNMKv%$^*83DRTGBhNmklOPWQasWERFHGFDSOKLmnbvCDfgXAqwLMnbvGfdewsxfghjiNM<>?:K7^%$#@!UNBv<Aqcfd$(HN<K>F?*HGREWQAZXY6^*8%FAL<FVbvfdqw2#se»…
Las cuales después de tratamientos relativamente sencillos se parsean en octetos para obtener el cifrado de sus seriales en base a la mac address o IP’s del equipo. Utilizando simples operadores lógicos se obtuvo un juego de passwords de los cuales solo 1 fue correcto:
IP: 10.74.1.109
Password: QSSVXkR9QSW
El Keygen aún esta pendiente. Sin embargo es de valia conocer los métodos que se utilizan para obtener el hash final correspondiente al serial de empresas de este tipo.
Espero este tutorial sea de valia.