[CTF WriteUp] 2020 Competencia de tecnología de ciberseguridad de "nueva infraestructura" para empresas centrales Solución preliminar del problema de cifrado

Cripto

Crypto_ezCrypto

Observe el texto cifrado, que es muy similar a la gramática inglesa después del reemplazo de letras, pero observe que hay un párrafo de .ubwbsjs y la puntuación generalmente está detrás, por lo que significa que el texto cifrado está invertido. En primer lugar, después de lo contrario, intente usar la herramienta de análisis de frecuencia de palabras para decodificar
Inserte la descripción de la imagen aquí

Obviamente, no es humano, pero el cifrado base64 de la bandera se puede confirmar básicamente. Vuelva a ejecutar la codificación base64 Zxmh que está fijada como el carácter de bandera.
Inserte la descripción de la imagen aquí

Después de un período de tiempo, el inglés obtenido básicamente se convirtió en una palabra, y el método utilizado fue ROT, pero notó que las letras mayúsculas son completamente incorrectas en semántica, así que adivine que el valor de las letras mayúsculas ROT es diferente de las letras minúsculas, escriba un programa para explotar:

#!/usr/bin/env python
# coding:utf-8
s = "!=4IJkynJlTaX8g7KvlaK :mokzwof svh tc vqfo bo fsrbi ubwg fsjcz o rfosv T fsjwf ubwaawfp svh mp bkcr rbL .hosvk hgsjfov tc grzswt sfsk hbsasjod svh bcdi grkcfq svh ,hssfhD zchgwfM bkcr ubwyzoH .ubwbsjs sbc hic rsyzok T gL"
s = s[::-1]
# print s
def change(c, a, b):
    dic1 = "abcdefghijklmnopqrstuvwxyz"
    dic2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    if c in dic1:
        return dic1[(dic1.index(c) + a)%26]
    elif c in dic2:
        return dic2[(dic2.index(c) + b)%26]
    else:
        return c

for i in range(26):
    for j in range(26):
        m = ""
        for k in s:
            m += change(k, i, j)
        if m.find("As I walked out one evening")>=0:
            print i, j, m

Descubrí que este es el caso, una ronda de 12 y otra ronda de 15, obtenga el texto cifrado de la bandera: ZmxhZ7s8MmIxYzkwYX4 =, la decodificación falla nuevamente y el éxito es más de la mitad. La parte de decodificación de letras mayúsculas y minúsculas es básicamente correcta, y la parte numérica es incorrecta. Por lo tanto, se supone que esta es una tabla de conversión base64. Los números 0-9 y los signos + / también son ROT. La tabla se confirma mediante experimentos.

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz456789+/0123

Escribe código de resolución de problemas para obtener una bandera

def myb64decode(text):
    dic = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz456789+/0123"
    b = ""
    for i in text:
        if i == "=":
            b += "000000"
        else:
            tmp = bin(dic.index(i))[2:]
            tmp = '0'*(6-len(tmp))+tmp
            b += tmp
    return ''.join(chr(int(b[i:i+8], 2)) for i in range(0, len(b), 8))

print myb64decode("ZmxhZ7s8MmIxYzkwYX4=")

bandera {82b1c90a}

Crypto_LD

(Este título es la pregunta original de GM del Concurso de Innovación Digital China 202004 obtenida modificando los datos) La
pregunta se da N y phi, por lo que puede encontrar pyq a partir de esto. De acuerdo con el código del título, la suma de un resto módulo py un resto módulo q es N-phi-1 = (p-1) + (q-1), y el resto del módulo p es como máximo p-1, y el resto módulo q El máximo es q-1, por lo que hay

pow(q ** 2 * x, (p-1)/2, p) = p - 1
pow(p ** 2 * x, (q-1)/2, q) = q - 1

Según la primera fórmula,

pow(q**2, (p-1)/2, p) * pow(x, (p-1)/2, p) = p-1
pow(q, p-1, p)* pow(x, (p-1)/2, p) = p-1

Según el teorema de Euler, el primer término es 1, por lo que pow (x, (p-1) / 2, p) = p-1. Lo
mismo ocurre con pow (x, (q-1) / 2, q) = q-1 ,F

x % p = pow(p-1, inv((p-1)/2, p), p)
x % q = pow(q-1, inv((q-1)/2, q), q)

De acuerdo con el teorema chino del residuo, podemos encontrar x, y luego intentar resolver cada c para concatenar la bandera final. El código completo de resolución de problemas es el siguiente:

#!/usr/bin/env python
# coding:utf-8
import gmpy2
from libnum import n2s

phi = ...
n = ...
c = [...]

pandq = n - phi + 1
pminq = int(gmpy2.iroot(pandq ** 2 - 4 * n, 2)[0])
p = (pandq + pminq)/2
q = pandq - p
rp = gmpy2.invert((p-1)/2, p)
xmodp = pow(p-1, rp, p)
rq = gmpy2.invert((q-1)/2, q)
xmodq = pow(q-1, rq, q)
x = (xmodp * q * gmpy2.invert(q, p) + xmodq * p * gmpy2.invert(p,q)) % n

