Cracking MRV MegaVision

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.

Cracking PowerPath EMC

Cuando hablamos de cracking de aplicaciones, siempre se piensa que solo aquellas que se encuentran en la red, para disposición del publico general son las que deben poseer diferentes y variados métodos de ofuscamiento para evitar que estas sean crackeadas y puedan utilizarse sin realizar el pago correspondiente de derechos, sin embargo no es así. En esta ocasión mostrare como crackear el PowerPath de EMC. Quien conozca un poco de storage sabrá de lo que hablamos, para los que no, PowerPath es una importante herramienta que sirve para realizar el balanceo de cargas entre diferentes paths que comunican los equipos de emc (Clariion, Symetrix, Celerra etc.), su operación licenciada es de vital importancia para mantener la alta disponibilidad de los LUN’s o discos asignados.

La version que utilizaremos de PowerPath es la siguiente: EMC powermt for PowerPath iSCSI (c) Version :1.1.0 (build 89):

Para realizar el debugging de usaremos el clásico OllyDbg, para revisar si el programa se encuentra empaquetado utilizaremos el también muy común PEiD. Aunque bueno este paso solo se realizó por mero protocolo, pues cuando un programa se encuentra empaquetado las instrucciones son ilegibles. El programa PowerPath posee varias partes las cuales funcionan bajo diferentes escenarios, el licenciamiento nos lo facilitan de manera significativa, pues la gente de emc tuvo la gran idea de poner una aplicación independiente únicamente para este fin. La aplicación se encuentra en la siguiente ruta:

C:\Archivos de programa\EMC\PowerPathiSCSI\EmcLicTool.exe

Por lo tanto esta es la aplicación que verificaremos, no se encuentre empaquetada u ofuscada con el fin de entorpecer nuestro trabajo.

La salida del PEiD nos muestra que la aplicación no se encuentra empaquetada de ninguna manera, incluso nos muestra que fue realizado en C++, con esto estamos listos para cargar el programa en OllyDBG. Pero antes realizaremos algunos ajustes al OllyDbg para evitar problemas durante el debugging.


Para que el OllyDbg no pare en cada intento de entrada a un modulo nuevo, vamos al menú principal y en «Options_Debuggin Options» seleccionamos «Debug» y marcamos «Ignore memory access violations in Kernel 32» y desmarcamos el resto. Posteriormente nos aseguramos de que no se detecta nuestro debugger con el IsDebuggerPresent, para lo cual se utilizará el Plugin de OllyDbg «IsDebuggerPresent» de Byte Patcher.

De esta manera no encontramos listos para realizar el debugging del programa. Luego de cargar y correr el programa obtenemos la siguiente salida:

La primera salida que nos marca el inicio de la aplicación:

