TwoForOne

https://github.com/Ganapati/RsaCtfTool

kali@kali:~/0.htb/challenges/Crypto/TwoForOne$ RsaCtfTool/RsaCtfTool.py --public "*.pem" --isroca
private argument is not set, the private key will not be displayed, even if recovered.
[-] Details for key2.pem:
[-] Public key key2.pem: is not roca, you are safe
[-] Details for key1.pem:
[-] Public key key1.pem: is not roca, you are safe
kali@kali:~/0.htb/challenges/Crypto/TwoForOne$ 

kali@kali:~/0.htb/challenges/Crypto/TwoForOne$ RsaCtfTool/RsaCtfTool.py --public "*.pem" --dumpkey
private argument is not set, the private key will not be displayed, even if recovered.
Details for key2.pem:
n: 25080356853331150673712092961488349508728123694382279186941974911344272809718201683391687288116618021523872262260746884803456249468108932413753368793568123710905490623939699616018064364038794824072468125668702688048418916712950393799664781694224559810656290997284081084848717062228887604668548576609649709572412523306016494962925450783098637867249337121156908328927249731928363360657779226929980928871118145919627109584218577535657544952661333527174942990937484743860494188129607347202336812042045820577108243818426559386634634103676467773122325120858908782192357380855678371737765634819794619802582481594876770433687
e: 343223
Details for key1.pem:
n: 25080356853331150673712092961488349508728123694382279186941974911344272809718201683391687288116618021523872262260746884803456249468108932413753368793568123710905490623939699616018064364038794824072468125668702688048418916712950393799664781694224559810656290997284081084848717062228887604668548576609649709572412523306016494962925450783098637867249337121156908328927249731928363360657779226929980928871118145919627109584218577535657544952661333527174942990937484743860494188129607347202336812042045820577108243818426559386634634103676467773122325120858908782192357380855678371737765634819794619802582481594876770433687
e: 65537

kali@kali:~/0.htb/challenges/Crypto/TwoForOne$ openssl rsa -pubin -inform PEM -text -noout <key1.pem 
RSA Public-Key: (2048 bit)
Modulus:
    00:c6:ac:b8:df:48:6e:66:71:d4:a5:56:48:03:e1:
    c3:21:4a:8e:27:4d:e0:ac:00:43:ec:28:c8:58:9f:
    37:7c:7e:8d:30:8b:c3:e3:02:85:03:84:34:4b:a7:
    98:88:85:62:0a:41:8e:6a:d9:55:57:82:84:fc:04:
    f2:89:f1:26:b3:8a:01:81:62:51:ce:f9:a1:4f:d4:
    c2:49:d9:6b:69:08:7f:a9:1b:2e:1a:db:dc:80:cb:
    96:ff:0c:cb:61:29:d8:f6:73:7d:a8:50:c4:51:f2:
    ed:3f:6c:b6:1c:36:89:1d:c9:24:d0:ab:28:f2:6a:
    df:0e:d3:57:ce:84:8d:02:ff:e0:09:12:71:4c:cf:
    63:72:c1:f4:10:80:e8:67:47:a0:30:3e:b5:cd:f6:
    ce:91:2f:11:44:fd:4f:55:74:3c:79:68:75:a1:4f:
    df:f8:f8:b6:62:15:0c:56:be:58:b0:92:39:77:1d:
    c4:4d:96:90:79:c4:ad:8f:d9:93:bc:63:0b:78:55:
    d2:e0:2e:8b:e1:68:24:dc:d5:ab:38:13:23:1c:17:
    31:11:0a:8b:d0:28:d7:a1:df:ab:89:2e:75:29:45:
    57:ba:fc:71:ae:af:5e:48:db:02:67:a6:db:63:d3:
    50:f9:95:06:8e:e1:ca:d6:d3:2d:f1:1a:49:bd:24:
    ba:97
Exponent: 65537 (0x10001)
kali@kali:~/0.htb/challenges/Crypto/TwoForOne$ openssl rsa -pubin -inform PEM -text -noout <key2.pem 
RSA Public-Key: (2048 bit)
Modulus:
    00:c6:ac:b8:df:48:6e:66:71:d4:a5:56:48:03:e1:
    c3:21:4a:8e:27:4d:e0:ac:00:43:ec:28:c8:58:9f:
    37:7c:7e:8d:30:8b:c3:e3:02:85:03:84:34:4b:a7:
    98:88:85:62:0a:41:8e:6a:d9:55:57:82:84:fc:04:
    f2:89:f1:26:b3:8a:01:81:62:51:ce:f9:a1:4f:d4:
    c2:49:d9:6b:69:08:7f:a9:1b:2e:1a:db:dc:80:cb:
    96:ff:0c:cb:61:29:d8:f6:73:7d:a8:50:c4:51:f2:
    ed:3f:6c:b6:1c:36:89:1d:c9:24:d0:ab:28:f2:6a:
    df:0e:d3:57:ce:84:8d:02:ff:e0:09:12:71:4c:cf:
    63:72:c1:f4:10:80:e8:67:47:a0:30:3e:b5:cd:f6:
    ce:91:2f:11:44:fd:4f:55:74:3c:79:68:75:a1:4f:
    df:f8:f8:b6:62:15:0c:56:be:58:b0:92:39:77:1d:
    c4:4d:96:90:79:c4:ad:8f:d9:93:bc:63:0b:78:55:
    d2:e0:2e:8b:e1:68:24:dc:d5:ab:38:13:23:1c:17:
    31:11:0a:8b:d0:28:d7:a1:df:ab:89:2e:75:29:45:
    57:ba:fc:71:ae:af:5e:48:db:02:67:a6:db:63:d3:
    50:f9:95:06:8e:e1:ca:d6:d3:2d:f1:1a:49:bd:24:
    ba:97
