Continuamos con la segunda entrega de Cruehead. En este caso nos encontramos con un único campo de contraseña para introducir.
El algoritmo
Abrimos con Olly y vemos dos saltos. El primer Call realiza una serie de operaciones con el serial introducido y el segundo comprueba si el serial es correcto.
A continuación llegamos aquí:
00401365 /$ C605 18214000 00 MOV BYTE PTR DS:[402118],0
0040136C |. 8B7424 04 MOV ESI,DWORD PTR SS:[ESP+4]
00401370 |. 56 PUSH ESI
00401371 |> 8A06 /MOV AL,BYTE PTR DS:[ESI] ; <---
00401373 |. 84C0 |TEST AL,AL
00401375 |. 74 19 |JE SHORT CRACKME2.00401390
00401377 |. FE05 18214000 |INC BYTE PTR DS:[402118]
0040137D |. 3C 41 |CMP AL,41 ; 41 = A
0040137F |. 72 04 |JB SHORT CRACKME2.00401385 ; ya es mayúscula
00401381 |. 3C 5A |CMP AL,5A ; 5A = Z
00401383 |. 73 03 |JNB SHORT CRACKME2.00401388 ; Convertir a mayúscula
00401385 |> 46 |INC ESI
00401386 |.^ EB E9 |JMP SHORT CRACKME2.00401371 ; Bucle -->
00401388 |> E8 25000000 |CALL CRACKME2.004013B2
0040138D |. 46 |INC ESI
0040138E |.^ EB E1 \JMP SHORT CRACKME2.00401371
00401390 |> 5E POP ESI
00401391 |. E8 03000000 CALL CRACKME2.00401399 ;Convertido a mayúsculas continuamos
00401396 |. EB 00 JMP SHORT CRACKME2.00401398
00401398 \> C3 RETN
Si nuestro serial contiene solo letras, las convierte a mayúsculas y seguimos aquí. En resumen hace XOR byte a byte entre nuestro serial y la frase «Messing_in_bytes»
00401399 /$ 33DB XOR EBX,EBX
0040139B |. 33FF XOR EDI,EDI
0040139D |> 8A8F A3214000 /MOV CL,BYTE PTR DS:[EDI+4021A3] ; Carga el primer byte de 4021A3
004013A3 |. 8A1E |MOV BL,BYTE PTR DS:[ESI] ;
004013A5 |. 84DB |TEST BL,BL
004013A7 |. 74 08 |JE SHORT CRACKME2.004013B1
004013A9 |. 32D9 |XOR BL,CL ; byteSerial XOR Byte"Messing_in..."
004013AB |. 881E |MOV BYTE PTR DS:[ESI],BL
004013AD |. 46 |INC ESI ;Siguiente byte de "Messing_in_bytes"
004013AE |. 47 |INC EDI ;Siguiente byte del serial
004013AF |.^ EB EC \JMP SHORT CRACKME2.0040139D
004013B1 \> C3 RETN ;XOR finalizado volvemos
Estado del DUMP (memoria) antes del XOR y con nuestro serial (12345678) cargado.
Si buscamos el comando REPE encontramos que si el flag Z = 1 el bucle se corta y que trabaja con bytes. El problema es que en Olly la instrucción REPE nosotros la vemos con un solo paso y nos puede pasar desapercibida.
En resumen, está comprobando los bytes de las direcciones 402150 (1F 2C 37 36 3B 3D 28 19 3D 26 1A 31 2D 3B 37 3E) con nuestro serial XOReado, 40217E en adelante, por lo que si hacemos XOR entre los bytes de 402150 y la frase «Messing_in_bytes» obtendremos la clave correcta.
M e s s i n g _ i n _ b y t e s
4D 65 73 73 69 6E 67 5F 69 6E 5F 62 79 74 65 73
XOR
1F 2C 37 36 3B 3D 28 19 3D 26 1A 31 2D 3B 37 3E
-----------------------------------------------
52 49 44 45 52 53 4F 46 54 48 45 53 54 4F 52 4D
R I D E R S O F T H E S T O R M
Serial: RIDERSOFTHESTORM
Renombramos entonces la extensión a png y continuamos.
Imagen oculta
Esta parte la afrontaremos con Steganabara, una herramienta muy útil que siempre uso cuando me enfrento a un reto «stego». En esta ocasión utilizaremos el análisis de color. Para ello pulsamos sobre «Analyse > Color table«.
En la tabla de colores tenemos la descomposición de colores RGBA y su frecuencia de aparición. Ordenamos por frecuencia descendiente y hacemos doble clic sobre la fila para abrir la imagen resultante.
A continuación un resumen de las imágenes obtenidas.
Como podéis observar, la imagen oculta es un código QR. Lo escaneamos con nuestra app preferida y obtenemos un texto encriptado.
A partir de aquí el reto pasa a ser de encriptación. Con el tiempo diferenciareis fácilmente el tipo de cifrado con sólo ver el texto. En este caso lo primero que se nos ocurre es comprobar dos cifrados clásicos como son el cifrado César y el Vigenere.
Tras desestimar el cifrado César realizamos un ataque de «fuerza bruta» al cifrado Vigenere mediante análisis estadístico. En la imagen que muestro a continuación se puede ver que la clave está cerca de ser «HPHQTC» pero todavía no se lee correctamente.
Ya que la fuerza bruta de por sí no termina de darnos la respuesta correcta, pasamos a probar algo muy útil, esto es, descifrar por fuerza bruta pero dándole una palabra para comparar. En este caso en concreto vemos que una posible palabra que pudiera estar en el texto encriptado es «PASSWORD», probamos y reto terminado.
Recién rescatados del inframundo que es mi disco duro, os traigo un paquete de seis crackmes facilones para vuestro uso y disfrute. Desgraciadamente ya no está en activo la web de retos de donde los saqué así que os los dejo en descargas.
Los cuatro primero están realizados en Dev-C++ 4.9.9.2 siendo de estilo consola de comandos. Los dos restantes compilados con MingWin32 GCC 3.x carecen de GUI y vamos, que no se han esmerado mucho en darles forma.
Level 1
No cuesta mucho dar con el código interesante mediante las referencias de texto. En Ollydbg clic derecho sobre el código y Search for > All referenced text strings.
La madre del cordero está en la dirección 401310 que es donde se lleva a cabo la función de comparación strcmp.
756296A0 msvcrt.strcmp 8B5424 04 MOV EDX,DWORD PTR SS:[ESP+4]
756296A4 8B4C24 08 MOV ECX,DWORD PTR SS:[ESP+8]
756296A8 F7C2 03000000 TEST EDX,3 ; 0-3 = 4 bucles. Divide la comprobación en 4 bloques
756296AE 75 3C JNZ SHORT msvcrt.756296EC ; salta si hemos terminado los 4 bucles
756296B0 > 8B02 MOV EAX,DWORD PTR DS:[EDX] ; coge 4 caracteres del serial (INICIO BUCLE)
756296B2 3A01 CMP AL,BYTE PTR DS:[ECX] ; compara el 1º/5º/9º/13º dígito en función del bucle
756296B4 75 2E JNZ SHORT msvcrt.756296E4 ; salto a zona mala
756296B6 0AC0 OR AL,AL
756296B8 74 26 JE SHORT msvcrt.756296E0
756296BA 3A61 01 CMP AH,BYTE PTR DS:[ECX+1] ; compara el 2º/6º/10º/14º dígito en función del bucle
756296BD 75 25 JNZ SHORT msvcrt.756296E4 ; salto a zona mala
756296BF 0AE4 OR AH,AH
756296C1 74 1D JE SHORT msvcrt.756296E0
756296C3 C1E8 10 SHR EAX,10
756296C6 3A41 02 CMP AL,BYTE PTR DS:[ECX+2] ; compara el 3º/7º/11º/15º dígito en función del bucle
756296C9 75 19 JNZ SHORT msvcrt.756296E4 ; salto a zona mala
756296CB 0AC0 OR AL,AL
756296CD 74 11 JE SHORT msvcrt.756296E0
756296CF 3A61 03 CMP AH,BYTE PTR DS:[ECX+3] ; compara el 4º/8º/12º/16º dígito en función del bucle
756296D2 75 10 JNZ SHORT msvcrt.756296E4 ; salto a zona mala
756296D4 83C1 04 ADD ECX,4
756296D7 83C2 04 ADD EDX,4
756296DA 0AE4 OR AH,AH
756296DC ^ 75 D2 JNZ SHORT msvcrt.756296B0 ; Si no hemos terminado...
756296DE 8BFF MOV EDI,EDI
756296E0 33C0 XOR EAX,EAX ; EAX = 0 que es lo deseado
756296E2 C3 RETN ; salimos de la función superando la comprobación
756296E3 90 NOP
756296E4 1BC0 SBB EAX,EAX ; Zona mala
756296E6 D1E0 SHL EAX,1
756296E8 83C0 01 ADD EAX,1 ; EAX = 1 implica bad boy
756296EB C3 RETN ; salimos de la función
Si atendemos al volcado vemos el serial bueno Kcgcv8LsmV3nizfJ.
Curiosamente, si introducimos el serial bueno el crackme no lo acepta. Fijándome en la comprobación veo que al introducir un serial de 16 caracteres inserta un carácter nulo (0x00) alterando el serial correcto y falseando la comprobación.
Ahora ya no podemos comprobarlo pero recuerdo que la web consideraba válido el serial Kcgcv8LsmV3nizfJ, por lo que considero lo anteriormente citado un bug o un intento de despiste del autor.
Level 2
Es exactamente igual que el anterior cambiando el serial por 6LPw3vDYja9KrT2V.
Level 3
La comprobación del serial es igual a las dos anteriores pero añade una función intermedia que suma 0xD a cada carácter de nuestro serial
En la comparación vemos que el serial bueno es AvrQQsXjDk25Jrh por lo que si restamos 0xD (13 en decimal) a cada carácter obtendremos el serial bueno.
0060FF10 41 76 72 51 51 73 58 6A 44 6B 32 35 4A 72 68 00 AvrQQsXjDk25Jrh.
41 76 72 51 51 73 58 6A 44 6B 32 35 4A 72 68
- D
34 69 65 44 44 66 4B 5D 37 5E 25 28 3D 65 5B
4 i e D D f K ] 7 ^ % ( = e [
Serial bueno: 4ieDDfK]7^%(=e[
Level 4
La comprobación del serial es igual que la anterior pero sustituyendo la función que sumaba un valor a cada dígito del serial por una que genera un hash con nuestro serial y después lo compara con otro hash almacenado en memoria. Si no nos viene a la mente el tipo de hash que puede ser PEiD ya nos avisaba de que efectivamente el crackme incorpora la función MD5.
La función MD5 hace tiempo que no se considera segura debido a la existencia de numerosos «diccionarios» de hashes que hacen que encontremos la solución en segundos. Yo he utilizado la web MD5 online pero existen muchas más.
La carta de presentación de este crackme es la imagen que veis arriba. Al explorarlo unos minutos enseguida nos damos cuenta de que no realiza ninguna comprobación y que nos está haciendo perder el tiempo. Ahí es cuando empezamos a revisar el ejecutable más a fondo y enseguida encontramos la solución con nuestro amigo el editor hexadecimal.
the answer is AttachedString
Level 6
Misma carta de presentación que el anterior y misma ausencia de comprobación del serial. En esta ocasión echando un vistazo a los recursos encontramos la solución rápidamente.
Hoy tenemos un crackme realizado en Visual C++ 6. Es el típico serial asociado a un nombre.
El algoritmo
Localizamos con Olly la rutina de comprobación del serial y empezamos a analizar. Vemos una serie de Calls que lo único que hacen es comprobar el tamaño de nuestro nombre y serial y si es <5 dígitos nos tira afuera.
Una vez pasada la traba anterior procede con un bucle para el nombre y otro para el serial. Yo he metido deurus y 123456. El bucle del nombre hace xor al los dígitos ascii con un valor incremental a partir de 1. Reconvierte el valor resultante en su caracter correspondiente y lo almacena.
Introducción Objetivo del juego y normas Código inicial Primeras modificaciones Terminando la faena Código ganador Curiosidades Enlaces Introducción Hace tiempo
Hace tiempo que me aficioné a los retos de Hacking y Cracking, y si bien la mayoría de ellos consisten en desencriptar una clave o realizar ingeniería inversa sobre un ejecutable, también los hay sobre programación pura y dura.
En esta ocasión se nos proporciona un código «muestra» parecido a PHP o C++ y tenemos que ingeniarnoslas para mejorarlo y ganar a la máquina.
Objetivo del juego y normas
El objetivo de esta misión es ganar a Tr0n en su propio juego: las carreras de motos. Se te proporcionará un programa (código) funcional para que veas como se controla el vehiculo. Usando tu inteligencia, tendrás que entender su uso y mejorarlo, ya que no es lo suficientemente bueno como para ganar a Tr0n. Tr0n lleva ya bastante tiempo en la parrilla de juegos y es bastante habilidoso 🙂
Cuando venzas a Tr0n un mínimo de 5 veces consecutivas, se te dará por superada esta prueba.
Buena suerte!!!
[ Available functions / Funciones disponibles ]
direction() returns current direction, change to a new one with direction([newdir])
getX(), getY() returns X and Y coordinates
collisionDistance() | collisionDistance([anydir]) returns the distance until collision
Note: parameters [*dir] can be empty or one of this values: UP DOWN LEFT or RIGHT
[ Constants / Constantes ]
UP DOWN LEFT RIGHT MAX_X MAX_Y
[ Rules / Reglas ]
Try to survive driving your bike and … / Intenta sobrevivir conduciendo tu moto y…
Don’t cross any line / No cruces ninguna línea
or crash with the corners! / o choques con las esquinas!
[ Mission / Mision ]
Use well this controller and beat Tr0n 5 consecutive times to score in this game
Usa bien este controlador y vence a Tr0n 5 veces consecutivas para puntuar en este juego
Código inicial
Nada más comenzar vemos que hemos perdido nuestra primera partida con el siguiente código:
Lo primero que tenemos que modificar son las distancias de las coordenadas que estan puestas en «<10» al mínimo, que sería «<2«. También sustituir la aleatoriedad «rand(0,1)==0» por algo más útil y comenzar a usar la función «collisionDistance()«.
Como podéis observar en el código inferior, usamos la función «collisionDistance()» para detectar cuando estamos a punto de chocar «collisionDistance() ==1» y para detectar a que lado nos conviene más girar en función de donde podamos recorrer más distancia «if($c->collisionDistance([LEFT]) >2) $c->direction(LEFT); else $c->direction(RIGHT);«.
El código anterior de por sí no nos resuelve mucho si no afinamos un poco más, comprobando todos las posibles colisiones y tomando la dirección correcta en función de la mayor distancia a recorrer.
El código no es infalible ya que como comprabaréis vosotros mismos, no se puede ganar siempre por el mero hecho de la aleatoriedad y de la suerte. Cuando dispongais de un código decente, ejecutarlo varias veces para estar seguros antes de desecharlo.
Curiosidades
Como se suele decir, la banca siempre gana, y en este caso no iba a ser menos y es que en caso de empate ¡la banca gana!
Por último deciros que podéis utilizar el código ya que la web detecta los códigos ganadores para que no se repitan.
Hoy tenemos un crackme realizado en Visual C++ 6. Es el típico serial asociado a un nombre.
El algoritmo
Localizamos con Olly la rutina de comprobación del serial y empezamos a analizar. Vemos una serie de Calls que lo único que hacen es comprobar el tamaño de nuestro nombre y serial y si es <5 dígitos nos tira afuera.
Una vez pasada la traba anterior procede con un bucle para el nombre y otro para el serial. Yo he metido deurus y 123456. El bucle del nombre hace xor al los dígitos ascii con un valor incremental a partir de 1. Reconvierte el valor resultante en su caracter correspondiente y lo almacena.
Introducción Herramientas utilizadas Desempacado con Ollydbg 2 (Videotutorial) Desempacado con Ollydbg 1 (Videotutorial) Análisis de la rutina del número de
El otro día navegando por la red fuí a dar a un mirror de la gran web «Karpoff Spanish Tutor«. Para los que no la conozcais, debeis saber que fué una referencia para el Cracking en la escena nacional. Contenía manuales, cursos, utilidades y todo lo que te pudieras imaginar y/o necesitar para iniciarte en el mundillo del Cracking. Por aquel entonces yo era un cigoto en esto de la Ingeniería Inversa pero la web de Karpoff sentó mis bases y contribuyó a mi afán por saber y compartir. El lector debería saber que estamos hablando de finales de los 90, por lo que este crackme y sucesivos de la web de Karpoff ahora pueden parecer más fáciles pero hay que tener en cuenta que ahora tenemos mejores herramientas.
El objetivo es sacar un serial valido o hacer un generador de llaves, esta hecho para newbies y no tiene ninguna otra proteccion.
El crackme está hecho en Delphi y no tiene ningún tipo de protección antidebug ni nada por el estilo.
El algoritmo
Abrimos Delphi Decompiler y buscamos en los eventos el botón de registro, en este caso se llama «focusClick» y vemos que su RVA apunta a la dirección «442AEC«, lo apuntamos y abrimos el crackme con Ollydbg.
En Olly pulsamos Ctrl+G e introducimos el offset anterior. Un poco más abajo vemos un Call interesante, entramos en el.
Dentro del Call vemos a simple vista dos funciones muy interesantes como son «GetVolumeInformationA» y «GetUserNameA«.
Traceamos el código y vemos que obtiene el número de serie del disco C y el usuario de windows y finalmente los concatena. Se puede ver a simple vista en el Stack o Pila.
No necesitamos saber nada más, probamos el número de serie cazado y funciona. Os adjunto el keygen hecho en C++.
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en activo y por lo tanto no se debería resolver utilizando esta información.
Realistic Challenge 2: You have heard about people being targeted by a new religion called Egitology. Another hacker infiltrated the group and discovered that the list of people they target is stored on the site but he doesn’t know where.
Break into the site, find the file and remove it. Also leave no evidence that you was ever there so they wont realise until its too late!
El enunciado del reto nos dice que tenemos que localizar la lista de objetivos y eliminarla sin dejar evidencias.
Analizando la seguridad de la víctima
Echamos un vistazo y vemos que tienen un Login para usuarios registrados, este será nuestro primer testeo.
Lo primero que se no viene a la cabeza con un formulario de este tipo es Inyección SQL, probamos varios métodos y tenemos suerte.
User: admin
Pass: ‘ or 1=1–‘;
Vemos que hemos entrado como admin y enseguida nos llama la atención «Back up Database«. Pulsamos a ver que pasa.
Obtenemos el hash de las claves de los usuarios Admin y SuperAdmin. Por suerte son hashes MD5. Obtenemos la clave de SuperAdmin y nos loguemos.
Solo nos queda borrar la lista de objetivos y nuestras huellas. Para ello borramos los siguientes archivos y reto superado.
Lista de objetivos: root/misc/targets
Logs: root/images/logs
En el primer vistazo con el editor hexadecimal ya vemos la solución al reto:
Pho
Al igual que el caso anterior con el editor hexadecimal tenemos más que suficiente para resolver el reto.
Minions
En el análisis inicial no destaca prácticamente nada excepto la palabra myadmin que podemos ver con un editor hexadecimal.
La palabra myadmin es una buena candidata a ser contraseña ante una decodificación. Probamos con lo estándar y conseguimos resultados con steghide. La decodificación nos devuelve la cadena AEMAVABGAGwAZQBhAHIAbgB7AHQAaABpAHMAXwBpAHMAXwBmAHU***** que rápidamente catalogamos como base64 para resolver el reto.
Unopenable
Se nos entrega una imagen GIF aparentemente corrupta. Estudiando un poco la cabecera de los archivos GIF llegamos rápidamente a la conclusión de que faltan los cuatro primeros bytes del archivo.
Una vez insertados los bytes podemos ver una animación que contiene una cadena de texto fácilmente reconocible como base64. La decodificamos y ya tenemos la solución.
Oreo
Mirando con un editor hexadecimal no encontramos nada excepto la frase This is not the flag you are looking for para intentar disuadirnos.
Cargamos la imagen en Aperi’Solvey enseguida nos llama la atención la sección Binwalk y un suculento Rar.
Descargamos el archivo Rar y al descomprimir nos encontramos con un archivo de texto con la misma frase desalentadora del inicio y una imagen JPG, esta vez con dos oreos. Inspeccionando la imagen damos con la solución.
Este BTM va otra vez sobre IPs. Si amigos del séptimo arte, viendo un capítulo de mi querida «The Sinner» me han vuelto a chirriar los dientes. La verdad que viendo el capítulo no te da tiempo a apreciarlo, únicamente me quedo con que aparece una URL y lo reviso a posteriori (esto lo digo para los curiosos que me preguntáis).
En esta ocasión me tiene un poco inquieto ya que es una serie que cuida enormemente los detalles y el fallo que os voy a mostrar parece intencionado. La imagen en cuestión es esta:
Fotograma del capítulo 2×06
Aparece un buscador con una URL más o menos creíble si no fuera porque la IP que aparece es IMPOSIBLE. La máxima IPv4 es 255.255.255.255, es decir, no han dado ni una, y eso es lo que me tiene mosca. Si hubieran utilizado 82.47.25.29 hubiera quedado bien y estaríamos hablando de un problema de geolocalización de IPs, ya que el rango 82.47.xx.xx le pertenece a UK y deberíamos discernir si el servidor está en EEUU o no…
En definitiva, puede ser un fallo a propósito, un guiño o tener un significado. No se que deciros, bueno si, ¡lo investigaré!
Rebuscando entre todo el caos que puede llegar a ser mi disco duro, he encontrado una serie de programas que utilizaba antiguamente cuando empezó a interesarme el Cracking. Ya sabéis que no soy partidario de crackear programas comerciales pero hoy voy a hacer una excepción ya que la versión del programa es muy vieja (1997) e incluso podría considerarse abandonware.
Este ejercicio es ideal para los que están empezando ya que es fácil localizar donde está el algoritmo y éste es sumamente sencillo.
Address Hex dump Command Comments
00402213 E8 78170000 CALL HEdit.00403990
........
004039C0 8BC1 MOV EAX,ECX
004039C2 99 CDQ
004039C3 33C2 XOR EAX,EDX
004039C5 2BC2 SUB EAX,EDX
004039C7 83E0 03 AND EAX,00000003
004039CA 33C2 XOR EAX,EDX
004039CC 2BC2 SUB EAX,EDX
004039CE 8A540C 04 MOV DL,BYTE PTR SS:[ECX+ESP+4] ;Coge el dígito i*3
004039D2 8A5C04 04 MOV BL,BYTE PTR SS:[EAX+ESP+4] ;Coge el dígito i
004039D6 8D4404 04 LEA EAX,[EAX+ESP+4] ;Guarda en memoria 12EE90
004039DA 32DA XOR BL,DL
004039DC 41 INC ECX ; i +=1
004039DD 81F9 00010000 CMP ECX,100 ;El bucle se repite 256 veces (0x100)
004039E3 8818 MOV BYTE PTR DS:[EAX],BL
004039E5 ^ 7C D9 JL SHORT HEdit.004039C0
004039E7 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
004039EB 85C0 TEST EAX,EAX ;Comprueba que el serial no sea 0
004039ED 7D 02 JGE SHORT HEdit.004039F1 ;Si es 0 se acabó
004039EF F7D8 NEG EAX
004039F1 3B8424 0C010000 CMP EAX,DWORD PTR SS:[ESP+10C] ;Comprobación de serial válido
004039F8 75 13 JNE SHORT HEdit.00403A0D ;Si no es igual bad boy
004039FA 85C0 TEST EAX,EAX ;Comprueba que el serial no sea 0
004039FC 74 0F JE SHORT HEdit.00403A0D ;Si es 0 se acabó
004039FE B8 01000000 MOV EAX,1
00403A03 5B POP EBX
00403A04 81C4 00010000 ADD ESP,100
00403A0A C2 0800 RETN 8
En resumen hace esto:
- Nombre introducido: deurus
- Convierte el nombre a mayúsculas
D E U R U S
44 45 55 52 55 53 (En Hexadecimal)
1) 55 xor 44 = 11
2) 53 xor 45 = 16
3) 00 xor 55 = 55
4) 00 xor 52 = 52
--------------- solo vale hasta aquí EAX(32 bits)
5) 00 xor 55 = 55
6) 00 xor 53 = 53
7) 00 xor 00 = 00
8) ...
HEX DEC
Serial = 52551611 = 1381307921
Como veis, realiza un bucle 256 veces pero como al final utiliza el registro EAX para hacer la comparación, solamente nos sirven las cuatro primeras operaciones. De hecho, no comprueba ni la longitud del nombre por lo que si introducimos un solo dígito como nombre, el serial será el valor ascii de ese dígito en decimal. La única comprobación que realiza es que el serial no sea 0.
var nombre = "deurus";
nombre = nombre.toUpperCase();
var serial = "";
serial = serial + nombre.charCodeAt(3).toString(16) + nombre.charCodeAt(2).toString(16);
serial = serial + (nombre.charCodeAt(5) ^ nombre.charCodeAt(1)).toString(16);
serial = serial + (nombre.charCodeAt(2) ^ nombre.charCodeAt(0)).toString(16);
serial = "Nº Serie: " + parseInt(serial,16);
document.write(serial);