0040B9A6 >/$ 55             PUSH EBP
0040B9A7  |. 8BEC           MOV EBP,ESP
0040B9A9  |. 6A FF          PUSH -1
0040B9AB  |. 68 689C4200    PUSH EmcLicTo.00429C68
0040B9B0  |. 68 C4F54000    PUSH EmcLicTo.0040F5C4                   ;  SE handler installation
0040B9B5  |. 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
0040B9BB  |. 50             PUSH EAX
0040B9BC  |. 64:8925 000000>MOV DWORD PTR FS:[0],ESP
0040B9C3  |. 83EC 58        SUB ESP,58
0040B9C6  |. 53             PUSH EBX
0040B9C7  |. 56             PUSH ESI
0040B9C8  |. 57             PUSH EDI
0040B9C9  |. 8965 E8        MOV DWORD PTR SS:[EBP-18],ESP
0040B9CC  |. FF15 1C724200  CALL DWORD PTR DS:[<&KERNEL32.GetVersion>;  kernel32.GetVersion

El PUSH EBP nos indica de donde inicia el programa, ahora usaremos el método mas común para encontrar la sentencia «IF» o CMP de validación, cuando introducimos un código erróneo, introducimos cualquier texto y verificamos el error que arroje:

Posteriormente buscamos la cadena «Key» para ubicar en el desensamblador la linea que nos llevara a este fragmento de código:

Text strings referenced in EmcLicTo:.text, item 5

Address=00401C31

Disassembly=PUSH EmcLicTo.00431344

Text string=ASCII «%s is an invalid license key.»

La seguimos en el desensamblador y observaremos lo siguiente:

00401BED   . 53             PUSH EBX
00401BEE   . 56             PUSH ESI
00401BEF   . 57             PUSH EDI
00401BF0   . 8BF1           MOV ESI,ECX
00401BF2   . 8945 F0        MOV DWORD PTR SS:[EBP-10],EAX
00401BF5   . 33DB           XOR EBX,EBX
00401BF7   . 6A 01          PUSH 1
00401BF9   . 895D FC        MOV DWORD PTR SS:[EBP-4],EBX
00401BFC   . E8 D9BD0100    CALL EmcLicTo.0041D9DA
00401C01   . 8B4E 5C        MOV ECX,DWORD PTR DS:[ESI+5C]
00401C04   . E8 C9F9FFFF    CALL EmcLicTo.004015D2
00401C09   . 8DBE 5C010000  LEA EDI,DWORD PTR DS:[ESI+15C]
00401C0F   . 8945 EC        MOV DWORD PTR SS:[EBP-14],EAX
00401C12   . 8B07           MOV EAX,DWORD PTR DS:[EDI]
00401C14   . 3958 F8        CMP DWORD PTR DS:[EAX-8],EBX
00401C17   . 0F84 B9000000  JE EmcLicTo.00401CD6
00401C1D   . 8B4E 5C        MOV ECX,DWORD PTR DS:[ESI+5C]
00401C20   . 50             PUSH EAX

00401C21   . E8 B8F4FFFF    CALL EmcLicTo.004010DE
00401C26   . 3BC3           CMP EAX,EBX
00401C28   . 74 57          JE SHORT EmcLicTo.00401C81
00401C2A   . 83F8 50        CMP EAX,50
00401C2D     74 09          JE SHORT EmcLicTo.00401C38
00401C2F   . FF37           PUSH DWORD PTR DS:[EDI]
00401C31   . 68 44134300    PUSH EmcLicTo.00431344                   ;  ASCII "%s is an invalid license key."
00401C36   . EB 26          JMP SHORT EmcLicTo.00401C5E
00401C38   > FF75 EC        PUSH DWORD PTR SS:[EBP-14]
00401C3B   . 8BCF           MOV ECX,EDI
00401C3D   . FF75 EC        PUSH DWORD PTR SS:[EBP-14]
00401C40   . E8 EB920100    CALL EmcLicTo.0041AF30
00401C45   . 8B4E 5C        MOV ECX,DWORD PTR DS:[ESI+5C]
00401C48   . 50             PUSH EAX
00401C49   . E8 F8F8FFFF    CALL EmcLicTo.00401546
00401C4E   . 6A FF          PUSH -1
00401C50   . 8BCF           MOV ECX,EDI
00401C52   . E8 B1920100    CALL EmcLicTo.0041AF08
00401C57   . FF37           PUSH DWORD PTR DS:[EDI]
00401C59   . 68 24134300    PUSH EmcLicTo.00431324                   ;  ASCII "%s has already been entered."

Para poder seguir la traza del programa pondremos un breakpoint en 00401BED . 53 PUSH EBX (F2) y seguiremos la traza paso a paso con F7.

Una vez que se realiza la corrida paso por paso nos podemos dar cuenta que la llamada CALL EmcLicTo.0041D9DA ubicada en la dirección 00401BFC efectivamente es la que realiza la validación inicial de cada uno de los caracteres que se van introduciendo, si analizamos la corrida del siguiente fragmento de código encontraremos lo siguiente: (siguiendo la llamada)

0041D9DA   $ B8 78654200    MOV EAX,EmcLicTo.00426578
0041D9DF   . E8 64DCFEFF    CALL EmcLicTo.0040B648
0041D9E4   . 83EC 24        SUB ESP,24
0041D9E7   . 53             PUSH EBX
0041D9E8   . 56             PUSH ESI
0041D9E9   . 57             PUSH EDI
0041D9EA   . 8BF1           MOV ESI,ECX
0041D9EC   . 8965 F0        MOV DWORD PTR SS:[EBP-10],ESP
0041D9EF   . FF75 08        PUSH DWORD PTR SS:[EBP+8]
0041D9F2   . 8D4D D4        LEA ECX,DWORD PTR SS:[EBP-2C]
0041D9F5   . 56             PUSH ESI
0041D9F6   . E8 81000000    CALL EmcLicTo.0041DA7C
0041D9FB   . E8 104F0000    CALL EmcLicTo.00422910
0041DA00   . 8BF8           MOV EDI,EAX
0041DA02   . 8365 08 00     AND DWORD PTR SS:[EBP+8],0
0041DA06   . 8365 FC 00     AND DWORD PTR SS:[EBP-4],0
0041DA0A   . 897D EC        MOV DWORD PTR SS:[EBP-14],EDI
0041DA0D   . 8B8F B8000000  MOV ECX,DWORD PTR DS:[EDI+B8]
0041DA13   . 8D87 B8000000  LEA EAX,DWORD PTR DS:[EDI+B8]
0041DA19   . 894D E8        MOV DWORD PTR SS:[EBP-18],ECX
0041DA1C   . 8B4E 1C        MOV ECX,DWORD PTR DS:[ESI+1C]
0041DA1F   . 8908           MOV DWORD PTR DS:[EAX],ECX
0041DA21   . 8B06           MOV EAX,DWORD PTR DS:[ESI]
0041DA23   . 8D4D D4        LEA ECX,DWORD PTR SS:[EBP-2C]
0041DA26   . 51             PUSH ECX

0041DA27   . 8BCE           MOV ECX,ESI
0041DA29   . FF90 84000000  CALL DWORD PTR DS:[EAX+84]
0041DA2F   . C745 08 010000>MOV DWORD PTR SS:[EBP+8],1
0041DA36   . EB 27          JMP SHORT EmcLicTo.0041DA5F
0041DA38   . B8 5CDA4100    MOV EAX,EmcLicTo.0041DA5C
0041DA3D   . C3             RETN

Lo que hace es obtener el tope de ESP y concatena la entrada del input text en la parte baja y alta del acumulador:

0041DA02   . 8365 08 00     AND DWORD PTR SS:[EBP+8],0
0041DA06   . 8365 FC 00     AND DWORD PTR SS:[EBP-4],0
0041DA0A   . 897D EC        MOV DWORD PTR SS:[EBP-14],EDI
0041DA0D   . 8B8F B8000000  MOV ECX,DWORD PTR DS:[EDI+B8]
0041DA13   . 8D87 B8000000  LEA EAX,DWORD PTR DS:[EDI+B8]

Posteriormente realiza una llamada mas que es precisamente la que necesitaríamos debuggear si quisiéramos hacer el keygen para PowerPath ( CALL EmcLicTo.0041DA7C y CALL EmcLicTo.00422910 ), prepara el resto de los registros con la información necesaria para regresar a su salto de origen guardando las direcciones de salto y regreso en ECX… sin embargo esa no es la prioridad, por lo tanto pasaremos a un breakpoint mas cercano al CMP definitivo. El nuevo Breakpoint lo fijaremos en: PUSH DWORD PTR DS:[EDI] ubicado en la dirección 00401C2F, justo una instrucción antes de emitir el mensaje de error, ahora bien, una instrucción arriba se encuentra el salto de validación definitivo entre lo que se devuelve de la llamada 00422910 acumulado en el ECX, si ECX es igual que el valor sostenido en el tope de nuestro stack (dump) entonces realiza un salto a la dirección de memoria: 00401C38 que es la que almacena el còdigo de escritura en los registros de PowerPath, informándole que la licencia fue introducida de manera correcta, de lo contrario no brinca y arroja el mensaje de Licencia Errónea (is an invalid licence key) y realiza un salto corto a la dirección JMP SHORT EmcLicTo.00401C5E indicándole a PowerPath no reescribir registros y dejar el programa en espera de nuevas entradas:

00401C26   . 3BC3           CMP EAX,EBX
00401C28   . 74 57          JE SHORT EmcLicTo.00401C81
00401C2A   . 83F8 50        CMP EAX,50
00401C2D     74 09          JE SHORT EmcLicTo.00401C38
00401C2F   . FF37           PUSH DWORD PTR DS:[EDI]
00401C31   . 68 44134300    PUSH EmcLicTo.00431344                   ;  ASCII "%s is an invalid license key."
00401C36   . EB 26          JMP SHORT EmcLicTo.00401C5E
00401C38   > FF75 EC        PUSH DWORD PTR SS:[EBP-14]
00401C3B   . 8BCF           MOV ECX,EDI
00401C3D   . FF75 EC        PUSH DWORD PTR SS:[EBP-14]
00401C40   . E8 EB920100    CALL EmcLicTo.0041AF30
00401C45   . 8B4E 5C        MOV ECX,DWORD PTR DS:[ESI+5C]
00401C48   . 50             PUSH EAX
00401C49   . E8 F8F8FFFF    CALL EmcLicTo.00401546
00401C4E   . 6A FF          PUSH -1
00401C50   . 8BCF           MOV ECX,EDI
00401C52   . E8 B1920100    CALL EmcLicTo.0041AF08
00401C57   . FF37           PUSH DWORD PTR DS:[EDI]
00401C59   . 68 24134300    PUSH EmcLicTo.00431324                   ;  ASCII "%s has already been entered."
00401C5E   > 8D45 F0        LEA EAX,DWORD PTR SS:[EBP-10]
00401C61   . 50             PUSH EAX
00401C62   . E8 F97E0100    CALL EmcLicTo.00419B60

00401C67   . 83C4 0C        ADD ESP,0C

PowerPath escribe en el registro del S.O. si la licencia es o no correcta entre otras cuestiones, eso lo podemos verificar por sus scripts poco seguros y a disposición de cualquier persona que se instalan con el software de manera nativa:

(cabecera de powermt.vbs)

REM MPIO EMC DSM Driver Powermt CLI

On Error Resume Next

Function GetDateTime()

MyTime = Now

GetDateTime = Mytime

End Function ‘GetDateTime()

Function Test()

On Error Resume Next

set configEnum = GetObject(«winmgmts:root\wmi:EMCMPIODSM_CONFIGINFO»).Instances_

If Err <> 0 Then

WScript.Echo «Device Not found»

WScript.Quit

End If

End Function

En este script queda evidenciado la utilización de DLL’s que los desarrolladores anexan a la API de Windows y de manera análoga acceden a registros de Windows que validan licencias. Por lo tanto solo basta obligar al programa de licenciamiento a que brinque esta validación para obligarlo a que escriba en el registro que nuestra licencia completamente fake es correcta. Para lograr esto cambiaremos la instrucción JE SHORT EmcLicTo.00401C38 ubicada en la dirección 00401C2D por JNZ SHORT 00401C38, la instrucción JNZ es lo contrario de JE, es decir evaluará si es diferente de 0 o de lo almacenado en el acumulador; ensamblamos y observamos que ocurre:

Ahora nos muestra la pantalla diciéndonos que la licencia fue introducida de manera correcta, y debido a que PowerPath posee poca granularidad en cuanto a la seguridad a nivel de código se refiere, nuestro sistema se encuentra licenciado al menos hasta la próxima que se reinicie el equipo:

Esta versión de PowerPath desarrollada por EMC es mas fácil de crackear que mucho del software que se encuentra en la red, el cual posee métodos de ofuscamiento para dificultar el cracking de la aplicación en cuestión y en general sirve para incrementar la experiencia en el cracking de aplicaciones.