lunes, 27 de agosto de 2018

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

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 resolví 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}.

sábado, 18 de agosto de 2018

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

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}.

En el siguiente post resolveré este reto de forma manual, es decir, sin utilizar ninguna herramienta para ello.

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

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}.

viernes, 17 de agosto de 2018

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

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.

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

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}".

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

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}.

lunes, 13 de agosto de 2018

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

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 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 OC ON WP PH HC DO GW QM BA IH KQ CO NO JQ ET SF ER EC ON ST RU KQ LA TA 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 OC ON WP PH TO DO GW QM BA IH KQ CO NO JQ ET OD ER EC ON ST RU KQ LA TA SQ AE PQ PW WI BA MN WG RA BD NC TE NE 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" aparece una vez en el criptograma. Haciendo la sustitución correspondiente 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 RI 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

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, "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" y "WX" se cifra como "ZY":

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.

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

- "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.

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

Ejemplo: en nuestro caso, "EN" se cifra como "NG", por lo que todas esas letras están en la misma fila o columna y, salvo que se exceda el borde de la fila o columna de la tabla, se encuentran seguidas y su orden 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" y "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 los 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 AU NC RI PT OG RA MA CI FR AD OC ON EL ME TO DO DE PL AY FA IR CO NO BJ ET OD ER EC ON ST RU IR LA TA BL AE MP LE AD AY PO DE RA SI OB TE NE RE LM EN SA JE 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 la clave es: "WHEATSON".

sábado, 11 de agosto de 2018

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

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 asociados 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): "Reunión secreta".