def egcd(a,b):
    if b==0:
        return 1,0
    else:
        x,y=egcd(b,a%b)
        return y,x-a/b*y

m = ''
for tmpc in c:
    # Rabin算法,首先计算mp和mq
    mp = pow(tmpc,(p+1)/4,p)
    mq = pow(tmpc,(q+1)/4,q)
    # 然后找到yp和yq,使得 yp*p + yq*q = 1
    yp, yq = egcd(p,q)
    # 根据以下公式计算出四个解,看哪个是正确的
    r0 = ( yp*p*mq + yq*q*mp ) % n
    r1 = n - r0
    s0 = ( yp*p*mq - yq*q*mp ) % n
    s1 = n - s0
    if ((r0**2) % n) - tmpc == 0:
        m += '0'
    else:
        m += '1'
print n2s(int(m,2))

marca {W0w_GRe4t_J0b_oF_Y0U}

Crypto_x0RSA

En esta pregunta, el texto cifrado c se cifra dos veces, se convierte en una cadena y se agrega con el prefijo cifrado, y luego se XOR con la contraseña conocida aurora, y luego XOR con la contraseña desconocida. Dado que se conocen los primeros seis dígitos del texto sin formato y el texto cifrado, los primeros seis dígitos se pueden usar para encontrar la contraseña desconocida, y luego se puede encontrar la c completa. el código se muestra a continuación:

# Step 1: get true c
c2 = "8fb4f15b5cdddde5b4050f96dbecb0030096dee4b00b019dd8e9b7070b96d4eab9040d9ad8efb807089ad5edb002089fdaefb6020c9eddeeb700089dd4efb9030199dce5b7010c97d8ecb4060c96d8efb70a099dd5eeb806089cddefb50b0b9ddaefb7050f9edde5b10b0b9fdcefb20b009cdde4b4030e9bdaedb4040d9cddeeb2000c9bd9e4b6020a9bdde4b8020a9edfecb7000f9fd9e4b5000b9fd4ecb4000c9ad5e9b603089adee9b90a0c98dbe4b0030997dbe5b1030a9fd5e9b5000b99deeab0010a99dcedb3060096d8e4b00a0b9fddebb6010a9cdeeeb5010d9bd5edb20b0b98dde8b7070b9adde8b50a0196ddeeb2030b9dddefb001009fd8eeb30a0997dfe5b5030c99d9ecb502089cd5e9b3020b96dbe4b1050c9adfefb3000c96dfecb003089dd4e8b1070998d5efb3060b9dd9efb5000c9dd8ecb6040a98d8ebb505019dd5efb60b0f98dfe4b907089edceab3000e99d5ebb8010e9ed8efb6060e9dd9e9b60b009bdde9b4050d9fdae9b602099edbe4b40a0d9edfe8b403009dddecb2070f99ddecb00b089fd9e9b60a0896d5edb407089fd4e8b7070c9ad9e9b4000a9dd4e4b8050a9cdde5b0070b9edfe9b4040199d4eab5000896d9e9b8050a9bdce8b60b009dd8efb9010e97dcebb7000999d8eab104009cd4e4b6070d96d9ecb4030c99d8edb3030c9dddeeb5030a9adaefb3010c9fd4edb90a0897dce4b3020b97d5ebb504099edcecb4010a97d5ebb8070c9fdcecb4030c9fd5ebb3040a97dee4b60a0f96daefb400099ddbedb805009fdfebb20b009cdfecb30b019fdfecb007099fdcebb6010f9bd4edb30a0997deeab005009adae5b8040c9bd9eab205009cd4ebb60a0d9cdfe4b906".decode('hex')
rankey = strxor(strxor(c2[:6], "cipher"), "aurora")
c = int(strxor(strxor(c2, rankey), "aurora")[6:])

obtener

c = 1856697110992918824464298787454294159011106271511363128280860862584155594269029395131248226266611808200238931950746057431333545971341991313163605943208153559470152489577910087800309443262712360025994919201672332342449038271564251549891330221212904329083840565141139421297906553223593110128504079225225243524177374646829278673984110723769692714275725478941456406471017959413550921134661118105479199054108564555453328996331814213457868743195496340578924282780663064707938974495150564020521340356222508089180921289647010152389694500150509627382979696253027096903638933128803114000672648029082716956897545736938679433985

Continúe participando en los cálculos posteriores. Junto a lidiar con esa extraña expresión, supongamos

x = e*phi+2*d+2000

Se sabe, donde pyq son 1024 bits, e es 256 bits yd es 2048 bits como máximo, entonces

x = e*(p-1)*(q-1) + 2*d + 2000

Divide ambos lados de la ecuación por n

x/n = e - e/p - e/q + e/n + 2*d/n + 2000/n

Observa la parte entera. Dado que e es mucho más pequeño que p, q, n, la parte entera de x / n está entre eye + 2. Después de verificar el número primo
, podemos encontrar e. Después de encontrar e, continuamos mirando el original fórmula:

x-2000 = e*(p-1)*(q-1) + 2*d

