A few words about project reports

Written on 19.12.2017 19:31 by Johannes Krupp

Hi all,

as grading of the first project is nearing completion, we’d like to clarify a few things and give you some hints for future reports.

Why and How

As you might have already guessed, the purpose of the report is for us to see that you have understood a vulnerability/an exploit and came up with a solution on your own. This usually boils down to answering two questions:

  1. Why exactly does something pose a vulnerability?
  2. How can this vulnerability be exploited to do “bad things”?


As an example, here are two solutions for task 1 we received:

When looking at the provided cipher it was hard to gain any information, because it was obviously encoded and not readable. We decided to write a short python script which decodes the given. cipher in ascii and store the result in an array so we can simply output it. The code we used is named

This solution raises more questions than it answers, e.g., what is meant be “decode”? How does the script decode things? Why is it possible to write a script that simply decodes the ciphertext?

A better solution is the following:

[…] From this snippet we can easily guess that we are dealing with a monoalphabetic substitution cipher of some sort. The easiest one to try here is a Caesar cipher. It’s just a few lines of codethere’s no reason not to try it before thinking about alternatives. […] Given that we only have 255 possible keys, we can simply try out all of them and see for which keys we obtain a meaningful plaintext – for readability, it pays off to just look at a small snippet, e.g., the first 50 characters. Again, we used a different approach. Being confident that we’d find the word “flag” in the plaintext, we just checked for its occurrence.

for i in range(256):
    dec = ' '.join(map(chr, [(ord(x)+i)%256 for x in cipher]))
    if 'flag' in dec:
        print "Found possible solution for key %d:"%i
        print dec

From this solution it becomes clear that the weakness of Caesar’s cipher is the fact, that there are only 255 possible ciphertexts for a given message, which makes it feasible to just try out all possibilities (this answers a)). It also shows enough code to explain how possibilities are computed and how the correct plaintext can be identified (this answers b)).

Source Code

As stated in the project presentation slides, your report should contain a technical description of your solution. However, many submissions we received were written like this:

We first read the as described on the assignment sheet and also in our Code/Exercise3 folder. The python file is called In the same file below the code for the key is the code that actually does the brute-forcing. We now run that code. This prints out loads of 2B strings on the command line and also writes it to a text document. […]

While it explains where the code that does “the brute-forcing” can be found and that it emits lots of 2B strings, it would have been much more insightful to state what “the brute-forcing” actually was, and what these 2B strings represent.

A better solution would have been

The memo reveals two severe security flaws which help us decrypt the captured data: Firstly, they use no padding. This has two implications on security: 1. Some message m always encrypts to the same ciphertext c as no randomization is added. 2. The size of the ciphertext space is upper-bounded by the size of the message space. Secondly, they only encrypt two bytes of plaintext at a time. Thus the size of the message space is upper-bounded by 2^16 = 65536. By putting all these observations together, we concluded that a simple dictionary attack is feasible.

Given the vulnerability, this part is pretty straight forward. The first step is to create a dictionary containing all the ciphertexts:

dic = dict()
for i in range(2**16):
    dic[pow(i, key.e , key.n)] = i


Of course, it is sometimes easier to explain something in code rather than describing it, so please don’t be afraid to include code snippets in your report. Ideally, the additional sourcecode you provide only serves as an additional resource for details, but your report should be fully understandable without looking at extra files.

Using Third-Party Tools

As already discussed on askbot (, you may use any third-party tools or libraries in your solutions, given that you understand how the tool works, and, more importantly, can explain to us, why it works. As an example, many of you found the RsaCtfTool ( helpful for task 2. Consider the following two submissions:

By looking at e and n of the publickey, we found that e is remarkibly small, so we searched for fitting attacks, one of them being the wiener-attack. […] As we looked through the descriptions of the attack, we found multiple scripts on github imple- menting this attack, so we tried them out. The first one was faulty, but the second one worked fine. We added the zip of the tool to the code folder.

While this submission clearly states that a third-party tool was used, it also becomes evident, that the submitters did not understand the attack or how the tool worked: The weak part of the key is not e. In fact, this value for e is commonly used in many RSA-keys. Further, while the wiener-attack is an attack against RSA, it is not applicable here. The weakness is rather in the fact that n is easily factorizable, by one prime being very small (53) and the other being a well-known mersenne prime (M4423), which allows to easily recompute phi(n) and obtain d. The only reason their “solution” worked was because the RsaCtfTool also implements a bunch of other attacks, one of them trying to factorize n.

In contrast, this submission which uses RsaCtfTool is perfectly fine:

After some web research, we found a tool which is able to perform many known attacks on a weak RSA scheme called RsaCtfTool. After installing and executing the tool in the commandline with the command

python2 RsaCtfTool-master/ --verbose --publickey RSApkey.pem --private

it automatically performs one attack after another, until an attack was successfull, or all attacks were executed. In our case, the verbose option informed us, that the ”factordb attack” was suc- cessfull. Examining the sourcecode of the RsaCtfTool showed, that this attack simply checks, if a certain online database ( has stored matching primes p and q such that p ∗ q = n and then it uses the invmod() function of the python package libnum, to compute the secret exponent d with e ∗ d = 1 mod ((p−1)(q−1)). With n, e and d, the RSA private key was computed and was displayed as the rest of the output. We saved the RSA private key in a file (RSAskey.pem) and used the decrypt() function of the Crypto.Publickey.RSA python package to decrypt the ciphertext (cipher).

This answer makes it clear that the weakness is due to factorizing n and also details how the private key d can be computed from the results.


  • Explain why and how your exploit works
  • Keep all relevant information in the pdf-report (but still submit your code)
  • If you use a third-party tool/library, explain why and how it works

All the best


P.S.: Posting this now might be related to the next project deadline on Thursday morning ;)

Privacy Policy | Legal Notice
If you encounter technical problems, please contact the administrators.