Laboratorium 5
Zadania laboratoryjne dla studentów 7 semestru IT - ocena 5.0

Poziom: ocena 5.0 - zaawansowana kryptoanaliza protokołów, ataki na tożsamość i migracja postkwantowa

Zestaw 10 praktycznych zadań laboratoryjnych do wykonania w trakcie zajęć (90–100 minut).
Kierunek: Informatyka, semestr 7, przedmiot: Kryptologia.
Podstawa materiałowa: wykład część 5 (bezpieczna wymiana informacji: PKI, TLS i uwierzytelnianie).

Wskazówki dla studenta i zasady realizacji:

  • Zadania na ocenę 5.0 wymagają głębokiej wiedzy kryptoanalitycznej, modelowania zaawansowanych wektorów ataków oraz inżynierii nowoczesnych protokołów: badania podatności weryfikacji PKI (Basic Constraints i Name Constraints), ataku Key Confusion na JWT (CVE-2015-9235), fałszowania tożsamości z wstrzyknięciem JWKS/JKU i SSRF, rekonstrukcji ataku wyroczni paddingu CBC (POODLE / Lucky Thirteen), modelowania ataku powtórzenia Replay Attack na TLS 1.3 0-RTT, implementacji wzorca Noise_IK protokołu WireGuard, protokołu SRP-6a z zerową wiedzą o haśle, symulacji ataku Golden Ticket na Kerberos i struktury PAC, weryfikacji znaczników czasu RFC 3161 i długoterminowej archiwizacji LTV oraz testowania hybrydowej wymiany kluczy postkwantowych ML-KEM-768 w TLS 1.3.
  • Wszystkie zadania są w pełni wykonalne bez praw administratora na systemie Windows - wykorzystują interpreter Python 3 z bibliotekami kryptograficznymi oraz nowoczesną konsolę OpenSSL w środowisku JSLinux Alpine lub na lokalnej stacji roboczej.
  • Każde zadanie realizowane jest w czasie 90–100 minut w trakcie zajęć laboratoryjnych. Środowisko zamrożone: JSLinux Alpine + openssl 3.x, Python 3.11+, cryptography 41+. Najpierw próba online, przy awarii od razu fallback offline bez utraty punktów.
  • Wymagania formalne sprawozdania laboratoryjnego:
    • Strona tytułowa zawierająca: imię i nazwisko studenta, numer albumu, kierunek, semestr, grupę laboratoryjną, rok akademicki, numer i temat laboratorium, numer oraz nazwę realizowanego zadania, deklarowaną ocenę (5.0).
    • Opis konfiguracji środowiska badawczego, wersji bibliotek oraz wykorzystanych poleceń.
    • Szczegółowy opis wykonanych czynności, uzasadnienie wyboru narzędzi, kod źródłowy autorskich skryptów kryptoanalitycznych, zrzuty ekranu oraz wklejone fragmenty danych dokumentujące rzetelne wykonanie pracy.
    • Struktura skrócona na zajęcia: tytuł, cel, lista komend/kod, 2-3 zrzuty z podpisami, wnioski 3-5 zdań. Pełne spisy tabel/rysunków i bibliografia tylko w pracy domowej.
Kryptologia
lab 5 - 5.0
Spis
Spis zadań laboratoryjnych na ocenę 5.0
01/10
Zadanie 1. Kryptoanaliza podatności weryfikacji PKI: atak na brak sprawdzania Basic Constraints (CA:FALSE jako CA) i Name Constraints
🖥️ Wymagane środowisko:
System: Windows + JSLinux Alpine (Python 3)
Oprogramowanie: przeglądarka + OpenSSL + Python 3 + jwt.io
Podstawa wykładowa: Część 5 - slajdy 5, 6, 8, 44: hierarchia zaufania, rozszerzenie Basic Constraints, podatność Moxie Marlinspike na pominięcie flagi CA, rozszerzenie Name Constraints.
Szacowany czas: ~90-100 min | trudność L | Artefakt: 1 plik/log/zrzut | Starter: LAB5_startery/pki_attack_szkielet.py, jwt_confusion_szkielet.py

Cel

Celem zadania jest praktyczne zbadanie i kryptoanaliza historycznych oraz współczesnych podatności w algorytmach walidacji ścieżki certyfikacji X.509. Student bada konsekwencje pominięcia weryfikacji flagi Basic Constraints (CA:FALSE), generuje sfałszowany certyfikat pośredni podpisany legalnym certyfikatem liścia oraz analizuje mechanizm ochrony domen za pomocą rozszerzenia Name Constraints.

Scenariusz – opis

W początkowych latach rozwoju protokołu SSL wiele bibliotek kryptograficznych zawierało krytyczne błędy w implementacji RFC 5280. Jednym z najsłynniejszych odkryć w historii PKI był atak zaprezentowany w 2002 roku przez badacza Moxie Marlinspike. Wykazał on, że popularne przeglądarki sprawdzały jedynie poprawność matematyczną podpisów cyfrowych wzdłuż łańcucha. Oprogramowanie całkowicie ignorowało natomiast weryfikację rozszerzenia Basic Constraints w certyfikatach pośrednich. W efekcie każdy posiadacz legalnego certyfikatu serwera WWW mógł użyć swojego klucza prywatnego do wystawienia certyfikatu dla dowolnej innej domeny. Certyfikat końcowy z flagą CA:FALSE stawał się w oczach wadliwego weryfikatora pełnoprawnym urzędem certyfikacji CA.

Co ma wykonać student / grupa

W środowisku JSLinux lub w Pythonie tworzysz plik pki_attack.py symulujący podatny oraz odporny silnik walidacji ścieżki. Dysponujesz zaufanym certyfikatem głównym Root CA oraz legalnym certyfikatem serwera moj-sklep.pl wystawionym z flagą CA:FALSE. Wcielając się w rolę napastnika dysponującego kluczem prywatnym serwera moj-sklep.pl, tworzysz nowy certyfikat dla domeny bank-krajowy.pl. Podpisujesz certyfikat banku kluczem prywatnym sklepu, tworząc dwustopniowy łańcuch: Root CA -> moj-sklep.pl -> bank-krajowy.pl.

W Pythonie implementujesz uproszczoną, naiwną funkcję weryfikacyjną sprawdzającą wyłącznie poprawność podpisów i tożsamość nazw Issuer. Uruchamiasz naiwny weryfikator na sfałszowanym łańcuchu, demonstrując pomyślną akceptację fałszywego certyfikatu banku.

Przykładowe kroki do wykonania jako sugestia

  1. Utwórz plik pki_attack.py i zaimportuj moduły x509, hashes, default_backend z biblioteki cryptography.
  2. Wygeneruj parę kluczy Root CA i samopodpisany certyfikat z rozszerzeniem BasicConstraints(ca=True, path_length=None).
  3. Wygeneruj certyfikat końcowy dla 'sklep.pl' podpisany przez Root CA z jawną flagą BasicConstraints(ca=False, path_length=None).
  4. Jako napastnik wygeneruj klucz i certyfikat dla 'bank.pl', podpisując go kluczem prywatnym 'sklep.pl'.
  5. Zbadaj strukturę sfałszowanego certyfikatu banku: Issuer to 'sklep.pl', Subject to 'bank.pl'.
  6. Napisz funkcję naive_verify_chain( chain, root_pubkey) sprawdzającą wyłącznie podpisy kryptograficzne.
  7. Przetestuj łańcuch w naiwnym weryfikatorze: odnotuj wynik 'Łańcuch PRAWIDŁOWY (BŁĄD BEZPIECZEŃSTWA!)'.
  8. Wyjaśnij w sprawozdaniu mechanizm ataku Moxie Marlinspike'a i jego skutki dla bezpieczeństwa HTTPS.
  9. Zaimplementuj bezpieczną funkcję rfc5280_verify_chain( chain, root_pubkey).
  10. Zapisz zrzuty ekranu z konsoli dokumentujące oba etapy kryptoanalizy i dołącz kod do sprawozdania.

