Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

crypto/cha-cha-slide #5

Merged
merged 3 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions cha-cha-slide/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM python:3.12-bookworm

WORKDIR /app

RUN wget -O ynetd.c \
https://raw.githubusercontent.com/johnsonjh/ynetd/e6fd08f8f5d0c6b8c18d645957e30ce012536ed4/ynetd.c \
&& echo "ec7509dec7737da54f8b18e1b5ba935d657f9f016c36cfc9ac08f9952373226f ynetd.c" | sha256sum -c \
&& gcc -o ynetd ynetd.c

COPY ./flag.txt .

WORKDIR /app/server

COPY ./server .

RUN pip install -r requirements.txt

ENTRYPOINT ["../ynetd", "-p", "3000", "python3 ./server.py"]
19 changes: 19 additions & 0 deletions cha-cha-slide/chall.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Cha-Cha Slide
categories:
- crypto
value: 75
flag:
file: ./flag.txt
description: |-
I made this cool service that lets you protect your secrets
with state-of-the-art encryption. It's so secure that we don't
even tell you the key we used to encrypt your message!
files:
- src: ./server/server.py
deploy:
nc:
build: .
expose: 3000/tcp
authors:
- Thomas
visible: true
1 change: 1 addition & 0 deletions cha-cha-slide/flag.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bcactf{b3_C4rEFu1_wItH_crypT0Gr4phy_7d12be3b}
1 change: 1 addition & 0 deletions cha-cha-slide/server/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pycryptodome==3.19.0
36 changes: 36 additions & 0 deletions cha-cha-slide/server/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from Crypto.Cipher import ChaCha20

from os import urandom

key = urandom(32)
nonce = urandom(12)

secret_msg = urandom(16).hex()

def encrypt_msg(plaintext):
cipher = ChaCha20.new(key=key, nonce=nonce)
return cipher.encrypt(plaintext.encode()).hex()

print('Secret message:')
print(encrypt_msg(secret_msg))

print('\nEnter your message:')
user_msg = input()

if len(user_msg) > 256:
print('\nToo long!')
exit()

print('\nEncrypted:')
print(encrypt_msg(user_msg))

print('\nEnter decrypted secret message:')
decrypted_secret_msg = input()

if len(decrypted_secret_msg) == len(secret_msg):
if decrypted_secret_msg == secret_msg:
with open('../flag.txt') as file:
print('\n' + file.read())
exit()

print('\nIncorrect!')
24 changes: 24 additions & 0 deletions cha-cha-slide/solve.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env -S deno run

// ChaCha20 works by XORing the plaintext with a stream generated from
// the (key, nonce) pair. Since this pair is reused for encrypting the
// secret message and the user's message, the following operations can be
// performed to reveal the secret plaintext given the secret ciphertext:
// 1. user_ciphertext = user_plaintext ⊕ stream
// 2. stream = user_plaintext ⊕ user_ciphertext
// 3. secret_plaintext = stream ⊕ secret_ciphertext

const fromHex = (hex: string) => hex.match(/.{2}/g)!.map(byte => parseInt(byte, 16))

const secretMsg = fromHex(prompt('Enter secret message:')!)

console.log('Enter this as your message: ' + '1'.repeat(secretMsg.length))

const encryptedUserMsg = fromHex(prompt('Enter encrypted user message:')!)

const decryptedSecretMsg = secretMsg
.map((v, i) => v ^ encryptedUserMsg[i])
.map(v => String.fromCharCode(v ^ '1'.charCodeAt(0)))
.join('')

console.log('Decrypted secret message: ' + decryptedSecretMsg)
Loading