-
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.
crypto(diffie-helman): add beginner challenge
- Loading branch information
1 parent
e7dc9ce
commit b6597bf
Showing
8 changed files
with
201 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,35 @@ | ||
name: "Diffie-Hellman" | ||
author: "feltf" | ||
category: crypto | ||
|
||
description: | | ||
Play the role of Bob (one of the two parties) in the Diffie-Hellman key | ||
exchange algorithm to obtain the shared secret! | ||
Then decrypt the encrypted flag that Alice will send to you! | ||
You don't have to implement the cryptographic algorithms from scratch. Take a look at the | ||
python crypto library [PyCryptodome](https://pycryptodome.readthedocs.io/en/latest/), | ||
it will help you to decrypt the flag. | ||
value: 500 | ||
type: dynamic_docker | ||
extra: | ||
initial: 500 | ||
minimum: 100 | ||
decay: 25 | ||
redirect_type: direct | ||
compose_stack: !filecontents docker-compose.yml | ||
|
||
flags: | ||
- GTBQ{d1ff1e_h3llm4n_key_exchang3_and_bas1c_crypt0} | ||
|
||
files: | ||
- public/server.py | ||
|
||
tags: | ||
- crypto | ||
- beginner | ||
|
||
state: visible | ||
version: "0.1" |
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,7 @@ | ||
version: '3' | ||
services: | ||
casino: | ||
build: ./setup/ | ||
image: ghcr.io/cybermouflons/gtbq-2024/diffie-hellman:latest | ||
ports: | ||
- 1337:1337 |
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 @@ | ||
../setup/server.py |
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 @@ | ||
FROM ubuntu:22.04 | ||
|
||
RUN apt-get update && apt-get install -y socat python3 python3-pip | ||
|
||
RUN mkdir /app | ||
WORKDIR /app | ||
|
||
COPY requirements.txt /app/ | ||
RUN pip install -r requirements.txt | ||
|
||
COPY secret.py/ /app/ | ||
COPY server.py/ /app/ | ||
|
||
EXPOSE 1337 | ||
CMD ["socat", "-v","TCP-LISTEN:1337,reuseaddr,fork", "EXEC:'python3 /app/server.py'"] |
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 @@ | ||
pycryptodome==3.20.0 |
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 @@ | ||
FLAG = b"GTBQ{d1ff1e_h3llm4n_key_exchang3_and_bas1c_crypt0}" |
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,79 @@ | ||
import secrets | ||
from secret import FLAG | ||
from Crypto.Protocol.KDF import HKDF | ||
from Crypto.Cipher import AES | ||
from Crypto.Util.Padding import pad | ||
from Crypto.Hash import SHA256 | ||
from Crypto.Util.number import long_to_bytes | ||
|
||
class DiffieHellman: | ||
def __init__(self) -> None: | ||
# Diffie-Hellman group (2048-bit MODP Group) | ||
self.p = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF | ||
self.q = (self.p-1)//2 # group order | ||
self.g = 2 # group generator | ||
|
||
def start(self): | ||
print(""" | ||
============================================================= | ||
| | | ||
| Diffie-Hellman Key Exchange: | | ||
| Derive a secret to decrypt the flag | | ||
| | | ||
============================================================= | ||
| (p,q,g) | | ||
| | | ||
| Alice Bob (you) | | ||
| O O | | ||
| /|\ /|\ | | ||
| / \ / \ | | ||
| flag | | ||
| | | ||
| chose random a in [1,q] | | ||
| A = g^a mod p | | ||
| | | ||
| A | | ||
| ----------------------> | | ||
| | | ||
| chose random b in [1,q] | | ||
| S = A^b mod p | | ||
| B = g^b mod p | | ||
| | | ||
| B | | ||
| <---------------------- | | ||
| | | ||
| S = B^a mod p | | ||
| K = HKDF-SHA256(S, 16, "") | | ||
| | | ||
| c, IV = AES-CBC(K, flag) | | ||
| ----------------------> | | ||
=============================================================""") | ||
|
||
print(f"(Info) p={self.p}") | ||
print(f"(Info) q={self.q}") | ||
print(f"(Info) g={self.g}") | ||
|
||
a = secrets.randbelow(self.q) + 1 # Alice's secret value | ||
A = pow(self.g, a, self.p) # Alice's public group member | ||
print(f"(Alice) Bob A is {A}") | ||
try: | ||
B = int(input("(Bob) Alice B is ")) | ||
except: | ||
print("(Error) B is an integer value member of the group (mod p)") | ||
return | ||
|
||
if pow(B, self.q, self.p) != 1: | ||
print("(Error) B is not in the group (mod p)") | ||
return | ||
|
||
S = pow(B, a, self.p) | ||
K = HKDF(long_to_bytes(S), 16, "", SHA256) | ||
|
||
cipher = AES.new(K, AES.MODE_CBC) | ||
c = cipher.encrypt(pad(FLAG, AES.block_size)) | ||
|
||
print(f"(Alice) Bob the encrypted flag (in hex) is {c.hex()} with IV {cipher.iv.hex()}") | ||
|
||
|
||
dhke = DiffieHellman() | ||
dhke.start() |
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,62 @@ | ||
#!/usr/bin/env python3 | ||
import os | ||
import secrets | ||
|
||
from telnetlib import Telnet | ||
|
||
from Crypto.Protocol.KDF import HKDF | ||
from Crypto.Cipher import AES | ||
from Crypto.Util.Padding import unpad | ||
from Crypto.Hash import SHA256 | ||
from Crypto.Util.number import long_to_bytes | ||
|
||
|
||
def solve(tn: Telnet): | ||
# Read p | ||
tn.read_until(b"p=") | ||
p = int((tn.read_until(b"\n")[:-1])) | ||
|
||
# Read q | ||
tn.read_until(b"q=") | ||
q = int((tn.read_until(b"\n")[:-1])) | ||
|
||
# Read g | ||
tn.read_until(b"g=") | ||
g = int((tn.read_until(b"\n")[:-1])) | ||
|
||
# Read Alice's public A | ||
tn.read_until(b"Bob A is ") | ||
A = int((tn.read_until(b"\n")[:-1])) | ||
|
||
# chose random b | ||
b = secrets.randbelow(q) + 1 | ||
# compute Bob's public B | ||
B = pow(g, b, p) | ||
# send public B | ||
tn.read_until(b"Alice B is ") | ||
tn.write(str(B).encode() + b"\n") | ||
|
||
# Read encrypted flag | ||
tn.read_until(b"Bob the encrypted flag (in hex) is ") | ||
c = bytes.fromhex(tn.read_until(b" ")[:-1].decode()) | ||
|
||
# Read IV | ||
tn.read_until(b"with IV ") | ||
IV = bytes.fromhex(tn.read_until(b"\n")[:-1].decode()) | ||
|
||
# Until here it can be done manually, i.e., extract info from server responses | ||
S = pow(A, b, p) | ||
K = HKDF(long_to_bytes(S), 16, "", SHA256) | ||
|
||
cipher = AES.new(K, AES.MODE_CBC, IV) | ||
flag = unpad(cipher.decrypt(c), AES.block_size) | ||
print(flag) | ||
|
||
if __name__ == "__main__": | ||
if "REMOTE" in os.environ: | ||
HOSTNAME = "" | ||
else: | ||
HOSTNAME = "localhost" | ||
PORT = 1337 | ||
with Telnet(HOSTNAME, PORT) as tn: | ||
solve(tn) |