Kontrola zaliczenia (checklist):

  1. Zrekonstruowano atak PKI na wektorze ze startera: certyfikat CA:FALSE przyjęty jako CA przez podatny weryfikator (fałszywy łańcuch przechodzi).
  2. Wykazano różnicę: weryfikator podatny (brak BasicConstraints — fałszerstwo działa) vs RFC 5280 (odrzut) + NameConstraints jako zapora; dołączono oba logi.
  3. Dołączono log ataku (sfałszowany intermediate) + kod łatki (twarda kontrola CA:TRUE/pathlen + NC).
  4. Opisano w 3–5 zdaniach kompromis: wygoda luźnej walidacji vs MitM Marlinspike'a, koszt audytu ścieżki.

Wariant offline (fallback): Praca w pełni offline na wektorach ze startera; brak OpenSSL 3.2/ML-KEM: opis i symulacja Python bez sieci; dołącz log ataku, kod łatki i opis kompromisu bezpieczeństwo–wydajność.

Sugerowane wnioski i podsumowanie - co student ma osiągnąć

Sprawozdanie z realizacji zadania musi zawierać następujące kluczowe wnioski i osiągnięcia:

  • Zrozumienie historycznej luki Moxie Marlinspike'a i mechanizmu jej wykorzystania w atakach MitM.
  • Praktyczna znajomość algorytmu walidacji ścieżki RFC 5280 i konieczności weryfikacji flagi Basic Constraints CA:TRUE.
  • Zrozumienie roli rozszerzenia Name Constraints w ograniczaniu wektorów ataku ze strony skompromitowanych CA pośrednich.
  • Umiejętność projektowania odpornych na manipulacje procedur sprawdzania uprawnień certyfikatów w aplikacjach.
Zadanie 1 - ilustracja
02/10
Zadanie 2. Kryptoanalityczny atak typu Key Confusion (CVE-2015-9235) na weryfikację podpisów tokenów JWT (RS256 vs HS256)
🖥️ Wymagane środowisko:
System: Windows + JSLinux Alpine (Python 3)
Oprogramowanie: przeglądarka + OpenSSL + Python 3 + jwt.io
Podstawa wykładowa: Część 5 - slajdy 32, 33: tokeny JSON Web Token, asymetria algorytmu RS256 vs symetria HS256, luka logiczna typu Key Confusion / Algorithm Confusion (CVE-2015-9235).
Szacowany czas: ~90-100 min | trudność L | Artefakt: 1 plik/log/zrzut | Starter: LAB5_startery/pki_attack_szkielet.py, jwt_confusion_szkielet.py

Cel

Celem zadania jest przeprowadzenie kryptoanalitycznego ataku pomylenia klucza (Key Confusion Attack) na mechanizm weryfikacji tokenów JWT. Student analizuje podatność bibliotek webowych, które weryfikują tokeny asymetryczne RS256 za pomocą symetrycznego algorytmu HS256, wykorzystując jawny klucz publiczny RSA serwera jako sekret HMAC do wygenerowania sfałszowanego tokena administracyjnego.

Scenariusz – opis

W nowoczesnych aplikacjach internetowych tokeny JWT podpisane asymetrycznie za pomocą RS256 są weryfikowane przez wiele mikroserwisów. Każdy mikroserwis posiada publiczny klucz RSA dostawcy tożsamości w formacie PEM do sprawdzania podpisów cyfrowych. Klucz publiczny jest z definicji jawny i powszechnie dostępny dla wszystkich klientów oraz potencjalnych atakujących. Krytyczna podatność typu Key Confusion opisana w biuletynie CVE-2015-9235 wynika z dynamicznego wyboru algorytmu na podstawie nagłówka tokena. Jeśli aplikacja serwerowa weryfikuje token metodą jwt.verify(token, pubkey), nie narzucając z góry dozwolonego algorytmu, pojawia się luka. Biblioteka kryptograficzna odczytuje pole alg z nagłówka tokena przysłanego przez klienta.

Co ma wykonać student / grupa

W środowisku laboratoryjnym przygotowujesz plik jwt_confusion.py modelujący serwer autoryzacyjny oraz klienta API. Generujesz asymetryczną parę kluczy RSA 2048-bit i eksportujesz klucz publiczny w standardowym formacie PEM. Implementujesz funkcję podatnego serwera API, która przyjmuje token JWT i weryfikuje go za pomocą ogólnej funkcji sprawdzającej z kluczem publicznym RSA. Jako audytor analizujesz strukturę tokena użytkownika o niskich uprawnieniach {"user": "jan", "admin": false}.

Pobierasz jawny klucz publiczny serwera w formacie PEM jako zwykły ciąg znaków. Tworzysz sfałszowany ładunek nadający pełne uprawnienia administratorskie: {"user": "jan", "admin": true}.

Przykładowe kroki do wykonania jako sugestia

  1. Utwórz plik jwt_confusion.py i zaimportuj moduły hmac, hashlib, json, base64 oraz cryptography.
  2. Wygeneruj parę kluczy RSA 2048-bit i zapisz klucz publiczny do zmiennej rsa_pub_pem w formacie PEM.
  3. Zdefiniuj poprawny token administratora podpisany kluczem prywatnym RSA (algorytm RS256).
  4. Napisz funkcję vulnerable_jwt_verify( token, key_material) symulującą podatną bibliotekę sprawdzającą algorytm z nagłówka.
  5. W podatnej funkcji dodaj warunek: if alg == 'RS256': rsa_verify(...) elif alg == 'HS256': hmac_verify( token, key_material).
  6. Zauważ, że key_material jest ciągiem rsa_pub_pem dla obu gałęzi.
  7. Przygotuj fałszywy nagłówek: {'alg': 'HS256', 'typ': 'JWT'}.
  8. Przygotuj fałszywy payload: {'user': 'attacker', 'admin': True, 'exp': 9999999999}.
  9. Zakoduj nagłówek i payload w formacie Base64URL i połącz je kropką: unsigned_token.
  10. Wykonaj zrzuty ekranu z wykonania ataku oraz skutecznej obrony i dołącz analizę podatności do sprawozdania.

Kontrola zaliczenia (checklist):

  1. Zrekonstruowano Key Confusion (CVE-2015-9235) na wektorze ze startera: token RS256 podrobiony jako HS256 kluczem publicznym RSA.
  2. Wykazano różnicę: weryfikator ufający headerowi (fałszerstwo przechodzi) vs twardo związany z kluczem (odrzut); dołączono oba logi.
  3. Dołączono log ataku (sfałszowany admin-token) + kod łatki (allowlist algorytmu per klucz, rozdzielone weryfikatory).
  4. Opisano w 3–5 zdaniach kompromis: elastyczność multi-alg vs pomylenie symetryk/asymetryk, lekcja CVE.

Wariant offline (fallback): Praca w pełni offline na wektorach ze startera; brak OpenSSL 3.2/ML-KEM: opis i symulacja Python bez sieci; dołącz log ataku, kod łatki i opis kompromisu bezpieczeństwo–wydajność.

Sugerowane wnioski i podsumowanie - co student ma osiągnąć

Sprawozdanie z realizacji zadania musi zawierać następujące kluczowe wnioski i osiągnięcia:

  • Zrozumienie mechanizmu ataku Key Confusion (CVE-2015-9235) wynikającego z mylenia kryptografii symetrycznej i asymetrycznej.
  • Świadomość krytycznego błędu polegającego na dynamicznym ufaniu deklaracji algorytmu zawartej w nagłówku tokena.
  • Praktyczna umiejętność fałszowania tokenów JWT z wykorzystaniem publicznego klucza RSA jako sekretu HMAC.
  • Znajomość metod obrony polegających na twardym wiązaniu algorytmu z kluczem w konfiguracji serwera aplikacji.
Zadanie 2 - ilustracja
03/10
Zadanie 3. Atak na fałszowanie tokenów JWT z wykorzystaniem wstrzyknięcia nagłówka JWKS / JKU i serwera kontrolnego
🖥️ Wymagane środowisko:
System: Windows + JSLinux Alpine (Python 3)
Oprogramowanie: przeglądarka + OpenSSL + Python 3 + jwt.io
Podstawa wykładowa: Część 5 - slajd 33: specyfikacja RFC 7515/7517, nagłówki JKU (JWK Set URL) i JWK, dynamiczne pobieranie kluczy weryfikujących, wektory SSRF i fałszowania tożsamości.
Szacowany czas: ~90-100 min | trudność L | Artefakt: 1 plik/log/zrzut | Starter: LAB5_startery/pki_attack_szkielet.py, jwt_confusion_szkielet.py

Cel

Celem zadania jest zbadanie podatności dynamicznej dystrybucji kluczy w standardzie JSON Web Signature (JWS). Student bada wektor ataku polegający na wstrzyknięciu nagłówka JKU (JWK Set URL) wskazującego na kontrolowany przez atakującego serwer kluczy, podpisuje fałszywy token własnym kluczem prywatnym oraz implementuje mechanizm obrony oparty na ścisłej białej liście domen i przypinaniu kluczy.

Scenariusz – opis

W architekturach wielodomenowych aplikacje często weryfikują tokeny wydane przez zewnętrzne serwery tożsamości OAuth 2.0. Standard RFC 7515 wprowadził opcjonalne nagłówki jku JWK Set URL oraz jwk JSON Web Key. Nagłówek jku wskazuje adres URL, z którego aplikacja weryfikująca ma dynamicznie pobrać zestaw kluczy publicznych JWKS. Jeśli aplikacja serwerowa bezkrytycznie pobiera klucz z adresu URL podanego w nagłówku każdego przychodzącego tokena, powstaje krytyczna luka. Atakujący może wygenerować własną parę kluczy RSA i opublikować klucz publiczny na własnym serwerze HTTP. Następnie atakujący konstruuje sfałszowany token z uprawnieniami administratora i podpisuje go swoim prywatnym kluczem.

Co ma wykonać student / grupa

W środowisku laboratoryjnym przygotowujesz skrypt jku_exploit.py zawierający model podatnego serwera API oraz serwera atakującego. Uruchamiasz prosty serwer HTTP w Pythonie symulujący złośliwy punkt dystrybucji kluczy JWKS pod adresem http://127.0.0.1:8888/keys.json. Generujesz asymetryczną parę kluczy RSA dla atakującego i publikujesz klucz publiczny w formacie JWK w serwerze atakującego. W module podatnego serwera API implementujesz funkcję weryfikacyjną pobierającą klucz z adresu podanego w nagłówku jku przychodzącego tokena.

Jako atakujący tworzysz token z nagłówkiem {"alg": "RS256", "jku": "http://127.0.0.1:8888/keys.json", "kid": "key-1"}. W ładunku umieszczasz tożsamość uprzywilejowaną: {"user": "admin", "permissions": ["all"]}.

Przykładowe kroki do wykonania jako sugestia

  1. Utwórz plik jku_exploit.py i zaimportuj moduły: http.server, threading, urllib.request, json, base64, cryptography.
  2. Wygeneruj parę kluczy RSA atakującego za pomocą modułu cryptography.hazmat.primitives.asymmetric.rsa.
  3. Wyeksportuj parametry publiczne (e, n) i zakoduj je w Base64URL tworząc słownik JWK: {'kty': 'RSA', 'kid': 'key-1', 'e': e_b64, 'n': n_b64}.
  4. Napisz i uruchom w osobnym wątku lekki serwer HTTP nasłuchujący na porcie 8888 i serwujący plik JWKS: {'keys': [jwk_attacker]}.
  5. Zaimplementuj podatną funkcję vulnerable_verify_jku( token): pobierz nagłówek, odczytaj jku_url, pobierz klucz przez urllib.request.urlopen(jku_url).
  6. Skonstruuj weryfikator RSA w oparciu o pobrany z sieci klucz JWK i zweryfikuj podpis tokena.
  7. Utwórz sfałszowany token ataku podpisany prywatnym kluczem atakującego z parametrem jku='http://127.0.0.1:8888/keys.json'.
  8. Przekaż sfałszowany token do vulnerable_verify_jku i zaobserwuj pomyślną akceptację tożsamości admina.
  9. Zanotuj wpis w logach serwera HTTP potwierdzający pobranie kluczy przez weryfikator.
  10. Zapisz zrzuty ekranu z działania symulatora oraz kod źródłowy do raportu laboratoryjnego.

Kontrola zaliczenia (checklist):

  1. Zrekonstruowano atak JKU/JWKS na wektorze ze startera: wstrzyknięty nagłówek do własnego JWKS + podpis własnym kluczem przechodzi na podatnym serwerze.
  2. Wykazano różnicę: pobieranie bez whitelist (podatne, SSRF-podobne) vs whitelist+HTTPS+pin (odrzut); dołączono logi HTTP.
  3. Dołączono log ataku (serwer kontrolny, JWK) + kod łatki (biała lista hostów, cache, kid pinning).
  4. Opisano w 3–5 zdaniach kompromis: dynamika JWS vs SSRF/tożsamość, koszt utrzymania zaufanych JWKS.

Wariant offline (fallback): Praca w pełni offline na wektorach ze startera; brak OpenSSL 3.2/ML-KEM: opis i symulacja Python bez sieci; dołącz log ataku, kod łatki i opis kompromisu bezpieczeństwo–wydajność.

Sugerowane wnioski i podsumowanie - co student ma osiągnąć

Sprawozdanie z realizacji zadania musi zawierać następujące kluczowe wnioski i osiągnięcia:

  • Zrozumienie mechanizmu dynamicznej dystrybucji kluczy publicznych za pomocą nagłówków JKU i JWK (RFC 7515/7517).
  • Świadomość podatności wynikającej z bezkrytycznego odpytywania zewnętrznych serwerów wskazywanych przez klienta.
  • Zrozumienie powiązania ataków kryptograficznych na tożsamość z podatnościami warstwy aplikacji (SSRF).
  • Umiejętność projektowania bezpiecznych mechanizmów pobierania kluczy z wykorzystaniem białych list i wymuszenia HTTPS.
Zadanie 3 - ilustracja
04/10
Zadanie 4. Kryptoanaliza podatności CBC i wyroczni dopełnienia w protokole TLS (rekonstrukcja mechanizmu ataku POODLE / Lucky Thirteen)
🖥️ Wymagane środowisko:
System: Windows + JSLinux Alpine (Python 3)
Oprogramowanie: przeglądarka + OpenSSL + Python 3 + jwt.io
Podstawa wykładowa: Część 5 - slajdy 15, 17, 18, 44: tryby CBC w warstwie rekordów TLS (MAC-then-Encrypt), kryptoanalityczna wyrocznia dopełnienia Vaudenaya, ataki POODLE oraz Lucky Thirteen, wycofanie szyfrów CBC w TLS 1.3.
Szacowany czas: ~90-100 min | trudność L | Artefakt: 1 plik/log/zrzut | Starter: LAB5_startery/pki_attack_szkielet.py, jwt_confusion_szkielet.py

Cel

Celem zadania jest kryptoanalityczne zbadanie słabości trybów CBC w protokole TLS oraz rekonstrukcja działania wyroczni dopełnienia (Padding Oracle). Student implementuje w języku Python model deszyfrowania rekordów TLS w schemacie MAC-then-Encrypt, analizuje wyciek informacji o poprawności dopełnienia oraz przeprowadza symulację odzyskiwania bajtów tekstu jawnego blok po bloku bez znajomości klucza szyfrującego.

Scenariusz – opis

Przez wiele lat podstawowym trybem szyfrowania w warstwie rekordów protokołów SSLv3 oraz TLS 1.0–1.2 był tryb CBC. W architekturze tych protokołów zastosowano niefortunny schemat konstrukcyjny znany jako MAC-then-Encrypt. W schemacie tym najpierw wyliczano kod MAC z danych, dołączano go do tekstu, a całość dopełniano paddingiem i szyfrowano w trybie CBC. W 2002 roku Serge Vaudenay opublikował przełomową pracę demonstrującą podatność wyroczni dopełnienia Padding Oracle. Wykazał on, że jeśli serwer w odmienny sposób reaguje na błąd niepoprawnego dopełnienia niż na błąd niepoprawnego kodu MAC, powstaje wyrocznia. Atakujący modyfikując przedostatni blok szyfrogramu może manipulować odszyfrowanym tekstem w ostatnim bloku.

Co ma wykonać student / grupa

W środowisku roboczym tworzysz plik padding_oracle_tls.py zawierający model wyroczni oraz moduł kryptoanalityczny. Implementujesz funkcję szyfrującą w trybie AES-CBC z losowym kluczem i wektorem IV, stosującą standardowe dopełnienie PKCS#7. Tworzysz funkcję wyroczni oracle(iv, ciphertext), która dokonuje deszyfrowania i sprawdza poprawność bajtów dopełnienia. Jeśli padding jest niepoprawny, wyrocznia zwraca False, a jeśli poprawny - zwraca True, nie ujawniając żadnego tekstu jawnego.

