This was basically the warm-up for the crypto category. We get an image which represents the encoded flag (as you’ll see in a moment, you can’t call it encrypted):
The flag format is also specified within the challenge: PICOCTF{}. We see that there are exactly 7 letters before {, so each number represents one letter ( ‘P’ -> 16, ‘I’ -> 9, ‘C’ -> 3, etc.). It didn’t take me long before discovering the rule: the letter ‘P’ is on the 16th position in the alphabet, the letter ‘I’ on the 9th, and so on. Because I am very lazy, I wrote a simple python script to get the flag:
After running the script, we get the flag:
Flag: PICOCTF{THENUMBERSMASON}
13 (100) {#13}
I won’t explain ROT13 here, you can find more about it online. One interesting to note, though, is that Linux has a program called ‘rot13’ that can be used to easily encode/decode a string using ROT13:
Flag: picoCTF{not_too_bad_of_a_problem}
Easy1 (100)
There’s also a file attached containing the following text:
Anyone who has a decent knowledge of cryptography will recognize this as a Vigenère cipher. We can use an online tool to get the flag:
Flag: picoCTF{CRYPTOISFUN}
caesar (100)
Along with the text, we ar given a file containing the following message:
The text between the curly braces (ynkooejcpdanqxeykjrnpavoth) is encrypted using a classical caesar cipher. We can use this tool to bruteforce the key (which is just the shift of the letters, so we only have 26 possible keys):
The plaintext was encrypted using the shift value 3.
Flag: picoCTF{crossingtherubiconvrtezsxl}
Flags (100)
We are also given the following image:
The flag is encoded using the maritime flag system. This article gives a very good explanation of this system. Basically, each flag represents a letter/number:
</figure>
The flag is all uppercase.
Flag: PICOCTF{F1AG5AND5TUFF}
Mr-Worldwide (200)
I still don’t understand the ‘musician’ clue. In order to obtain the flag, we search each of those coordinates on google and take the first letter of the city they point to.
For the first pair of coordinates, for example, the first letter of the city name is K.
Flag: picoCTF{KODIAK_ALASKA}
Tapping (200)
This time, we get an address and a port to connect to. Unfortunately, the returned text is static and the challenge is simple 😛
The ‘tapping coming in from the wires’ is a clear reference to Morse code. There are a lot of online tools that can decode the flag; I used this one.
We just need to replace ? with {} and capitalize the text.
Flag: PICOCTF{M0RS3C0D31SFUN903140448}
la cifra de (200)
Again, we are given an IP address and a port number to connect to:
After multiple attempts in decrypting the ciphertext, I found it to be encrypted with the Vigenère cipher. In order to decrypt the ciphertext, we also need a key, which is usually a word. I used this online tool to crack the key:
In addition to the plaintext, the tool also gives us the key: flag.
Flag: picoCTF{b311a50_0r_v1gn3r3_c1ph3rb6cdf651}
rsa-pop-quiz (200)
If you do not know anything about RSA, I recommend one of my previous articles. Let’s connect to the specified IP & port and see what we have to do:
There will be several ‘problems’ that test our understanding of RSA. I will post a screenshot with every problem, along with a python code snippet that shows the formulas I used. If you don’t understand something, feel free to ask me in the comments or just USE GOOGLE. The first problem is pretty simple:
The second problem implies using the same formula:
Because of the factoring problem, the 3rd problem does not have a solution:
The fourth problem requires a new formula for phi/totient(n):
The fifth problem finally requires us to encrypt a plaintext:
Having only the ciphertext and the public key (WHICH WAS SECURELY GENERATED), it’s impossible to deduce the plaintext:
The 7th problem swiftly moves us in the direction of decryption, introducing the formula for d:
The 8th problem asks us to decrypt a ciphertext:
After finishing the last problem, the service tells us that the plaintext is the numeric representation of the flag string. We an easily recover the flag using the long_to_bytes() function:
Flag: picoCTF{wA8_th4t$_ill3aGal..o1c355060}
miniRSA (300)
I would like to start by telling you that the ‘small thing’ is located in the attached file, not outside your computer. Speaking of the attached file, it contains an RSA public key and a ciphertext:
When e is very small (3), N very big and the plaintext is short, the ciphertext becomes the plaintext raised to the power of e: ct = pt ^ e mod n = pt ^ e if pt ^ e < n. We can use python to extract the flag:
We just have to paste the ciphertext, click on ‘solve’ and wait a few seconds. In addition, we can just fill in the missing letters, as the flag consists of an intuitive sentence.
Flag: frequency_is_c_over_lambda_drtmtnddlw
b00tl3gRSA2 (400)
As a general rule, we can switch e with d and RSA will still work. However, if the e value is small or a default value (like 3/65537), the cryptographic system can be easily broken, as d will be known. Also, I have to appreciate that n and e change for every connection we make to the server:
Because a default value of e was assigned to d, we don’t need to bruteforce anything (d=65537). We can use python (again) to get the flag:
Flag: picoCTF{bad_1d3a5_4986370}
AES-ABC (400)
Along with the challenge’s text, we get an encrypted file and the python script used to encrypt the original file:
Basically, the nth block of AES-ABC represents the sum of the first n blocks of AES-ECB. The .ppm extension looked familiar, so I searched the web and found the following image:
</figure>
The .ppm extension was used to demonstrate this property of AES-EBC. If we are able to recover the file encrypted image using ECB mode, we should theoretically be able to read the flag. I used the following script to get that image:
After running the script, a new file is created that contains the readable flag:
Flag: picoCTF{d0Nt_r0ll_yoUr_0wN_aES}
b00tl3gRSA3
The public key changes for every connection, so I’ll just save some parameters in a file, as the flag will (hopefully) not change in the near future:
From the challenge text, we know that n has more than 2 prime factors. This makes RSA insecure, as the prime factors have to get smaller in order to generate a 2048-bit n. Alpetron’s Integer Factorization Calculator is able factorize n in less than 2 seconds:
We can now easily calculate d and decrypt the ciphertext. The only difference between 2-prime RSA and this implementation is that we need to use a more generalized formula for totient(n) (phi is equal to the product of all the factors of n, each decreased by 1). I used the following script o get the flag:
The script outputs exactly one thing: the flag.
Flag: picoCTF{too_many_fact0rs_8024768}
john_pollard (500)
We are also given a public RSA certificate:
We can use pyCrypto’s built-in PEM parser to get n and e:
n is very small (4966306421059967), so we can use Alpetron again to get p and q: