Quantcast
Channel: El blog de García Larragan y Cía
Viewing all 639 articles
Browse latest View live

Criptografía (CVII): Reto 22

$
0
0
Otro reto de dificultad media sobre criptografía. En esta ocasión se trata de descifrar un criptograma obtenido mediante un criptosistema consistente en la sustitución de pares de letras o digramas empleando una tabla o matriz generada por una clave.

Como siempre, se admiten soluciones en forma de comentarios a esta entrada. Pasado un tiempo iré proporcionando pistas para su resolución, un máximo de tres, y posteriormente actualizaré este post con la solución.

Reto 22: "LO RD PL AY FA IR".

Evidentemente, ya sabes a qué criptosistema me refiero (ver este post en el que lo explico), pero lo importante en este reto es descifrar el criptograma asociado al mismo, cosa que entiendo no es fácil sin conocer la clave. Para facilitar esta tarea te proporciono, también como recurso asociado al reto, texto en claro conocido correspondiente al criptograma. ¿Puedes descifrarlo?.

Dificultad:
Tipo:           Criptografía.

RecursosCriptogramaQE QT DW XN QT PT CW TP AW CH NG KL WB LY TP AT QD YT LZ BE WT LY TN NB WA ZE NS QW MC SN BN BK FS WY BS QK RE NF QT QH BK KM WI NS NB WP PH HC FS GW QM BA IH KQ SN BN JQ AW SF TP TN NB CW LZ KQ QW WT SQ TA PQ PW WI BA MN WG QT BD NC WA GN PT MP NG BW GA NG SR TQ NV

Texto en claro conocido (se corresponde con el inicio del criptograma)PA RA SU PE RA RE ST ER ET OT EN DR AS QU ER EA LI ZA RU NA TA QU EC ON TE XT OC LA RO CO NO CI DO

******** 18/07/2018
Pista 1:     La persona que aparece en el retrato que ilustra este post no es Lyon Playfair. ¿Quién es?. No me acuerdo si esto puede ser relevante, incluso un atajo, para resolver este reto, pero centrémonos en el enunciado, se trata de realizar un ataque con texto claro conocido :).

******** __/__/____
Pista 2:     Por publicar.

******** __/__/____
Pista 3:     Por publicar.

******** __/__/____
Solución (por publicar).

******** PRÓXIMO RETO
Reto 23:   Por publicar.

Criptografía (CVIII): Solución Reto 21

$
0
0
El  enunciado del vigésimoprimer reto que puse en este post era el siguiente:

"Al igual que en el famoso Western, en el Departamento de Sistemas de mi empresa cometieron dos errores a la hora de generar las claves RSA de los empleados y enviarles mensajes cifrados, posibilitando que un criptoanalista en ciertas circunstancias pueda descifrar algunos de estos últimos sin necesidad de conocer la clave privada de los usuarios que los reciben. ¿Puedes descifrar sin factorizar el módulo los dos criptogramas interceptados a sendos usuarios?".

Este reto es de criptografía y su solución es:

1.- Ya decía en las pistas que puse para facilitar la resolución de este reto que podemos considerar que el "primer error" que cometió el Departamento de Sistemas de mi empresa fue utilizar el mismo módulo para diversos usuarios, aunque con diferente exponente público para cada uno de ellos, y que el "segundo error" se produciría si, además, se envían a varios de ellos criptogramas correspondientes al mismo texto en claro, ya que ello facilitaría el ataque mediante módulo común. Ver este post donde lo explico.

2.- Pues bien, vamos a ver si esto es así y para ello creo un script en Python (no soy ningún experto y seguro que se puede hacer mucho mejor):

#   Solucion Reto 21

def inv(num1, num2):
global r0, s0, t0

r0 = num1
r1 = num2
s0 = 1
t0 = 0
s1 = 0
t1 = 1

while r1 != 0:
q = r0//r1
r = r0%r1
s = s0 - q * s1
t = t0 - q * t1
r0 = r1
r1 = r
s0 = s1
s1 = s
t0 = t1
t1 = t

return  r0, s0, t0

e1 = int(input('Introduzca el exponente de la clave publica del usuario 1 (e1) ... : '))
e2 = int(input('Introduzca el exponente de la clave publica del usuario 2 (e2) ... : '))
n = int(input('Introduzca el modulo (n) comun a ambos usuarios .................. : '))
c1 = int(input('Introduzca el criptograma enviado al usuario 1 (c1) .............. : '))
c2 = int(input('Introduzca el criptograma enviado al usuario 2 (c2) .............. : '))

inv(e1, e2)

print ""
if r0 != 1:
print "No existe inverso"
m =""
elif s0 < 0:
s = t0
t = s0
inv(c1, n)
          m = ((c2 ** s)%n)*(s0 ** (-t))%n
else:
s = s0
t = t0
inv(c2, n)
m = ((c1 ** s)%n)*(s0 ** (-t))%n

print "Mensaje en claro enviado a ambos usuarios ........................ :", m

3.- Ejecuto el script anterior:
Como se observa el mensaje en claro en decimal enviado a ambos usuarios es 388768887412929781326699.

4.- Convierto el mensaje anterior a hexadecimal, lo que me da: 5253342034373734636B.

5.- Obtengo la representación ASCII y ya puedo ver la clave del reto: "RS4 4774ck":

******** PRÓXIMO RETO
Reto 22: "LO RD PL AY FA IR".

Criptografía (CIX): Solución Reto CTFLearn "Skynet Is (Almost) Taking Over"

$
0
0
En este post la solución a otro de los retos de criptografía de la plataforma CTFLearn.

Este reto tiene el título "Skynet Is (Almost) Taking Over" y mi valoración sobre su dificultad es: .

Su enunciado dice lo siguiente:


Skynet is using a very small list of primes for RSA style encryption purposes. In fact their list is only the size of the smallest odd prime. One of the robots sent a message to three other robots. These are futuristic robots with the ability to use quantum computing and so they don't mind prime factoring huge numbers.You can't do that though. Find out what message the robot sent to his friends. Flag is in flag{} format.

Y nos dan los siguientes datos:


e: 65537

c1: 5024836662627906750454817701922271080214720765897113783786369197810770999608528443597447448508876214100063962982376037712548944474807897847869334582773452689962992522987755069402952836848501053684233233850594080254869
n1: 10603199174122839808738169357706062732533966731323858892743816728206914395320609331466257631096646511986506501272036007668358071304364156150345138983648630874220488837685118753574424686204595981514561343227316297317899

c2: 130884437483098301339042672379318680582507704056215246672305503902799253294397268030727540524911640778691710963573363763216872030631281953772411963153320471648783848323158455504315739311667392161460121273259241311534
n2: 5613358668671613665566510382994441407219432062998832523305840186970780370368271618683122274081615792349154210168307159475914213081021759597948038689876676892007399580995868266543309872185843728429426430822156211839073

c3: 40136988332296795741662524458025734893351353026652568277369126873536130787573840288544348201399567767278683800132245661707440297299339161485942455489387697524794283615358478900857853907316854396647838513117062760230880

n3: 43197226819995414250880489055413585390503681019180594772781599842207471693041753129885439403306011423063922105541557658194092177558145184151460920732675652134876335722840331008185551706229533179802997366680787866083523

