Tema

Deadline: 21 noiembrie 2021, ora 23:55

Actualizări

9.11.2021 - am reîncărcat arhiva de texte criptate pentru Task 2 (MTP), erau 15 fișiere în loc de 11, ultimele 4 nu vă ajutau cu nimic.

Task 1 - CBC Encryption (50p)

Pentru acest exercițiu, aveți acces la un serviciu de criptare care poate cripta și decripta folosing AES CBC.

Ai reușit să obții o bucată de cod din implementarea serverului:

server.py
key = ### REDACTED ###
 
class EncryptRequest(BaseModel):
    plaintext: bytes
 
class DecryptRequest(BaseModel):
    ciphertext: bytes
 
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):
    return PlainTextResponse(str(exc), status_code=400)
 
 
@app.post('/encrypt')
async def encrypt(req: EncryptRequest):
    plaintext = b64decode(req.plaintext)
    cipher = AES.new(key, AES.MODE_CBC, iv=key)
    ciphertext = cipher.encrypt(pad(plaintext))
    ct_b64 = b64encode(ciphertext)
    return ct_b64
 
@app.post('/decrypt')
async def decrypt(req: DecryptRequest):
    cipher = AES.new(key, AES.MODE_CBC, iv=key)
    ciphertext = b64decode(req.ciphertext)
    plaintext = cipher.decrypt(ciphertext)
    pt_b64 = b64encode(plaintext)
    return pt_b64
 
def pad(pt):
    pad_len = AES.block_size - len(pt) % AES.block_size
    padding = bchr(pad_len) * pad_len
    return pt + padding

Încearcă să găsești vulnerabilități în implementarea acestui serviciu și scrie un script care să extragă cheia secretă din server.

Serverul se găsește aici: http://141.85.224.119:31800

Poți găsi detalii despre endpoint-urile serviciului pe pagina principală a serverului. Serverul are două endpoint-uri HTTP POST pe care le poți chema, encrypt și decrypt, fiecare primind un parametru (plaintext și ciphertext, respectiv) în format base64 și întoarce datele în format base64 de asemenea.

Update: Dacă vă ajută, puteți porni de la următorul schelet de cod (scris în python3)

skel.py
import requests
import base64
 
URL = 'http://141.85.224.119:31800/'
 
def call_encrypt(plaintext):
    P = b64encode(plaintext)
    data = { 'plaintext': P.decode() }
    resp = requests.post(URL + 'encrypt', json=data)
    C = b64decode(resp.content)
    return C
 
def call_decrypt(ciphertext):
    C = b64encode(ciphertext)
    data = { 'ciphertext': C.decode() } 
    resp = requests.post(URL + 'decrypt', json=data)
    P = b64decode(resp.content)
    return P
 
def main():
    ### TODO: write solution here ###
    pass
 
if __name__ == '__main__':
    main()

Atentie! functiile call_encrypt si call_decrypt primesc ca parametru un bytearray, NU un string.

Puteti folosi bytearray(), bytes() sau ””.encode() pentru a va construi mesajul/ciphertextul.

Task 2 - Multi-Time Pad (50p)

OTP (One Time Pad) este o tehnică de criptare care lucrează pe streamuri de date (adica, este un stream cipher). În OTP, mesajul și cheia trebuie să aibă aceeași dimensiune în număr de biți, iar algoritmul de criptare este operația XOR: $OTP(k, m) = k \oplus m$.

Avantajul folosirii OTP este dată de proprietatea de perfect secrecy: atâta timp cât nu cunoaștem cheia de criptare, un ciphertext poate corespunde oricărui mesaj posibil, cu aceeași probabilitate. Cu alte cuvinte, dacă avem acces la un ciphertext criptat cu OTP, nu putem ști care este mesajul din spate, fără a-l decripta. Această proprietate nu mai este adevărată în cazul în care folosim cheia de mai multe ori (de unde și numele de one-time pad).

Ideea de atac din spatele many-time pad (MTP) se bazează pe faptul că dacă $C1 = K \oplus M1$, iar $C2 = K \oplus M2$, atunci $C1 \oplus C2 = K \oplus M1 \oplus K \oplus M2 = M1 \oplus M2$. Cum vă poate ajuta această observație în a sparge MTP?

Simbolul $\oplus$ reprezintă operația XOR.

Scopul vostru este să scrieți un script cu care să decriptați mesajele criptate prin OTP cu aceeași cheie din această arhivă: ciphertexts.zip.

Vă puteți folosi de indiciile de la exercițiul bonus de la primul laborator. Nu este însă suficientă rularea scriptului mtp pentru rezolvarea temei, va trebui să vă scrieți scriptul vostru care descoperă mesajele decriptate.

Nu rezolvați exercițiul manual ca apoi să faceți un print într-un script :). Ne așteptăm ca scriptul să fie cât mai general (să poată să meargă pe input-uri similare, chiar dacă cu mici erori). Nu este problemă dacă există mici erori pe anumite poziții, dar se înțelege textul în mare parte. Daca obțineți cel puțin 70% din cheie/text este suficient, dar vă încurajez să vă apropiați cât mai mult de 100%.

Trimitere Temă

Rezolvarea trebuie trimisă într-o arhivă pe Moodle [1] care să conțină câte un folder pentru fiecare task în care să aveți un script care rulează tema și un fișier README în care descrieți pe scurt abordarea voastra. Puteți avea și fișiere adiționale pe lângă script-ul principal, dar trebuie să scrieți în README cum trebuie rulată soluția.

[1] https://curs.upb.ro/2021/mod/assign/view.php?id=90930

ic/teme/tema2021.txt · Last modified: 2021/11/16 00:29 by tiberiu.iorgulescu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0