Jako kryptoanalityk dysponujesz wyłącznie wektorem IV oraz dwoma blokami szyfrogramu C0 i C1 zawierającymi poufny token sesyjny. Implementujesz algorytm ataku na ostatni bajt bloku: iterujesz po wszystkich 256 możliwych wartościach bajtu w bloku C0.

Przykładowe kroki do wykonania jako sugestia

  1. Utwórz plik padding_oracle_tls.py i zaimportuj moduły: os z biblioteki standardowej oraz AES z cryptography.hazmat.primitives.ciphers.
  2. Zdefiniuj tajny klucz serwera: SECRET_KEY = os.urandom(16).
  3. Napisz funkcję pad_pkcs7( data, block_size=16) oraz unpad_pkcs7( data) rzucającą wyjątek ValueError przy błędnym paddingu.
  4. Napisz funkcję encrypt_record( plaintext): dodaj padding PKCS#7 i zaszyfruj w trybie AES-CBC z losowym IV.
  5. Zaimplementuj wyrocznię padding_oracle(iv, ciphertext): odszyfruj dane kluczem SECRET_KEY i zwróć True jeśli unpad_pkcs7 zakończy się sukcesem, w przeciwnym razie False.
  6. Przygotuj tajną wiadomość sesyjną o długości 16 bajtów: 'SECRET_TOKEN_42!'.
  7. Wygeneruj zaszyfrowany wektor testowy: iv, ciphertext = encrypt_record(tajna_wiadomosc).
  8. Podziel szyfrogram na bloki 16-bajtowe C0 i C1.
  9. Zaimplementuj pętlę odgadującą bajt pozycji 15 bloku C0: iteruj po kandydatach val od 0 do 255.
  10. Zapisz zrzuty ekranu z konsoli prezentujące postęp odzyskiwania bajtów oraz dołącz schemat ataku do sprawozdania.

Kontrola zaliczenia (checklist):

  1. Zrekonstruowano Padding Oracle (POODLE/Lucky13-toy) na wektorze ze startera: MAC-then-Encrypt CBC odszyfrowane blok po bloku manipulacją IV/poprzednika.
  2. Wykazano różnicę: CBC+MacThenEncrypt (wyciek, pełny odzysk) vs AEAD (brak wycieku); dołączono logi bajtów.
  3. Dołączono log ataku (kolejne bajty P) + kod łatki (TLS 1.3 bez CBC, encrypt-then-MAC/AEAD, stały czas).
  4. Opisano w 3–5 zdaniach kompromis: historia POODLE/Lucky13, 256 prób/bajt, dlaczego CBC wypadło z 1.3.

Wariant offline (fallback): Praca w pełni offline na wektorach ze startera; brak OpenSSL 3.2/ML-KEM: opis i symulacja Python bez sieci; dołącz log ataku, kod łatki i opis kompromisu bezpieczeństwo–wydajność.

Sugerowane wnioski i podsumowanie - co student ma osiągnąć

Sprawozdanie z realizacji zadania musi zawierać następujące kluczowe wnioski i osiągnięcia:

  • Głębokie zrozumienie podatności Padding Oracle w trybach szyfrowania CBC i schemacie MAC-then-Encrypt.
  • Matematyczna znajomość mechanizmu odzyskiwania tekstu jawnego blok po bloku poprzez manipulację wektorem IV/poprzednim blokiem.
  • Zrozumienie genezy historycznych ataków na protokół TLS (POODLE, Lucky Thirteen).
  • Świadomość przewagi konstrukcyjnej szyfrów ze zintegrowanym uwierzytelnianiem AEAD i przyczyn usunięcia CBC z TLS 1.3.
Zadanie 4 - ilustracja
05/10
Zadanie 5. Modelowanie i analiza bezpieczeństwa ataku powtórzenia (Replay Attack) w protokole TLS 1.3 0-RTT (Early Data) w Pythonie
🖥️ Wymagane środowisko:
System: Windows + JSLinux Alpine (Python 3)
Oprogramowanie: przeglądarka + OpenSSL + Python 3 + jwt.io
Podstawa wykładowa: Część 5 - slajdy 18, 19: optymalizacja wydajnościowa TLS 1.3 0-RTT (Early Data), wznowienie sesji z kluczem PSK, kryptoanalityczny problem podatności na atak powtórzenia (Replay Attack), mechanizmy obronne.
Szacowany czas: ~90-100 min | trudność L | Artefakt: 1 plik/log/zrzut | Starter: LAB5_startery/pki_attack_szkielet.py, jwt_confusion_szkielet.py

Cel

Celem zadania jest analiza kompromisu pomiędzy wydajnością a bezpieczeństwem na przykładzie mechanizmu 0-RTT (Early Data) w protokole TLS 1.3. Student modeluje w języku Python proces wznowienia sesji za pomocą klucza PSK, symuluje atak powtórzenia przechwyconego pakietu danych wczesnych skutkujący podwójnym wykonaniem operacji finansowej oraz implementuje mechanizmy ochronne po stronie serwera.

Scenariusz – opis

Protokół TLS 1.3 wprowadził rewolucyjną optymalizację czasu nawiązywania połączenia zwaną trybem 0-RTT Early Data. W trybie tym klient wznawiający sesję może wysłać pierwsze dane aplikacji już w pakiecie ClientHello bez oczekiwania na odpowiedź serwera. Dane te są szyfrowane kluczem Pre-Shared Key PSK wynegocjowanym podczas poprzedniej sesji. Ceną za natychmiastowe przesyłanie danych jest jednak fundamentalna utrata ochrony przed atakami powtórzeniowymi Replay Attacks. Ponieważ pakiet 0-RTT jest wysyłany przed uzgodnieniem świeżych wartości losowych serwera, pasywny podsłuchiwacz może przechwycić ten pakiet. Następnie atakujący może przesłać dokładnie ten sam pakiet do serwera po raz drugi, trzeci lub wielokrotnie.

Co ma wykonać student / grupa

W środowisku laboratoryjnym przygotowujesz plik tls_0rtt_sim.py implementujący symulację protokołu TLS 1.3. Modelujesz węzeł serwera bankowego udostępniający endpoint API do realizacji przelewów środków. W fazie początkowej klient i serwer przeprowadzają pełne uzgodnienie 1-RTT, ustalając wspólny sekret sesyjny PSK.

Następnie klient rozłącza się i przygotowuje sesję wznowioną z wykorzystaniem trybu 0-RTT Early Data. Klient szyfruje kluczem PSK treść żądania HTTP: 'POST /transfer HTTP/1.1\r\nKwota: 1000 PLN\r\nOdbiorca: Ewa'. Klient wysyła pakiet Early Data do serwera, a serwer natychmiast realizuje przelew, aktualizując saldo konta.

Przykładowe kroki do wykonania jako sugestia

  1. Utwórz plik tls_0rtt_sim.py i zaimportuj moduły: os, time, json, hashlib oraz cryptography.
  2. Zdefiniuj klasę BankServer z początkowym saldem konta: balance = 5000 oraz logiem transakcji.
  3. Zaimplementuj w serwerze metodę initial_handshake(): wygeneruj bilet sesyjny ticket_id oraz klucz psk_key.
  4. W klasie Client zapisz otrzymany ticket_id oraz psk_key do pamięci podręcznej sesji.
  5. Zaimplementuj w kliencie generowanie pakietu 0-RTT: zaszyfruj kluczem PSK żądanie przelewu 1000 PLN.
  6. Wyślij pakiet 0-RTT do serwera i odnotuj realizację transakcji: saldo spada z 5000 do 4000 PLN.
  7. Zaimplementuj klasę Attacker, która przechwytuje i przechowuje kopię wysłanego pakietu binarnego.
  8. Atakujący przesyła przechwycony pakiet do serwera 2 razy z rzędu bez wiedzy klienta.
  9. Odnotuj, że na podatnym serwerze transakcja została wykonana trzykrotnie, a saldo spadło do 2000 PLN.
  10. Wykonaj zrzuty ekranu z przebiegu ataku oraz skutecznej obrony i dołącz listing kodu do sprawozdania.