Exponent: 343223 (0x53cb7)
kali@kali:~/0.htb/challenges/Crypto/TwoForOne$ 

Common Modulus Attack (same n)
https://gist.github.com/ofaurax/6103869014c246f962ab30a513fb5b49
python3 241.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys,gmpy,base64

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

def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        raise Exception('modular inverse does not exist')
    else:
        return x % m

def pad_even(x):
        return ('', '0')[len(x)%2] + x

def CipherB2n(c):
    c = base64.b64decode(c)
    temp = ''
    for i in c:
        temp += pad_even(str(hex(i))[2:])
    temp = eval('0x'+temp)
    return (temp)

def CipherN2b(m):
    hex_m=hex(m)[2:]
    if hex_m[-1] == 'L' :
        hex_m=hex_m[:-1]
    return bytes.fromhex(hex_m).decode('utf-8')

if __name__ == '__main__':
    sys.setrecursionlimit(1000000)
    e1 = 65537 
    e2 = 343223
    s = egcd(e1, e2)
    s1 = s[1]
    s2 = s[2]
    c1 = 'RBVdQw7Pllwb42GDYyRa6ByVOfzRrZHmxBkUPD393zxOcrNRZgfub1mqcrAgX4PAsvAOWptJSHbrHctFm6rJLzhBi/rAsKGboWqPAWYIu49Rt7Sc/5+LE2dvy5zriAKclchv9d+uUJ4/kU/vcpg2qlfTnyor6naBsZQvRze0VCMkPvqWPuE6iL6YEAjZmLWmb+bqO+unTLF4YtM1MkKTtiOEy+Bbd4LxlXIO1KSFVOoGjyLW2pVIgKzotB1/9BwJMKJV14/+MUEiP40ehH0U2zr8BeueeXp6NIZwS/9svmvmVi06Np74EbL+aeB4meaXH22fJU0eyL2FppeyvbVaYQ=='
    c2 ='TSHSOfFBkK/sSE4vWxy00EAnZXrIsBI/Y6mGv466baOsST+qyYXHdPsI33Kr6ovucDjgDw/VvQtsAuGhthLbLVdldt9OWDhK5lbM6e0CuhKSoJntnvCz7GtZvjgPM7JDHQkAU7Pcyall9UEqL+W6ZCkiSQnK+j6QB7ynwCsW1wAmnCM68fY2HaBvd8RP2+rPgWv9grcEBkXf7ewA+sxSw7hahMaW0LYhsMYUggrcKqhofGgl+4UR5pdSiFg4YKUSgdSw1Ic/tug9vfHuLSiiuhrtP38yVzazqOZPXGxG4tQ6btc1helH0cLfw1SCdua1ejyan9l1GLXsAyGOKSFdKw=='
    c1 = CipherB2n(c1)
    c2 = CipherB2n(c2)
    n = 25080356853331150673712092961488349508728123694382279186941974911344272809718201683391687288116618021523872262260746884803456249468108932413753368793568123710905490623939699616018064364038794824072468125668702688048418916712950393799664781694224559810656290997284081084848717062228887604668548576609649709572412523306016494962925450783098637867249337121156908328927249731928363360657779226929980928871118145919627109584218577535657544952661333527174942990937484743860494188129607347202336812042045820577108243818426559386634634103676467773122325120858908782192357380855678371737765634819794619802582481594876770433687 
    if s1<0:
        s1 = - s1
        c1 = modinv(c1, n)
    elif s2<0:
        s2 = - s2
        c2 = modinv(c2, n)
    m=(pow(c1,s1,n)*pow(c2,s2,n)) % n
    print(m)
    print(CipherN2b(m))
kali@kali:~/0.htb/challenges/Crypto/TwoForOne$ python3 241.py 
29754482138600667824873548828684976503132905299031678355938493565
HTB{C0mmon_M0dUlu5S_1S_b4D}
https://github.com/HexPandaa/RSA-Common-Modulus-Attack/blob/master/rsa-cm.py
kali@kali:~/0.htb/challenges/Crypto/TwoForOne$ python3 rsa-cm.py -c1 message1 -c2 message2 -k1 key1.pem -k2 key2.pem
[+] Recovered message:
29754482138600667824873548828684976503132905299031678355938493565
[+] Recovered bytes:
b'HTB{C0mmon_M0dUlu5S_1S_b4D}'
#getflag.py
from Crypto.Util.number import *
from Crypto.PublicKey import RSA
import base64
import gmpy2

