-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit da959b2
Showing
1,170 changed files
with
217,373 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Fall CTF 2024 Challenge Repo | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Solution | ||
|
||
It's very easy to factor the given prime with wolfram alpha or dCode. | ||
After you've got the factors, all you need to do is walk through the RSA decryption algorithm in the guides book. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
name: "Baby RSA" | ||
author: Sagnik | ||
category: Crypto | ||
description: |- | ||
RSA-1024, RSA-2048, RSA-4096 exist. How about RSA-64? | ||
**author**: Sagnik | ||
value: 500 | ||
type: dynamic | ||
tags: | ||
- easy | ||
extra: | ||
initial: 500 | ||
decay: 150 | ||
minimum: 100 | ||
flags: | ||
- fallctf{small_n_bad} | ||
files: | ||
- rsa.txt | ||
hints: | ||
- Keep in mind RSA normally works on 1024 bit integers at the minimum. This n is much smaller than that. Can we brute force the primes? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import binascii | ||
|
||
flag = "small_n_bad" | ||
flag = binascii.hexlify(flag.encode("utf-8")) | ||
m = int(flag, 16) | ||
|
||
p = 17378651858107286503 | ||
q = 12428326454008306487 | ||
n = p*q | ||
print(n) | ||
|
||
e = 17 | ||
c = pow(m, e, n) | ||
|
||
print(hex(int(c))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
from Crypto.Util.number import long_to_bytes, bytes_to_long | ||
import random | ||
|
||
#use the miller-rabin primality test to generate 2 random large primes | ||
def miller_rabin(n, k=40): | ||
if n in [2, 3]: return True | ||
if n < 2 or n % 2 == 0: return False | ||
r, d = 0, n - 1 | ||
while d % 2 == 0: r, d = r + 1, d // 2 | ||
def witness(a): | ||
x = pow(a, d, n) | ||
if x == 1 or x == n - 1: return True | ||
return any(pow(x, 2**i, n) == n - 1 for i in range(r-1)) | ||
return all(witness(random.randint(2, n - 2)) for _ in range(k)) | ||
def generate_large_prime(bits): | ||
gen_candidate = lambda : random.getrandbits(bits) | 1 | (1 << bits - 1) | ||
return next(filter(miller_rabin, iter(lambda: gen_candidate(), None))) | ||
|
||
# Generate two 1024-bit primes for RSA | ||
prime1 = generate_large_prime(64) | ||
prime2 = generate_large_prime(64) | ||
|
||
print(f"p = {prime1}") | ||
print(f"q = {prime2}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
n = 215987558623115398761128944381942444961 | ||
e = 17 | ||
fallctf{612c0496141e3bb1fae92923929ba5f8} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import binascii | ||
|
||
c = int('612c0496141e3bb1fae92923929ba5f8', 16) | ||
|
||
# You can find these however you want (factordb, wolfram alpha, brute force, etc) | ||
p = 17378651858107286503 | ||
q = 12428326454008306487 | ||
|
||
# public key | ||
n = p*q | ||
e = 17 | ||
|
||
totient = (p-1)*(q-1) | ||
|
||
# this is "fast" in sage, use pow(e, -1, totient) in python 3.8+, cry in python < 3.8 | ||
d = pow(e, -1, totient) | ||
print(d) | ||
|
||
solved_m = pow(c, d, n) | ||
print(binascii.unhexlify(hex(int(solved_m))[2:])) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Solution | ||
the salad.txt file reads: | ||
``` | ||
Hknai eloqi kzkn wiap, ykjoaypapqan wzeleoyejc ahep. Lkpajpe ejpanzqi lkpajpe, lkpajpe qnjw iwppeo ikhheo wlpajp qnjw. Iwppeo lwnpqneajp oajaypqo ewyqheo iwcjeo oaz zewi jwi ikjpao. Iwcjw aop iwcjw, fqopk jeoh mqeomqa rah qp. Dwy oailan oailan repwa yqnwxepqn haypqo repwa jeoe lneieo. Wqcqa anwp ldwnapnw lhwyanwp rahep fqopk ejpacan ldwoahhqo oyahaneomqa iwcjeo. Jwpkmqa: aop_wzeleoyejc_lhwpaw. Bejexqo iwcjw wqypkn hwyqo. Lknppepkn baqcewp ldwoahhqo, repwa bejexqo baheo lneieo. | ||
Japqo pailkn eilanzeap bwyeheoe yhwoo; iwcjeo okzwhao. Ldwnapnw qhpneyeao lkoqana bwqyexqo pailkn ykiikzk hak, dwxepwooa abbeyepqn wz:H Zeypqi rahep wp ykjcqa lhwyanwp zecjeooei ap hecqhw ajei. Yhwoo ikhheo lajwpexqo: ejyalpko_oai ikhaopea_wqcqa_wzeleoyejc. Ldwoahhqo hwyqo jwoyapqn ikhaopea ez hexank jeoh lknppepkn iwteiqo ie. Pda oaynap iaoowca eo: pdeo_owhwz_pwopao_cnawp. | ||
Yhwoo rqhlqpwpa ynwo jeoe wyyqiowj ejyalpko. Xhwjzep jqhhw iknxe mqwi lnapeqi nezeyqhqo cnwrezw zeypqi. Ykiikzk hecqhw ndkjyqo aqeoikz lkpajpe lhwyanwp bwyeheoe ikhheo. Jeoe hwyejew knjwna baheo wz jqjy qhpneyeao bnejcehhw iwteiqo. Rah jay ykjoaypapqn ykjzeiajpqi oqoyelep, wqypkn lahhajpaomqa qnjw. | ||
``` | ||
|
||
If we go to [CyberChef](https://gchq.github.io/CyberChef/), | ||
we have a tool that can reverse any text by the entered enough. | ||
|
||
We can change the rotation amount through the drop down until we get something that might look readable. | ||
Upon using amt "4", we see some text that reads "Lorem ipsum..." | ||
![alt text](image.png) | ||
Now while this isn't english like we would normally expect, Lorem Ipsum texts are latin placeholders, and so any time we see the text show up, we know we found the right amount. Sure enough, if we scroll down the output, we see: | ||
|
||
![alt text](image-1.png) | ||
Thus, our flag is `fallctf{this_salad_tastes_great}` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
name: "Caesar Salad" | ||
author: Sagnik | ||
category: Crypto | ||
description: |- | ||
Can you find the secret sauce? I hid it with this amazing salad. | ||
Flag is of the format fallctf{secret message}, | ||
where the secret message should be contained in the decrypted text | ||
**author**: Sagnik | ||
value: 500 | ||
type: dynamic | ||
tags: | ||
- beginner | ||
extra: | ||
initial: 500 | ||
decay: 150 | ||
minimum: 100 | ||
flags: | ||
- fallctf{this_salad_tastes_great} | ||
files: | ||
- salad.txt | ||
hints: | ||
- This is a classic [Caesar Cipher](https://en.wikipedia.org/wiki/Caesar_cipher) | ||
- Check out [Cyber Chef](https://gchq.github.io/CyberChef/) for a helpful tool! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Hknai eloqi kzkn wiap, ykjoaypapqan wzeleoyejc ahep. Lkpajpe ejpanzqi lkpajpe, lkpajpe qnjw iwppeo ikhheo wlpajp qnjw. Iwppeo lwnpqneajp oajaypqo ewyqheo iwcjeo oaz zewi jwi ikjpao. Iwcjw aop iwcjw, fqopk jeoh mqeomqa rah qp. Dwy oailan oailan repwa yqnwxepqn haypqo repwa jeoe lneieo. Wqcqa anwp ldwnapnw lhwyanwp rahep fqopk ejpacan ldwoahhqo oyahaneomqa iwcjeo. Jwpkmqa: aop_wzeleoyejc_lhwpaw. Bejexqo iwcjw wqypkn hwyqo. Lknppepkn baqcewp ldwoahhqo, repwa bejexqo baheo lneieo. | ||
Japqo pailkn eilanzeap bwyeheoe yhwoo; iwcjeo okzwhao. Ldwnapnw qhpneyeao lkoqana bwqyexqo pailkn ykiikzk hak, dwxepwooa abbeyepqn wz:H Zeypqi rahep wp ykjcqa lhwyanwp zecjeooei ap hecqhw ajei. Yhwoo ikhheo lajwpexqo: ejyalpko_oai ikhaopea_wqcqa_wzeleoyejc. Ldwoahhqo hwyqo jwoyapqn ikhaopea ez hexank jeoh lknppepkn iwteiqo ie. Pda oaynap iaoowca eo: pdeo_owhwz_pwopao_cnawp. | ||
Yhwoo rqhlqpwpa ynwo jeoe wyyqiowj ejyalpko. Xhwjzep jqhhw iknxe mqwi lnapeqi nezeyqhqo cnwrezw zeypqi. Ykiikzk hecqhw ndkjyqo aqeoikz lkpajpe lhwyanwp bwyeheoe ikhheo. Jeoe hwyejew knjwna baheo wz jqjy qhpneyeao bnejcehhw iwteiqo. Rah jay ykjoaypapqn ykjzeiajpqi oqoyelep, wqypkn lahhajpaomqa qnjw. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Solution | ||
|
||
Given Alice's x coordinate, it isn't too difficult to extract the $y$ coordinate, as we know it must be on the defined Elliptic curve. Without sage, you can do this by calculating | ||
$$y^2 = x^3 + ax + b$$ | ||
directly, and then doing a modular square root operation. This is done using the mod_sqrt function, which checks if $y^2$ is a quadratic residue mod $p$ (easy as $p$ is $3 \mod 4$), | ||
and if so, does | ||
$$\left(y^2\right)^{\frac{p+1}{4}} \mod p$$ | ||
|
||
This should give one of the two possible points that could be the secret. | ||
|
||
If you do use sage, the challenge becomes much easier. All you need to do is define the Elliptic curve object `E` using the params given and then call `E.lift_x(Q_a_x)` to find Alice's 2 possible $y$ coords, either from which you can find either shared secret through calculating the points on the curve corresponding to $S = [n_B]Q_a$ | ||
|
||
Either point works, as the x-coordinate is all you need. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
name: "Curveball" | ||
author: Sagnik | ||
category: Crypto | ||
description: |- | ||
Hi there Bob! Let's say you wanted to send a handshake to Alice. You choose a curve | ||
`y^2 = (x^3 + ax + b) mod p` and generator point `G(G_x, G_y)`. | ||
Now Alice was going to send you her public point Q_a, but it seems that the transmission glitched, and | ||
you only got her x coordinate, `Q_a_x`. Can you still get your shared secret? | ||
**Note**: The actual shared secret for the decryptor would be the SHA-256 hash of the x coordinate of the shared secret. | ||
So that would be `sha256(S_x)` | ||
**Note**: There is two shared secrets you can arrive at, only one of them will work. | ||
**author**: Sagnik | ||
value: 500 | ||
type: dynamic | ||
tags: | ||
- hard | ||
extra: | ||
initial: 500 | ||
decay: 150 | ||
minimum: 100 | ||
flags: | ||
- fallctf{n0t_s0_s3cr3t_anYm0r3} | ||
files: | ||
- decryptor.py | ||
- client.json | ||
hints: | ||
- See [ECDH](https://cryptobook.nakov.com/asymmetric-key-ciphers/ecdh-key-exchange) for more info about the protocol. | ||
- Is it possible to get back Alice's y coordinate? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"ecdhke_client": { | ||
"iv": "e7646ff19954f0db69379d8dc902abbc", | ||
"ciphertext": "a2bd63234c90778210edbb62d67ec020154187652a57636549e21f52ed6c965c", | ||
"curve_params": { | ||
"a": 123001240123101920407, | ||
"b": 2390490212093, | ||
"p": 269123855285160332211801709888382470147, | ||
"G_x": 141223464919893415164492319302044521923, | ||
"G_y": 105945507900846830121381021840356606089 | ||
}, | ||
"given": { | ||
"Q_a_x": 19299658936035824596857706134874824001, | ||
"n_B": 853735663 | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
from Crypto.Cipher import AES | ||
from Crypto.Util.Padding import pad, unpad | ||
import hashlib | ||
|
||
|
||
def is_pkcs7_padded(message): | ||
padding = message[-message[-1]:] | ||
return all(padding[i] == len(padding) for i in range(0, len(padding))) | ||
|
||
|
||
def decrypt_flag(shared_secret: int, iv: str, ciphertext: str): | ||
# Derive AES key from shared secret | ||
sha1 = hashlib.sha1() | ||
sha1.update(str(shared_secret).encode('ascii')) | ||
key = sha1.digest()[:16] | ||
# Decrypt flag | ||
ciphertext = bytes.fromhex(ciphertext) | ||
iv = bytes.fromhex(iv) | ||
cipher = AES.new(key, AES.MODE_CBC, iv) | ||
plaintext = cipher.decrypt(ciphertext) | ||
|
||
if is_pkcs7_padded(plaintext): | ||
return unpad(plaintext, 16).decode('ascii') | ||
else: | ||
return plaintext.decode('ascii') | ||
|
||
|
||
shared_secret = '?' #the sha256 hash of the 2 coordinates of the shared secret concatenated together, SHA-256(S_x|S_y) | ||
iv = '?' #from ecdhke client | ||
ciphertext = '?' #from ecdhke client | ||
|
||
print(decrypt_flag(shared_secret, iv, ciphertext)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
from Crypto.Cipher import AES | ||
from Crypto.Util.Padding import pad | ||
import hashlib | ||
import os | ||
|
||
def encrypt_flag(shared_secret: int, iv: str, flag: str): | ||
# Derive AES key from shared secret | ||
sha1 = hashlib.sha1() | ||
sha1.update(str(shared_secret).encode('ascii')) | ||
key = sha1.digest()[:16] | ||
|
||
# Encrypt the flag | ||
cipher = AES.new(key, AES.MODE_CBC, iv) | ||
ciphertext = cipher.encrypt(pad(flag.encode('ascii'), 16)) | ||
|
||
return ciphertext.hex() | ||
|
||
shared_secret = 'df700d2f1344ef3bdc60394e643af298fe7983f34f73da973797ecfb4a790575' # Replace with your actual shared secret | ||
iv = os.urandom(16) # Randomly generate a 16-byte IV | ||
|
||
# Flag to encrypt | ||
flag = "fallctf{n0t_s0_s3cr3t_anYm0r3}" | ||
|
||
# Encrypt the flag | ||
ciphertext = encrypt_flag(shared_secret, iv, flag) | ||
|
||
# Print the IV and encrypted flag in hexadecimal format | ||
print("IV:", iv.hex()) | ||
print("Encrypted flag:", ciphertext) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
## The solution file. | ||
import hashlib | ||
def modinv(a, p): | ||
""" Return the modular inverse of a mod p using the extended Euclidean algorithm """ | ||
if a == 0: | ||
return 0 | ||
lm, hm = 1, 0 | ||
low, high = a % p, p | ||
while low > 1: | ||
ratio = high // low | ||
nm, new = hm - lm * ratio, high - low * ratio | ||
lm, low, hm, high = nm, new, lm, low | ||
return lm % p | ||
|
||
def elliptic_curve_add(P, Q, a, p): | ||
""" Add two points P and Q on an elliptic curve with given parameters """ | ||
if P is None: | ||
return Q | ||
if Q is None: | ||
return P | ||
if P == Q: # Point doubling | ||
x1, y1 = P | ||
if y1 == 0: | ||
return None # Point at infinity | ||
lam = (3 * x1**2 + a) * modinv(2 * y1, p) % p | ||
else: # General point addition | ||
x1, y1 = P | ||
x2, y2 = Q | ||
if x1 == x2 and y1 != y2: | ||
return None # P + Q = O (point at infinity) | ||
lam = (y2 - y1) * modinv(x2 - x1, p) % p | ||
|
||
x3 = (lam**2 - x1 - (x2 if P != Q else x1)) % p | ||
y3 = (lam * (x1 - x3) - (y1 if P != Q else y1)) % p | ||
|
||
return (x3, y3) | ||
|
||
def legendre_symbol(a, p): | ||
""" Compute the Legendre symbol a|p. Returns 1 if a is a quadratic residue mod p, -1 otherwise """ | ||
return pow(a, (p - 1) // 2, p) | ||
|
||
# calculate modular square root from y using legendre symbol | ||
def mod_sqrt(a, p): | ||
""" Compute the modular square root of a mod p, if it exists """ | ||
if legendre_symbol(a, p) != 1: | ||
return None # no sqrt exists | ||
if a == 0: | ||
return 0 | ||
if p % 4 == 3: | ||
return pow(a, (p + 1) // 4, p) | ||
# For general case where p % 4 != 3, use Tonelli-Shanks or other methods | ||
raise NotImplementedError("General modular square root not implemented") | ||
|
||
def elliptic_curve_mult(P, k, a=123001240123101920407, p=269123855285160332211801709888382470147): | ||
""" Perform scalar multiplication using the double-and-add method """ | ||
result = None # Start with the point at infinity | ||
addend = P | ||
|
||
while k > 0: | ||
if k & 1: | ||
result = elliptic_curve_add(result, addend, a, p) | ||
addend = elliptic_curve_add(addend, addend, a, p) | ||
k >>= 1 | ||
|
||
return result | ||
|
||
# Curve parameters | ||
a = 123001240123101920407 | ||
b = 2390490212093 | ||
p = 269123855285160332211801709888382470147 | ||
G = (141223464919893415164492319302044521923, 105945507900846830121381021840356606089) | ||
|
||
|
||
Q_a_x = 19299658936035824596857706134874824001 | ||
y_squared = (Q_a_x**3 + a * Q_a_x + b) % p | ||
y = mod_sqrt(y_squared, p) | ||
Q_a = (Q_a_x, y) | ||
|
||
#secret: | ||
n_B = 853735663 | ||
S = elliptic_curve_mult(Q_a, n_B) | ||
print(f"The shared secret S(x, y) = {S}") | ||
secret = hashlib.sha256(f"{S[0]}".encode('utf-8')).hexdigest() | ||
print(f"Shared secret to use: {secret}") |
Oops, something went wrong.