Solución: Evidentemente, el enunciado del reto nos dice que los módulos que nos dan comparten factores no triviales entre sí ("...is using a very small list of primes for RSA style encryption purposes"). Por tanto, descifrar los criptogramas será un asunto trivial, ya que si un atacante puede encontrar dos módulos RSA distintos, n1 y n2, que comparten un factor primo pero tienen diferentes segundos factores primos, puede factorizar fácilmente y de forma muy eficiente ambos módulos calculando su MCD para obtener el factor primo compartido y dividiendo cada uno de ellos entre este último para encontrar el otro factor primo de cada uno de ellos, con lo que el atacante puede entonces calcular ambas claves privadas.

Veámoslo. Para ello utilizo el software "Fortaleza de Cifrados" (Herramientas > Cálculo del MCD):
mcd(n1, n2) = 1173821128899717744763168991586024137475923012574062580049287532012184965219319828285650431646942194944437493
mcd(n1, n3)
= 9033062119150775356115605417902072538098631081058159551678022048966520848600866260935959311606867286026034943
mcd(n2,n3) = 4782124405899304514745349491894350894228449009067812460621545024973542842784947583120716593095450482771264061

Con lo que queda claro que lo que decía el enunciado es cierto ("In fact their list is only the size of the smallest odd prime"), para calcular las claves se han utilizado sólo esos 3 números primos diferentes.

Obtengo ahora los tres criptogramas. Para ello utilizo el software "ExpoCrip" (Criptosistemas > RSA):

p1 = 1173821128899717744763168991586024137475923012574062580049287532012184965219319828285650431646942194944437493

q1 = n1 / p1 = 9033062119150775356115605417902072538098631081058159551678022048966520848600866260935959311606867286026034943
d1 = 4058813459285894720262057382498008693884059743178992752830677789043240634075531780497947803398409616647168596996375898813393632803863008293266814189602127894014263466865909580208566775955662894025240267470669009026537

c1 = 5024836662627906750454817701922271080214720765897113783786369197810770999608528443597447448508876214100063962982376037712548944474807897847869334582773452689962992522987755069402952836848501053684233233850594080254869
m1149691910197864237420173554223426538596418158029693

En hexadecimal:
666C61677B77696C6C5F68655F62655F6261636B7D

ASCII:
flag{will_he_be_back}

Con lo que ya sabemos la flag para pasar este reto, pero descifro los dos últimos criptogramas.

p2 = 4782124405899304514745349491894350894228449009067812460621545024973542842784947583120716593095450482771264061

q2 = n2 / p2 = 1173821128899717744763168991586024137475923012574062580049287532012184965219319828285650431646942194944437493
d2 = 761957958351811574665908973055198601684911845712156707315390608408869221581643107249417210892016022838062099282438454813702653752551827888703014635138157271543974622958219283063532121046162838351879479076989192389633

c2 = 130884437483098301339042672379318680582507704056215246672305503902799253294397268030727540524911640778691710963573363763216872030631281953772411963153320471648783848323158455504315739311667392161460121273259241311534
m2 = 149691910197864237420173554223426538596418158029693

En hexadecimal:
666C61677B77696C6C5F68655F62655F6261636B7D

ASCII:
flag{will_he_be_back}

Y finalmente el último criptograma.

p3 = 9033062119150775356115605417902072538098631081058159551678022048966520848600866260935959311606867286026034943

q3 = n3 / p3 = 4782124405899304514745349491894350894228449009067812460621545024973542842784947583120716593095450482771264061
d3 = 34778852757328807131051299342491994341058130963838199538975252386805579197756200373810293576383442829820831731234905058826980321999439169115820880963749482420614868325205813650296015377675722669359309160247107758432873

c3 = 40136988332296795741662524458025734893351353026652568277369126873536130787573840288544348201399567767278683800132245661707440297299339161485942455489387697524794283615358478900857853907316854396647838513117062760230880
m3 = 149691910197864237420173554223426538596418158029693

En hexadecimal:
666C61677B77696C6C5F68655F62655F6261636B7D

ASCII:
flag{will_he_be_back}


Por tanto, lo que ya sabíamos descifrando el primer criptograma, la solución es: flag{will_he_be_back}.

Programación (I): Solución Reto CTFLearn "The adventures of Boris Ivanov. Part 3"

$
0
0
En este post la solución a uno de los retos de programación de la plataforma CTFLearn.

Este reto tiene el título "The adventures of Boris Ivanov. Part 3" y mi valoración sobre su dificultad es: .

Su enunciado dice lo siguiente:


The KGB agent Boris Ivanov found the place where one of the criminals was hiding for a long time. Unfortunately the criminal disappeared and more than that he shredded the piece of paper with important information. Help Boris to restore it. Here is a bin with the strips of paper. P.S.: Boris is an experienced agent and he instantly realized that the size of the sheet was 500x500.


Solución: creo el siguiente script de Python para intentar recomponer la hoja de papel triturada y que según el enunciado del reto contiene información importante.

from PIL import Image

The_adventures_of_Boris_Ivanov_Part_3 = Image.new("RGB",(500,500),"black")

file = 0

while file < 500:
imagen = str(file) + ".png"
image = Image.open(imagen)
The_adventures_of_Boris_Ivanov_Part_3.paste(image, (0,file))
file = file + 1

The_adventures_of_Boris_Ivanov_Part_3.save("The_adventures_of_Boris_Ivanov_Part_3.png")

The_adventures_of_Boris_Ivanov_Part_3.show()

Y tras ejecutar este script, la última instrucción muestra el archivo generado:
como se observa, en esta imagen se distingue la siguiente cadena (hexadecimal):

66 6c 61 67 7b 74 68 33 5f 4b 47 42 5f 6c 30 76 33 73 5f 43 54 46 7d.

Obtengo la representación ASCII de esta cadena y ya puedo ver la solución del retoflag{th3_KGB_l0v3s_CTF}.

Programación (II): Solución Reto CTFLearn "Can your memory handle prime numbers?"

$
0
0
En este post la solución a otro de los retos de programación de la plataforma CTFLearn.

Este reto tiene el título "Can your memory handle prime numbers?" y mi valoración sobre su dificultad es: .

Su enunciado dice lo siguiente:


How many prime numbers are smaller than 987163160? Give the answer in base64 format.


Flag: CTF{number_in_base64_format}.

Solución: utilizo el siguiente script de Python.

from time import time

def buscar_primos(num_max):
      global primos, tot_primos
      primos = [2]
      tot_primos = 1
      i = 3
      while i <= num_max:
             es_primo = True
             sqrt = int(i**(0.5) + 1)
             for primo in primos:
                   if i%primo == 0:
                           es_primo = False
                           break
                   if primo >= sqrt:
                           break
             if es_primo:
                   primos.append(i)
                   tot_primos = tot_primos + 1
             i = i+2
      return primos, tot_primos

num_max = int(input('Introduzca el numero del que hay que buscar numeros primos menores que el ... : '))
tiempo_inicial = time()
buscar_primos(num_max)
print""
print "Total de numeros primos hasta el numero", num_max, "...", tot_primos

tiempo_final = time()
tiempo_ejecucion = tiempo_final - tiempo_inicial
print 'Tiempo de ejecucion en segundos:',tiempo_ejecucion

Y tras ejecutar este script, tras aproximadamente 6.985,06599998 segundos (1 h:56 m:25 s; duración que lógicamente depende del equipo empleado, pero que ya nos indica que no es un algoritmo precisamente muy eficiente), obtengo que el total de números primos menores que 987.163.160 es de 50.227.870:
Codifico ese número en base 64:  NTAyMjc4NzA=, y esa cadena es la solución del reto, es decir, CTF{NTAyMjc4NzA=}.

Programación (III): Reto 1

$
0
0
Comienzo con éste la serie de posts dedicada a retos de programación. En esta ocasión se trata de un reto de dificultad media en el que también se ve involucrada la criptografía (RSA).

Doy prevalencia a la programación sobre la criptografía en la catalogación de este reto porque, aunque también puede resolverse mediante software especializado en el citado criptosistema, e incluso mediante herramientas online, creo que es más didáctico resolverlo programando un poco. Daré la solución utilizando scripts en Python, y después utilizando un software especializado (GenRSA).

Como siempre, se admiten soluciones en forma de comentarios a esta entrada. Pasado un tiempo iré proporcionando pistas para su resolución, un máximo de tres, y posteriormente actualizaré este post con la solución.

Reto 1: "¿Dónde están mis primos?".

¿Puedes descifrar el criptograma (c) que se facilita como recurso asociado al reto?. Para ello tendrás que averiguar, de entre los diez números que figuran también como recursos asociados al reto, cuáles son los dos números primos que empleé para generar el par de claves, pública y privada. Ah..., se me olvidaba, también, es importante saber que el exponente de la clave pública es 65537.

Dificultad:
Tipo:          Criptografía y Programación.

Recursos:

 Criptograma (c):

19540121635188537345358256218589804991768201721161131762725576309946535122066936808018783197762215969471912470021001969220984795188062190362486872408585600660909527541197115931492260330924640537702338727828442553111808496971708597051904074142715130233086589949040249732660022809559417277634504521309499127903

- Números:

1: 10898008009708008780770807788008080970870807789097077878789097899780909978008879850943972857834701038509312570938751127353275327584676855972432509876555671

2: 6970909907535456845245900574123258621357962100144789563299863277125541953157624321987512870026998632478523699426715682463589214597788876543398567867846327

3: 686093586538642545812257896357895421852262652417859832148917289962541275632564185266541233759147215932715389395462137895222147258962,3002145072520012739223

4: 7852497395886953355486089906143943764072813626900674506724734867963143474700652040892883297447998412932980094926645645676833309384750715234427287603375523

5: 8448798523566985215875986321145002562301025877960230457321862036914723962009987536212544756321036587451298756214753232012475899623541201275896300125478951

6: 9545785212365425820124235796241546988985754465210230124570258953002951423214589567899875124478023569024500625417897654231023589562300125458956230147125497

7: 11546475231585200150650321054780985226541235797862154233214588967452312365247564789218523579600147025869012457896585877215677985232145689753201203210478997

8: 7980968350976578537876384001248452359875564210320200157899874412365211125485231032232021500144587789515888956320142578954124632012001547259823789562142563

9: 9124875625205915987965456213324582698871025076228547556201470259630152146325423012487591023365289247805611242365125627894321562998756021320568907895201471

10: 13289614374906100508941828501066167368622862591677389198666259247049362650461068945523025972016475211576320507278374215384515235884920444306665134048073627

- Exponente clave pública (e):

65537

******** __/__/____
Pista 1:     Por publicar.

******** __/__/____
Pista 2:     Por publicar.

******** __/__/____
Pista 3:     Por publicar.

******** __/__/____
Solución (por publicar).

******** PRÓXIMO RETO
Reto 2:     Por publicar.

Programación (IV): Solución Reto 1

$
0
0
El  enunciado del primer reto de programación que puse en este post era el siguiente:

"¿Puedes descifrar el criptograma (c) que se facilita como recurso asociado al reto?. Para ello tendrás que averiguar, de entre los diez números que figuran también como recursos asociados al reto, cuáles son los dos números primos que empleé para generar el par de claves, pública y privada. Ah..., se me olvidaba, también es importante saber que el exponente de la clave pública es 65537".

Este reto es de criptografía y programación y su solución es:

1.- Ya decía en el citado post que en primer lugar iba a crear un script en Python para intentar resolver este reto. El siguiente:

from random import randint
from time import time

def inv(n1, n):
    """
    Calculo del inverso multiplicativo de un numero (n1) modulo n
    """
    global a, u0
    a = n1
    b = n
    u0 = 1
    u1 = 0
    v0 = 0
    v1 = 1
    while b != 0:
        q = a//b
        r = a-b*q
       u = u0-q*u1
       v = v0-q*v1
       a = b
       b = r
       u0 = u1
       u1 = u
       v0 = v1
       v1 = v
    if a != 1:
        u0 = 0
    elif u0 < 0:
        u0 = n+u0
    return a, u0

def exp_modular(base, exponente, modulo):
    """
    Funcion exponenciacion modular rapida
    """
    global x
    B = bin(exponente)[2:]
    x = 1
    i = 0
    while i < len(B):
        x = (x**2)%modulo
        if B[i]=="1":
            x = x*base%modulo
        i = i+1
    return x

def es_primo(numero):
    """
    Funcion que nos indica si un numero es compuesto o, por el contrario y con un alto
    nivel de confianza, es primo (Test de primalidad de Miller-Rabin).
    Tiene que recibir el numero entero impar
    """
    r = numero-1
    k = 10
    t = 0
    i = 1
    s= 0
    while r%2 == 0:
        s =  s+1
        r  =  r/2
    while i <= k and t != 1:
        a = randint(2, numero - 1)
        j = 0
        exp_modular(a, r, numero)
        y = x
        if y <> 1 and y <> numero - 1:
           j = 1
            while y <> numero - 1 and t <> 1 and j <= s - 1:
                  y = y**2%numero
                  if y == 1:
                     t = 1
                  else:
                     j = j+1
            if y <> numero -1:
                  t = 1
         i = i+1
    if t == 0:
        return True
    else:
         return False

def t_chino_resto(p, q, n, d, c):
    """
    Descifrado RSA utilizando el teorema chino del resto
    """
    global m
    inv(p, q)
    p1 = u0
    dp = d%(p-1)
    dq = d%(q-1)
    cp = c%p
    cq = c%q
    k1 = exp_modular(cp, dp, p)
    k2 = exp_modular(cq, dq, q)
    m = k1+p*(((k2-k1)*p1)%q)
    return m

p = int(input('Introduzca el factor primo del modulo p ......... : '))
q = int(input('Introduzca el factor primo del modulo q ......... : '))

error = 0
if p < 2 or q < 2:
         error = 1
         print 'Los factores del modulo deben ser numeros naturales mayores que 1'
if error == 0:
         if es_primo(p) == False:
            error = 1
            print 'El factor del modulo p debe ser un numero primo'
         if es_primo(q) == False:
            error = 1
            print 'El factor del modulo q debe ser un numero primo'
if error == 0:
        n = p*q
         print 'modulo n ........................................ :', n
         fi = (p-1)*(q-1)
         print 'fi(n) ........................................... :', fi
         e = int(input('Introduzca el exponente de la clave publica e ... : '))
         inv(e, fi)
         if a !=1:
            error = 1
            print e, ' no es primo relativo de ', fi
         else:
            print 'exponente de la clave privada (d) ............... :', u0
if error == 0:
         c = int(input('Introduzca el criptograma c ..................... : '))
         tiempo_inicial = time()
         t_chino_resto(p, q, n, u0, c)
         print 'm (decimal) ..................................... :', m
         tiempo_final = time() 
         tiempo_ejecucion = tiempo_final - tiempo_inicial
         print 'Tiempo de ejecucion en segundos:',tiempo_ejecucion

1.1.- Ejecuto este script con los dos primeros números facilitados como recursos asociado al reto; tras introducir el primer número como 'p' (primer factor primo del módulo) y el segundo como 'q' (segundo factor primo del módulo), obtengo (test de primalidad de Miller-Rabin, ver este post donde lo explico) que ninguno de ambos es primo:
Por tanto, descarto ambos números y vuelvo a ejecutar el script con el tercer y cuarto números, y obtengo que el único de ellos que es primo es el cuarto:
Fijo el cuarto número como como 'p' (primer factor primo del módulo) y voy probando el resto de ellos como 'q' (segundo factor primo del módulo). Los dos únicos números primos de la lista son el cuarto y el décimo, y tras ejecutar el script con ambos números e introducir el exponente de la clave pública (e), 65537, y el critograma (c) obtengo que m (el mensaje en claro en decimal) es: 437191574114813999946507697086805092.
1.2.- Convierto el mensaje (m) anterior a hexadecimal, lo que me da:  543335745F5072316D346C31643464.

1.3.- Obtengo la representación ASCII y ya puedo ver la clave del reto: "T35t_Pr1m4l1d4d":

2.- Una vez resuelto el reto mediante el script de Python, tal y como dije en post en el que enuncié este reto, lo resuelvo utilizando un software especializado, genRSA 2.1.

2.1.- De la misma forma que en el caso anterior, introduzco el primer número como 'p' (primer factor primo del módulo) y el segundo como 'q' (segundo factor primo del módulo), y el software me indica que ninguno de ambos es primo.
Por tanto, descarto ambos números e introduzco el tercer y cuarto números, y el software me indica que el único de ellos que es primo es el cuarto:
Fijo el cuarto número como 'p' (primer factor primo del módulo) y voy probando el resto de ellos como 'q' (segundo factor primo del módulo). Los dos únicos números primos de la lista son el cuarto y el décimo:
Introduzco el exponente de la clave pública (e), 65537, y genero el par de claves (pulso el botón "Generación Manual"), pública y privada:
y descifro el criptograma (Operaciones > Cifrar_Descifrar), introduciendo el criptograma (c) y pulsando el botón "Descifrar Datos"; obtengo que m (el mensaje en claro en decimal, "Datos Descifrados") es: 437191574114813999946507697086805092.
2.2.- Convierto el mensaje (m) anterior a hexadecimal, lo que me da: 543335745F5072316D346C31643464.

2.3.- Obtengo la representación ASCII y ya puedo ver la clave del reto: "T35t_Pr1m4l1d4d":

******** PRÓXIMO RETO
Reto 2 (Programación): Por publicar.

Criptografía (CX): Solución Reto 22

$
0
0
El  enunciado del vigésimosegundo reto que puse en este post era el siguiente:

"Evidentemente, ya sabes a qué criptosistema me refiero (ver este post en el que lo explico), pero lo importante en este reto es descifrar el criptograma asociado al mismo, cosa que entiendo no es fácil sin conocer la clave. Para facilitar esta tarea te proporciono, también como recurso asociado al reto, texto en claro conocido correspondiente al criptograma. ¿Puedes descifrarlo?".


Este reto es de criptografía y su solución es:


1.- Tal y como decía en el citado post, el cifrado de Playfair es un criptosistema que consiste en en la sustitución de pares de letras o digramas empleando una tabla o matriz generada por una clave.


Por tanto, lo primero que podemos hacer conociendo parte del texto en claro, como es el caso de este reto, es sustituir los digramas del texto cifrado por sus respectivos digramas conocidos del texto en claro.

En nuestro reto tenemos que:

CriptogramaQE QT DW XN QT PT CW TP AW CH NG KL WB LY TP AT QD YT LZ BE WT LY TN NB WA ZE NS QW MC SN BN BK FS WY BS QK RE NF QT QH BK KM WI NS NB WP PH HC FS GW QM BA IH KQ SN BN JQ AW SF TP TN NB CW LZ KQ QW WT SQ TA PQ PW WI BA MN WG QT BD NC WA GN PT MP NG BW GA NG SR TQ NV

Texto en claro conocido (se corresponde con el inicio del criptograma)PA RA SU PE RA RE ST ER ET OT EN DR AS QU ER EA LI ZA RU NA TA QU EC ON TE XT OC LA RO CO NO CI DO

Por lo que podemos sustituir todas las veces que aparezca "QE" en el criptograma por "PA"; "QT" por "RA"; y así sucesivamente. Obteniendo: 

CriptogramaPA RA SU PE RA RE ST ER ET OT EN DR AS QU ER EA LI ZA RU NA TA QU EC ON TE XT OC LA RO CO NO CI DO WY BS QK RE NF RA QH CI KM WI OCON WP PH HC DO GW QM BA IH KQ CO NO JQ ET SF TP ECONSTRU KQ LATA SQ TA PQ PW WI BA MN WG RA BD NC WA GN RE MP EN BW GA EN SR TQ NV

Además, si "PA" se cifra como "QE", "AP" se cifra como "EQ"; si "RA" se cifra como "QT", "AR" se cifra como "TQ"; y así sucesivamente.

Por tanto, podemos sustituir todas las veces que aparezca "EQ" en el criptograma por "AP"; "TQ" por "AR"; y así sucesivamente. Obteniendo: 

CriptogramaPA RA SU PE RA RE ST ER ET OT EN DR AS QU ER EA LI ZA RU NA TA QU EC ON TE XT OC LA RO CO NO CI DO WY BS QK RE NF RA QH CI KM WI OCON WP PH TO DO GW QM BA IH KQ CO NO JQ ET ODER EC ON ST RU KQ LA TA SQ AE PQ PW WI BA MN WG RA BD NC TENE RE MP EN SA GA EN SR AR NV

Tenemos ya descifrado parcialmente el criptograma (lo resaltado en color rojo), pero ahora viene lo difícil.

Intento reconocer ya algunas palabras. Sin forzar mucho la situación, creo que en la tercera línea se puede adivinar la palabra "RECONSTRUIR" o "RECONSTRUIRLA", para lo que "KQ" debería cifrarse como "IR". Haciendo las sustituciones correspondientes obtenemos:

CriptogramaPA RA SU PE RA RE ST ER ET OT EN DR AS QU ER EA LI ZA RU NA TA QU EC ON TE XT OC LA RO CO NO CI DO WY BS QK RE NF RA QH CI KM WI OC ON WP PH TO DO GW QM BA IH IR CO NO JQ ET OD ER EC ON ST RU IR LA TA SQ AE PQ PW WI BA MN WG RA BD NC TE NE RE MP EN SA GA EN SR AR NV 

"QK" no aparece en el criptograma.

Todavía, al menos yo, no puedo adivinar muchas más palabras. ¿Qué más podemos hacer?. Pues lo único que se me ocurre es:

1.- Análisis de frecuencias de bigramas.

2.- Reconstrucción de la tabla de cifrado siguiendo las siguientes reglas conforme al criptosistema de Playfair (seguro que no son las únicas reglas que se pueden obtener):