Kontrola zaliczenia (checklist):

  1. Wymodelowano replay 0-RTT na wektorze ze startera: przechwycony Early Data odtworzony jako druga operacja (podwójny zakup/zapis) bez alarmu.
  2. Wykazano różnicę: 0-RTT bez anty-replay (podatne) vs single-use ticket/cache ClientHello (odrzut duplikatu); dołączono oba logi.
  3. Dołączono log ataku (dwa wykonania) + kod łatki (0-RTT tylko idempotentne GET, anty-replay po stronie serwera).
  4. Opisano w 3–5 zdaniach kompromis: 1-RTT mniej vs brak forward/replay-safety, koszt stanu serwera.

Wariant offline (fallback): Praca w pełni offline na wektorach ze startera; brak OpenSSL 3.2/ML-KEM: opis i symulacja Python bez sieci; dołącz log ataku, kod łatki i opis kompromisu bezpieczeństwo–wydajność.

Sugerowane wnioski i podsumowanie - co student ma osiągnąć

Sprawozdanie z realizacji zadania musi zawierać następujące kluczowe wnioski i osiągnięcia:

  • Głębokie zrozumienie mechanizmu TLS 1.3 0-RTT (Early Data) i kompromisu pomiędzy opóźnieniem a bezpieczeństwem.
  • Świadomość braku ochrony przed atakami powtórzeniowymi (Replay Attacks) we wczesnych danych aplikacji.
  • Zrozumienie krytycznej zasady stosowania 0-RTT wyłącznie dla żądań idempotentnych (np. bezpieczne metody HTTP GET).
  • Praktyczna znajomość mechanizmów ochrony serwerowej: Single-Use Tickets oraz buforowania skrótów ClientHello.
Zadanie 5 - ilustracja
06/10
Zadanie 6. Analiza protokołu wymiany kluczy Noise Protocol Framework i kryptografii WireGuard vs IPsec IKEv2 w Pythonie
🖥️ Wymagane środowisko:
System: Windows + JSLinux Alpine (Python 3)
Oprogramowanie: przeglądarka + OpenSSL + Python 3 + jwt.io
Podstawa wykładowa: Część 5 - slajdy 38, 39: protokoły VPN, porównanie IPsec (IKEv2, ESP/AH) i WireGuard, Noise Protocol Framework (wzorce wymiany kluczy), kryptografia nowoczesna (Curve25519, ChaCha20-Poly1305, BLAKE2s).
Szacowany czas: ~90-100 min | trudność L | Artefakt: 1 plik/log/zrzut | Starter: LAB5_startery/pki_attack_szkielet.py, jwt_confusion_szkielet.py

Cel

Celem zadania jest kryptoanalityczne porównanie architektury klasycznego protokołu IPsec z nowoczesnym rozwiązaniem WireGuard opartym na schemacie Noise Protocol Framework. Student analizuje złożoność obu standardów, implementuje w języku Python symulację wzorca wymiany kluczy Noise_IK (Noise Interactive Handshake) wykorzystywanego w WireGuard oraz bada właściwości natychmiastowego Perfect Forward Secrecy i ochrony tożsamości.

Scenariusz – opis

Zabezpieczanie komunikacji w warstwie sieciowej VPN tradycyjnie opierało się na standardzie IPsec. Protokół IPsec wraz z mechanizmem wymiany kluczy IKEv2 charakteryzuje się ogromną złożonością specyfikacji liczącej setki stron. Wielość trybów pracy (Tunnel vs Transport), nagłówków (AH vs ESP) oraz dziesiątki ciphersuite'ów generowały liczne luki w implementacjach. Przełomem stał się protokół WireGuard zaprojektowany przez Jasona Donenfelda w oparciu o Noise Protocol Framework. WireGuard odrzucił negocjację parametrów kryptograficznych na rzecz sztywnego zestawu nowoczesnych algorytmów. Wymiana kluczy opiera się na krzywej Curve25519, szyfrowanie na ChaCha20-Poly1305, a haszowanie na funkcji BLAKE2s.

Co ma wykonać student / grupa

W środowisku laboratoryjnym przygotowujesz plik noise_wireguard.py implementujący maszynę stanową wzorca Noise_IK. Definiujesz stałe klucze statyczne dla Inicjatora (Alice) oraz Respondenta (Bob) z wykorzystaniem algorytmu X25519. Inicjator posiada wiedzę o kluczu publicznym Respondenta przed rozpoczęciem transmisji (wzorzec IK). Inicjalizujesz stan symetryczny SymmetricState: klucz łańcuchowy Chaining Key ck oraz skrót protokołu handshake hash h.

Inicjator losuje klucz efemeryczny e i wykonuje operację DH(e, s_bob) typu es, miksując wynik do klucza łańcuchowego. Inicjator szyfruje swój klucz statyczny s_alice za pomocą wygenerowanego klucza i wysyła pierwszy komunikat do Respondenta.

Przykładowe kroki do wykonania jako sugestia

  1. Utwórz plik noise_wireguard.py i zaimportuj moduły os, hashlib z biblioteki standardowej oraz X25519 z cryptography.
  2. Zdefiniuj funkcję KDF na bazie HKDF-SHA256 lub BLAKE2s miksującą dane wejściowe z kluczem łańcuchowym ck.
  3. Wygeneruj statyczne pary kluczy tożsamości: s_alice_priv, s_alice_pub oraz s_bob_priv, s_bob_pub.
  4. Zainicjalizuj stan protokołu: ck = hashlib.sha256(b'Noise_IK_25519_ChaChaPoly_BLAKE2s').digest() oraz h = ck.
  5. Krok 1 (Inicjator): wygeneruj efemeryczną parę kluczy e_alice_priv, e_alice_pub.
  6. Inicjator oblicza DH(e_alice, s_bob): secret_es = e_alice_priv.exchange(s_bob_pub).
  7. Zmiksuj secret_es z kluczem łańcuchowym: ck, k1 = kdf(ck, secret_es).
  8. Inicjator szyfruje swój klucz publiczny s_alice_pub kluczem k1 i dołącza do pakietu.
  9. Inicjator oblicza DH(s_alice, s_bob): secret_ss = s_alice_priv.exchange(s_bob_pub) i miksuje z ck: ck, k2 = kdf(ck, secret_ss).
  10. Sporządź tabelę porównawczą architektury WireGuard vs IPsec (liczba linii kodu jądra, ciphersuites, podatność DoS, RTT).

Kontrola zaliczenia (checklist):

  1. Zaimplementowano Noise_IK-toy i porównano z IKEv2 na wektorze ze startera: 4×DH, chaining key przez KDF, brak negocjacji vs setki opcji IPsec.
  2. Wykazano różnicę: WireGuard/Noise (prosty, szybki audyt) vs IPsec (elastyczny, duża powierzchnia); dołączono tabelę ról i logi handshake.
  3. Dołączono log symulacji + kod łatki (agility tylko w wersjonowaniu, jeden AEAD, PSK opcjonalnie).
  4. Opisano w 3–5 zdaniach kompromis: prostota vs interoperacyjność, KDF-mix jako forward secrecy, koszt złożoności.

Wariant offline (fallback): Praca w pełni offline na wektorach ze startera; brak OpenSSL 3.2/ML-KEM: opis i symulacja Python bez sieci; dołącz log ataku, kod łatki i opis kompromisu bezpieczeństwo–wydajność.

Sugerowane wnioski i podsumowanie - co student ma osiągnąć

Sprawozdanie z realizacji zadania musi zawierać następujące kluczowe wnioski i osiągnięcia:

  • Zrozumienie rewolucyjnej prostoty protokołu WireGuard w stosunku do złożoności standardu IPsec IKEv2.
  • Matematyczna znajomość wzorca wymiany kluczy Noise_IK opartego na 4 operacjach Diffiego-Hellmana.
  • Zrozumienie mechanizmu ciągłego miksowania sekretów w Chaining Key za pomocą KDF.
  • Świadomość zalet eliminacji elastyczności algorytmicznej (brak negocjacji ciphersuites) w redukcji powierzchni ataku.
