crypto
Challenges

Secure-Server

John Doe uses this secure server where plaintext is never shared. Our Forensics Analyst was able to capture this traffic and the source code for the server. Can you recover John Doe's secrets?
strings capture.pcap
server.py
passive cryptanalysis — we just get the value and reverse engineer it
I didn't do too much beside
stringsthecapture.pcapfile and trace the flawed implementation
Since we know both from the pcap:
john_input(what John enter) —flag ⊕ john_key = encrypted_flagenc2(the print statement)
We can recover the server's secret key using the XOR property:
enc2 = XOR(john_input, server_key)Therefore:
server_key = XOR(john_input, enc2)Once we have the server key, we can decrypt:
flag = XOR(final_input, server_key)
the
decin the code is thefinal_inputwe were looking for

scriptCTF{x0r_1s_not_s3cur3!!!!}
RSA - 1

Yú Tóngyī send a message to 3 peoples with unique modulus. But he left it vulnerable. Figure out :)
I translated the challenge description as:
(Yú Tóngyī) sending
Same message to multiple people
Different moduli ("unique modulus" for each person)
Left it "vulnerable"
Looking at out.txt, we see:
3 different moduli (
n1,n2,n3)3 different ciphertexts (
c1,c2,c3)Same small exponent (
e = 3)Number of messages = exponent value (3 messages, e=3)
We could see that
This is a classic RSA vulnerability so I highly recommend you to read over the CTR article, since the conditions met. We can just follows the theorem and decrypt the flag
Here are the math for...whoever needs it.


scriptCTF{y0u_f0und_mr_yu's_s3cr3t_m3g_12a4e4}
Mod

Just a simple modulo challenge
The challenge generates a random 32-byte (256-bit) secret and implements this simple protocol:
Accept a number from the user
Return
number % secret(our input % secret)Ask for a guess of the secret
Give the flag if the guess is correct
I solved this challenge using a somewhat unconventional approach that involved a fair bit of "educated" guessing. Looking back, I think I got lucky with it 💀.
My solution on the other hands tho...
In my mind: "This is a crypto challenge, so it must require advanced mathematical attacks"
Reality: "a simple logic flaw that can be exploited with basic knowledge"
I think I was heading towards the same direction...although slightly off.
I fundamentally exploits the relationship:
large_number = quotient × secret + remainderSo when we can send a
large_prime = 2^256 + 1and receiveremainder, we can rearrange it to:secret = (large_prime - remainder) / quotientNext:
secretranges from ~2^248 to 2^256 (a wild assumption)large_prime = 2^256 + 1-->
quotient = (2^256 + 1) // secretwill be 1 or 2Then try each possible quotient
qin the estimated rangeCalculate potential secret using
secret = (large_prime - remainder) / qVerify the answer by checking if
large_prime % potential_secret == remainder
scriptCTF{-1_f0r_7h3_w1n_4a3f7db1_43eed08ce9f6}
Secure-Server-2
This is an upsolve - I couldn't solve this challenge during the live competition, but I'm working through it afterwards for learning purposes.
This time, the server is even more secure, but did it actually receive the secret? Simple brute-force won't work!
Solution:
4 keys, each 16 bits (2 bytes)
individual keys are small and easily brute force, it is impossible if combined them.
So we have
We want to find K3 and K4 such that
E4(E3(Value 1)) = Value 2
The same logic for finding K1 and K2.
The "Meet in the Middle".
From the LEFT: encrypt all possible K3 values on Value 1
From the RIGHT: decrypt all possible K4 values on Value 2
Look for where they MEET
We then proceed to reverse the entire process with the all the keys (from Value 1)
scriptCTF{s3cr37_m3ss4g3_1337!_7e4b3f8d}
EaaS

Email as a Service! Have fun...
Let's first analyze the source code that was given to us.
When we connect / run to the server:
We get assigned a random email: Something like
abcdefghij@notscript.sorcererWe must provide a password in hex: Must be a multiple of 16 bytes (AES block size)
Password restrictions: Cannot contain our email address or the string
@script.sorcererThe server encrypts our password using AES-CBC with the same key and IV for both encryption and decryption
So what is our win conditions? To get the flag, we need to:
Trigger
has_flag = Trueby convincing the server that we received an email from the sorcerersCheck messages to read the flag
The server will only set has_flag = True if we can submit encrypted data that when decrypted:
Ends with exactly
@script.sorcerer(last 16 bytes)Contains our assigned email (hint: as one of the comma-separated recipients)
The problem: The server forbids us from including @script.sorcerer and our email in the input, but requires the decrypted output to end with @script.sorcerer and contain our email!, the lines responsible for our problem:
Input validation (what we submit):
Output validation (what gets decrypted):
So of course...we need to find a way to manipulate our input so that after encryption and decryption, it magically contains the forbidden strings.
Well...then we have to understand what the encryption method is being used ...AES-CBC...classic
I think the articles below will do a better job at explaining the CBC Bit-Flipping Attack than I do
The key is that in CBC mode, you can precisely control changes to plaintext by manipulating the previous ciphertext block.
scriptCTF{CBC_1s_s3cur3_r1ght?_3c38ba9890e9}
Last updated