2.1.- Si "X" cifra (o descifra) como "Y" en cualquier par de letras, "X " e "Y" pertenecen a la misma fila o columna de la tabla. Ejemplo: en nuestro caso, como "PA" se cifra como "QE" y, por tanto, "P" y "Q" están en la misma fila o columna, y "A" y "E" están en la misma fila o columna.

2.2.- Si el par de letras "XW" se cifra como "YZ" e "YZ" se descifra como "XW":

2.2.1.- "X" y "W" no pertenecen a la misma fila ni a la misma columna, e "Y" y "Z" no pertenecen a la misma fila ni a la misma columna.

2.2.2.- "X" e "Y" pertenecen a la misma fila, y "W" y "Z" pertenecen a la misma fila.

2.2.3.- "X" y "Z" pertenecen a la misma columna, y "W" e "Y" pertenecen a la misma columna.

Por supuesto, en ese caso "WX" se cifrará como "ZY", y "ZY" se descifrará como "WX", lo que nos da la misma información.

Ejemplo: en nuestro caso, como "RE" se cifra como "PT"  y "PT" se descifra como "RE"

- "R" y "E" no están en la misma fila ni en la misma columna, "P" y "T" no están en la misma fila ni en la misma columna.

- "R" y "P" pertenecen a la misma fila, y "E" y "T" pertenecen a la misma fila.

- "R" y "T" pertenecen a la misma columna, y "E" y "P" pertenecen a la misma columna.

Evidentemente, en nuestro caso "ER" se cifra como "TP" y "TP" se descifra como "ER", lo que nos da la misma información.

2.3.- Si "XY" se cifra como "YZ", entonces "X", "Y" y "Z" están en la misma fila o columna, y su orden en la fila o columna es  "X", "Y" y "Z", salvo que se exceda el borde de la fila o columna de la tabla.

Ejemplo: en nuestro caso, "EN" se cifra como "NG", por lo que todas esas letras están en la misma fila o columna y su orden más probable es "E", "N" y "G".

2.4.- Si "X" se cifra como "Y" tanto en "UX" -> "VY" como en "WX" -> "ZY", siendo esas letras que preceden a "X" e "Y" diferentes, entonces: "X" e "Y" están en la misma fila, "U" y "V" están en la misma fila, y "W" y "Z" están en la misma fila.

Ejemplo: en nuestro caso, "A" se cifra como "T" tanto en "RA" -> "QT" como en "ZA" -> "YT". Como las letras que preceden a "A" y "T" son todas diferentes, entonces: "A" e "T" están en la misma fila, "R" y "Q" están en la misma fila, y "Z" e "Y" están en la misma fila.


Dicho todo lo anterior, aunque ya lo sospechaba, del análisis de frecuencias de lo bigramas no obtengo mayor información, ya que el criptograma no es muy largo y los bigramas más frecuentes (repetidos 4 y 3 veces) forman parte del texto claro conocido.

Por tanto, sólo me queda intentar reconstruir la tabla de cifrado utilizando las citadas reglas. Intento recoger en una tabla el criptoanálisis realizado:
A partir de aquí y tras bastantes quebraderos de cabeza (nadie dijo que iba a ser fácil), obtengo la tabla empleada en el cifrado:
Y completo el descifrado:

Texto en claroPA RA SU PE RA RE ST ER ET OT EN DR AS QU ER EA LI ZA RU NA TA QU EC ON TE XT OC LA RO CO NO CI DO AUNCRIPTOG RA MA CI FRAD OC ON ELME TO DO DEPLAYFAIR CO NO BJ ET OD ER EC ON ST RU IR LA TA BL AE MPLEADAYPODE RA SIOB TE NE RE LM EN SA EJ EN CL AR OX 

Es decir, quitando la letra "X" del final (incluida porque el número de caracteres del texto en claro es impar):

Texto en claroPARA SUPERAR ESTE RETO TENDRAS QUE REALIZAR UN ATAQUE CON TEXTO CLARO CONOCIDO A UN CRIPTOGRAMA CIFRADO CON EL METODO DE PLAYFAIR CON OBJETO DE RECONSTRUIR LA TABLA EMPLEADA Y PODER ASI OBTENER EL MENSAJE EN CLARO 


Para finalizar, en la pista que puse para facilitar la resolución de este reto, decía que la persona que aparece en el retrato que ilustra ese post y éste no es Lyon Playfair, y preguntaba: ¿Quién es?.

Para averiguarlo buscamos el retrato con "Google Imágenes":
Tras arrastrar la imagen obtenemos lo siguiente:
Es decir, ese retrato es de Charles Wheatstone, quién, tal y como nos cuenta wikipedia fue realmente el inventor del cifrado de Playfair.

Por lo que esta pista era un atajo para resolver este reto :), ya que si nos fijamos la clave para generar la tabla de cifrado es precisamente el apellido de este científico e inventor británico, Es decir, quitando las letras repetidas: "WHEATSON".

Codificación (I): Solución Reto CTFLearn "What's Your Favorite Number of the Alpha"

$
0
0
En este post la solución a uno de los retos de codificación de la plataforma CTFLearn.

Este reto tiene el título "What´s Your Favorite Number of the Alpha" y mi valoración sobre su dificultad es: ☆☆.

Su enunciado dice lo siguiente:


The flag accidentally got changed into something else. Here is the flag: ¥¦§¸ªßØÌÉÃÊÐÅËá If it helps, I think the first letter was an A (capitalized)... Title is supposed to be "What's Your Favorite Number of the Alphabet, got cut off :(.


Solución: Nos dicen que el primer carácter "¥" de la bandera corrupta es una "A" mayúscula. La representación unicode de "¥" en decimal es 165 y la de "A" es 65. Por tanto, pruebo con un pequeño script en Python para ver si nos revela la bandera (resto 100 a la representación decimal unicode de cada carácter de la bandera corrupta para obtener la representación decimal unicode de cada carácter de la bandera original y muestro esta última):

#!/usr/bin/env python
# -*- coding: utf-8 -*-

cipher = "¥¦§¸ªßØÌÉÃÊÐÅËá"
solution = ""
for x in cipher:
     solution = solution + (chr(ord(x)-100))

print solution

Tras ejecutar este script obtengo:
Por tanto, la solución del reto es: ABCTF{the_flag}.

Codificación (II): Solución Reto CTFLearn "Privacy Matters"

$
0
0
En este post la solución a otro de los retos de codificación de la plataforma CTFLearn.

Este reto tiene el título "Privacy Matters" y mi valoración sobre su dificultad es: ☆☆.

Su enunciado dice lo siguiente:


The URL that has the flag got corrupted again... here it is: êööòõ¼±±åñæçòçð°ëñ±ðëåîçø´²±è÷îî±øûÛÓüɱ


Solución: Al tratarse de una URL supongo que el principio de la cadena de caracteres que nos dan se corresponde con http. La representación unicode de "ê" en decimal es 234 y la de "h" es 104. Por tanto, pruebo con un pequeño script en Python para ver si nos revela la URL (resto 130 a la representación decimal unicode de cada carácter de la URL corrupta para obtener la representación decimal unicode de cada carácter de la URL original y muestro esta última):

#!/usr/bin/env python
# -*- coding: utf-8 -*-

cipher = "êööòõ¼±±åñæçòçð°ëñ±ðëåîçø´²±è÷îî±øûÛÓüɱ"
solution = ""
for x in cipher:
     solution = solution + (chr(ord(x)-130))

print solution

Tras ejecutar este script obtengo:
Por tanto, la URL original es: https://codepen.io/niclev20/full/vyYQzG/.

Accedo a esa URL:
Y, pulsando "Change View > Editor View" o a través del código fuente de la página, enseguida encuentro la solución al reto: "ABCTF{harder_this_time}".

Explotación Web (I): Solución Reto CTFLearn "Basic Injection"

$
0
0
En este post la solución a uno de los retos de explotación Web de la plataforma CTFLearn.

Este reto tiene el título "Basic Injection" y mi valoración sobre su dificultad es: ☆☆.

Su enunciado dice lo siguiente:


See if you can leak the whole database. https://web.ctflearn.com/web4/


Solución: Por el título parece evidente que se trata de un reto de SQL injection. Pruebo con lo más básico de este tipo de ataques.

Accedo a la web
 introduzco ' or 1 = 1# en "Input", obteniendo lo siguiente:
Por tanto, la solución del reto es: fl4g_giv3r.

Explotación Web (II): Solución Reto CTFLearn "Inj3ction Time"

$
0
0
En este post la solución a otro de los retos de explotación Web de la plataforma CTFLearn.

Este reto tiene el título "Inj3ction Time" y mi valoración sobre su dificultad es: ☆☆.

Su enunciado dice lo siguiente:


I stumbled upon this website: http://web.ctflearn.com/web8/ and I think they have the flag in their somewhere. UNION might be a helpful command.

Solución: Al igual que en el anterior, por el título parece evidente que se trata de un reto de SQL injection.

Antes que nada comentar que no soy ningún experto en SQL, sólo sé lo que recuerdo de mi época de programador, que fue hace mucho tiempo, y tampoco soy un especialista en este tipo de ataques web, por lo que si explico mal la solución de este reto agradecería que algún amable lector de este humilde blog me corrija.

En cualquier caso, lo que hice para intentar resolver este reto fue lo siguiente:

Accedo a la web y me encuentro lo siguiente:
Introduzco 1 en "ID:" y obtengo el mismo resultado:
Introduzco 2 en "ID:" y cambian los datos que se muestran:
Introduzco 1 or 1 = 1# en "ID:", lo que en el caso de que esta web sea vulnerable a SQL injection nos debería devolver todas las filas de la tabla, ya que 1 = 1 es siempre verdadero; y se muestra lo siguiente:
Por tanto, esta web es vulnerable a SQL injection.

Asimismo, parece que la consulta de la que se muestra la información tiene, al menos, 4 columnas (la correspondiente a "ID" más aquellas que se corresponderían a los tres datos que se muestran para cada "ID"). Intento verificar si esto es así introduciendo 1 or 1 = 1 order by 5# en "ID:"; y obtengo lo siguiente:
Por tanto, la consulta original tiene menos de 5 columnas y, además, como no se muestra ningún mensaje de error sino que únicamente desaparece la información que se está mostrando, yo diría que esta página es sólo vulnerable a Blind SQL Injection (Inyección SQL ciega), es decir, si la consulta que realizo es verdadera se muestra la información correspondiente mientras que si es falsa no se muestra resultado alguno.

Intento ahora ver el nombre de las tablas de la base de datos, para lo que introduzco 1 or 1 = 1 union select 1,table_name,3,4 from information_schema.tables where table_schema = database()# en "ID"; y se muestra lo siguiente:
La base de datos tiene dos tablas: "w0w_y0u_f0und_m3" y "webeight". Por el nombre de las tablas, parece claro que la que contiene la bandera es la primera de ellas.

Intento ahora ver el nombre de las columnas de esas dos tablas, para lo que introduzco 1 or 1 = 1 union select 1,column_name,3,4 from information_schema.columns where table_schema = database()# en "ID"; y se muestra lo siguiente:
Por los resultados obtenidos hasta el momento, creo que la bandera se encuentra en la columna "f0und_m3" de la tabla "w0w_y0u_f0und_m3", por lo que introduzco 1 or 1 = 1 union select 1, f0und_m3,3,4 from w0w_y0u_f0und_m3# en "ID":
Por tanto, la solución del reto es: abctf{uni0n_1s_4_gr34t_c0mm4nd}.

Explotación Web (III): : Solución Reto Hackerfire "Kept in Secret"

$
0
0
En este post la solución a uno de los retos de explotación Web de la plataforma HackerFire.

Este reto tiene el título "Kept in Secret" y mi valoración sobre su dificultad es: ☆☆.

Su enunciado dice lo siguiente:


Now that you know the basic ideas behind SQL injection, can you use the techniques you've learned to extract the password for the admin?.

Solución: Tal y como dice el enunciado se trata de obtener la password del administrador mediante SQL injection.

Accedo a la web y me encuentro lo siguiente:
Tras el registro ("Register") y posterior introducción de usuario y password en el formulario "Login", busco ("Search") el usuario con el que me he conectado("a"); y obtengo lo siguiente:
En esta ocasión, para resolver este reto utilizo sqlmap, que, tal y como se dice en su página oficial, es una herramienta de código abierto de prueba de penetración que automatiza el proceso de detección y explotación de vulnerabilidades de inyección SQL.

En primer lugar obtengo las bases de datos mediante el siguiente comando: sqlmap.py -u "http://challenges.hackerfire.com:30005/profiles.php?search=a" --dbs
Como vemos, sqlmap detecta que el Sistema de Gestión de Base de Datos es 'MySQL' por lo que no es necesario realizar pruebas para otros DBMS´s y pulsamos la tecla "Enter":
Tras finalizar la ejecución, tal y como se observa en la figura anterior, veo que existen dos bases de datos: "information_schema" y "Secrets".

A continuación obtengo las tablas de la base de datos "Secrets" mediante el siguiente comando: sqlmap.py -u "http://challenges.hackerfire.com:30005/profiles.php?search=a" -D Secrets --tables
Como se ve en la figura anterior hay una única tabla, "users", en la base de datos "Secrets".

Obtengo ahora las columnas y el contenido de la tabla "users" mediante el siguiente comando: sqlmap.py -u "http://challenges.hackerfire.com:30005/profiles.php?search=a" -D Secrets -T users --dump
En la figura anterior veo las columnas de la tabla "users" y el vaciado o volcado del contenido de ésta lo deja en un fichero CSV. Abro ese archivo y veo que la fila correspondiente al nombre de usuario "admin" contiene lo siguiente:

1,Admin,admin,flag{pa55w0rd5_ar3_b1g_s3cr3t5},doing admin duties

Por tanto, ya tengo la password del administrador, que es la solución del reto:  flag{pa55w0rd5_ar3_b1g_s3cr3t5}.

Explotación Web (IV): Solución Reto Hackerfire "Kept in Secret" (II)

$
0
0
Decía en el anterior post que en éste iba a solucionar el reto de explotación Web de la plataforma HackerFire, que en el citado post se resuelve con sqlmap, de forma manual, es decir, sin utilizar ninguna herramienta para ello.

Recuerdo la información sobre el reto a resolver:

Este reto tiene el título "Kept in Secret" y mi valoración sobre su dificultad es: ☆☆.

Su enunciado dice lo siguiente:


Now that you know the basic ideas behind SQL injection, can you use the techniques you've learned to extract the password for the admin?.

Solución: Tal y como dice el enunciado se trata de obtener la password del administrador mediante SQL injection.