Zadanie 6 - ilustracja
07/10
Zadanie 7. Implementacja i analiza kryptograficzna protokołu Secure Remote Password (SRP-6a) z zerową wiedzą o haśle
🖥️ Wymagane środowisko:
System: Windows + JSLinux Alpine (Python 3)
Oprogramowanie: przeglądarka + OpenSSL + Python 3 + jwt.io
Podstawa wykładowa: Część 5 - slajdy 24, 26, 27: uwierzytelnianie bez ujawniania hasła, protokoły PAKE (Password-Authenticated Key Exchange), protokół Secure Remote Password (SRP-6a, RFC 5054), odporność na podsłuch.
Szacowany czas: ~90-100 min | trudność L | Artefakt: 1 plik/log/zrzut | Starter: LAB5_startery/pki_attack_szkielet.py, jwt_confusion_szkielet.py

Cel

Celem zadania jest dekonstrukcja i implementacja protokołu PAKE na przykładzie standardu Secure Remote Password SRP-6a w języku Python. Student bada mechanizm uwierzytelniania, w którym hasło nigdy nie jest przesyłane przez sieć, a serwer nie przechowuje hasła ani jego prostego skrótu, analizuje operacje potęgowania modularnego oraz weryfikuje dowody zerowej wiedzy M1 i M2.

Scenariusz – opis

Tradycyjne systemy uwierzytelniania przesyłają hasło przez sieć w kanale TLS lub opierają się na weryfikacji skrótu po stronie serwera. W przypadku ataku kompromitacji bazy danych serwera skróty haseł stają się celem ataków słownikowych offline. Rewolucyjną alternatywą są protokoły wymiany kluczy uwierzytelniane hasłem Password-Authenticated Key Exchange PAKE. Najpopularniejszym ustandaryzowanym protokołem tej klasy jest SRP-6a zdefiniowany w dokumencie RFC 5054. W protokole SRP serwer przechowuje wyłącznie losową sól s oraz matematyczny weryfikator v = g^x mod N, gdzie x jest skrótem z soli i hasła. Nawet całkowity wyciek bazy danych serwera nie pozwala atakującemu na bezpośrednie podszycie się pod użytkownika.

Co ma wykonać student / grupa

W środowisku roboczym tworzysz plik srp_engine.py z implementacją arytmetyki dużej precyzji. Wybierasz znormalizowane parametry RFC 5054: 2048-bitową bezpieczną liczbę pierwszą N oraz generator grupy g = 2. Obliczasz stałą mnożnikową protokołu k = H(N, g) za pomocą funkcji skrótu SHA-256. Implementujesz fazę rejestracji użytkownika: losujesz 16-bajtową sól s, obliczasz x = H(s, hasło) oraz weryfikator v = g^x mod N.

Zapisujesz sól s oraz weryfikator v w bazie serwera, upewniając się, że hasło zostało trwale usunięte z pamięci. Implementujesz fazę logowania (Krok 1): klient losuje wartość tajną a i wysyła A = g^a mod N.

Przykładowe kroki do wykonania jako sugestia

  1. Utwórz plik srp_engine.py i zaimportuj moduły: os, hashlib z biblioteki standardowej Pythona.
  2. Zdefiniuj parametry grupy RFC 5054 (MODP-2048): dużą liczbę pierwszą N (szesnastkowo) oraz generator g = 2.
  3. Zaimplementuj funkcję haszującą H(*args) łączącą argumenty binarne i zwracającą liczbę całkowitą ze skrótu SHA-256.
  4. Oblicz parametr mnożnika k: k = H(N, g).
  5. Zaimplementuj procedurę rejestracji: s = os.urandom(16); x = H(s, b'tajne_haslo_studenta'); v = pow(g, x, N).
  6. Zapisz parę (s, v) do słownika serwera symulującego bazę tożsamości.
  7. Klient rozpoczyna logowanie: losuje tajne a = int.from_bytes(os.urandom(32), 'big') i oblicza A = pow(g, a, N).
  8. Klient wysyła login 'student' oraz A do serwera.
  9. Serwer weryfikuje czy A % N != 0, losuje b = int.from_bytes(os.urandom(32), 'big') i oblicza B = (k * v + pow(g, b, N)) % N.
  10. Zapisz zrzuty ekranu z konsoli prezentujące pomyślne uzgodnienie sekretu oraz dołącz kod źródłowy do sprawozdania.

Kontrola zaliczenia (checklist):

  1. Zaimplementowano SRP-6a na wektorze ze startera: v=g^x, pełna wymiana bez wysyłania hasła, obie strony liczą ten sam K, weryfikacje M1/M2.
  2. Wykazano różnicę: SRP (baza z weryfikatorem — słownik offline nie działa) vs plaintext-hash (kradzież bazy = łamanie); dołączono logi.
  3. Dołączono log protokołu + kod łatki (duże N, sól per user, zero-knowledge po obu stronach).
  4. Opisano w 3–5 zdaniach kompromis: PAKE vs PKI, koszt modularny, weryfikator jako tarcza bazy.

Wariant offline (fallback): Praca w pełni offline na wektorach ze startera; brak OpenSSL 3.2/ML-KEM: opis i symulacja Python bez sieci; dołącz log ataku, kod łatki i opis kompromisu bezpieczeństwo–wydajność.

Sugerowane wnioski i podsumowanie - co student ma osiągnąć

Sprawozdanie z realizacji zadania musi zawierać następujące kluczowe wnioski i osiągnięcia:

  • Zrozumienie rewolucyjnej koncepcji protokołów PAKE (Password-Authenticated Key Exchange).
  • Matematyczna znajomość działania weryfikatora SRP (v = g^x mod N) uniemożliwiającego ataki słownikowe z bazy serwera.
  • Głębokie zrozumienie dwustronnego uwierzytelniania z zerową wiedzą o haśle (Zero-Knowledge Proof).
  • Praktyczna umiejętność implementacji zaawansowanej arytmetyki modularnej w języku Python.
Zadanie 7 - ilustracja
08/10
Zadanie 8. Kryptoanaliza struktur biletów Kerberos i symulacja wektora ataku Golden Ticket / Pass-the-Ticket w Pythonie
🖥️ Wymagane środowisko:
System: Windows + JSLinux Alpine (Python 3)
Oprogramowanie: przeglądarka + OpenSSL + Python 3 + jwt.io
Podstawa wykładowa: Część 5 - slajdy 28, 29: bilet TGT Kerberos, konto nadrzędne KRBTGT w Active Directory, szyfrowanie biletów kluczem nadrzędnym (krbtgt NTLM hash / AES key), wektor ataku Golden Ticket.
Szacowany czas: ~90-100 min | trudność L | Artefakt: 1 plik/log/zrzut | Starter: LAB5_startery/pki_attack_szkielet.py, jwt_confusion_szkielet.py

Cel

Celem ćwiczenia jest kryptoanaliza wewnętrznych struktur danych protokołu Kerberos oraz symulacja zaawansowanego ataku klasy Golden Ticket w języku Python. Student bada budowę biletu Ticket Granting Ticket (TGT), analizuje strukturę PAC (Privilege Attribute Certificate), symuluje konsekwencje przejęcia klucza nadrzędnego konta krbtgt oraz fabrykuje nieograniczony bilet administratorski omijający mechanizmy KDC.

Scenariusz – opis

W infrastrukturze domenowej przedsiębiorstw Active Directory opiera się na protokole Kerberos v5. Centralnym elementem zaufania w całej domenie jest konto nadrzędne o nazwie KRBTGT. Klucz kryptograficzny tego konta (pochodzący z hasła krbtgt) służy do szyfrowania i podpisywania wszystkich biletów TGT. Bilet TGT zawiera strukturę PAC Privilege Attribute Certificate, w której zapisane są identyfikatory SID grup użytkownika. Serwery usług weryfikujące bilety serwisowe bezkrytycznie ufają informacjom poświadczonym przez KDC. Jeśli zaawansowany napastnik zdoła wydobyć skrót klucza konta KRBTGT, uzyskuje absolutną kontrolę nad domeną.

Co ma wykonać student / grupa

W katalogu projektowym tworzysz plik golden_ticket_sim.py modelujący struktury danych biletów Kerberos w Pythonie. Definiujesz parametry domeny: identyfikator SID domeny, konto użytkownika oraz tajny klucz konta KRBTGT. Analizujesz format ASN.1 biletu Ticket oraz struktury Privilege Attribute Certificate PAC. Tworzysz strukturę PAC zawierającą identyfikatory grup: dopisujesz do listy identyfikator SID domeny z końcówką -512 (Domain Admins).

