├── README.md ├── RSA └── __init__.py ├── RSA_Ciphertext.py ├── __init__.py ├── __init__.pyc ├── exploits ├── RSAObject.py ├── RSAObject.pyc ├── __init__.py ├── __init__.pyc ├── common_modulus.py ├── common_modulus.pyc ├── common_modulus_factor.py ├── common_modulus_factor.pyc ├── common_rsa_functions.py ├── common_rsa_functions.pyc ├── factoring.py ├── fermat.py ├── hastad.py ├── simple_CRT.py ├── simple_CRT.pyc ├── wiener.py └── wiener.pyc ├── main.py ├── notes.txt ├── rsa.py ├── rsa.pyc ├── sagetest.py ├── test_files ├── __init__.py ├── __init__.pyc ├── common_factor_test.txt ├── common_moduli_test.txt ├── crt_test.txt ├── projecttest.py └── rsaobjtest.py ├── util.py ├── util.pyc └── utilities └── __init__.py /README.md: -------------------------------------------------------------------------------- 1 | # Project Writeup 2 | ###Overview 3 | Cryptography challenges are popular in Capture the Flag (CTF) competitions and many of them involve exploiting a vulnerability in a poorly implemented RSA cryptosystem. These vulnerabilities make it possible to either factor an RSA modulus in a reasonable amount of time or compute the plaintext message directly. Often the workflow for solving one these RSA problems involves figuring out which vulnerability is present, researching exploits for that vulnerability, and writing a program/script implementing an exploit. Assuming that the vulnerability is not revealed in the problem statement, each of these steps can take a significant amount of time. On top of that there is also the time spent debugging the exploit implementation. 4 | 5 | To help reduce the amount of time spent on each of these steps, we have developed an RSA exploit library for CTF challenges related to RSA cryptosystems. Many commonly known exploits, including Wiener's Attack, Hastad's Broadcast Attack, Common Modulus attack are already implemented for the user. In addition, various prime factorization methods each with their own special use cases are included. If the required exploit is already implemented by our library, the time required to research, code, and debug a solution is significantly reduced. If the RSA vulnerability or required exploit is not immediately known, a user could run a battery of exploits against the provided ciphertexts and RSA key data in an attempt to uncover more information. Moreover, a RSA problem may be vulnerable to more than one attack, which may be unknown to both user and problem author. Thus, the library can also be used to test CTF challenges for correctness, thus reducing the amount time required to implement solution scripts. 6 | 7 | 8 | ###Existing Research/Work 9 | ##### 1. Twenty Years of Attacks on the RSA Cryptosystem 10 | This paper provides a survey of many potential vulnerabilities in the RSA cryptosystem and describes the exploits for each. Among the discussed exploits are common modulus, Wiener's attack, Boneh Durfee attack, Hastad's Broadcast attack, and Franklin-Reiter Related Message attack. We used this paper as a basis for determining which exploits to include in our library. 11 | #####2. https://github.com/pablocelayes/rsa-wiener-attack 12 | Github user pablocelayes has written a collection of python scripts that implement Wiener's 13 | attack on RSA. When the private exponent(d) is less than N^(1/4), Wiener's attack can use continued fraction approximations to recover d. 14 | #####3 https://github.com/mimoo/RSA-and-LLL-attacks 15 | Github user mimoo appears to have written a collection of sage scripts that implement LLL 16 | lattice based attacks on RSA. LLL lattice reduction is an algorithm created by Coppersmith 17 | that can be used for finding roots of polynomial equations. His implementation of Boneh Durfee's attack is included in our library. 18 | #####4 http://ahack.ru/write-ups/ructf-quals-14.htm 19 | User Black Fan provided an implementation of the Franklin-Reiter Related Message attack that we modified to be more general. 20 | #####5 https://github.com/rk700/attackrsa/tree/master/attackrsa 21 | Github user rk700 has written implementations for both Hastad's Broadcast attack and the Fermat factorization method. Our library's implementations of both exploits were derived from his work. 22 | 23 | ###Approach and Implementation 24 | ##### Introduction 25 | During our research, we were unable to find a single library or tool that presented RSA exploits in coherent and easy to use fashion. We did find many implementations of RSA exploits that various CTF competitors around the world had posted in their writeups. However, many of them were coded in such a way that they were specific to the problem being solved and could not be applied to other problems. The implementations that were coded to be general often required different sets of parameters and it was unlikely that implementations for two different exploits would provide a common interface. To solve these issues, we decided to develop a library that provided both general implementations of various exploits for RSA vulnerabilities and a uniform interface through which these exploits could be run. 26 | 27 | ##### Architecture 28 | We implemented a class called RSAData to store all of the information associated with a particular RSA challenge, i.e. ciphertext plaintext pair and the RSA key elements used to manipulate that text data. At the moment, RSAData is implemented as a combination of the RSAObj class from pycrypto and a simple TextData class that we implemented ourselves. The RSAObj class is used to store and create all of the RSA key elements. This includes the modulus N, public exponent e, private exponent d, and primes p and q. We leveraged RSAObj's preexisting functionality for encryption and decryption. The TextData class stores the ciphertext, plaintext, and an ID number. Some of the exploits in our library only work if all ciphertexts were generated from the same plaintext. TextData objects with the same ID number contain ciphertexts that were generated from the same plaintext. The ID number field must be set by the user. 29 | 30 | Each exploit is implemented as a class that extends a base Exploit class. The base Exploit class only exports one method called run that takes two parameters. The first parameter is a list of RSAData objects and the second is a dictionary that can be used to specify additional information for particular exploits. For example, the Franklin-Reiter exploit requires a polynomial that specifies the relationship between two plaintext messages that were used to generate known ciphertexts. The presence of the run method provides a common interface that a user can use to call any exploit after the list of RSAData objects has been populated. Extracting the required information from the RSAData objects is handled by the run function and any subroutines called from there. 31 | 32 | ##### Usage 33 | We envision the common workflow as follows, first, the user will initialize a list of RSAData objects using information from the problem. Initializing an RSAData object reqires first initializing an RSAObj and a TextData object. The RSAObj should be initialized using our rsa_obj function which is actually a wrapper for pycrypto's construct function. The parameters to this function are as follows: 34 | 35 | ``` 36 | n: RSA modulus 37 | e: public exponent 38 | d: private exponent 39 | p: first prime factor 40 | q: second prime factor 41 | ``` 42 | All of the above parameters are long type. 43 | 44 | n and e are required parameters while the others are optional. We expect that in most CTF problems, the user will only provide n and e. 45 | 46 | The parameters to the TextData initializer are as follows: 47 | ``` 48 | c: ciphertext 49 | m: plaintext 50 | idnum: ID number identifies plaintext, two TextData object containing cipertext corresponding to same plaintext, have same idnum. 51 | ``` 52 | All of the above parameters have an integer type (they don't have to be explicitly declared as long type). 53 | 54 | None of these parameters are required and even the TextData object itself is an optional parameter in the RSAData init function. However, many exploits require ciphertexts, so the user needs to specify c and idnum in those cases. 55 | 56 | An example of initializing a RSAData object is shown below: 57 | ``` 58 | import RSAExploits 59 | 60 | n = #value 61 | e = #value 62 | c = #value 63 | idnum = #value 64 | 65 | rsaobj = RSAObj(n, e) 66 | txt = TextData(c_text=c, idnum=idnum) 67 | rsadata = RSAData(rsaobj, txt) 68 | ``` 69 | 70 | After the users have initialized a list of RSAData objects, they have two options. They can, either run a predefined list of exploits against their RSAData objects, or they can specify the desired exploit manually by instantiating a class for that exploit and invoking its run method. Examples of both scenarios are shown below: 71 | 72 | ``` 73 | # Run a predefined list of exploits 74 | rsadata_list = [] # Assume this list has already been populated 75 | rsa_cracker.init() 76 | rsa_cracker.attack(rsadata_list) 77 | ``` 78 | 79 | ``` 80 | # Specify an exploit to run 81 | rsadata_list = [] # Assume this list has already been populated 82 | exploit = Common_Modulus() 83 | exploit.run(rsadata_list) 84 | ``` 85 | 86 | The run function in each exploit attemptS to uncover missing information in each RSAData object in the provided list. For all of the currently implemented exploits, this means either recovering d,p, and q (private exponent and prime factors) or the plaintext message m. Any recovered information is updated in the corresponding RSAData object. If a run function is able to uncover any information in any of the RSAData objects, it returns True. Otherwise, it returns False. If a run function returns True, most CTF players would then want to know what the recovered flag is. Often, this flag is a string. If the successful exploit recovered the private exponent d, the user would first need to decrypt the ciphertext before attempting to print the message. If the successful exploit recovered the message, the user would just need to convert the plaintext from an integer form to ASCII. Examples of both scenarios are shown below: 87 | 88 | ``` 89 | # Exploit recovered the private exponent d 90 | rsadata.decrypt() 91 | print num2string(rsadata.get_m()) 92 | ``` 93 | 94 | ``` 95 | # Exploit recovered the private exponent d 96 | print num2string(rsadata.get_m()) 97 | ``` 98 | 99 | num2string is a function included when the user imports RSAExploits and it converts an integer to its hex representation and then interprets it as ASCII. 100 | 101 | Some of the exploits require extra information that did not fit cleanly into the RSAData object. To handle these special cases, a second optional parameter is accepted by each exploit's run() function. This parameter is a dictionary containing key-value pairs where the key is a string that is equivalent to the name of an exploit class and the value is the extra information required. For example, the Franklin-Reiter exploit requires a polynomial that describes the relationship between two plaintext messages that produced two known ciphertexts. The documentation for individual exploits should be checked to see if they require any extra information. An example usage of the dictionary is shown below: 102 | 103 | ``` 104 | from sage.all_cmdline import * 105 | rsadata_list = [] # Assume this list has been populated 106 | n = some_value 107 | x = PolynomialRing(ZZ.quo(n*ZZ), 'x').gen() 108 | poly = x - 5 109 | info_dict = {} 110 | info_dict["Franklin_Reiter"] = poly 111 | Franklin_Reiter().run(rsadata_list, info_dict) 112 | ``` 113 | 114 | ##### Exploits 115 | At the moment the following exploits/factorization methods are available: 116 | * Boneh Durfee attack on low private exponents 117 | * Common Modulus 118 | * Common Factor (common prime factors in moduli) 119 | * ECM Factorization (special condition: one of the primes should be much smaller) 120 | * Fermat Factorization (special condition: p and q are very close together) 121 | * Franklin-Reiter Related Message attack (special condition: relation between messages) 122 | * Hastad's Broadcast attack (special condition: number of RSAData should be greater than or equal to e) 123 | * Quadratic Sieve Factorization (2nd fastest general purpose factoring algorithm) 124 | * Wiener's attack (special condition: low private exponent) 125 | 126 | ##### Expansion 127 | Adding new exploits to our module is pretty straightforward. A new .py file should be created and placed in the exploits folder, that declares a new class extending Exploit. This new class must implement a run function that applies the exploit to a list of RSAData objects, and optionally uses the dictionary to receive extra information. 128 | 129 | ##### Sage 130 | Some of the included exploits in the library require sage to run. For example Franklin_Reiter relies on Sage's ability to handle polynomials. However, Sage is not required to use our library. If the user attempts to run any exploits that require Sage, an error message will be printed. Exploits that do not require Sage will run just fine. 131 | 132 | ##### Installation 133 | From command line run the following: 134 | ``` 135 | sudo apt-get update 136 | git clone https://github.com/vik001ind/RSAExploits.git 137 | sudo pip install RSAExploits/ 138 | 139 | # If sage is installed, run the following commands as well 140 | cd RSAExploits/ 141 | sudo sage -python setup.py install 142 | ``` 143 | 144 | ##### Pylint 145 | At the moment we are ignoring any errors concerning variable names or imports from sage. We know that the error messages about imports from sage are not correct and we feel that many of the variable names (eg: N, e, d) are named appropriately given the context of RSA. 146 | 147 | ###CTF Problem examples: 148 | 149 | ####CTF Problem: Hack You 2014 - CRYPTONET: 150 | We have intercepted communication in a private network. It uses a strange protocol based on RSA cryptosystem. 151 | Can you still prove that it is not secure enough and get the flag? 152 | 153 | Analysis of server RSA implementation and capture file: 154 | * Integer encoded plain-text message is less than modulus 155 | * Public exponent(e) remains constant (17), but modulus(N) varies 156 | * 19 ciphertexts are captured 157 | 158 | This cryptosystem is vulnerable to Hastad's Broadcast Attack. Hastad's attack uses the Chinese Remainder Theorem to recover the plaintext message given a list of ciphertexts, moduli, and the public exponent e. It is guaranteed to succeed if the same plaintext message was used to generate all ciphertexts, the public exponent e is the same in all encryptions, the number of ciphertexts is greater than or equal to e, all of the moduli are greater than the plaintext, all of the moduli are unique, and all of the moduli are coprime (if they are not coprime then they share a common factor and another exploit can be used). Ideally, a user needs to extract the ciphertexts, moduli, and public exponent from the packet capture file and provide that information to our library. Our library would run through a list of exploits that includes Hastad's attack and would recover the plaintext. If the user realizes that the correct exploit is Hastad's attack, they could specify the correct exploit and not have to wait for all of the other exploits to finish executing. The corresponding script might resemble the following: 159 | 160 | ``` 161 | from RSAExploits import rsa_cracker 162 | from RSAExploits import RSAData 163 | from RSAExploits import rsa_obj 164 | from RSAExploits import TextData 165 | from RSAExploits import num2string 166 | from RSAExploits import Hastad 167 | import sys 168 | 169 | sys.setrecursionlimit(10000) 170 | 171 | # Parse and store all of the ciphertexts provided by the file 172 | rsadata_list = [] 173 | c = None 174 | e = None 175 | N = None 176 | f = open("hastadlist.txt", 'r') 177 | for line in f: 178 | if line.startswith("e"): 179 | e = long(line.split(" ")[2]) 180 | elif line.startswith("n"): 181 | N = long(line.split(" ")[2], 0) 182 | elif line.startswith("ciphertext"): 183 | c = long(line.split(" ")[2], 0) 184 | rsadata_list.append(RSAData(rsa_obj(N, e), TextData(c, 1))) 185 | f.close() 186 | 187 | # Library specific call 188 | # Run the exploit by specifying it 189 | if Hastad().run(rsadata_list): 190 | print num2string(rsadata_list[0].get_m()) 191 | ``` 192 | 193 | 194 | ####CTF Problem: Hack.lu 2014 - Wiener: 195 | It’s gold rush time! The New York Herald just reported about the Californian gold rush. We know a sheriff there is hiring guys to help him fill his own pockets. We know he already has a dreadful amount of gold in his secret vault. However, it is protected by a secret only he knows. When new deputies apply for the job, they get their own secret, but that only provies entry to a vault of all deputy sheriffs. No idiot would store their stuff in this vault. But maybe we can find a way to gain access to the sheriff’s vault? Have a go at it: 196 | nc wildwildweb.fluxfingers.net 1426 197 | 198 | Analysis of server RSA implementation: 199 | * Public key is accessible through server 200 | * The size of the private exponent(d) in bits is around 1/5 of the modulus 201 | 202 | The name of the problem gives it away, but this cryptosystem is vulnerable to Wiener's Attack. Wiener's attack is able to recover the private exponent d when d < N^(1/4). Once again, our library could be used to reduce the amount of time needed to write a script that uses Wiener's attack to recover the private key and decrypt the message. The script that the user has to write might resemble the following: 203 | 204 | ``` 205 | from RSAExploits import rsa_cracker 206 | from RSAExploits import RSAData 207 | from RSAExploits import rsa_obj 208 | from RSAExploits import TextData 209 | from RSAExploits import num2string 210 | from RSAExploits import Wiener 211 | import sys 212 | 213 | sys.setrecursionlimit(10000) 214 | 215 | # Parse and store all of the ciphertexts provided by the file 216 | rsadata_list = [] 217 | rsadata_list.append(RSAData(rsa_obj(n, e))) # Assume n and e have been initialized 218 | if Wiener().run(rsadata_list): 219 | print (rsadata_list[0].get_d()) 220 | ``` 221 | 222 | 223 | ####CTF Problem: PicoCTF 2014 - RSA Mistakes: 224 | Daedalus Corp seems to have had a very weird way of broadcasting some secret data. We managed to find the server code that broadcasted it, and one of our routers caught some of their traffic - can you find the secret data? We think someone may have requested the secret using someone else's user id by accident, but we're not sure. 225 | 226 | Analysis of server RSA implementation and capture file: 227 | * All messages are encrypted using a public exponent of 3 228 | * Two messages have been encrypted using the same public key (N,e) 229 | * Those 2 messages are related by a known polynomial 230 | 231 | This problem is vulnerable to the Franklin-Reiter Related Message attack. When two messages differ by a known amount and are encrypted using the same public key, then we compute the message directly. However, the Franklin-Reiter attack will only terminate in a reasonable amount of time if the public exponent e is small. Lucky for us, that is the case. So, a user of our library should only have to provide the modulus, public exponent, two ciphertexts, and a polynomial representing the relationship of the two plaintext messages used to generate the ciphertexts. The rest of the work would be taken care of by the pre-implemented Franklin-Reiter exploit. The resulting script might resemble the following: 232 | 233 | ``` 234 | from sage.all_cmdline import * 235 | from RSAExploits import rsa_cracker 236 | from RSAExploits import RSAData 237 | from RSAExploits import rsa_obj 238 | from RSAExploits import TextData 239 | from RSAExploits import num2string 240 | from RSAExploits import mod_inv 241 | from RSAExploits import Franklin_Reiter 242 | import sys 243 | 244 | sys.setrecursionlimit(10000) 245 | 246 | # Assume N, e, c1, c2, a, and b have been initialized 247 | 248 | info_dict = {} 249 | rsadata_list = [] 250 | rsadata_list.append(RSAData(rsa_obj(long(N), long(e)), TextData(c1))) 251 | rsadata_list.append(RSAData(rsa_obj(long(N), long(e)), TextData(c2))) 252 | 253 | x = PolynomialRing(ZZ.quo(N*ZZ), 'x').gen() 254 | poly = a*x + b 255 | info_dict["Franklin_Reiter"] = poly 256 | 257 | # Run exploit 258 | if Franklin_Reiter().run(rsadata_list, info_dict): 259 | plaintext = rsadata_list[0].get_m() 260 | print num2string(plaintext) 261 | 262 | ``` 263 | 264 | The actual full script that solves RSA Mistakes would be a little more involved. The plaintext messages are transformed before they are encrypted resulting in a few more steps at the end. 265 | 266 | 267 | ### Future Work 268 | There are still many RSA exploits that have yet to be implemented/added to our library. Among these are Coppersmith's Short Pad attack, Partial Key Exposure attacks, and Hastad's generalized broadcast attack. Future work could involve implementing these new exploits, improving code quality of the library, improving code efficiency, and improving usability. 269 | -------------------------------------------------------------------------------- /RSA/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eazebu/RSAExploits/dd6da21fa052744945d73e6166e7adf8cde9086b/RSA/__init__.py -------------------------------------------------------------------------------- /RSA_Ciphertext.py: -------------------------------------------------------------------------------- 1 | from Crypto.PublicKey import RSA 2 | from rsa import set_RSAobj 3 | 4 | class RSA_Ciphertext: 5 | def __init__(self, c, n, e, d=None, p=None, q=None): 6 | self.c = c 7 | if c != None and n != None and e != None and d == None and p == None and q == None: 8 | self.rsa = set_RSAobj(n, e) 9 | elif c != None and n != None and e != None and d != None and p == None and q == None: 10 | self.rsa = set_RSAobj(n, e, d) 11 | elif c != None and n != None and e != None and d != None and p != None and q == None: 12 | self.rsa = set_RSAobj(n, e, d, p) 13 | elif c != None and n != None and e != None and d != None and p != None and q != None: 14 | self.rsa = set_RSAobj(n, e, d, p, q) 15 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | import exploits 2 | -------------------------------------------------------------------------------- /__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eazebu/RSAExploits/dd6da21fa052744945d73e6166e7adf8cde9086b/__init__.pyc -------------------------------------------------------------------------------- /exploits/RSAObject.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import sys 3 | 4 | CIPHERTEXT = 0 5 | EXPONENT = 1 6 | MODULUS = 2 7 | 8 | 9 | class RSAObject: 10 | def __init__(self, ciphertext_file, identical_messages): 11 | 12 | self.ciphertexts = [] 13 | self.identical_messages = identical_messages 14 | 15 | # Parse and store all of the ciphertexts provided by the file 16 | ciphertext = None 17 | c = 0 18 | e = 0 19 | N = 0 20 | f = open(ciphertext_file, 'r') 21 | for line in f: 22 | if line.startswith("ciphertext"): 23 | c = int(line.split(" ")[2], 0) 24 | elif line.startswith("e"): 25 | e = int(line.split(" ")[2]) 26 | elif line.startswith("N"): 27 | N = int(line.split(" ")[2], 0) 28 | ciphertext = (c, e, N) 29 | self.ciphertexts.append(ciphertext) 30 | f.close() 31 | 32 | @staticmethod 33 | def get_ciphertext(ciphertext): 34 | return ciphertext[CIPHERTEXT] 35 | 36 | @staticmethod 37 | def get_exponent(ciphertext): 38 | return ciphertext[EXPONENT] 39 | 40 | @staticmethod 41 | def get_modulus(ciphertext): 42 | return ciphertext[MODULUS] 43 | 44 | -------------------------------------------------------------------------------- /exploits/RSAObject.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eazebu/RSAExploits/dd6da21fa052744945d73e6166e7adf8cde9086b/exploits/RSAObject.pyc -------------------------------------------------------------------------------- /exploits/__init__.py: -------------------------------------------------------------------------------- 1 | import RSAObject 2 | import common_modulus 3 | -------------------------------------------------------------------------------- /exploits/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eazebu/RSAExploits/dd6da21fa052744945d73e6166e7adf8cde9086b/exploits/__init__.pyc -------------------------------------------------------------------------------- /exploits/common_modulus.py: -------------------------------------------------------------------------------- 1 | from fractions import gcd 2 | from common_rsa_functions import egcd as egcd 3 | from common_rsa_functions import modinv as modinv 4 | from RSAObject import RSAObject 5 | 6 | # Create a dictionary of ciphertexts keyed by the modulus 7 | # used to encrypt them 8 | def group_ciphertexts_by_moduli(ciphertexts): 9 | 10 | modulus_dictionary = {} 11 | 12 | for ciphertext in ciphertexts: 13 | if ciphertext.rsa.n in modulus_dictionary: 14 | modulus_dictionary[ciphertext.rsa.n].append(ciphertext) 15 | else: 16 | modulus_dictionary[ciphertext.rsa.n] = [ciphertext] 17 | 18 | return modulus_dictionary 19 | 20 | # Returns True if n1 and n2 are coprime and False otherwise 21 | def coprime(n1, n2): 22 | return gcd(n1, n2) == 1 23 | 24 | 25 | # Attempt to decrypt a ciphertext using the common modulus exploit 26 | def common_modulus_exploit(ciphertext1, ciphertext2): 27 | 28 | if ciphertext1.rsa.n != ciphertext2.rsa.n: 29 | return None 30 | if not coprime(ciphertext1.rsa.e, ciphertext2.rsa.e): 31 | return None 32 | 33 | N = ciphertext2.rsa.n 34 | c1 = ciphertext1.c 35 | c2 = ciphertext2.c 36 | 37 | # Because gcd(e1, e2) = 1, we know that there must exist two integers 38 | # X, Y such that Xe1 + Ye2 = 1. The values of X and Y can be computed 39 | # using the Extended Euclidean algorithm 40 | g,x,y = egcd(ciphertext1.rsa.e, ciphertext2.rsa.e) 41 | 42 | # If either x or y is negative, we need to compute the multiplicative 43 | # modular inverse of the corresponding ciphertext and negate x/y. 44 | # c1 ^ -a = c1* ^ a where c1* is the multiplicative modular inverse of c1. 45 | if x < 0: 46 | x = -x 47 | c1 = modinv(c1, N) 48 | 49 | if y < 0: 50 | y = -y 51 | c2 = modinv(c2, N) 52 | 53 | # Compute (c1^ x * c2 ^ y) mod N 54 | plaintext = (pow(c1, x, N) * pow(c2, y, N)) % N 55 | 56 | return plaintext 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /exploits/common_modulus.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eazebu/RSAExploits/dd6da21fa052744945d73e6166e7adf8cde9086b/exploits/common_modulus.pyc -------------------------------------------------------------------------------- /exploits/common_modulus_factor.py: -------------------------------------------------------------------------------- 1 | from common_rsa_functions import egcd as egcd 2 | from common_rsa_functions import modinv as modinv 3 | from RSAObject import RSAObject 4 | from fractions import gcd 5 | from sage.all_cmdline import * 6 | from RSAExploits.RSA_Ciphertext import * 7 | 8 | # Check if the moduli used to encrypt 2 ciphertexts have a common factor 9 | # If so, this function will attempt to recover the private exponent 10 | # used for decryption. Returns a list of ciphertexts that can now be 11 | # decrypted. 12 | def common_factor(c1, c2): 13 | 14 | decryptable = [] 15 | p = long(gcd(c1.rsa.n, c2.rsa.n)) 16 | if p == 1: 17 | return decryptable 18 | q1 = long(c1.rsa.n / p) 19 | q2 = long(c2.rsa.n / p) 20 | 21 | if p in Primes() and q1 in Primes(): 22 | totient = (p- 1) * (q1 - 1) 23 | d = long(modinv(c1.rsa.e, totient)) 24 | c1.rsa.p = p 25 | c1.rsa.q = q1 26 | c1 = RSA_Ciphertext(c1.c, c1.rsa.n, c1.rsa.e, d, p, q1) 27 | decryptable.append(c1) 28 | 29 | if p in Primes() and q2 in Primes(): 30 | totient = (p- 1) * (q2 - 1) 31 | d = long(modinv(c2.rsa.e, totient)) 32 | c2.rsa.p = p 33 | c2.rsa.q = q2 34 | c2 = RSA_Ciphertext(c2.c, c2.rsa.n, c2.rsa.e, d, p, q2) 35 | decryptable.append(c2) 36 | 37 | return decryptable 38 | 39 | -------------------------------------------------------------------------------- /exploits/common_modulus_factor.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eazebu/RSAExploits/dd6da21fa052744945d73e6166e7adf8cde9086b/exploits/common_modulus_factor.pyc -------------------------------------------------------------------------------- /exploits/common_rsa_functions.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Extended Euclidean algorithm 4 | def egcd(a, b): 5 | if a == 0: 6 | return (b, 0, 1) 7 | else: 8 | g, y, x = egcd(b % a, a) 9 | return (g, x - (b // a) * y, y) 10 | 11 | # Returns the modular multiplicative inverse of (a mod m) 12 | def modinv(a, m): 13 | g, x, y = egcd(a, m) 14 | if g != 1: 15 | raise Exception('modular inverse does not exist') 16 | else: 17 | return x % m 18 | -------------------------------------------------------------------------------- /exploits/common_rsa_functions.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eazebu/RSAExploits/dd6da21fa052744945d73e6166e7adf8cde9086b/exploits/common_rsa_functions.pyc -------------------------------------------------------------------------------- /exploits/factoring.py: -------------------------------------------------------------------------------- 1 | #http://www.sagemath.org/doc/thematic_tutorials/explicit_methods_in_number_theory/integer_factorization.html 2 | 3 | 4 | from sage.all_cmdline import * 5 | from Crypto.Util.number import * 6 | 7 | 8 | # works when one prime factor is much smaller (20-30 digits) 9 | def _ecm(l): 10 | print "Factoring using ECM:" 11 | print ecm.factor(l) 12 | ''' 13 | #example: 14 | k = getStrongPrime(512) 15 | r = next_prime(2**70); 16 | l = k*r 17 | result = ecm.factor(l); 18 | print result 19 | ''' 20 | 21 | # works for prime factors of around 130 bits 22 | def _qsieve(l): 23 | print "Factoring using Quadratic Sieve:" 24 | print qsieve(l) 25 | 26 | ''' 27 | example 28 | sage: p = next_prime(2^128) 29 | sage: q = next_prime(2^130) 30 | sage: n = p*q 31 | sage: %time qsieve(n) 32 | ''' 33 | -------------------------------------------------------------------------------- /exploits/fermat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from sympy import integer_nthroot 4 | 5 | 6 | def execute(key): 7 | limit=10000 8 | a, exact = integer_nthroot(key.n, 2) 9 | max = a + limit 10 | while a < max: 11 | b2 = a*a - key.n 12 | if b2 >= 0: 13 | b, exact = integer_nthroot(b2,2) 14 | if b*b == b2: 15 | break 16 | a += 1 17 | if a < max: 18 | p = a+b 19 | q = a-b 20 | return True, p, q 21 | else: 22 | return False 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /exploits/hastad.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | #import gmpy 4 | 5 | from RSAExploits import util 6 | 7 | def execute(keys, cs): 8 | ''' 9 | ns: array of n 10 | e: public exponent 11 | cs: array of cipher text 12 | ''' 13 | ns = [] 14 | for key in keys: 15 | ns.append(key.n) 16 | e = keys[0].e 17 | return decrypt(ns,cs,e) 18 | 19 | def decrypt(ns,cs,e): 20 | s = util.CRT(ns, cs) 21 | pt = util.int_nthroot(s, e) 22 | if pt is not None: 23 | return pt 24 | else: 25 | print "Cannot find %dth root of %s" % (e, hex(s)) 26 | return None 27 | 28 | 29 | -------------------------------------------------------------------------------- /exploits/simple_CRT.py: -------------------------------------------------------------------------------- 1 | from fractions import gcd 2 | from common_rsa_functions import egcd as egcd 3 | from common_rsa_functions import modinv as modinv 4 | from RSAObject import RSAObject 5 | 6 | # Find the kth root of n 7 | def iroot(k, n): 8 | u, s = n, n+1 9 | while u < s: 10 | s = u 11 | t = (k-1) * s + n // pow(s, k-1) 12 | u = t // k 13 | return s 14 | 15 | 16 | def chinese_remainder_theorem(ciphertexts): 17 | """Solve the chinese remainder theorem 18 | 19 | Given a list of items (a_i, n_i) solve for x such that x = a_i (mod n_i) 20 | such that 0 <= x < product(n_i) 21 | 22 | Assumes that n_i are pairwise co-prime. 23 | """ 24 | 25 | # Determine N, the product of all n_i 26 | N = 1 27 | for ciphertext in ciphertexts: 28 | N *= RSAObject.get_modulus(ciphertext) 29 | 30 | # Find the solution (mod N) 31 | result = 0 32 | for ciphertext in ciphertexts: 33 | n = RSAObject.get_modulus(ciphertext) 34 | a = RSAObject.get_ciphertext(ciphertext) 35 | m = N//n 36 | d, s, r = egcd(m, n) 37 | if d != 1: 38 | raise "Input not pairwise co-prime" 39 | result += a*s*m 40 | 41 | # Make sure we return the canonical solution. 42 | return result % N 43 | 44 | 45 | # Check for the presence of Chinese Remainder Theorem exploit within the ciphertexts 46 | def attack(rsa_object): 47 | exponent_dictionary = {} 48 | print "Simple CRT Test" 49 | if not rsa_object.identical_messages: 50 | print "Exiting because not all ciphertexts were generated from the same message" 51 | print "------------------------------------------------------------------------" 52 | return 53 | 54 | for ciphertext in rsa_object.ciphertexts: 55 | if RSAObject.get_exponent(ciphertext) in exponent_dictionary: 56 | exponent_dictionary[RSAObject.get_exponent(ciphertext)].append(ciphertext) 57 | else: 58 | exponent_dictionary[RSAObject.get_exponent(ciphertext)] = [ciphertext] 59 | 60 | for key in exponent_dictionary: 61 | if len(exponent_dictionary[key]) > 1: 62 | print "Common Exponents Found" 63 | break 64 | else: 65 | print "No Common Exponents Found" 66 | for key in exponent_dictionary: 67 | if len(exponent_dictionary[key]) > 1: 68 | CRT_exploit(exponent_dictionary[key]) 69 | 70 | # Assumes that all moduli in the provided list are relatively prime 71 | def CRT_exploit(ciphertexts): 72 | 73 | num_texts = len(ciphertexts) 74 | exponent = RSAObject.get_exponent(ciphertexts[0]) 75 | print str(num_texts) + " ciphertexts are using public exponent: " + str(exponent) 76 | 77 | result = chinese_remainder_theorem(ciphertexts) 78 | print "Attempt to recover plaintext: " + str(hex(iroot(exponent,result))) 79 | 80 | 81 | -------------------------------------------------------------------------------- /exploits/simple_CRT.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eazebu/RSAExploits/dd6da21fa052744945d73e6166e7adf8cde9086b/exploits/simple_CRT.pyc -------------------------------------------------------------------------------- /exploits/wiener.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import re 4 | import math 5 | from sympy.solvers import solve 6 | from sympy.core.numbers import Integer 7 | from sympy import * 8 | from sympy import invert 9 | from fractions import gcd 10 | from Exploit import Exploit 11 | from RSAExploits.util import modInv 12 | 13 | class wiener(Exploit): 14 | roots = [] 15 | rsadataset = [] 16 | found = None 17 | n = None; e = None; d = None; p = None; q = None; psi = None; 18 | def run(self, rsadata): 19 | print ("Wiener: Running Attack...") 20 | 21 | if type (rsadata) is not list: 22 | self.rsadataset.append(rsadata) 23 | else: 24 | self.rsadataset = list(rsadata) 25 | 26 | for rdata in self.rsadataset: 27 | self.n = rdata.rsaobj.n 28 | self.e = rdata.rsaobj.e 29 | self.roots = self.execute(self.n,self.e) 30 | if self.roots != None: 31 | self.p, self.q = self.roots 32 | rdata.rsaobj.p = self.p 33 | rdata.rsaobj.q = self.q 34 | self.psi = (self.p-1)*(self.q-1) 35 | self.d = modInv(self.e, self.psi) 36 | rdata.rsaobj.d = long(int(self.d)) 37 | rdata.setD(rdata.rsaobj.d) 38 | if rdata.txt.c != None: 39 | rdata.decrypt() 40 | self.found = 1 41 | self.n = None; self.e = None; self.d = None; self.p = None; self.q = None; self.psi = None; 42 | if self.found != None: 43 | print("Wiener: Success, roots found, assigned in rsadata.") 44 | return True 45 | else: 46 | print("Wiener: Failure, roots not found.") 47 | return False 48 | 49 | 50 | def check(self, rsadata): 51 | print ("Wiener: Checking Attack...") 52 | if self.execute(rsadata.rsaobj.n, rsadata.rsaobj.e) != None: 53 | return True 54 | else: 55 | return False 56 | 57 | @staticmethod 58 | def conFraction(fraction): 59 | (a,b) = fraction 60 | v=[] 61 | v.append(0) 62 | while not a == 1: 63 | (x,y) = fraction 64 | try: 65 | r = y / x 66 | a = y % x 67 | except ZeroDivisionError as details: 68 | print ("Exception occured:",details) 69 | print("Continuing to next RSA data...") 70 | return None 71 | b=x 72 | fraction = (a,b) 73 | v.append(r) 74 | v.append(b) 75 | return v 76 | 77 | @staticmethod 78 | def makeIndexedConvergent(sequence, index): 79 | (a,b)=(1,sequence[index]) 80 | while index>0: 81 | index-=1 82 | (a,b)=(b,sequence[index]*b+a) 83 | return (b,a) 84 | 85 | @staticmethod 86 | def makeConvergents(sequence): 87 | r=[] 88 | for i in xrange(0,len(sequence)): 89 | r.append(wiener.makeIndexedConvergent(sequence,i)) 90 | return r 91 | 92 | @staticmethod 93 | def execute(N,e): 94 | v = wiener.conFraction((e,N)) 95 | if v is None: 96 | return None 97 | conv = wiener.makeConvergents(v) 98 | for frac in conv: 99 | (k,d)=frac 100 | if k == 0: 101 | continue 102 | phiN=((e*d)-1)/k 103 | if ((pow(N-phiN+1, 2) - 4*N) <= 0 ): # (b^2 -4ac) <= 0 104 | continue 105 | # solving equation (a**2 + b*x + c) 106 | x = Symbol('x', integer=True) 107 | roots = [] 108 | roots = solve(x**2 -(N-phiN+1)*x + N, x, rational=False) 109 | 110 | if len(roots) == 2: 111 | if type(roots[0]) is Integer and type(roots[0]) is Integer: 112 | 113 | if(roots[0]*roots[1] == N): 114 | return roots 115 | 116 | 117 | -------------------------------------------------------------------------------- /exploits/wiener.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eazebu/RSAExploits/dd6da21fa052744945d73e6166e7adf8cde9086b/exploits/wiener.pyc -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import subprocess 3 | 4 | attackList = {'wiener':('Ne','pq'), 5 | 'fermat':('N','pq'), 6 | 'hastad':('NC','P'), 7 | 'coppersmith':('NE','pq')} 8 | 9 | sageList = ['coppersmith','factoring'] 10 | 11 | def execute(attack, rsadata, extras=None): 12 | if attack not in attackList: 13 | print "Attack exploit not present." 14 | sys.exit(1) 15 | if attack in sageList: 16 | script_locals = dict() 17 | execfile("RSAExploits/sagetest.py", dict(), script_locals) 18 | print(script_locals["ret"]) 19 | -------------------------------------------------------------------------------- /notes.txt: -------------------------------------------------------------------------------- 1 | Welcome to the Daedalus Corp Message Service 2 | Please send me a public key and an ID. We'll encrypt the message and send it to you. 3 | b8c58f3a888c8918d07e04298edeb393f962df849058704e3cc4c0ec939d09235877b60bff9914ed16f5adeab0cdf880aa84e125f436d57171015f2a168b5b8d22c3d 4 | 1f40ff6455e33a8ad837431f17f3783cb0abb275aab553b9f07cfb9cd3f33d649f79ec5814be8c72355af682de27e68436c6749d7ce616c0a22c691e8ff 3 175 5 | 0x1df4e438b9b28a3be1b19c33044df52ba4cbc90f7af80e28063fabb7f1d3a8d70f759963f99f9c0bac1b9e31babab1fd68e30eff9c9d5b29c31b7d84a4ddc97de8f 6 | beb9595b9cea554cbe6a55152d151e694e4fa19388ebaf854000b48cc079072950598e27cdc01a0a49968baa5cdef3c00ed73e918dfc61ba50478c229f7acL 7 | 8 | Welcome to the Daedalus Corp Message Service 9 | Please send me a public key and an ID. We'll encrypt the message and send it to you. 10 | fd2adfc8f9e88d3f31941e82bef75f6f9afcbba4ba2fc19e71aab2bf5eb3dbbfb1ff3e84b6a4900f472cc9450205d2062fa6e532530938ffb9e144e4f9307d8a2ebd01 11 | ae578fd10699475491218709cfa0aa1bfbd7f2ebc5151ce9c7e7256f14915a52d235625342c7d052de0521341e00db5748bcad592b82423c556f1c1051 3 37 12 | 0x81579ec88d73deaf602426946939f0339fed44be1b318305e1ab8d4d77a8e1dd7c67ea9cbac059ef06dd7bb91648314924d65165ec66065f4af96f7b4ce53f8edac10 13 | 775e0d82660aa98ca62125699f7809dac8cf1fc8d44a09cc44f0d04ee318fb0015e5d7dcd7a23f6a5d3b1dbbdf8aab207245edf079d71c6ef5b3fc04416L 14 | 15 | Welcome to the Daedalus Corp Message Service 16 | Please send me a public key and an ID. We'll encrypt the message and send it to you. 17 | b3faca5b217fb38026ea06ad314f17656f8b2f155e1709afac5fd91d5b55ae6ac09eafb8c8065065a4bee53b21143fd0b20e8245e1550b7ff5b5c5df05e25d820d4691 18 | 13dd64f944760ec596a4628f155a66b3bd20c8d37341155441e331832c808403b390a3f7c55ba7cae740c4dcab632dae5d50b07e2bf0bfdd12ad840107 3 90 19 | 0x458c120ce1d39f1e1acd5d7f5f8dd51d5a88ce57980cf78f9b346d48362b851dff81af3b4f9678fbcdca8e74e2262f46735d00e8c2bfb00b8fd7857c84b2816653f4 20 | 9657c4466996c763bb75330ed401decdef4fc86e797dc99d51e2bec3ac696c67c06960f75102f166f2a92f7ef030371ec256abe96b7e420e62971e88fdf2L 21 | 22 | Welcome to the Daedalus Corp Message Service 23 | Please send me a public key and an ID. We'll encrypt the message and send it to you. 24 | a6d410051ea8f831fe4026abbd1ed92b7bf9a300f87367b9eda19c8cec052a1284cf50907316679004aab6274c1c3479d49a30e9ade95ea049538d0ec848f217a44faf1 25 | ffdb62e5ebb591cf24cdbf26e6bd300403acc4d6c2b4e6a0fa42c5776f9e68eec2062e1a9a86e3aafec9e6ce60d4b249dc178aa70576df3ebe6722321 3 188 26 | 0x60fffcfde748be62a8fc66087d33b90c950846c49d34f74007984ea7c7f60b20199a03fc702b75d9a6f4ddbe7701bff7e1d965e6aaf5b49bd4b4785085a0be3a6c194 27 | f74696fe1725ecf879537d565a662bee8aa30f6d0cf87011922d41d2affcd5c22144665c3ca0ba920c94e8360b38f992a4d1b93308f44a0eb5f5a3c5a9dL 28 | 29 | Welcome to the Daedalus Corp Message Service 30 | Please send me a public key and an ID. We'll encrypt the message and send it to you. 31 | fd2adfc8f9e88d3f31941e82bef75f6f9afcbba4ba2fc19e71aab2bf5eb3dbbfb1ff3e84b6a4900f472cc9450205d2062fa6e532530938ffb9e144e4f9307d8a2ebd01ae 32 | 578fd10699475491218709cfa0aa1bfbd7f2ebc5151ce9c7e7256f14915a52d235625342c7d052de0521341e00db5748bcad592b82423c556f1c1051 3 52 33 | 0x1348effb7ff42372122f372020b9b22c8e053e048c72258ba7a2606c82129d1688ae6e0df7d4fb97b1009e7a3215aca9089a4dfd6e81351d81b3f4e1b358504f024892 34 | 302cd72f51000f1664b2de9578fbb284427b04ef0a38135751864541515eada61b4c72e57382cf901922094b3fe0b5ebbdbac16dc572c392f6c9fbd01eL 35 | 36 | 37 | 38 | Welcome to the Daedalus Corp Messagerf Service 39 | Please send me a public key and an ID. We'll encrypt the message and send it to you. 40 | a04f35d80cb1d204c8d74ab48e658b081fb3250775c28c37807d4d0d669ff87f92add4ca150ab4a1fee6978cd1e26f7f5b124a2656252a6d5a8624e0ded5e508460611fa9 41 | b0034f2e35c49e2d0fbed10feda06e30102604acfc197327f5da0afe8e33cd66510693e81e838f28ab5164026dfb3dac014696b79463e65d90407eb 3 90 42 | 0x1bba15a7386dfaa8a54289adf2031979671aade84780b880149d1de7027d85b4c25f7110793873083f36e4ce300a1b1dcf1d18eeebce65f00e6e5409235a43ff435f685 43 | b8527c322b772b86d2936cc4d26b4d6578a04dc54cdeb61dc5de76a339eb00f7ef3a6dd10aa1b5afde092b028e92318049baf7c286c50e06d1a7668deL 44 | 45 | 46 | Welcome to the Daedalus Corp Message Service 47 | Please send me a public key and an ID. We'll encrypt the message and send it to you. 48 | 9e1f451d0f0a9bb7ac851aa27faf0d6c75c29be4d9f62fc0b1c0635e2a2b2c90cab0d7fa8e1d9543aa157b0a484662a56b63afc3b512241b3a72e62ac4350cd7e0de065f00 49 | bc20a55df4b62bc803471f92a8febe3e4bb375ff2fa16b6370721e23c5298f1bfc5d0da207bc14ac1668a0a252ec377127a8c07dff04dbddc802d3 3 188 50 | 0x422c7f36ed7428f479655a44ac5342be85a051115d15eeb3f814539b006d1eb0be7b42d35961f24aa6734b85430250411f7d568d8c993f5487e70a2d450678e0c6924525 51 | 61e37a3819177e9bc56b45305bb5e8f04fed1677a5f84b820ea5d6b80a579ae223eb276646dd599609409c20169cd4dba613604da9b873f6a42528d6L 52 | -------------------------------------------------------------------------------- /rsa.py: -------------------------------------------------------------------------------- 1 | 2 | from Crypto.PublicKey import RSA 3 | 4 | def set_RSAobj(n,e,d=None,p=None,q=None): 5 | if n != None and e != None and d == None and p == None and q == None: 6 | key = RSA.construct((n, e)) 7 | elif n != None and e != None and d != None and p == None and q == None: 8 | p, q = RecoverPrimeFactors(n, e, d) 9 | key = RSA.construct((n, e, d, p, q)) 10 | elif n != None and e != None and d != None and p != None and q == None: 11 | key = RSA.construct((n, e, d, p, n//p)) 12 | elif n != None and e != None and d != None and p != None and q != None: 13 | key = RSA.construct((n, e, d, p, q)) 14 | return key 15 | 16 | def encrypt(key, pt): 17 | return key.encrypt(pt, 1L) 18 | 19 | def decrypt(key, ct): 20 | return key.decrypt(ct) 21 | 22 | def sign(key, pt): 23 | return key.sign(pt,1L) 24 | 25 | def verify(key, m, sg): 26 | return key.verify(m, sg) 27 | 28 | 29 | import fractions #for gcd function (or easily implementable to avoid import) 30 | import random #for random elements drawing in RecoverPrimeFactors 31 | 32 | def failFunction(): 33 | print("Prime factors not found") 34 | 35 | def outputPrimes(a, n): 36 | p = fractions.gcd(a, n) 37 | q = int(n / p) 38 | if p > q: 39 | p, q = q, p 40 | # print("Found factors p and q") 41 | # print("p = {0}".format(str(p))) 42 | # print("q = {0}".format(str(q))) 43 | return p,q 44 | 45 | 46 | def RecoverPrimeFactors(n, e, d): 47 | """The following algorithm recovers the prime factor 48 | s of a modulus, given the public and private 49 | exponents. 50 | Function call: RecoverPrimeFactors(n, e, d) 51 | Input: n: modulus 52 | e: public exponent 53 | d: private exponent 54 | Output: (p, q): prime factors of modulus""" 55 | 56 | k = d * e - 1 57 | if k % 2 == 1: 58 | failFunction() 59 | return 0, 0 60 | else: 61 | t = 0 62 | r = k 63 | while(r % 2 == 0): 64 | r = int(r / 2) 65 | t += 1 66 | for i in range(1, 101): 67 | g = random.randint(0, n) # random g in [0, n-1] 68 | y = pow(g, r, n) 69 | if y == 1 or y == n - 1: 70 | continue 71 | else: 72 | for j in range(1, t): # j \in [1, t-1] 73 | x = pow(y, 2, n) 74 | if x == 1: 75 | p, q = outputPrimes(y - 1, n) 76 | return p, q 77 | elif x == n - 1: 78 | continue 79 | y = x 80 | x = pow(y, 2, n) 81 | if x == 1: 82 | p, q = outputPrimes(y - 1, n) 83 | return p, q 84 | 85 | 86 | '''Test 87 | key = RSA.generate(1024) 88 | 89 | k = set_RSAobj(key.n,key.e,key.d,key.p) 90 | print k.p 91 | print key.n == k.p*k.q 92 | ''' 93 | -------------------------------------------------------------------------------- /rsa.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eazebu/RSAExploits/dd6da21fa052744945d73e6166e7adf8cde9086b/rsa.pyc -------------------------------------------------------------------------------- /sagetest.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def trysage(): 4 | try: 5 | import subprocess 6 | p = subprocess.check_call(['sage1','-v'], stdout=subprocess.PIPE) 7 | found = True 8 | 9 | except OSError: 10 | found = False 11 | 12 | return found 13 | ret = trysage() 14 | 15 | 16 | -------------------------------------------------------------------------------- /test_files/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eazebu/RSAExploits/dd6da21fa052744945d73e6166e7adf8cde9086b/test_files/__init__.py -------------------------------------------------------------------------------- /test_files/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eazebu/RSAExploits/dd6da21fa052744945d73e6166e7adf8cde9086b/test_files/__init__.pyc -------------------------------------------------------------------------------- /test_files/common_factor_test.txt: -------------------------------------------------------------------------------- 1 | ciphertext = 0x0 2 | e = 65537 3 | N = 0x9bd81d1485b39495b0506728527602e9d930a0d73a9e3df7439b056a218a6c4f6c761d651edae9b3441d5ef60b1d625c081906d87b9db8fa79d855efa263c7e235d6e013c94b8738c016f0908243257768678440ba99b8762993937d883b7357381a007bf29800e6066f531027f51fd92c16e67200da385adf744260206bb73bL 4 | 5 | ciphertext = 0x0 6 | e = 65537 7 | N = 0xb1d89966b4e656cd32f55231292d1157a38de0e05d1f12035512da25610d4b694f20c1436f14521494656f4262afd25caf9247a9d53acfdefbae0b200b0c0aa6f6d0675ad296f51207ce515cd15c43b44e8ab7df4f7052ec251ed27108a521cc7111c3dcb0426bedd38656d85b4656b83ae9dcec1dae31af3b6868c802fd7737L 8 | 9 | ciphertext = 0x0 10 | e = 65537 11 | N = 0xad6597032a2b47677aa5faa38998d9af4dee9b075777e0a4504f2d408a0294b232748da729f2daf704d7ed94acea2ae39585948ab1bed929335bcf932a26b032e59d6b413394b77a2343c30cbcbaeaa36f7abdac43cb79850376c0db8c06bb666a1c2c6c47570bd859ffe1312fc4ff7999e39ee1d0ff9ab967185759d954fba3L 12 | 13 | ciphertext = 0x0 14 | e = 65537 15 | N = 0xa05fda87850c684d410680f6de6303a7591e67bdad2d8166f2d4222545f0b16728615d0b543e56d697f1c77095b9328daf8a4dadb662295b3d8ad781e7bb7dd9013a5bde03da61c20afe8dcb7f5571bcb454c33fbb3a094e35370769a2fad3ade211569b141203394663990b8b36e8ac67be08ecdc9ed37e3104e5b9b41c5f75L 16 | 17 | ciphertext = 0x49f573321bdb3ad0a78f0e0c7cd4f4aa2a6d5911c90540ddbbaf067c6aabaccde78c8ff70c5a4abe7d4efa19074a5249b2e6525a0168c0c49535bc993efb7e2c221f4f349a014477d4134f03413fd7241303e634499313034dbb4ac96606faed5de01e784f2706e85bf3e814f5f88027b8aeccf18c928821c9d2d830b5050a1eL 18 | e = 65537 19 | N = 0xc20a1d8b3903e1864d14a4d1f32ce57e4665fc5683960d2f7c0f30d5d247f5fa264fa66b49e801943ab68be3d9a4b393ae22963888bf145f07101616e62e0db2b04644524516c966d8923acf12af049a1d9d6fe3e786763613ee9b8f541291dcf8f0ac9dccc5d47565ef332d466bc80dc5763f1b1139f14d3c0bae072725815fL 20 | 21 | ciphertext = 0x0 22 | e = 65537 23 | N = 0xa6e54809e7867cf4fbc4da1f24993f03ddd85d4c624fb600d22f83839b45dc48dca38a3bb3b2b04790126f5705a6651c335281834a0888cb83685e6151983201d8d570c1f9c41be0fd432f49455e6042b92ce393ffcb79e95231ea1f16e6a5be173fa702d139920fca50a250b50230802a467f158b5b9d97874ea3c0408d7ed3L 24 | 25 | ciphertext = 0x0 26 | e = 65537 27 | N = 0xa8fd269a05184dd3f59cceae4750d6e10805dffea44b40413cda19905090eed1dd35259a55acc9c1d875f5cb7e68a5800b1e3d71b058ffc53d3bb6990d7c8f34f03f9817b63e3e0fd84e137874b83a42d422832739f2af9bb96110158a2cbc8d510a16ae80c4f2d2d41575da342d89018237308f1e57bac256beef65f4c04433L 28 | 29 | ciphertext = 0x0 30 | e = 65537 31 | N = 0xc09cbd27ee0abcfabf1dc1c48c54f9042842d01dfe8b41df696924f94f31635498c542ddd84ed64b339c62ec7c20cfe1da2471ff83fe713381d86de875bded7a33060d4cfad4001be9ae91599d37ce6fb91c01dd3392e3f61e83f0c0105a3fe592107f76970eb1f4dac73a2603f0df4bf06a3e32913eedf4efdfa09a287084c7L 32 | 33 | ciphertext = 0x0 34 | e = 65537 35 | N = 0xaaaab30abbb73870d1fe8bda8af8e2eb2fa8d0e633aee4506d325bfc9ea744a2f9251eb1c4d2aca7978ac9ea5d1f149cd6c61d946a33377061946bf9cb3439179467b9edcd3c9e81651df500373ac740570cdebb9503353dca629e8b1676606129c82e6e85411461e31abae3c02a6de17ea102fe6eea4756cc3a9c2d0a076843L 36 | 37 | ciphertext = 0x0 38 | e = 65537 39 | N = 0xb35c1ef9b9d6ba509de52e0a6bb387bd4d5738b63d223180fa5a26fe6c7c8682069bf9f880075742ad021eab3516f5cfdf2a526eaa70e556b27b8f4a72847ac75872ac1d82d499f084886d4a84c7a9e2a0a55c6a83d6b41b79a6beb553093f4d5c63f21eba9f3e0781c2bc6ef41a61b71a1273d84367988cbb34ee5f50e28955L 40 | 41 | ciphertext = 0x0 42 | e = 65537 43 | N = 0x9f3d977cb5d20aedab3d85780b4e8767e2fb2588454e3fb199fc10109feeec2024b57b6404622ce1b31efedf8d190947e47d07b6c3935fa69c44b4e08ae8b676c3545218dee1a289dd7be8c6902f6e3af865a97637c0409c58721a5808517e578436033e51e627227c2e1f832ffb94ce6ca98e37d0ed5317dfa3b07210f22f57L 44 | 45 | ciphertext = 0x0 46 | e = 65537 47 | N = 0xa4c3211c7d21abf9da1246f800b7261a3b60a637a0ba3ae17e5b4330f7259b6d94ff00f89ace47c173762d67d2957bbc5a050b6080459598f05e26181e481ffdcb84aa46a85f88e315f0723c349d225a00d22fdb7b01d5ca25fcaae790dae11d5166912efffdc89964ec0c5e0cc9bb042b36fc8197f06a49a7bef752c19afc21L 48 | 49 | ciphertext = 0x0 50 | e = 65537 51 | N = 0x99ed807831b10f3993b9e2a8a4d4fc3e1c836383e68884d8140d5ca333e3e6b4277729a46a2bf7b03198dbcc65b15a346dced787f7ada9292b27d9a7a342b72f87d78f54020a88a78b814b846dc698d3f3f00519a87ffc5eef109a222812bc918ed7a8765089925b71384dd0bd05ed4f85bb5e287f2a543cc59e67dfcce660e9L 52 | 53 | ciphertext = 0x0 54 | e = 65537 55 | N = 0xc03567d6065b72d0c7e0a1e5d10d0b40f86f30581f2fa71c2d8dc99207d80682f4a27db23012819535b616d1e5c50f5cf9739cb5f188b378bb290c0253b684d3483668b7ccdede8a74bcb7d50f057f0d1fac9d89ef63dfb7b11169030c36516fce4268efc1b5709ecefed15d24945d2afcb598cd022d1114e53a07aeb63abca3L 56 | 57 | ciphertext = 0x0 58 | e = 65537 59 | N = 0xb990ad5c2feb27b5f32f0c4cde0187c5c4a7d644bcab78f663c234637c525696775f51d1de7b2daa886185092e9994f527fc37583284a79dc9a814f76a02af0d2ef68c338f6c53a64f7c12c835d49004eb7b81621a011f68ec9aedbb755ef26dacc46acf52ba5971bc159398ac9b55cb5761ecd7305ceeef8f9ef815d6dc2577L 60 | 61 | ciphertext = 0x0 62 | e = 65537 63 | N = 0x9ff7ce9470675d9d563138b74a724cedc35fa92a946601aa49c85dd71d008cb748ec5f55a63c8be95c3935349daed1b9f0309735d88de5102dad37eecb5d68152e5a73dacfebafbf6a98d62eb009981c750ee1833cd2f36b39ba7d5206d821131e97bb322ea00a948cb9fedec20ea50d4b652c34784a59f757232b0392bc707dL 64 | 65 | ciphertext = 0x0 66 | e = 65537 67 | N = 0x9982a9c74ec6c286cb0d52d369cdafe5cde5c161e2c33b9300ff4e264fd0afe4217293c997ccfd0a4ffdd5c57d2cfd11b6c0265b4038b3eafbcb20036a34ecb1e6055bdfbdbf5d928cd619216e2cc5182da45be32d6dc6198246e638977349fe1a497685d019f63c33cca067d478af5eb463818db74bd221b46a0b2e99620a81L 68 | 69 | ciphertext = 0x0 70 | e = 65537 71 | N = 0x996d0ddb5d1b87208546a6a2aaec5f90f66f9aa9b6326bbdaaf6e84784651ae70ef7d936f78ff0f06ecb3938fb2ad5afb4dcc9062bd9f1e74ad458148852091b809f67e33b330913a5ab39e855f091342edda0077c502bc321c537dfe76aa4760177da908e9fc2a3eefd30ebff5404a092b520253d01339e42420ffe69d8c163L 72 | 73 | ciphertext = 0x0 74 | e = 65537 75 | N = 0xd99500dbf015195e1483e46c1731ab53b65af86bb74e6ed93829fad5ff8e45dc2230eb1513b3204ab2154c71487c362e35c3a7253937098c31eb348b9d35638841ff30d8c0fe58b9622465d1e3e5ec56746112f6e1903972471d6dc7055321b819c0c72e5618c36d1480b72a5b0c53c157afbb4f20d122c1657f5a6ae189dd4dL 76 | 77 | ciphertext = 0x0 78 | e = 65537 79 | N = 0xb79d8bb2e12d4a6778ff7aea4376e91a3f6a8c7d87ed64d44f260b9f09cc90b5f55f20392b0693d8aebc630823426a8ba9e2f9d621003335e11a9d4641a95d586e99a587c4156b332b249287aec12f18048e218066774688a4ca590602f1777557a9c273c787296ac86ac0564840e28437a1b43a28723346589cf72f9837d1ebL 80 | 81 | ciphertext = 0x0 82 | e = 65537 83 | N = 0x9fac6b1dcb8673ed80de321bd0be744a40e724c768850a619f9a76e307eaa4e4e2e7c5c421bbb1ced616a909e791155740326a23187a4adc06e6e4cfdeb20e39eb01be8ed414a33369a95a8d065da53aff8042897b573c5970500f1345368055e6a79ed15a47d470e194651886023dbe0f8b06ee80cdab85743a8504dfbe88afL 84 | 85 | ciphertext = 0x0 86 | e = 65537 87 | N = 0xdfea5e54e5682b3f97903d836f8d8eec439ab6228ce65c1d7abae0d9d908baa4cc30d255476b9e5de9b2e4cee1460a683ae9ca26c77537a2d067c4afbdabd6b819671ef3183b6ad38721064a5a656024b3c539a77974b595cfd60572dbe1f4ac8e01a8a6f1a9760d0f76b04db38530d9cfe122945dcee9bc3eb4fdd73cf0e24dL 88 | 89 | ciphertext = 0x0 90 | e = 65537 91 | N = 0xd81815f04c7c24cfcc7d3f27dd49fda43f5802ab2e1ea5d3ad8afcd6622e24678cb89781c4fad92e227393c3a384685b05dbad4d012916ba71b4bf8cb62c8133deb097e87e39bfbfc4146ed632a715fd7da68596a98da24ed3e8ac4623762b51c0c36276999416e6990f5ceb7f24e78622724293d4c3e7299043a2af00d412f3L 92 | 93 | ciphertext = 0x0 94 | e = 65537 95 | N = 0xd8a3b256b377f1f759e95141cfbfc78c7a034ff8fff65f0804fea78541a745419672b6edfacc4a5c650841e8c8cfba97f6d487408b4264e09b4900bafdd92f0a1ea345a92eab34bc411b5c8a13b2bb42bec1ec12fac48e2cc21a4fec17faeadac6952e97afcce643a9e4ac415f1ef9e7c4846d69ff26f4ed54279b39266fe213L 96 | 97 | ciphertext = 0x0 98 | e = 65537 99 | N = 0xca723ba7ba4b3803fd92737765be5d19ac52076e16f987bfc66006c502a923d548b1da5e3a874dbbc3fdc91dff3f61617433bd46f1cc6e916e1ca678b1ae17764f1c51ee55f6c9ee9acab968597ee9a006ef09232a04ed75b7245bd84244b1baa00600af9de01540f95f130af88494c745973efe2f55f77bd91b15dce552c67bL 100 | 101 | ciphertext = 0x0 102 | e = 65537 103 | N = 0xd24b2221a47ccc3e234e77340788efacb5f75ee75095828c9666e93d69a915c8a5d43e74c2622f57f89ea5affd3174efcd7f049069183687f51265fdba7056f41fc863c645fc793a66ae29f7a7747b652d1c99a7218171c8beffe546d2cdcb67f6ce95554e829d6228579bd09ee6901c11a9a6399ed2f38bc732dc3f51ee7db1L 104 | 105 | ciphertext = 0x0 106 | e = 65537 107 | N = 0xbb8ebf41b748cc4430ed79acfbeeabb48b1cdd17e849c6a5c48b80eeea0869d02c64024152e6ed8dee65978acaee50f47a342939415ae2b684dc9dc43c3b1a10a7a594c77745ffd302122d948233b784d7dbbd2cfa6e30b6598b59e85738200d23d6fe5cd834510179eaa63cf96fa117a898faf959e0a680428a43c03627a921L 108 | 109 | ciphertext = 0x0 110 | e = 65537 111 | N = 0xc4e99bb797133465963c548bb1deb921b168d8efb6b8b7f0fdc62e085f82041eabc890878744e7e3d4c26921fc726e0d4ff11c9214d07a91be3928608564dcfac15e28f91a012920777a4492a13201533162163a28850aabf4536aa0c79bd94925801869215906394eeecf487e5d63ce3256d36fc3f7b3d43a38ba268928cbbbL 112 | 113 | ciphertext = 0x0 114 | e = 65537 115 | N = 0xa50b2c79b3a455abdfab1cd1407cac67e41424edaeb73fec3a056fe8ef742a9213e06c93206ef9e699ed8e05b9ebb961ee93d6d29fa949be262594ddc9e4fac3ff167f9c7f9101087998e8a6553f966c41e9c895e151715a7d528f7d432635b4756ec37756194b871100a6d0d1541091e90d9628af920bad39499d0392bfdd4dL 116 | 117 | ciphertext = 0x0 118 | e = 65537 119 | N = 0xc187dafa0090eb4ee53b6104bde64a2f2309ca34c62aa338cf31ebc647a28fdcc71934b1d174eb4cc8f5a326d26d7dba7e8bba7769619f66635f27b62fe34b93523d6a5cd92bcf770ba53e375ddd1a75a34344acd818b9855a7cf37012dfa9a5da93b780eaf506019fcdcb6bd25711c8074e56a751660bbcd24ac66cd8737adbL 120 | 121 | ciphertext = 0x0 122 | e = 65537 123 | N = 0x8e25bc8390c1bcfbf690d31309867fbf6a61ddb05112438a5cbb66a53aaf7410d9c6504e75207a70ebd9b8f721b554cd69ab6b21a18a07442543012e8fb174ff4e95b409fd6b23690f5cd29e6105633cbc60df6d4bcbfc631ed8a807c3b3c4f7e0ad2bb47446f05e280f1fcde40f4185eec29933f5f6ba560312ccab75a95975L 124 | 125 | ciphertext = 0x0 126 | e = 65537 127 | N = 0x9e57206a7b7934fe20426e17196eab2f61d8a20edac758544df9dd6eecd4962d64cfb16dd16010815ace5593fca70b1115f18e73d4df4b7d86bea59f9c20e174d9b2088d3aff83e9e8a6c13ba8b81f8fd9a2b47c1db5214fdb8d20df965339e16df97045e07eeddc4673c8a010e32bc5653f04fa696bd3e8ae7ee14c9821d41fL 128 | 129 | ciphertext = 0x0 130 | e = 65537 131 | N = 0xa9652b10d43f44d4b48a4330801c8f14a2559839210b537f074ae035a284996ccaaa8f2bd3a93162c16e2c640e39422b776155b0be5ff0f2ee15a3f771aad294b1037032363844b3a042e16afac74d615662be56bb8fb7f06df6e5fd671a9bf884bb994d4a5ca97982cb2cb10afb5d0c5675d86ef35a89f9952e43a24c4e5d35L 132 | 133 | ciphertext = 0x0 134 | e = 65537 135 | N = 0x9b69a104315cf72be5946c55cc505ad0ad446aa874ee8afb8bdbafe41601fb1ae96ef2bef1e12dbe291edba1ea6c465cc11e0246fd3eaa4288597ba3110d444392f45e1a8bc9dd0ea62a16b169f140533b0dc9cafbddfb9039e05f16f619e7310b915147ce9e82a1b3732205030ccb5147855a21b38b2ed5f1430159ecb59379L 136 | 137 | ciphertext = 0x0 138 | e = 65537 139 | N = 0x959ba44fb29b3c03328424697bbe9bc8e44faca263802a965e04efad1ee0f1ec8be004ad9b1191e9eaf557f2dce9aac8cac043e6b009b7a64a90ee489d689f349cfa128a2e0233473dc909766c05197889f7054f770ae841408d968dbfa8ce1ba0ff3c4936f3a5cef6075bf31e83a558d6bae4e130d2d80493597da3b77420b1L 140 | 141 | ciphertext = 0x0 142 | e = 65537 143 | N = 0xc3b88e5d6fdc3b3c045c991145665ab816b06d825a0930b7eeee732883b8bb87ae0ba7547011154ebe47cac3f2eafabf001e1ae6f810cfc149054c142259938d854d140856f69b555007d8941b2e5cb0eada522b2184078813f5b79a3bb189b6c7a8d80541752cd1b20dc482805aebd0bcfb0d8cf70c72ae46d89a87be86e9adL 144 | 145 | ciphertext = 0x0 146 | e = 65537 147 | N = 0x987cd190f7c3c18244e79983dbd7b167abc5d0d18140d336ad08dda8df2574852ad88b6add14f6c6a660805b27cc96eedfaf5be545cead3cbd067e63f7215e7835bbcd22bc875acc902cf02292f72581f1c83780ac80e136a5ccb7036bdb143cf073c5ee5be7b705a2a28b72fbedd051749a61a300c0548545dee3726d4684d9L 148 | 149 | ciphertext = 0x0 150 | e = 65537 151 | N = 0xe60fb4b75dafbbfe03f4406e7bb6ef5cf7e623fd48df0dc75d2ba55046dc9581b26a9c0e900875fa8e63cedc005c36e5faa57fa9139317f3c100be951018cd3f4d2f53863e06f671bab868eef74f501552ec0a09ad65eb4cc05195a02745ef09ceb582baef1af832cdafde2d16508a459e5f194a32324ebe7417897592500787L 152 | 153 | ciphertext = 0x0 154 | e = 65537 155 | N = 0xa175155a1184b1216493f49e0920d18798ae0aa087e8854d97a8419a8689f1461ead569c6bb7949bb498b8066fe69342b77418b9e1e6829573c6b573ecbb9263c68fef932fa6d957a48d133dd452daa7ea49c7e50c027eb49e82f4fd91a2f9bf3c22a41e9531d6b509eb828bace6cc34293f3763a4f37fa34b62c218ea222ee5L 156 | 157 | ciphertext = 0x0 158 | e = 65537 159 | N = 0xab74f2e7390332cda4ea8f4cc845554c29b9e4cb5c7fbe72879e384cdd1aaed0148c8ad8412ea710dcd439e2b5aea353257d2e3f857b48b6ecf5681076f7770a95faaa8ff8ae976c81ee6fd4a3fbeb851853657232b085b8c2c3856d857d87e6025876353b44d186a013051f9ccee47e94e97380ac6414191bfa115602fb6993L 160 | 161 | ciphertext = 0x0 162 | e = 65537 163 | N = 0xa0f42d9050e481fd5302a68d1181b503cbbd908af121a0e4d06362bb4d1bdba2f429e7862554ea979eb8cc47cf7d4be0650eade7584b74c279f81cfb81ed4b3ea29c3a4d18f654e399782fa377995dc5ac0ee6b6057e76a7ec6b89f79a097ba0896c444b382ad918dbba0d221039d18de7b3e9dd97f172834dfbb0ee00a47595L 164 | 165 | ciphertext = 0x0 166 | e = 65537 167 | N = 0xb03cb8314300cc39e64aecc0de7e7a9d956be9adcf830950cb28c9dd7278accc6b62dc442b019c8959fa277add5a6edb6dfc9aa2d317e0bcba2401665f1ddceb29fbe05c7b2937bb064cb5eb75b63defdfd79a49c58440ba3f5d8823c9c0eab71c791dd4bddfca06275bb722844e096196c9670e81c49e657a6abb70b1a17029L 168 | 169 | ciphertext = 0x0 170 | e = 65537 171 | N = 0x9d9a05f121cc7beec5518711422f8c2f23c39f3e384424d7edd3fd73a0602a06ced85cc23fd6c6f8ea2e097efd828af223aadb5ef499d72012b557ead30cf2abb501238d0d9f21b6b0ec72c88c9d7e08e6f66f0db45c8b9a67524df65a6de831d771e8de5a202716badee934ea140d5625d8349edf7293c89d1a8bb5d7482299L 172 | 173 | ciphertext = 0x0 174 | e = 65537 175 | N = 0xabdb5b49eb543f03c08e855214214aa48a94c5c76c1369e7b01a294d4f52572b626fc3e43c077a06d09210ae6ab69d2f8a575efff64bf2a89169d391c0b799317c0b2db8c2e3fbcd04be1f3e38c9fd17853963cf47c8e86e8df2f0738581bfc32d6a12947a1984769f0b31e91a381dbae2ba53d5e15570b9e3a3adbf203a0813L 176 | 177 | ciphertext = 0x0 178 | e = 65537 179 | N = 0xc751f270bddd893a9a671f055b4926b2092b60bc36b56380e3e6f082db38b7b635c01e605c629599bfd0e949f5f52f604934e81d6587288934e23e707e6d9308bb2d6199a5598811ff00201be308f4c54b678c58f84384365fa1522ab666b15a7381d42661e5a09d78ef418f82db6b7e71760961d39df25c8c3da1f2ef7f5dc3L 180 | 181 | ciphertext = 0x0 182 | e = 65537 183 | N = 0xacfb63f2dcd4b8271f12b83fe3bc152602610ebc6e74908ce2ce8a79e5b2a9e5a4590f6664415a8713a538a26530524bd4ede310bd3bcd4720a9071dd7a093eab44f09a36a5252666659d3b0a38ad9d638fc6bda24ae98667e6e4c2b030dda91f2d20e3665fa9748865d813eea28a3b7a6888ade15cc508f8acecfdd4e7b279bL 184 | 185 | ciphertext = 0x0 186 | e = 65537 187 | N = 0xae44a0a4213c57ea45f972c2f3c10c115464f9cfe68bf97e6554e5b761680519fb3d88a1942b0fd48391c0113ff41d4300bef30121fee9c680d4f897f4956fd6752887f2cd07e103a974f94b388981a6c633a3442a4c41f957b17cb81b7c8b7986ab218c7c0f426c64ac8c3bec3e6c79dd74824fd8bf3ec68776ab41bcce3873L 188 | 189 | ciphertext = 0x0 190 | e = 65537 191 | N = 0xc975c9c9a8c06a86dad8e5b67ab4f17d8de2219e5866fe9114cba92af621184a0e219c8f89922c8a08c82bf61fca8a1a32c0fa0e06ae4789619954133c2bf87ceaea6d6deac7a2c47f29bad940616df8a50e3172da4ce9ba4d1b766ec94a2c910b1849d5475d3cb2b72fd6a77883c60aa677e1da111aff31c990d89586848a1fL 192 | 193 | ciphertext = 0x0 194 | e = 65537 195 | N = 0xbb76c3d84e9d4dd4ec81e47e5a029fd1c7b244ac0199947a40aaa8f8142c6748dcd4595c2c70bfb85e05b348ebb39c12622b5cce40478e5c0e25be7b024f584ebfd91bae90e3fdcf9cb3fe757bb0a38e9daf75c3c7b684ed940a1af619816dc8bbafba1a1a7783ec4886085a12468e737e0eac461b14b4b8ac71b25ade782f3dL 196 | 197 | ciphertext = 0x0 198 | e = 65537 199 | N = 0xab81a7bcbd3f1a8759a116c2175613702d10ebe2cac55f3b906ce621259000507bc3dbdbd305296fc671b10be8a7769ea4273782175cd75a7e82a6e2687e7bb6fbb89cffc85f882ea918bb9474570f0fa4fd0a04edb052834e43695e5b25e66bcbab2cf5a15ca3abe55a9042299a291770aac2306004289276b9aed73cbb6583L 200 | 201 | ciphertext = 0x0 202 | e = 65537 203 | N = 0x9224fb97c913e3b9d830c6424983a1d95c0e99a5bc317dfabad7e569e9b310d5618526f8162dce4c8f29f5f7c4ea825bde44c53b9019963cd67f8b919c21b4034ed8ba51199c9d243a73a61e99625b2e49801b4097b161e85bb6883a55030f0be2878f853cfaa4410f6429225e5256c0509e5af6a2fc2643804036f1207d8719L 204 | 205 | -------------------------------------------------------------------------------- /test_files/common_moduli_test.txt: -------------------------------------------------------------------------------- 1 | ciphertext = 0xb3faca5b217fb38026ea06ad314f17656f8b2f155e1709afac5fd91d5b55ae6ac09eafb8c8065065a4bee53b21143fd0b20e8245e1550b7ff5b5c5df05e25d820d469113dd64f944760ec596a4628f155a66b3bd20c8d37341155441e331832c808403b390a3f7c55ba7cae740c4dcab632dae5d50b07e2bf0bfdd12ad840107L 2 | e = 3 3 | N = 0x458c120ce1d39f1e1acd5d7f5f8dd51d5a88ce57980cf78f9b346d48362b851dff81af3b4f9678fbcdca8e74e2262f46735d00e8c2bfb00b8fd7857c84b2816653f49657c4466996c763bb75330ed401decdef4fc86e797dc99d51e2bec3ac696c67c06960f75102f166f2a92f7ef030371ec256abe96b7e420e62971e88fdf2L 4 | 5 | ciphertext = 0xa04f35d80cb1d204c8d74ab48e658b081fb3250775c28c37807d4d0d669ff87f92add4ca150ab4a1fee6978cd1e26f7f5b124a2656252a6d5a8624e0ded5e508460611fa9b0034f2e35c49e2d0fbed10feda06e30102604acfc197327f5da0afe8e33cd66510693e81e838f28ab5164026dfb3dac014696b79463e65d90407ebL 6 | e = 3 7 | N = 0x1bba15a7386dfaa8a54289adf2031979671aade84780b880149d1de7027d85b4c25f7110793873083f36e4ce300a1b1dcf1d18eeebce65f00e6e5409235a43ff435f685b8527c322b772b86d2936cc4d26b4d6578a04dc54cdeb61dc5de76a339eb00f7ef3a6dd10aa1b5afde092b028e92318049baf7c286c50e06d1a7668deL 8 | 9 | ciphertext = 0x702f3ee5a52e44f5af0d74f389659e2cd91918de370f60c67574edc59a391a5630965a56ce9e8646ee64348910de3ba3e670da53f73f5da360d63436e365e9108d1dcfd8d4756b080b5dc58be805fa61351964588016f15802811f2d333057f971857c14658449f1d9cfe41c7af55743013a7ba178d49c701ade66de12257bc3L 10 | e = 327381934393961 11 | N = 0x90d472ac7939ea71b387bf5ab1605c74db4dee8db8048afc406173880c2a7334eaa48ad89b08a4cb4f73da1d3d2c9421b62cbe89470d7fa62d3d22169ed70ea7f296e996f8def6a30275a72d71f15503e9e007359cda78358e8fcf46c1999c25e9bd345fd96b07c44c5a209dc998fb693644b451c2252bc3671cf7895f3ffb25L 12 | 13 | ciphertext = 0x8dacc54322dd8b88980d29aca6c9bacdf88f2e1bcb70865f8c2c9554a55e56444718f0da8edf74d8b94c18fb8f23509f388291c0bdf3b1d63c087f630955130bd077f3dc96cbef43ca68a4c36eaf0bbbf8aae486b9c567e18c5755911c6c252cb2335e583724379bfebe1928bc75eecb6d733e2be1fb58db71956eaa85c594ebL 14 | e = 229345007 15 | N = 0x90d472ac7939ea71b387bf5ab1605c74db4dee8db8048afc406173880c2a7334eaa48ad89b08a4cb4f73da1d3d2c9421b62cbe89470d7fa62d3d22169ed70ea7f296e996f8def6a30275a72d71f15503e9e007359cda78358e8fcf46c1999c25e9bd345fd96b07c44c5a209dc998fb693644b451c2252bc3671cf7895f3ffb25L 16 | 17 | ciphertext = 0x3acb5736767a1c3d083223879e00c3e3c4e309b23993706a4b0a8837ad7599c8952f860151cc3bf10f69d304648e60c1a6a96d4595770c556b8c9e17aea70380114993a857e8d2580cd6db8ae0de33811bea871af6123c5b79c3d586c45b78fa9bb3021ff07244275a9262934a0a39d3cb174ebb17a04270da4be89e1db6c53eL 18 | e = 493170072613343 19 | N = 0x90d472ac7939ea71b387bf5ab1605c74db4dee8db8048afc406173880c2a7334eaa48ad89b08a4cb4f73da1d3d2c9421b62cbe89470d7fa62d3d22169ed70ea7f296e996f8def6a30275a72d71f15503e9e007359cda78358e8fcf46c1999c25e9bd345fd96b07c44c5a209dc998fb693644b451c2252bc3671cf7895f3ffb25L 20 | 21 | ciphertext = 0x50db7a84304eb8c5d3d14ad83462b8910e84d9b967719309ffd65c3bd8102dffa262f562660626a02d1f16c61e7924b652edc19fb252fd91b2d1ee90f4e53a52eeaedaabb8b9f24f3f934b9bc87db2d368caacf52a33bba4214b23f04926bf2b5da417f82d7dc2c00ce69b530efff7dd08ec2b93e53e0571ed16192e61cc867eL 22 | e = 58695430075608541063 23 | N = 0x90d472ac7939ea71b387bf5ab1605c74db4dee8db8048afc406173880c2a7334eaa48ad89b08a4cb4f73da1d3d2c9421b62cbe89470d7fa62d3d22169ed70ea7f296e996f8def6a30275a72d71f15503e9e007359cda78358e8fcf46c1999c25e9bd345fd96b07c44c5a209dc998fb693644b451c2252bc3671cf7895f3ffb25L 24 | 25 | ciphertext = 0x3214393771f3be87aaa061db4e9a69bac38acd974b7bfa9a5f14eef1b730b84c849d739b37e134643d177669189c79596ae76539b88c88489319a0daaf6ba4fba0189252b006fa324bdf5724c673353d88cb7ab9ee7b26a1c4110ab885132f7d585c4ebe26e8514a8d61e32caa098d0584ac8b50ab470870b603d0f2dec2683bL 26 | e = 1431595855502647343 27 | N = 0x90d472ac7939ea71b387bf5ab1605c74db4dee8db8048afc406173880c2a7334eaa48ad89b08a4cb4f73da1d3d2c9421b62cbe89470d7fa62d3d22169ed70ea7f296e996f8def6a30275a72d71f15503e9e007359cda78358e8fcf46c1999c25e9bd345fd96b07c44c5a209dc998fb693644b451c2252bc3671cf7895f3ffb25L 28 | 29 | ciphertext = 0x53f61167c948c02dae251757d1a34f25873fb4db489c97ef6a2ac15a713cfbcba79e1fc8a67156ffa5df64d6385ee9af335af50db549e875a92ffd4f649c9ed2c12bc0370a43275c251e67ba13ef4a251a0fb580ac28e27e22fb4b73855e9628d5a3cc80065ef8a248913822680975d920e8c1bdab7601d9dc78b9bd6695756dL 30 | e = 255926348009 31 | N = 0x90d472ac7939ea71b387bf5ab1605c74db4dee8db8048afc406173880c2a7334eaa48ad89b08a4cb4f73da1d3d2c9421b62cbe89470d7fa62d3d22169ed70ea7f296e996f8def6a30275a72d71f15503e9e007359cda78358e8fcf46c1999c25e9bd345fd96b07c44c5a209dc998fb693644b451c2252bc3671cf7895f3ffb25L 32 | 33 | ciphertext = 0x6f595585fe4c58683eb44d56b89152642e2e241dccac3191dfea6c787b544c13de18bbcad58b689b2763bf87da5053bb522b59954d91a6f4c4a1f30d484aa4e75546178459c8e692f1aebca885b49af59d9bea8bc05aa5403e2351f02360c095e39d30ffb2b3b56ae8254820a032fa16312df7275563c7a5e1d68fafb6914545L 34 | e = 98667017957097957526903 35 | N = 0x90d472ac7939ea71b387bf5ab1605c74db4dee8db8048afc406173880c2a7334eaa48ad89b08a4cb4f73da1d3d2c9421b62cbe89470d7fa62d3d22169ed70ea7f296e996f8def6a30275a72d71f15503e9e007359cda78358e8fcf46c1999c25e9bd345fd96b07c44c5a209dc998fb693644b451c2252bc3671cf7895f3ffb25L 36 | 37 | ciphertext = 0x26078e8237dd2ec6cfec6f45203ba787431b7e3beea12440d1955db666fc1a6398d3a6ff82bb998be38a63d12da017c3d1e219a20fcc7a76c440a09cdf5099ee5618427e0f91dddbdf4adf85b46c9d061b6efe536dd1532f4e2a9a6836cf5ff2da6fb3384f0fa6b6ea3580f36ba8201ebbb8ffdc80a73e1a0026d0ae92378500L 38 | e = 13788812262241 39 | N = 0x90d472ac7939ea71b387bf5ab1605c74db4dee8db8048afc406173880c2a7334eaa48ad89b08a4cb4f73da1d3d2c9421b62cbe89470d7fa62d3d22169ed70ea7f296e996f8def6a30275a72d71f15503e9e007359cda78358e8fcf46c1999c25e9bd345fd96b07c44c5a209dc998fb693644b451c2252bc3671cf7895f3ffb25L 40 | 41 | -------------------------------------------------------------------------------- /test_files/crt_test.txt: -------------------------------------------------------------------------------- 1 | ciphertext = 0x458c120ce1d39f1e1acd5d7f5f8dd51d5a88ce57980cf78f9b346d48362b851dff81af3b4f9678fbcdca8e74e2262f46735d00e8c2bfb00b8fd7857c84b2816653f49657c4466996c763bb75330ed401decdef4fc86e797dc99d51e2bec3ac696c67c06960f75102f166f2a92f7ef030371ec256abe96b7e420e62971e88fdf2L 2 | e = 3 3 | N = 0xb3faca5b217fb38026ea06ad314f17656f8b2f155e1709afac5fd91d5b55ae6ac09eafb8c8065065a4bee53b21143fd0b20e8245e1550b7ff5b5c5df05e25d820d469113dd64f944760ec596a4628f155a66b3bd20c8d37341155441e331832c808403b390a3f7c55ba7cae740c4dcab632dae5d50b07e2bf0bfdd12ad840107L 4 | 5 | ciphertext = 0x1bba15a7386dfaa8a54289adf2031979671aade84780b880149d1de7027d85b4c25f7110793873083f36e4ce300a1b1dcf1d18eeebce65f00e6e5409235a43ff435f685b8527c322b772b86d2936cc4d26b4d6578a04dc54cdeb61dc5de76a339eb00f7ef3a6dd10aa1b5afde092b028e92318049baf7c286c50e06d1a7668deL 6 | e = 3 7 | N = 0xa04f35d80cb1d204c8d74ab48e658b081fb3250775c28c37807d4d0d669ff87f92add4ca150ab4a1fee6978cd1e26f7f5b124a2656252a6d5a8624e0ded5e508460611fa9b0034f2e35c49e2d0fbed10feda06e30102604acfc197327f5da0afe8e33cd66510693e81e838f28ab5164026dfb3dac014696b79463e65d90407ebL 8 | -------------------------------------------------------------------------------- /test_files/projecttest.py: -------------------------------------------------------------------------------- 1 | # This script was written assuming that the RSAExploits directory 2 | # is located in the same directory as this script 3 | 4 | from RSAExploits.RSA_Ciphertext import * 5 | from RSAExploits.exploits import common_modulus as common_modulus 6 | from RSAExploits.exploits import common_modulus_factor as common_modulus_factor 7 | from RSAExploits.exploits import simple_CRT as simple_CRT 8 | 9 | # Parse and store all of the ciphertexts provided by the file 10 | ciphertexts = [] 11 | c = None 12 | e = None 13 | N = None 14 | f = open("common_moduli_test.txt", 'r') 15 | for line in f: 16 | if line.startswith("ciphertext"): 17 | c = long(line.split(" ")[2], 0) 18 | elif line.startswith("e"): 19 | e = long(line.split(" ")[2]) 20 | elif line.startswith("N"): 21 | N = long(line.split(" ")[2], 0) 22 | ciphertexts.append(RSA_Ciphertext(c, N, e)) 23 | f.close() 24 | modulus_dictionary = common_modulus.group_ciphertexts_by_moduli(ciphertexts) 25 | for key in modulus_dictionary: 26 | for i in range(0, len(modulus_dictionary[key]) - 1): 27 | for j in range(1, len(modulus_dictionary[key])): 28 | plaintext = common_modulus.common_modulus_exploit(modulus_dictionary[key][i], modulus_dictionary[key][j]) 29 | if plaintext != None: 30 | print hex(plaintext)[2:-1].decode("hex") 31 | ######################################################################## 32 | 33 | ciphertexts = [] 34 | c = None 35 | e = None 36 | N = None 37 | f = open("common_factor_test.txt", 'r') 38 | for line in f: 39 | if line.startswith("ciphertext"): 40 | c = long(line.split(" ")[2], 0) 41 | elif line.startswith("e"): 42 | e = long(line.split(" ")[2]) 43 | elif line.startswith("N"): 44 | N = long(line.split(" ")[2], 0) 45 | ciphertexts.append(RSA_Ciphertext(c, N, e)) 46 | f.close() 47 | for i in range(0, len(ciphertexts) - 1): 48 | for j in range(1, len(ciphertexts)): 49 | decryptable = common_modulus_factor.common_factor(ciphertexts[i], ciphertexts[j]) 50 | if len(decryptable) > 0: 51 | plaintext = decryptable[0].rsa.decrypt(decryptable[0].c) 52 | if plaintext == 0: 53 | continue 54 | print hex(plaintext)[2:-1].decode("hex") 55 | exit(0) 56 | ''' 57 | my_object = RSAObject("crt_test.txt", 1) 58 | common_modulus.attack(my_object) 59 | common_modulus_factor.attack(my_object) 60 | simple_CRT.attack(my_object) 61 | 62 | my_object = RSAObject("common_factor_test.txt", 0) 63 | common_modulus.attack(my_object) 64 | common_modulus_factor.attack(my_object) 65 | simple_CRT.attack(my_object) 66 | 67 | my_object = RSAObject("common_moduli_test.txt", 1) 68 | common_modulus.attack(my_object) 69 | common_modulus_factor.attack(my_object) 70 | simple_CRT.attack(my_object) 71 | ''' 72 | -------------------------------------------------------------------------------- /test_files/rsaobjtest.py: -------------------------------------------------------------------------------- 1 | 2 | from RSAExploits.exploits import wiener 3 | from Crypto.PublicKey import RSA 4 | 5 | def set_RSAobj(n,e,d=None,p=None,q=None): 6 | if n != None and e != None and d == None and p == None and q == None: 7 | key = RSA.construct((n, e)) 8 | elif n != None and e != None and d != None and p == None and q == None: 9 | key = RSA.construct((n, e, d)) 10 | elif n != None and e != None and d != None and p != None and q == None: 11 | key = RSA.construct((n, e, d, p)) 12 | elif n != None and e != None and d != None and p != None and q != None: 13 | key = RSA.construct((n, e, d, p, q)) 14 | 15 | return key 16 | 17 | 18 | 19 | key = RSA.generate(1024) 20 | 21 | 22 | k = set_RSAobj(key.n,key.e,key.d) 23 | 24 | print wiener.check(k.n,k.e) 25 | 26 | -------------------------------------------------------------------------------- /util.py: -------------------------------------------------------------------------------- 1 | 2 | from sympy import integer_nthroot 3 | 4 | def isprintable(s, codec='utf8'): 5 | try: s.decode(codec) 6 | except UnicodeDecodeError: 7 | return False 8 | else: 9 | return True 10 | 11 | 12 | def int_nthroot(n, r): # returns (rounded root, whether root is int) 13 | (root, exact) = integer_nthroot(n,r) 14 | if exact: 15 | return root 16 | else: 17 | return None 18 | 19 | def CRT(ds, rs): 20 | ''' 21 | Chinese Remainder Theorem 22 | ds: array of dividers 23 | rs: array of remainders 24 | Return the number s such that s mod ds[i] = rs[i] 25 | ''' 26 | length = len(ds) 27 | if not length == len(rs): 28 | print "The lengths of the two must be the same" 29 | return None 30 | 31 | p = i = prod = 1 32 | s = 0 33 | for i in range(length): 34 | prod *= ds[i] 35 | for i in range(length): 36 | p = prod // ds[i] 37 | s += rs[i] * modInv(p, ds[i]) * p 38 | return s % prod 39 | 40 | 41 | def modInv(a, m): 42 | ''' 43 | Return r such that a*r mod m = 1 44 | ''' 45 | g, x, y = eGCD(a, m) 46 | if g != 1: 47 | print("no inverse") 48 | return None 49 | else: 50 | return x % m 51 | 52 | 53 | def eGCD(a, b): 54 | ''' 55 | Extended Euclidean gcd. Return g,x,y such that ax+by=g=gcd(a,b) 56 | ''' 57 | if a == 0: 58 | return (b, 0, 1) 59 | else: 60 | g, y, x = eGCD(b%a, a) 61 | return (g, x-(b//a)*y, y) 62 | -------------------------------------------------------------------------------- /util.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eazebu/RSAExploits/dd6da21fa052744945d73e6166e7adf8cde9086b/util.pyc -------------------------------------------------------------------------------- /utilities/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eazebu/RSAExploits/dd6da21fa052744945d73e6166e7adf8cde9086b/utilities/__init__.py --------------------------------------------------------------------------------