Multiplica ambos lados por e

e*(x-2000) = e*e*(p-1)*(q-1) + 2*e*d
e*(x-2000) = e*e*(p-1)*(q-1) + 2*(a*(p-1)*(q-1)+1)
e*(x-2000)-2 = (e*e+2*a)*(p-1)*(q-1)

Por lo tanto, e * (x-2000) -2 es un múltiplo entero de phi y se puede obtener. sabemos

pow(c, d, n) = pow(pow(m, e, n), d, n) = pow(m, ed, n) = m * pow(m, phi, n) ** a = m

Entonces calcule dd = inv (e, e * (x-2000) -2), hay

pow(m, e*(x-2000)-2, n) = pow(m, phi, n) ** b = 1
pow(c, dd, n) = pow(pow(m, e, n), dd, n) = pow(m, e*dd, n) = m * pow(m, e*(x-2000)-2, n) ** a = m

El código completo de resolución de problemas es el siguiente:

#!/usr/bin/env python
# coding:utf-8
import gmpy2
from libnum import n2s

def strxor(a, b):
    return "".join(chr(ord(a[i])^ord(b[i%len(b)])) for i in range(len(a)))

x = 1267982668072513231452891863043424295599834859100149573631132691595983329470423884239104289369242212251891490867692440047416100533141306836274387621030189535353453497214687975530093393776691837662099778202721802783459072343625657847902483364574074675844370114187041501516164524844560501180602491635032095054050468409668106317972933045713247586266030529732217997511486967953665597945551895583076407217918050242533151323363573068151249311147549761111688506751695988878207998582474739061539806489240491925479395640190191976972656159237635585081329365088001534308652965962150210160485125292710903028061655467118074792803701813091473848960821379158422678252985725282494730999219827545731624223169002
n = 12481674614855685953431310069139262770181111896679332858866368534047537666480569760106869666713999606187655666521091324286510186479595436084367101655509452542502349245680670188096288818989023660590513347753471182289817286176898990883927311061256037550588683828709224481144088322585331288408741487874543701938368655046545540421273512332162617552393131417390793555393898354606731643126500725127350104840163420140767953528301349877632196173183839299220917643489404456656955737164844088165024091907559909967664122295807264526567102312418385269875719242576503849975407146024422857786698109651727438983673071610691953929487

# Step 1: get true c
c2 = "8fb4f15b5cdddde5b4050f96dbecb0030096dee4b00b019dd8e9b7070b96d4eab9040d9ad8efb807089ad5edb002089fdaefb6020c9eddeeb700089dd4efb9030199dce5b7010c97d8ecb4060c96d8efb70a099dd5eeb806089cddefb50b0b9ddaefb7050f9edde5b10b0b9fdcefb20b009cdde4b4030e9bdaedb4040d9cddeeb2000c9bd9e4b6020a9bdde4b8020a9edfecb7000f9fd9e4b5000b9fd4ecb4000c9ad5e9b603089adee9b90a0c98dbe4b0030997dbe5b1030a9fd5e9b5000b99deeab0010a99dcedb3060096d8e4b00a0b9fddebb6010a9cdeeeb5010d9bd5edb20b0b98dde8b7070b9adde8b50a0196ddeeb2030b9dddefb001009fd8eeb30a0997dfe5b5030c99d9ecb502089cd5e9b3020b96dbe4b1050c9adfefb3000c96dfecb003089dd4e8b1070998d5efb3060b9dd9efb5000c9dd8ecb6040a98d8ebb505019dd5efb60b0f98dfe4b907089edceab3000e99d5ebb8010e9ed8efb6060e9dd9e9b60b009bdde9b4050d9fdae9b602099edbe4b40a0d9edfe8b403009dddecb2070f99ddecb00b089fd9e9b60a0896d5edb407089fd4e8b7070c9ad9e9b4000a9dd4e4b8050a9cdde5b0070b9edfe9b4040199d4eab5000896d9e9b8050a9bdce8b60b009dd8efb9010e97dcebb7000999d8eab104009cd4e4b6070d96d9ecb4030c99d8edb3030c9dddeeb5030a9adaefb3010c9fd4edb90a0897dce4b3020b97d5ebb504099edcecb4010a97d5ebb8070c9fdcecb4030c9fd5ebb3040a97dee4b60a0f96daefb400099ddbedb805009fdfebb20b009cdfecb30b019fdfecb007099fdcebb6010f9bd4edb30a0997deeab005009adae5b8040c9bd9eab205009cd4ebb60a0d9cdfe4b906".decode('hex')
rankey = strxor(strxor(c2[:6], "cipher"), "aurora")
c = int(strxor(strxor(c2, rankey), "aurora")[6:])

# Step 2: decrypt
x -= 2000
e = x/n
new = e*x-2
dd = gmpy2.invert(e, new)
print n2s(pow(c, dd, n))

bandera {s1mplE_x0r_uND_rs4}

Supongo que te gusta

Origin blog.csdn.net/cccchhhh6819/article/details/109324871
Recomendado
Clasificación