Budujesz ładunek biletu TGT z tożsamością nieistniejącego użytkownika 'ghost_admin' oraz okresem ważności ustawionym na 10 lat. Szyfrujesz sfałszowany bilet za pomocą przejętego klucza konta KRBTGT przy użyciu szyfru AES-256 w trybie CBC lub CTS z HMAC-SHA1.

Przykładowe kroki do wykonania jako sugestia

  1. Utwórz plik golden_ticket_sim.py i zaimportuj moduły: os, time, struct, json, hashlib oraz cryptography.
  2. Zdefiniuj domenowy SID: DOMAIN_SID = 'S-1-5-21-1234567890-1234567890-1234567890'.
  3. Zdefiniuj tajny klucz konta nadrzędnego: KRBTGT_AES_KEY = os.urandom(32).
  4. Zbuduj strukturę PAC: pac_data = {'user': 'attacker', 'user_rid': 1001, 'group_sids': [DOMAIN_SID + '-512', DOMAIN_SID + '-513']}.
  5. Odnotuj, że RID 512 reprezentuje elitarną grupę administratorów domeny Domain Admins.
  6. Zbuduj strukturę biletu TGT: tgt_payload = {'username': 'attacker', 'realm': 'CORP.LOCAL', 'authtime': time.time(), 'endtime': time.time() + 315360000, 'session_key': os.urandom(32).hex(), 'pac': pac_data}.
  7. Zwróć uwagę na czas ważności endtime wynoszący 10 lat (315360000 sekund) zamiast domyślnych 10 godzin.
  8. Zaszyfruj ładunek biletu TGT kluczem KRBTGT_AES_KEY: enc_ticket = encrypt_aes(KRBTGT_AES_KEY, json.dumps(tgt_payload).encode()).
  9. Zaimplementuj moduł serwera docelowego ServiceServer z funkcją authorize_access(ticket_bytes).
  10. Zapisz zrzuty ekranu z wykonania ataku oraz procedury obronnej do sprawozdania laboratoryjnego.

Kontrola zaliczenia (checklist):

  1. Zasymulowano Golden Ticket na wektorze ze startera: podrobiony TGT (fałszywy PAC) z klucza KRBTGT przechodzi na podatnym weryfikatorze.
  2. Wykazano różnicę: brak kontroli (fałszywy admin przechodzi) vs detekcja anomalii (czas/шифр, podwójna rotacja KRBTGT leczy); dołączono logi.
  3. Dołączono log ataku (struktura TGT/PAC) + kod łatki (monitoring, rotacja KRBTGT ×2, least privilege).
  4. Opisano w 3–5 zdaniach kompromis: centralizacja KDC vs jedna korona (KRBTGT), koszt rotacji w lesie.

Wariant offline (fallback): Praca w pełni offline na wektorach ze startera; brak OpenSSL 3.2/ML-KEM: opis i symulacja Python bez sieci; dołącz log ataku, kod łatki i opis kompromisu bezpieczeństwo–wydajność.

Sugerowane wnioski i podsumowanie - co student ma osiągnąć

Sprawozdanie z realizacji zadania musi zawierać następujące kluczowe wnioski i osiągnięcia:

  • Zrozumienie kryptograficznej architektury biletów TGT oraz struktury certyfikatu uprawnień PAC w protokole Kerberos.
  • Świadomość katastrofalnych skutków kompromitacji klucza nadrzędnego konta KRBTGT w sieci korporacyjnej.
  • Praktyczna znajomość mechanizmu ataku Golden Ticket i fałszowania tożsamości z pominięciem kontrolera domeny.
  • Zrozumienie metod detekcji anomalii biletów oraz procedury ratunkowej opartej na podwójnej rotacji hasła KRBTGT.
Zadanie 8 - ilustracja
09/10
Zadanie 9. Matematyczna weryfikacja znaczników czasu RFC 3161 (TSA) i długoterminowej archiwizacji podpisów (PAdES/XAdES LTV)
🖥️ Wymagane środowisko:
System: Windows + JSLinux Alpine (Python 3)
Oprogramowanie: przeglądarka + OpenSSL + Python 3 + jwt.io
Podstawa wykładowa: Część 5 - slajdy 34, 35: transakcje elektroniczne, rozporządzenie eIDAS, znacznik czasu (Time-Stamping Authority - TSA, RFC 3161), długoterminowa archiwizacja podpisów LTV (Long-Term Validation).
Szacowany czas: ~90-100 min | trudność L | Artefakt: 1 plik/log/zrzut | Starter: LAB5_startery/pki_attack_szkielet.py, jwt_confusion_szkielet.py

Cel

Celem zadania jest praktyczne zbadanie kryptograficznego mechanizmu znakowania czasem Time-Stamping Protocol (RFC 3161) oraz architektury długoterminowej weryfikacji podpisów cyfrowych LTV (PAdES/XAdES). Student generuje kryptograficzne żądanie znacznika czasu TSR, odpytuje publiczny serwer TSA, weryfikuje podpis urzędu czasu oraz analizuje problem wygasania certyfikatów i łamania algorytmów w wieloletniej archiwizacji dokumentów.

Scenariusz – opis

Podpis cyfrowy złożony pod dokumentem PDF lub XML jest w pełni weryfikowalny w momencie jego składania. Pojawia się jednak krytyczny problem prawny i techniczny, gdy certyfikat podpisującego wygaśnie po roku lub zostanie unieważniony po latach. Weryfikator w przyszłości nie jest w stanie stwierdzić, czy podpis został złożony przed unieważnieniem klucza, czy po nim. Rozwiązaniem tego problemu w prawie europejskim (rozporządzenie eIDAS) jest kwalifikowany znacznik czasu. Protokół RFC 3161 definiuje niezależną trzecią stronę zwaną Time-Stamping Authority TSA dysponującą precyzyjnym zegarem atomowym. Klient przesyła do TSA wyłącznie kryptograficzny skrót dokumentu (hasz), zachowując pełną poufność jego treści.

Co ma wykonać student / grupa

W środowisku JSLinux lub w Pythonie tworzysz plik dokumentu tekstowego umowa_handlowa.pdf zawierający treść prawną. Za pomocą narzędzia openssl ts generujesz binarne żądanie znacznika czasu Time Stamp Request TSR. Wskazujesz algorytm skrótu SHA-256 oraz dodajesz flagę żądania certyfikatu serwera w odpowiedzi. Wysyłasz zapytanie do publicznego, darmowego serwera znacznika czasu (np. freetsa.org) za pomocą polecenia curl przez HTTP. Odbierasz binarną odpowiedź Time Stamp Response TSR i zapisujesz ją do pliku znacznik.tsr.

Przykładowe kroki do wykonania jako sugestia

  1. Utwórz katalog roboczy i plik dokumentu: echo 'Umowa sprzedaży nieruchomości z dnia 01.01.2024' > umowa.txt.
  2. Wygeneruj żądanie znacznika czasu z pliku umowa.txt z opcją certyfikatu: openssl ts -query -data umowa.txt -sha256 -cert -out zadanie.tsq.
  3. Dokonaj inspekcji binarnego żądania TSQ w konsoli: openssl ts -query -in zadanie.tsq -text.
  4. Zanotuj wyliczony skrót SHA-256 oraz unikalną wartość losową Nonce zabezpieczającą przed powtórzeniem.
  5. Wyślij żądanie do publicznego serwera TSA (FreeTSA): curl -s -H 'Content-Type: application/timestamp-query' --data-binary '@zadanie.tsq' https://freetsa.org/tsr > odpowiedz.tsr.
  6. Sprawdź rozmiar odebranego pliku odpowiedz.tsr (powinien wynosić około 3-5 kB z dołączonym certyfikatem).
  7. Wyświetl treść otrzymanego znacznika czasu w czytelnej formie: openssl ts -reply -in odpowiedz.tsr -text.
  8. Zlokalizuj w wyjściu pola: Status: Granted, Time stamp (dokładny czas UTC z dokładnością do milisekund) oraz Serial number.
  9. Pobierz publiczny certyfikat urzędu FreeTSA: curl -s https://freetsa.org/files/cacert.pem > tsa_root.pem oraz curl -s https://freetsa.org/files/tsa.crt > tsa_cert.pem.
  10. Zapisz zrzuty ekranu z konsoli oraz dołącz analizę prawno-techniczną eIDAS do sprawozdania laboratoryjnego.