Accedo a la web y me encuentro lo siguiente (compacto un poco la información que se muestra para que se vea mejor):
Como ya realicé el registro ("Register") cuando escribí el post anterior,  introduzco el usuario y password, "a" y "a" en ambos casos, en el formulario "Login" y se muestra la relación de usuarios.


Introduzco a' order by 4# y obtengo lo siguiente:
Por tanto, parece que la consulta de la que se muestra la información tiene sólo 3 columnas (las correspondientes a "Username", "Name" y "Description).

Intento obtener el nombre de las tablas de la base de datos, para lo que introduzco a' union select 1,table_name,3 from information_schema.tables where table_schema = database()# y se muestra lo siguiente:
La base de datos contiene una única tabla: "users".

Intento ahora ver el nombre de las columnas de esa tabla, para lo que introduzco a' union select 1,column_name,3 from information_schema.columns where table_schema = database()#  y se muestra lo siguiente:
Finalmente, introduzco a' union select 1,username,password from users# y obtengo:
Por tanto, la solución del reto es: flag{pa55w0rd5_ar3_b1g_s3cr3t5}.

Programación (V): Solución Reto RingZer0 Team "Hash me please"

$
0
0
En este post la solución a uno de los retos de programación de la plataforma RingZer0 Team.

Este reto tiene el título "Hash me please" y mi valoración sobre su dificultad es: ☆☆.

Su enunciado dice lo siguiente:


You have 2 seconds to hash this message using sha512 algorithm.


Send the answer back using: https://ringzer0team.com/challenges/13/[your_hash].

----- BEGIN MESSAGE -----

EV9uVdNX2iuMnXZBhiJ1oc2fFoL2WFirrhLckp0cxkOL8EcfNL71OZ7jdJc0ekhwrTyC9oFwzk7xOaDsLAkqpiAtRCjWMqi4aHw9V1wlbtJQtc95DjmSrMb9flVRC4MCB9Cn0Yz2h8JBbIxESKn9mp8sAUa2OMvgLXtCMSvUR5mTDJnljAlwPjPg4P9IruO3i8vURQEzMQifqwrAWDXCNCJHhIgz2UsbTOWBvr0788douvPhYDKC5j9dRfDK0WMKAybWP1TN0X2kiHs7b2z6cyaUEEvuq75Rw6DbXnPNaHYifhfgaEdc3eWxIhSYfNGBK9CxmibmQ0vV7A2755aYaXmI44xaI3Bi34GfcIsSyNEwewu9suYsia1d5odDiEMbzihCQzkfdPBhcWhuh6Np6Fs2Uvv2084pgbRXB23EIvMKhU5oQIENeWFYi1R9ZMp6N7UfZNKy8n8f73uOCZrGLXvUOdTEP8At6kyVX9jWmi1kbmYDbgaN3wxHzhbegCxcNWYBW8n8geiir7MsdM568tExBGCH80KMNydzxqxEvGMMDo5G00DZk7nLDPjCGTejihIGy6aTDNw61rDSi7Is4V4yBd17X5g6dPDBLDlegIb8ZFQ8CorxalVBpMydIEaLjDdV7p0dX1cNwSLZ73m8e8zuLXxjsxVC0ZnYee1254GsNihKbuIfs8A3VXcelYHcNV0RZSKUMhcppk0qEzwWxWPjKSoVGVYjGO1vxCg9JipYtffXFCK3pqdZ9rLFdzPJeH4B9bBJjQyDWErs61lliobhGNMJdsii0dJZebzoSXREr9Wo08A8nBfTfSsibBq1F0RK1gZJ4HemG1AwZ0vcsBWxjfFlGWccMTND0CdU9h6F8x2Ynn1FON3YSy9pkcsXV5rMxuwxCt2BQVp49gAOUtDDSCT3EbQq782vspSUJLlpwBkwIKas4DWN6FGBHnRElKZE0HpziBPF201BA2UvvG9rbFSJTAd5b2A1APrJh7f9X7BoZlJkRICTeksYLwUN
----- END MESSAGE -----

Solución: utilizo el siguiente script de Python.


import requests
import hashlib
import re
s = requests.session()

url = 'https://ringzer0team.com'

payload = {'username':  'tu usuario', 'password': 'tu contraseña'}

s.post(url+'/login',payload)
r2 = s.get(url+'/challenges/13')

#Obtener el mensaje
message = re.findall('----- BEGIN MESSAGE -----< br />\r\n\t\t(.*?)< br />\r\n\t\t----- END MESSAGE -----', r2.text, re.DOTALL)
message = message[0]
print('message = ', message)

#Hash sha512 del mensaje
hash_object = hashlib.sha512(str.encode(message))
hex_dig = hash_object.hexdigest()
print('hash = ', hex_dig)

#Obtener la solucion
r3 = s.get(url+'/challenges/13/'+str(hex_dig))
flag = re.findall('< div class="alert alert-info">(.*?)< /div>', r3.text, re.DOTALL)
print(flag)

Ejecuto este script:
Y obtengo la solución: FLAG-mukgu5g2w932t2kx1nqnhhlhy4.

Programación (VI): Solución Reto RingZer0 Team "Hash breaker"

$
0
0
En este post la solución a otro de los retos de programación de la plataforma RingZer0 Team.

Este reto tiene el título "Hash breaker" y mi valoración sobre su dificultad es: .

Su enunciado dice lo siguiente:


You have 3 seconds to break this hash.

Send the answer back using: https://ringzer0team.com/challenges/56/[clear_text]



----- BEGIN HASH -----
2dbd76e41756796a0b1ed09f68ae94d3b8c62b56
----- END HASH -----

Solución: ¿Qué tiene de diferente este reto frente al anterior, y cuya solución puse en este mismo blog?. Pues creo que es muy similar, pero en este caso entiendo que hay que dar un paso previo y por eso lo califico como un poco más difícil.

Me explico, en principio, un hash no se puede revertir, es decir, a partir del resumen no puede obtenerse el texto en claro que lo generó, pero existen diferentes servicios on-line que, contando con bases de datos de gran cantidad de estos resúmenes (pares de 'texto en claro' y 'hash'), pueden indicar si el hash introducido, siempre y cuando figure en su base de datos, coincide con algún texto en claro concreto.

Por tanto, el primer paso que dí consistió en utilizar un servicio de esa clase para intentar averiguar qué tipo de hash se emplea en este reto y, además, si existe algún patrón en el texto en claro utilizado.

Pues bien, descubrí que el tipo de hash usado en este reto es 'sha1' y que el texto en claro es siempre un número de 4 dígitos.

Por tanto, es fácil obtener la solución del reto empleando un poco de fuerza bruta, para lo que utilizo el siguiente script de Python.

import requests
import hashlib
import re
s = requests.session()

url = 'https://ringzer0team.com'

payload = {'username': 'tu usuario', 'password': 'tu contraseña'}

s.post(url+'/login',payload)
r2 = s.get(url+'/challenges/56')

#Obtener el hash
hash = re.findall('----- BEGIN HASH -----< br />\r\n\t\t(.*?)< br />\r\n\t\t----- END HASH -----', r2.text, re.DOTALL)
hash = hash[0]
print('Hash = ', hash)

#revertir el hash (el tipo de hash es sha1 y el texto en claro es siempre un numero de 4 digitos. Ataque por fuerza bruta)
i = 1000
while i <= 9999:
    hash_i = hashlib.sha1(str.encode(str(i)))
    if hash_i.hexdigest() == hash:
       hash_decode = i
       i = 10000
    else:
       i= i+1
print ('Hash decode =', hash_decode)

#Obtener la solucion
r3 = s.get(url+'/challenges/56/'+str(hash_decode))
flag = re.findall('< div class="alert alert-info">(.*?)< /div>', r3.text, re.DOTALL)
print(flag)

Ejecuto este script:
Y obtengo la solución: FLAG-G1095M88Tk837G9AC0EA6q3N.

Programación (VII): Solución Reto WeChall "Can you read me"

$
0
0
En este post la solución a uno de los retos de programación de la plataforma WeChall.

Este reto tiene el título "Can you read me" y mi valoración sobre su dificultad es: .

Su enunciado dice lo siguiente:


A friend and me have a bet running, that you won't beat his OCR program in scanning text out of images.
His average scan time is 2.5 seconds, can you beat that?.


Y nos dan una imagen como la siguiente:
Soluciónutilizo el siguiente script de Python.

from PIL import Image
from io import BytesIO
from urllib.parse import quote as urlencode
from bs4 import BeautifulSoup
import pytesseract
import requests
import re

s = requests.session()

url = 'https://www.wechall.net/'
image_url = url+'challenge/can_you_readme/gimme.php'
solution_url = url+'challenge/can_you_readme/index.php'

payload = {'username': 'tu usuario', 'password': 'tu contraseña'}

s.post(url,payload)
r2 = s.get(image_url)

#Obtener el texto
captcha = Image.open(BytesIO(r2.content))
captcha.save('read_me.png')
print('Resolviendo Captcha')
captcha_text = pytesseract.image_to_string(captcha)
print('Texto extraido',captcha_text)

#Enviar la solucion
r3 = s.get(solution_url + '?action=Answer&solution=' + urlencode(captcha_text)).text
r3 = BeautifulSoup(r3, 'html.parser')
if r3.select('.gwf_errors'):
   exit(r3.select('.gwf_errors li')[0].text)
print(r3.select('.gwf_messages li')[0].text)

Ejecuto este script:
Y, como se observa en la figura anterior, la respuesta es correcta.

Programación (VIII): Solución Reto HackThis "Coding Level 1"

$
0
0
En este post la solución a uno de los retos de programación de la plataforma HackThis.

Este reto tiene el título "Coding Level 1" y mi valoración sobre su dificultad es: .

Su enunciado dice lo siguiente:


The words have been jumbled up, your task is to write some code to return them to alphabetical order. Then submit your answer in the same format, for example: ant, badger, cattle, zebra. You have 5 seconds to complete the mission.


nos dan una lista de palabras como la siguiente:
Soluciónutilizo el siguiente script de Python.

import requests

def sort(string):
    string=string.split(", ")
    return ", ".join(sorted(string))

url="https://www.hackthis.co.uk/levels/coding/1"
login="https://www.hackthis.co.uk/?login"
payload={"username":"tu usuario","password":"tu contraseña"}

#Empezar una sesion
s=requests.Session()

#Login
s.post(login,data=payload)

#Obtener palabras desordenadas
response=s.get(url).text
words=response[response.find("< textarea>")+10:response.find("< /textarea")]
print("Words:",words)

#Ordenar las palabras alfabeticamente
answer=sort(words)
print("Answer:",answer)

#Enviar la respuesta
payload={"answer":answer}
s.post(url,data=payload)
response=s.get(url).text
if ("Incomplete" in response):
   print("Incorrect answer")
else:
   print("Correct answer")

Ejecuto este script:
Y, como se observa en la figura anterior, la respuesta es correcta.

Programación (IX): Solución Reto HackThis "Coding Level 2"

$
0
0
En este post la solución a otro de los retos de programación de la plataforma HackThis.

Este reto tiene el título "Coding Level 2" y mi valoración sobre su dificultad es: .

Su enunciado dice lo siguiente:


A string has been encoded using a very simple custom encryption method, explained here, decrypt the message. You have a 5 second time limit for each attempt.


nos dan una lista de palabras como la siguiente:
La explicación del método de cifrado es:
Soluciónutilizo el siguiente script de Python.

import requests

def Decipher(string_encoded):
    print("")
    print("Cadena cifrada..........................",string_encoded)
    print("Longitud cadena cifrada.................",len(string_encoded))
    i=0
    ascii_str=""
    string_decoded=""
    while i < len(string_encoded):
          if string_encoded[i]!="":
             ascii_char=126-(int(string_encoded[i]+string_encoded[i+1])-32)
             ascii_str=ascii_str+str(ascii_char)+","
             string_decoded=string_decoded+chr(ascii_char)
             i+=3
          else:
             ascii_str=ascii_str+" ,"
             string_decoded=string_decoded+""
             i+=2
    print("Caracteres ASCII decimal................",ascii_str)
    print("Cadena descifrada.......................",string_decoded)
    return string_decoded

url="https://www.hackthis.co.uk/levels/coding/2"
login="https://www.hackthis.co.uk/?login"
payload={"username":"tu usuario","password":"tu contraseña"}

#Empezar una sesion
s=requests.Session()

#Login
s.post(login,data=payload)

#Obtener mensaje cifrado
response=s.get(url).text
cipher_message=response[response.find("< textarea>")+10:response.find("< /textarea")]

#Descifrar mensaje
answer=Decipher(cipher_message)

#Enviar la respuesta
payload={"answer":answer}
s.post(url, data=payload)
response=s.get(url).text
if ("Incomplete" in response):
     print("Incorrect answer")
else:
     print("Correct answer")

Ejecuto este script:

Y, como se observa en la figura anterior, la respuesta es correcta.

Codificación (III): Solución Reto RingZer0 Team "Ask your grandpa!" (I)

$
0
0
En este post la solución a uno de los retos de codificación de la plataforma RingZer0 Team.

Este reto tiene el título "Ask your grandpa!" y mi valoración sobre su dificultad es: ☆☆.

En este reto sólo nos dan un archivo jpg que contiene una imagen de una tarjeta perforada.


En concreto, la tarjeta de este reto tiene 80 columnas (en las siguientes imágenes se ha recortado para que se aprecien mejor las perforaciones y su significado) y es la siguiente:

Antes de intentar leerla, conviene recordar que tal y como nos cuenta Wikipedia en el enlace anterior: "Las 10 posiciones inferiores representaban (de arriba a abajo) los dígitos del 0 al 9. Las dos posiciones superiores de una columna eran llamadas perforación de zona 12 (superior), y perforación de zona 11".

Una columna con dos perforaciones, una en la zona [12,11,0] + otra en la zona de dígitos [1-9], era una letra; una columna con una perforación en la zona de dígitos [0-9] era un dígito; una columna con otras perforaciones concretas diferentes a las indicadas era un carácter especial (por ejemplo: [2]+[8] = ":"; [0]+[3]+[8] = "," ; etc.).


Es decir, tal y como se puede ver en la siguiente figura, la  primera columna, con una perforación en la zona [12] + una perforación en el dígito [1], sería la letra "A"; la segunda columna, con una perforación en la zona [12] + una perforación en el dígito [2], sería la "B"; etc.
Solución: en primer lugar, a partir de la explicación dada anteriormente, soluciono este reto de forma manual, y en un post siguiente lo haré mediante un script de python.
Por tanto, la solución a este reto es: FLAG-B493801CDB-831ABDDFA628AC31.
Viewing all 639 articles
Browse latest View live