with open('key1.pem') as f:
    pk1 = RSA.import_key(f.read())

with open('key2.pem') as f:
    pk2 = RSA.import_key(f.read())

with open('message1') as f:
    c1 = base64.b64decode(f.read())
    c1 = bytes_to_long(c1)

with open('message2') as f:
    c2 = base64.b64decode(f.read())
    c2 = bytes_to_long(c2)

g, a1, a2 = gmpy2.gcdext(pk1.e, pk2.e)
m = pow(c1, a1, pk1.n) * pow(c2, a2, pk2.n) % pk1.n
print(long_to_bytes(m))
#rsa-cm.py
#!/bin/env python3
# -*- coding: utf-8 -*-

__author__ = "HexPandaa"


from Crypto.PublicKey import RSA
from Crypto.Util.number import (
  long_to_bytes,
  bytes_to_long,
  GCD
)
import gmpy2
from base64 import b64decode

import argparse
import sys


def parse_args():
    parser = argparse.ArgumentParser(description="A simple script to perform RSA common modulus attacks.",
                                     epilog="More info at https://github.com/HexPandaa/RSA-Common-Modulus-Attack/")
    parser.add_argument("-c1", type=argparse.FileType("r"), metavar="ciphertext1", required=True,
                        help="The first ciphered message")
    parser.add_argument("-c2", type=argparse.FileType("r"), metavar="ciphertext2", required=True,
                        help="The second ciphered message")
    parser.add_argument("-k1", type=argparse.FileType("rb"), metavar="pubkey1", required=True,
                        help="The first public key")
    parser.add_argument("-k2", type=argparse.FileType("rb"), metavar="pubkey2", required=True,
                        help="The second public key")
    parser.add_argument("-o", type=argparse.FileType("wb"), metavar="outfile", required=False,
                        help="Output file")
    args = parser.parse_args()
    return args


# Source: https://crypto.stackexchange.com/a/60404
def bytes_to_integer(data):
    output = 0
    size = len(data)
    for index in range(size):
        output |= data[index] << (8 * (size - 1 - index))
    return output


def integer_to_bytes(integer, _bytes):
    output = bytearray()
    for byte in range(_bytes):
        output.append((integer >> (8 * (_bytes - 1 - byte))) & 255)
    return output


# Source: https://github.com/ashutosh1206/Crypton/blob/master/RSA-encryption/Attack-Common-Modulus/exploit.py
def egcd(a, b):
    if (a == 0):
        return (b, 0, 1)
    else:
        g, y, x = egcd(b % a, a)
        return (g, x - (b // a) * y, y)


# Calculates a^{b} mod n when b is negative
def neg_pow(a, b, n):
    assert b < 0
    assert GCD(a, n) == 1
    res = int(gmpy2.invert(a, n))
    res = pow(res, b*(-1), n)
    return res


# e1 --> Public Key exponent used to encrypt message m and get ciphertext c1
# e2 --> Public Key exponent used to encrypt message m and get ciphertext c2
# n --> Modulus
# The following attack works only when m^{GCD(e1, e2)} < n
def common_modulus(e1, e2, n, c1, c2):
    g, a, b = egcd(e1, e2)
    if a < 0:
        c1 = neg_pow(c1, a, n)
    else:
        c1 = pow(c1, a, n)
    if b < 0:
        c2 = neg_pow(c2, b, n)
    else:
        c2 = pow(c2, b, n)
    ct = c1*c2 % n
    m = int(gmpy2.iroot(ct, g)[0])
    return m


def main(args):
    pubkey1 = RSA.import_key(args.k1.read())
    pubkey2 = RSA.import_key(args.k2.read())
    c1 = b64decode(args.c1.read())
    c1 = bytes_to_long(c1)
    c2 = b64decode(args.c2.read())
    c2 = bytes_to_long(c2)

    # We first check that the modulus N of both public keys are equal
    if pubkey1.n != pubkey2.n:
        sys.stderr.write("[ERROR] The modulus of both public keys must be the same\n")
        sys.exit(1)
    if GCD(pubkey1.e, pubkey2.e) != 1:
        sys.stderr.write("[ERROR] The greatest common denominator between the exponent of each keys should be 1\n")
        sys.exit(2)
    deciphered_message = common_modulus(
          pubkey1.e,
          pubkey2.e,
          pubkey1.n,
          c1,
          c2
    )
    deciphered_bytes = long_to_bytes(deciphered_message)

    print("[+] Recovered message:")
    print(deciphered_message)
    print("[+] Recovered bytes:")
    print(deciphered_bytes)

    if args.o:
        args.o.write(deciphered_bytes)


if __name__ == '__main__':
    args = parse_args()
    main(args)

Navigation