Kontrola zaliczenia (checklist):

  1. Wygenerowano TSQ/TSR (RFC 3161) i zweryfikowano LTV na wektorze ze startera: token TSA na hash dokumentu, archiwizacja PAdES/XAdES z OCSP/CRL w środku.
  2. Wykazano różnicę: podpis z TSA+LTV (weryfikowalny po latach, po wygaśnięciu certa) vs sam podpis (martwy po wygaśnięciu); dołączono logi openssl ts.
  3. Dołączono log żądań/tokenów + kod łatki (kolekcjonowanie dowodów, re-timestamping przed słabnięciem algo).
  4. Opisano w 3–5 zdaniach kompromis: eIDAS/niezaprzeczalność vs koszt TSA i rozmiarów LTV, degradacja krypto w czasie.

Wariant offline (fallback): Praca w pełni offline na wektorach ze startera; brak OpenSSL 3.2/ML-KEM: opis i symulacja Python bez sieci; dołącz log ataku, kod łatki i opis kompromisu bezpieczeństwo–wydajność.

Sugerowane wnioski i podsumowanie - co student ma osiągnąć

Sprawozdanie z realizacji zadania musi zawierać następujące kluczowe wnioski i osiągnięcia:

  • Zrozumienie krytycznej roli kwalifikowanego znacznika czasu (RFC 3161) w zapewnianiu niezaprzeczalności podpisów w prawie eIDAS.
  • Praktyczna znajomość procesu generowania żądań TSQ oraz weryfikacji tokenów TSR z wykorzystaniem OpenSSL.
  • Zrozumienie problemu wygasania certyfikatów i degradacji kryptograficznej w wieloletniej archiwizacji dokumentów.
  • Znajomość poziomów podpisów elektronicznych LTV (Long-Term Validation) integrujących dane OCSP/CRL wewnątrz kontenera dokumentu.
Zadanie 9 - ilustracja
10/10
Zadanie 10. Hybrydowa wymiana kluczy w protokole TLS: integracja algorytmu post-kwantowego ML-KEM-768 z ECDH X25519 w OpenSSL 3.2+
🖥️ Wymagane środowisko:
System: Windows + JSLinux Alpine (Python 3)
Oprogramowanie: przeglądarka + OpenSSL + Python 3 + jwt.io
Podstawa wykładowa: Część 5 - slajdy 16, 20, 52: ewolucja TLS w stronę odporności postkwantowej (PQC), zagrożenie SNDL (Store Now, Decrypt Later), hybrydowe mechanizmy KEM (X25519 + ML-KEM-768 / Kyber-768 wg FIPS 203), OpenSSL 3.2+.
Szacowany czas: ~90-100 min | trudność L | Artefakt: 1 plik/log/zrzut | Starter: LAB5_startery/pki_attack_szkielet.py, jwt_confusion_szkielet.py

Cel

Celem zadania jest praktyczne zbadanie wdrażania kryptografii postkwantowej (PQC) w protokole TLS 1.3. Student bada hybrydowy mechanizm wymiany kluczy łączący klasyczny schemat eliptyczny X25519 z algorytmem opartym na kratach ML-KEM-768 (standaryzowany Kyber wg FIPS 203), analizuje pakiety ClientHello/ServerHello pod kątem narzutu rozmiaru kluczy oraz testuje odporność na zagrożenie Store Now, Decrypt Later.

Scenariusz – opis

Gwałtowny rozwój komputerów kwantowych stanowi śmiertelne zagrożenie dla współczesnej kryptografii asymetrycznej. Algorytm Shora pozwala na złamanie algorytmów RSA oraz kryptografii krzywych eliptycznych w czasie wielomianowym. Najbardziej bezpośrednim zagrożeniem jest atak SNDL Store Now, Decrypt Later (zbieraj teraz, odszyfruj później). Wrogie agencje wywiadowcze rejestrują i archiwizują zaszyfrowany ruch TLS, licząc na możliwość jego odszyfrowania za kilka lat. W odpowiedzi amerykański instytut NIST oraz organizacja IETF opracowały nowe standardy kryptografii postkwantowej PQC. Podstawowym algorytmem kapsułkowania kluczy KEM stał się schemat ML-KEM oparty na trudności problemu Learning With Errors na kratach.

Co ma wykonać student / grupa

W środowisku laboratoryjnym uruchamiasz nowoczesną wersję pakietu OpenSSL (wersja 3.2 lub nowsza) obsługującą grupy hybrydowe PQC. Sprawdzasz listę obsługiwanych grup wymiany kluczy poleceniem openssl list -kem-algorithms lub przeglądasz parametry TLS. Identyfikujesz ustandaryzowaną grupę hybrydową IETF o nazwie x25519_kyber768 lub x25519_mlkem768. Nawiązujesz połączenie TLS 1.3 z publicznym serwerem wspierającym PQC (np. serwery Cloudflare lub specjalne endpointy testowe). W poleceniu openssl s_client jawnie wymuszasz użycie grupy hybrydowej za pomocą parametru -groups.

Przykładowe kroki do wykonania jako sugestia

  1. W konsoli sprawdź wersję biblioteki OpenSSL: openssl version (upewnij się o obecności nowoczesnej wersji 3.x).
  2. Wypisz dostępne grupy wymiany kluczy TLS: openssl list -tls-groups (lub wyszukaj frazę kyber / mlkem).
  3. Zidentyfikuj nazwę grupy postkwantowej: x25519_kyber768 lub x25519_mlkem768.
  4. Nawiąż połączenie testowe z serwerem wspierającym PQC (np. Cloudflare): openssl s_client -connect cloudflare.com:443 -servername cloudflare.com -groups x25519_kyber768.
  5. Zlokalizuj w wyjściu linię Temp Key dokumentującą wynegocjowaną grupę hybrydową.
  6. Zanotuj długość klucza i parametry negocjacji TLS 1.3.
  7. Nawiąż dla porównania tradycyjne połączenie wyłącznie z grupą X25519: openssl s_client -connect cloudflare.com:443 -servername cloudflare.com -groups X25519.
  8. Zapisz surowe pakiety ClientHello dla obu przypadków za pomocą opcji -msg lub -trace.
  9. Porównaj rozmiar rozszerzenia Key Share: w tradycyjnym X25519 wynosi ono 36 bajtów (4 B nagłówka + 32 B klucza).
  10. Dołącz zrzuty ekranu z konsoli oraz obliczenia narzutu sieciowego do sprawozdania laboratoryjnego.

Kontrola zaliczenia (checklist):

  1. Uruchomiono hybrydę X25519+ML-KEM-768 na wektorze ze startera (OpenSSL 3.2+ lub symulacja): secret = KDF(ECDH||KEM), handshake TLS 1.3 działa, rozmiary zmierzone.
  2. Wykazano różnicę: sam X25519 (mały, lecz SNDL) vs hybryda (odporna kwantowo, +~1 kB, fragmentacja); dołączono tabelę rozmiarów/czasów.
  3. Dołączono log negocjacji grup + kod łatki (hybrydowe grupy, fallback klasyczny, MTU/Jumbo ogarnięte).
  4. Opisano w 3–5 zdaniach kompromis: SNDL na dziś vs koszt pasma, FIPS 203, strategia migracji PQC.

Wariant offline (fallback): Praca w pełni offline na wektorach ze startera; brak OpenSSL 3.2/ML-KEM: opis i symulacja Python bez sieci; dołącz log ataku, kod łatki i opis kompromisu bezpieczeństwo–wydajność.

Sugerowane wnioski i podsumowanie - co student ma osiągnąć

Sprawozdanie z realizacji zadania musi zawierać następujące kluczowe wnioski i osiągnięcia:

  • Zrozumienie natury zagrożenia Store Now, Decrypt Later (SNDL) dla współczesnych danych szyfrowanych w internecie.
  • Praktyczna znajomość hybrydowych mechanizmów KEM łączących klasyczne krzywe eliptyczne z kryptografią kratową (FIPS 203).
  • Świadomość wyzwań inżynieryjnych wynikających ze znacznego wzrostu rozmiaru kluczy publicznych (fragmentacja MTU).
  • Umiejętność konfiguracji i diagnostyki grup postkwantowych w nowoczesnym ekosystemie protokołu TLS 1.3.
Zadanie 10 - ilustracja
Podgląd