Zadania w tym zestawie mają charakter opisowo-praktyczny i są przeznaczone na ocenę maksymalnie 5.0. Każda grupa laboratoryjna wybiera dokładnie jedno zadanie z dziesięciu przygotowanych studiów przypadków, a na jego realizację ma 180 minut. Zespoły liczą dwie lub trzy osoby i pracują na systemie Linux, Windows lub MikroTik RouterOS, korzystając wyłącznie z bezpłatnych programów i ogólnodostępnych narzędzi teleinformatycznych. W odróżnieniu od zadań na ocenę dobrą poziom 5.0 wymaga połączenia analizy matematycznej algorytmów, konfiguracji wyspecjalizowanych narzędzi obronnych oraz weryfikacji wymogów normatywno-prawnych w obszarze ochrony kryptograficznej. Praca grupy polega na wieloaspektowej analizie protokołów, zaprojektowaniu bezpiecznego środowiska, przeprowadzeniu weryfikacji technicznej oraz udokumentowaniu wniosków. Oceniana jest zdolność połączenia rygorystycznych wymogów prawnych z konkretną konfiguracją techniczną wykazującą skuteczne ograniczenie ryzyka teleinformatycznego.
Z laboratorium każda grupa przygotowuje jedno łączne sprawozdanie w formacie PDF o objętości od ośmiu do dwunastu stron znormalizowanego tekstu. Dokument rozpoczyna się stroną tytułową zawierającą pełną nazwę uczelni, nazwę przedmiotu, imiona i nazwiska studentów wraz z numerami albumów, kierunek, numer grupy dziekańskiej oraz rok akademicki. Bezpośrednio pod stroną tytułową należy wkleić pełną treść wybranego zadania wraz z poleceniami i schematem. Układ merytoryczny pracy obejmuje wstęp teoretyczny, szczegółowe rozwinięcie inżynierskie oraz podsumowanie z wnioskami odpowiadającymi na pytanie, czego zespół się nauczył. W sprawozdaniu musi znaleźć się czytelny schemat połączeń, wykaz użytego oprogramowania, kompletne pliki konfiguracyjne oraz rzeczywiste listingi poleceń konsoli z interpretacją wyników. Pomiary i zrzuty ekranu należy przedstawić jako własne rezultaty uzyskane w środowisku laboratoryjnym, wyjaśniając parametry zależne od systemu. Wnioski końcowe muszą wskazywać, które środki ochronne zespół wdrożył, a które odrzucił i z jakim uzasadnieniem technicznym. Każde odwołanie do przepisów i norm musi precyzyjnie wskazywać obowiązujący akt prawny zweryfikowany na dzień realizacji ćwiczenia. Sprawozdanie musi jednoznacznie dowodzić, że grupa w pełni zrozumiała istotę problemu i prawidłowo wykonała wszystkie kroki procedury technicznej. Obrona sprawozdania odbywa się podczas zajęć w formie krótkiego wystąpienia grupy i merytorycznej dyskusji nad przyjętymi rozwiązaniami.
Zadanie bazuje na treściach Wykładu 2 (Poufność danych i kryptoanaliza implementacyjna), Wykładu 3 (Jednokierunkowe funkcje skrótu, kody uwierzytelniania HMAC i struktura Merkle-Damgård) oraz Wykładu 6 (Trendy rozwoju kryptologii, sprzętowe moduły bezpieczeństwa HSM i odporność na ataki fizyczne). Ćwiczenie weryfikuje kierunkowe efekty uczenia się: W1 (dogłębna znajomość kryptoanalizy różnicowej, metod wstrzykiwania błędów DFA oraz propagacji anomalii bitowych w kompresji), W4 (architektura sprzętowych modułów HSM, specyfikacja standardu PKCS#11 v2.40 oraz izolacja kluczy kryptograficznych), U1 (konstrukcja symulatora ataku glitchingowego w języku Python badającego załamanie dyfuzji rejestrów roboczych), U2 (inicjalizacja magazynu SoftHSM2 oraz programowanie operacji HMAC przez PyKCS11), U3 (szacowanie wektora bazowego i środowiskowego CVSS v4.0), U4 (inżynieria reguł detekcyjnych Sigma dla systemów monitorowania SIEM) oraz K2 (świadomość zagrożeń wynikających z fizycznych anomalii pracy układów scalonych). Wymagania normatywne obejmują standardy NIST FIPS 180-4 (Secure Hash Standard), NIST FIPS 198-1 (The Keyed-Hash Message Authentication Code), OASIS PKCS #11 Cryptographic Token Interface v2.40, klasyfikację CWE-1256 oraz techniki taktyki Credential Access matrycy MITRE ATT&CK: T1110.002 i T1552.004.
Głównym celem zadania jest zbadanie mechanizmów kryptoanalizy różnicowej opartej na wstrzykiwaniu błędów (Differential Fault Analysis – DFA) w wewnętrzne rejestry stanu funkcji kompresji SHA-256. Grupa laboratoryjna analizuje propagację zaburzeń bitowych w 64 rundach algorytmu Merkle-Damgård oraz weryfikuje kryteria ścisłego lawinowego wpływu (SAC) i niezależności bitów (BIC). W części analitycznej studenci tworzą w języku Python demonstrator ataku glitchingowego, który poprzez zaburzenie jednego bitu w rundzie 60 redukuje przestrzeń poszukiwań stanu wewnętrznego. Ćwiczenie pozwala zrozumieć, że błędy sprzętowe indukowane w procesorze mogą całkowicie zniweczyć matematyczne właściwości funkcji skrótu.
W części defensywnej celem jest przeniesienie operacji wyliczania HMAC-SHA256 do bezpiecznego magazynu sprzętowego SoftHSM2 z interfejsem PKCS#11. Studenci konfigurują obiekt klucza z flagami uniemożliwiającymi odczytanie materiału kryptograficznego z pamięci RAM serwera aplikacyjnego. Końcowym etapem jest przygotowanie reguły Sigma dla systemu monitorowania SIEM, która koreluje serie anomalnych błędów weryfikacji skrótów.
Państwowy Instytut Łączności – PIB w Warszawie prowadzi badania laboratoryjne nad odpornością kryptograficznych modułów łączności rządowej. W trakcie audytu bezpieczeństwa mikrokontrolerów weryfikujących podpisy HMAC-SHA256 zbadano podatność układów na zaburzenia sygnału zegarowego oraz chwilowe spadki napięcia zasilania (clock/voltage glitching). Eksperymenty wykazały, że wywołanie błędu jednobitowego w końcowych rundach funkcji kompresji powoduje załamanie dyfuzji i umożliwia odtworzenie rejestrów roboczych.
Zespół audytorów wciela się w rolę inżynierów Purple Team, których zadaniem jest przeprowadzenie kontrolowanej weryfikacji podatności oraz zaprojektowanie kompleksowych mechanizmów zaradczych. Red Team przygotowuje skrypt weryfikujący różnicę pomiędzy poprawnym a zaburzonym skrótem SHA-256, dowodząc możliwości wyznaczenia wewnętrznych zmiennych stanu A i E oraz skrajnej redukcji złożoności obliczeniowej ataku na klucz HMAC.
Blue Team projektuje architekturę odporną na fizyczne i logiczne ataki boczno-kanałowe poprzez separację procesów obliczeniowych. Zamiast realizować operacje HMAC w niezabezpieczonej pamięci procesu w systemie Linux, zespół wdraża programowy moduł SoftHSM2 emulujący układ HSM zgodny ze standardem PKCS#11. Klucz symetryczny generowany jest bezpośrednio na tokenie z atrybutami zabraniającymi eksportu, a operacje kryptograficzne zlecane są za pośrednictwem biblioteki PKCS#11.
Całość rozwiązania zostaje objęta telemetrią bezpieczeństwa. Zespół obronny opracowuje regułę Sigma wykrywającą próby ataku glitchingowego na podstawie lawinowego wzrostu nieudanych weryfikacji integralności komunikatów. Zdarzenia te są rejestrowane i korelowane w systemie SIEM, co umożliwia natychmiastowe zablokowanie atakowanego kanału transmisji.
W kryptoanalizie DFA kluczowe znaczenie ma dokładna lokalizacja rundy, w której następuje zaburzenie. W przypadku SHA-256 każda runda wykorzystuje nieliniowe funkcje Ch (Choose) oraz Maj (Majority), a także operacje rotacji bitowej Sigma. Zaburzenie wprowadzone na 4 rundy przed końcem nie ulega pełnemu rozproszeniu, co pozwala na analityczne wyznaczenie wartości rejestrów roboczych z równań różnicowych.
Aby zapobiec wyciekowi materiału kluczowego w trakcie incydentu naruszenia integralności pamięci RAM, moduł SoftHSM2 wykonuje wszystkie operacje HMAC wewnętrznie. Poniższe zestawienie poleceń i kodów źródłowych demonstruje symulację ataku DFA, bezpieczną konfigurację magazynu PKCS#11 oraz inżynierię reguły detekcyjnej Sigma.
W trakcie konfiguracji SoftHSM2 należy zadbać o poprawne ustawienie zmiennej środowiskowej SOFTHSM2_CONF wskazującej na dedykowany plik konfiguracyjny. Podczas weryfikacji kodu z użyciem PyKCS11 obiekt klucza jest identyfikowany wyłącznie za pomocą uchwytu numerycznego (handle), co uniemożliwia procesowi odczytanie jego rzeczywistych bajtów.
Reguła Sigma powinna precyzyjnie definiować warunek progowy wykrywania, korelując identyfikatory kluczy oraz adresy źródłowe. W środowisku produkcyjnym seria kilkudziesięciu błędów weryfikacji w ciągu kilku sekund jednoznacznie wskazuje na próbę ataku glitchingowego lub manipulacji boczno-kanałowej.
# Utworzenie lokalnego środowiska dla SoftHSM2
mkdir -p /home/student/lab6_hsm/tokens
cat << 'EOF' > /home/student/lab6_hsm/softhsm2.conf
directories.tokendir = /home/student/lab6_hsm/tokens
objectstore.backend = file
log.level = INFO
EOF
export SOFTHSM2_CONF=/home/student/lab6_hsm/softhsm2.conf
# Inicjalizacja tokena ze slotem 0
softhsm2-util --init-token --free --label "HSM_GOV_TOKEN" --so-pin 87654321 --pin 12345678
# Weryfikacja zainicjalizowanego tokena
pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so -L
#!/usr/bin/env python3
# Symulacja zaburzenia jednobitowego w rundzie 60 kompresji SHA-256
def rotr(x, n):
return ((x >> n) | (x << (32 - n))) & 0xFFFFFFFF
def ch(x, y, z):
return (x & y) ^ (~x & z)
def maj(x, y, z):
return (x & y) ^ (x & z) ^ (y & z)
def sigma0(x):
return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22)
def sigma1(x):
return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25)
def sha256_step(a, b, c, d, e, f, g, h, w, k):
t1 = (h + sigma1(e) + ch(e, f, g) + k + w) & 0xFFFFFFFF
t2 = (sigma0(a) + maj(a, b, c)) & 0xFFFFFFFF
new_a = (t1 + t2) & 0xFFFFFFFF
new_e = (d + t1) & 0xFFFFFFFF
return new_a, a, b, c, new_e, e, f, g
# Stan poczatkowy przed runda 60
a, b, c, d = 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a
e, f, g, h = 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
w_val, k_val = 0x80000000, 0x748f82ee
# 1. Obliczenie prawidlowe
a1, b1, c1, d1, e1, f1, g1, h1 = sha256_step(a, b, c, d, e, f, g, h, w_val, k_val)
# 2. Wstrzykniecie bledu 1-bitowego w rejestrze E (glitch)
e_fault = e ^ 0x00000001
a2, b2, c2, d2, e2, f2, g2, h2 = sha256_step(a, b, c, d, e_fault, f, g, h, w_val, k_val)
print(f"[+] Roznica w rejestrze A (delta A): 0x{a1 ^ a2:08X}")
print(f"[+] Roznica w rejestrze E (delta E): 0x{e1 ^ e2:08X}")
print("[+] Wynik DFA: Ograniczona dyfuzja w 4 ostatnich rundach ujawnia stan wewnetrzny!")
#!/usr/bin/env python3
import PyKCS11
import PyKCS11.LowLevel
pkcs11 = PyKCS11.PyKCS11Lib()
pkcs11.load("/usr/lib/softhsm/libsofthsm2.so")
slots = pkcs11.getSlotList(tokenPresent=True)
session = pkcs11.openSession(slots[0], PyKCS11.CKF_SERIAL_SESSION | PyKCS11.CKF_RW_SESSION)
session.login("12345678")
# Szablon klucza z zakazem ekstrakcji
key_template = [
(PyKCS11.CKA_CLASS, PyKCS11.CKO_SECRET_KEY),
(PyKCS11.CKA_KEY_TYPE, PyKCS11.CKK_GENERIC_SECRET),
(PyKCS11.CKA_LABEL, "HMAC_GOV_KEY"),
(PyKCS11.CKA_VALUE, bytes.fromhex("11223344556677889900aabbccddeeff00112233445566778899aabbccddeeff")),
(PyKCS11.CKA_SENSITIVE, True),
(PyKCS11.CKA_EXTRACTABLE, False),
(PyKCS11.CKA_SIGN, True),
(PyKCS11.CKA_VERIFY, True)
]
key_handle = session.createObject(key_template)
print(f"[+] Klucz HMAC utworzony pomyslnie w SoftHSM2! Uchwyt: {key_handle}")
session.logout()
session.closeSession()
export SOFTHSM2_CONF=/home/student/lab6_hsm/softhsm2.conf
# Lista obiektow w tokenie
pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --login --pin 12345678 --list-objects
# Proba nieautoryzowanego odczytania klucza (oczekiwany blad CKR_ATTRIBUTE_SENSITIVE)
pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --login --pin 12345678 \
--type secrkey --label "HMAC_GOV_KEY" --read-object || echo "[OK] Klucz jest chroniony przed odczytem!"
title: Wykrycie Anomalii Weryfikacji Integralnosci HMAC
id: a871d3e2-8921-4f12-a1b2-sha256dfa001
status: experimental
description: Wykrywa gwaltowny wzrost liczby bledow weryfikacji HMAC-SHA256 sugerujacy probe ataku DFA lub boczno-kanalowego
references:
- https://cwe.mitre.org/data/definitions/1256.html
author: Purple Team Lab
date: 2026/09/29
logsource:
category: application
product: crypto_service
detection:
selection:
event_type: 'crypto_hmac_failure'
algorithm: 'HMAC-SHA256'
timeframe: 10s
condition: selection | count() > 30
fields:
- client_ip
- service_name
- error_code
falsepositives:
- Awaria komunikacji sieciowej podczas synchronizacji kluczy
level: high
tags:
- attack.credential_access
- attack.t1110.002
# Pobranie identyfikatora PID procesu crypto_service
PID=$(pgrep -f "crypto_service" | head -n 1)
# Sprawdzenie zmapowanych przestrzeni pamieci procesu
cat /proc/${PID}/maps | grep -i "softhsm"
# Potwierdzenie zablokowania uprawnien ptrace dla nieuprzywilejowanych uzytkownikow
sysctl kernel.yama.ptrace_scope
Poniższa lista zawiera propozycje zagadnień i wniosków technicznych, które warto uwzględnić w sprawozdaniu z tego zadania:
Przykładowe wnioski (wzór do sprawozdania): Laboratoryjna analiza statystyczna rund kompresji SHA-256 wykazała, że zaburzenie pojedynczego taktu zegara procesora w 60. rundzie kompresora powoduje propagację błędu pozwalającą na odtworzenie rejestrów roboczych za pomocą kryptoanalizy DFA. Standardowe testy SAC i BIC potwierdziły matematyczną odporność algorytmu w warunkach nominalnych, jednak brak sprzętowych zabezpieczeń przeciwzakłóceniowych w mikrokontrolerze stworzył krytyczną lukę fizyczną. Przeniesienie obliczeń HMAC do certyfikowanego modułu HSM spełniającego wymogi FIPS 140-3 całkowicie zneutralizowało podatność na ataki wstrzykiwania błędów zasilania. Podsystem kryptograficzny wykonuje obecnie redundantne obliczenia skrótu i porównuje wyniki przed ich wyemitowaniem na magistralę. Zaimplementowana reguła Sigma w centrum operacji bezpieczeństwa natychmiast alarmuje o klastrach błędów weryfikacji pakietów, chroniąc rządowe węzły łączności przed zaawansowaną ingerencją fizyczną.
Zadanie opiera się na treściach Wykładu 2 (Podstawy ochrony, poufność i nienaruszalność danych), Wykładu 3 (Własności jednokierunkowych funkcji skrótu, paradoks dnia urodzin i odporność na kolizje) oraz Wykładu 6 (Kryptografia postkwantowa PQC i bezstanowe podpisy cyfrowe oparte na funkcjach skrótu). Ćwiczenie weryfikuje kierunkowe efekty uczenia się: W1 (dogłębna znajomość ataku kolizji na wybrane przedrostki Chosen-Prefix Collision, złożoności kryptoanalitycznej na MD5 oraz struktury Merkle-Damgård), W2 (architektura bezstanowych podpisów postkwantowych SLH-DSA / FIPS 205 opartych na drzewach XMSS i jednorazowych podpisach WOTS+), U1 (konstrukcja i manipulacja drzewem obiektów binarnych formatu PDF w celu podmiany treści prawnej), U2 (wdrożenie i weryfikacja schematów SLH-DSA w OpenSSL 3.4 z dostawcą OQS-Provider), U3 (analiza ryzyka według metodyki CVSS v4.0), U4 (inżynieria sygnatur detekcyjnych YARA i reguł SIEM dla zmanipulowanych struktur PDF) oraz K1 (zrozumienie konsekwencji prawnych wynikających z fałszowania dokumentacji urzędowej zgodnie z rozporządzeniem eIDAS). Wymagania normatywne obejmują standardy NIST FIPS 205 (Stateless Hash-Based Digital Signature Standard), ISO 32000-1 (Document management - Portable document format), Rozporządzenie Parlamentu Europejskiego i Rady (UE) nr 910/2014 (eIDAS), klasyfikację CWE-328 oraz techniki T1565.001 i T1036 matrycy MITRE ATT&CK.
Głównym celem zadania jest praktyczne zbadanie kryptoanalitycznej podatności funkcji skrótu na atak kolizji na wybrane przedrostki (Chosen-Prefix Collision – CPC) oraz jej wpływu na autentyczność dokumentów binarnych PDF. Studenci analizują strukturę wewnętrzną formatu PDF oraz mechanizmy warunkowego renderowania obiektów w celu wygenerowania dwóch dokumentów o sprzecznej treści prawnej posiadających identyczny skrót MD5. W części ofensywnej zespół bada, jak wykorzystanie bloków kolizyjnych pozwala na podmianę sentencji orzeczenia sądowego przy zachowaniu ważności podpisu kryptograficznego. Ćwiczenie uzmysławia krytyczne niebezpieczeństwo stosowania przestarzałych funkcji skrótu w systemach elektronicznego obiegu dokumentów.
W części defensywnej celem jest wdrożenie odpornego na ataki kolizyjne standardu postkwantowego podpisu cyfrowego SLH-DSA (FIPS 205 / SPHINCS+). Studenci konfigurują narzędzia kryptograficzne bazujące wyłącznie na funkcjach skrótu, gwarantujące bezpieczeństwo przed komputerami kwantowymi. Końcowym etapem jest opracowanie reguły detekcyjnej wykrywającej specyficzne artefakty bloków kolizyjnych w strumieniach binarnych PDF.
W Sądzie Najwyższym wdrożono pilotażowy system cyfrowego podpisywania orzeczeń sądowych. W wyniku zaniedbania w specyfikacji starszych modułów archiwizacji, baza orzecznictwa dopuszczała weryfikację integralności plików PDF za pomocą skrótów MD5 oraz SHA-1. Zespół audytorów bezpieczeństwa otrzymał zadanie wykazania krytycznego ryzyka prawnego wynikającego z możliwości sfabrykowania orzeczenia uniewinniającego posiadającego identyczny skrót jak wyrok skazujący.
Red Team wykorzystuje technikę Chosen-Prefix Collision opisaną przez Stevensa, łącząc ją z architekturą drzewa obiektów PDF. Tworzone są dwa pliki wyjściowe o różnych przedrostkach: jeden zawiera treść orzeczenia uniewinniającego, a drugi wyroku skazującego. Poprzez wstrzyknięcie precyzyjnie wyliczonych bloków kolizyjnych oraz ukrycie drugiego strumienia w niewidocznym obiekcie formularza, oba pliki generują identyczny skrót kryptograficzny MD5.
Zespół Blue Team przeprowadza audyt incydentu i wdraża natychmiastowe środki zaradcze. Zamiast polegać na podatnych schematach, inżynierowie migrują procedury podpisu na postkwantowy algorytm SLH-DSA (FIPS 205), którego bezpieczeństwo opiera się na bezstanowych drzewach skrótów i jednorazowych sygnaturach Winternitza (WOTS+). Schemat ten jest w pełni odporny na algorytm Shora i ataki kolizyjne.
Równolegle Blue Team wdraża regułę skanującą przychodzące dokumenty PDF pod kątem anomalii strukturalnych, takich jak wielokrotne definicje słowników /Catalog, nietypowe przesunięcia w tabeli krosowej /XRef oraz obecność znanych sygnatur kolizyjnych. Mechanizm blokuje podejrzane pliki przed dopuszczeniem ich do obiegu prawnego.
W ataku Chosen-Prefix Collision na format PDF wykorzystuje się fakt, że parser czyta obiekty w sposób sekwencyjny. Wstrzykując blok kolizyjny do obiektu strumienia /Length, można sprawić, że w pierwszym dokumencie parser uzna treść orzeczenia uniewinniającego za aktywną, podczas gdy w drugim pliku ten sam blok danych zostanie zinterpretowany jako komentarz, aktywując treść orzeczenia skazującego.
Algorytm SLH-DSA (dawniej SPHINCS+) eliminuje ryzyko kolizji poprzez zastosowanie wielopoziomowej struktury drzew Merkle'a (hypertree) oraz jednorazowych podpisów WOTS+. Podpis cyfrowy zawiera ścieżki uwierzytelniania wewnątrz drzew, a bezpieczeństwo bazuje wyłącznie na trudności znalezienia drugiego przeciwobrazu w bezpiecznych funkcjach skrótu (SHA-256 lub SHAKE256).
Podczas przygotowywania przedrostków binarnych w Pythonie należy zadbać o wyrównanie do pełnych bloków 512-bitowych (64 bajty). Jakakolwiek rozbieżność w długości przedrostków uniemożliwi poprawne wygenerowanie wektorów kolizyjnych przez algorytmy optymalizacji kryptoanalitycznej.
Reguła YARA powinna sprawdzać obecność specyficznych anomalii w nagłówkach i słownikach PDF, w tym podejrzanie dużych bloków danych binarnych umieszczonych w nagłówku pliku przed pierwszym słownikiem strony oraz nietypowych znaków podziału w tabeli krosowej.
#!/usr/bin/env python3
import sys
def align_prefix(filename, output_name):
with open(filename, "rb") as f:
data = f.read()
pad_len = (64 - (len(data) % 64)) % 64
padded_data = data + b"% " + b"A" * (pad_len - 2) if pad_len >= 2 else data
if pad_len == 1:
padded_data = data + b"\n"
with open(output_name, "wb") as f:
f.write(padded_data)
print(f"[+] Plik {output_name} wyrownany. Dlugosc: {len(padded_data)} bajtow (mod 64 == 0).")
if __name__ == "__main__":
if len(sys.argv) < 3:
print("Uzycie: python3 align_prefix.py <input.pdf> <aligned_prefix.bin>")
sys.exit(1)
align_prefix(sys.argv[1], sys.argv[2])
# Wygenerowanie bloków kolizyjnych CPC (przykładowe wywołanie fastcoll)
fastcoll -p prefix_wyrok1.bin -o cpc_wyrok1.bin cpc_wyrok2.bin
# Sprawdzenie skrótów MD5 wygenerowanych plików binarnych
md5sum cpc_wyrok1.bin cpc_wyrok2.bin
# Sprawdzenie skrótów SHA-256 wykazujące brak tożsamości na nowoczesnych funkcjach
sha256sum cpc_wyrok1.bin cpc_wyrok2.bin
#!/usr/bin/env python3
# Laczenie wygenerowanych blokow kolizyjnych ze struktura obiektow orzeczenia
with open("cpc_wyrok1.bin", "rb") as f1, open("cpc_wyrok2.bin", "rb") as f2:
b1 = f1.read()
b2 = f2.read()
# Cialo wspolne dokumentu PDF definiujace dwa obiekty tekstowe
pdf_body = b'''
5 0 obj
<< /Length 40 >>
stream
Sentencja: Sad uznaje oskarzonego za NIEWINNEGO.
endstream
endobj
6 0 obj
<< /Length 40 >>
stream
Sentencja: Sad uznaje oskarzonego za WINNEGO kary.
endstream
endobj
xref
0 7
trailer << /Root 1 0 R >>
%%EOF
'''
with open("wyrok_uniewinniajacy.pdf", "wb") as f_out:
f_out.write(b1 + pdf_body)
with open("wyrok_skazujacy.pdf", "wb") as f_out:
f_out.write(b2 + pdf_body)
print("[+] Zbudowano oba dokumenty PDF. Skroty MD5 sa identyczne, tresc orzeczenia jest skrajnie rozna!")
# Wygenerowanie pary kluczy postkwantowego algorytmu SLH-DSA (SPHINCS+)
openssl genpkey -propquery ?oqs_provider -algorithm slh-dsa-sha2-128s -out slh_private.key
openssl pkey -in slh_private.key -pubout -out slh_public.key
# Podpisanie autentycznego orzeczenia sądowego
openssl dgst -sha256 -sign slh_private.key -out wyrok_sig.pqc wyrok_uniewinniajacy.pdf
# Poprawna weryfikacja orzeczenia autentycznego
openssl dgst -sha256 -verify slh_public.key -signature wyrok_sig.pqc wyrok_uniewinniajacy.pdf
# Proba weryfikacji podpisu na podmienionym wyroku skazujacym (oczekiwany blad weryfikacji)
openssl dgst -sha256 -verify slh_public.key -signature wyrok_sig.pqc wyrok_skazujacy.pdf || echo "[OK] Podpis PQC odrzucil sfalszowany plik!"
rule PDF_Chosen_Prefix_Collision_Anomaly
{
meta:
description = "Wykrywa anomalie struktury PDF typowe dla wstrzykiwania blokow kolizyjnych MD5"
author = "Purple Team Laboratory"
date = "2026-09-29"
reference = "CWE-328 / eIDAS"
strings:
$pdf_header = "%PDF-"
$trailer = "trailer"
$xref = "xref"
$dup_length = /\/Length\s+\d+.*?\/Length\s+\d+/
condition:
$pdf_header at 0 and
#xref > 1 and
$trailer and
($dup_length or filesize < 2000000)
}
# Skanowanie repozytorium orzeczen pod katem anomalii binarnych
yara -w pdf_cpc_detect.yar /home/student/orzeczenia/
# Wyswietlenie szczegolowych informacji o strukturze obiektow PDF
pdf-parser --stats wyrok_skazujacy.pdf
Poniższa lista zawiera propozycje zagadnień i wniosków technicznych, które warto uwzględnić w sprawozdaniu z tego zadania:
Przykładowe wnioski (wzór do sprawozdania): Praktyczna konstrukcja exploita Chosen-Prefix Collision na algorytm MD5 dobitnie dowiodła, że dopuszczenie starszych funkcji skrótu w systemie orzecznictwa sądowego stwarza bezprecedensowe zagrożenie prawne. Wykorzystując specyfikę drzewa obiektów formatu PDF, wygenerowano dwa wykluczające się wyroki sądowe, które posiadały identyczny skrót kryptograficzny i ten sam formalnie poprawny podpis cyfrowy. Odsłonięcie alternatywnej treści poprzez minimalną modyfikację tabeli xref pokazało, jak łatwo można podważyć wiarygodność orzeczenia przed sądem. W ramach natychmiastowej modernizacji architektury wdrożono bezstanowy postkwantowy algorytm podpisów cyfrowych NIST FIPS 205 (SLH-DSA), którego bezpieczeństwo opiera się wyłącznie na nienaruszalności nowoczesnych funkcji haszujących. Przeprowadzona migracja gwarantuje bezwzględną nienaruszalność akt sądowych i pełną odporność na ataki komputerów kwantowych przez kolejne dziesięciolecia.
Zadanie bazuje na treściach Wykładu 2 (Podstawy ochrony, warunki integralności i autentyczności), Wykładu 3 (Funkcje skrótu Merkle-Damgård, atak z rozszerzeniem długości Length Extension Attack oraz nowoczesna konstrukcja gąbki Keccak/SHA-3) oraz Wykładu 6 (Ochrona systemów sterowania przemysłowego OT i bezpieczna telemetria). Ćwiczenie weryfikuje kierunkowe efekty uczenia się: W1 (dogłębna znajomość właściwości dopełnienia blokowego w Merkle-Damgård oraz wektora ataku LEA), W3 (matematyka permutacji Keccak-f[1600], funkcja cSHAKE oraz odporność konstrukcji gąbki KMAC256 wg NIST SP 800-185), U1 (implementacja exploita w języku Python manipulującego ramkami protokołu IEC 60870-5-104 bez znajomości klucza uwierzytelniającego), U2 (wdrożenie bezpiecznej biblioteki KMAC256 w warstwie transmisji SCADA), U3 (analiza ryzyka według metodyki CVSS v4.0 dla systemów infrastruktury krytycznej), U4 (inżynieria sygnatur Suricata NIDS dla protokołów telemechaniki) oraz K1 (odpowiedzialność inżynierska za ciągłość działania sieci przesyłowej zgodnie z dyrektywą NIS 2 i ustawą o KSC). Wymagania normatywne obejmują standardy NIST SP 800-185 (SHA-3 Derived Functions: cSHAKE and KMAC), IEC 60870-5-104 (Network access for IEC 60870-5-101 using standard transport profiles), IEC 62351-3/5, klasyfikację CWE-943 oraz techniki T0814 i T0855 z matrycy MITRE ATT&CK for ICS.
Nadrzędnym celem zadania jest zbadanie podatności funkcji skrótu opartych na dopełnieniu Merkle-Damgård na atak z rozszerzeniem długości (Length Extension Attack – LEA) w przemysłowych sieciach automatyki elektroenergetycznej. Studenci analizują strukturę ramki telemechaniki protokołu IEC 60870-5-104 zabezpieczanej naiwnym schematem H(key || message) z użyciem SHA-256. W części ofensywnej zespół tworzy w języku Python exploit doklejający nieautoryzowaną komendę wyłączenia wyłącznika stacji transformatorowej wraz z prawidłowym dopełnieniem kryptograficznym. Ćwiczenie dowodzi, że znajomość samego skrótu autentycznej wiadomości pozwala na wygenerowanie ważnego uwierzytelnienia bez posiadania tajnego klucza symetrycznego.
W części defensywnej celem jest migracja protokołu uwierzytelniania na nowoczesny standard gąbki KMAC256 (NIST SP 800-185). Studenci implementują funkcję opartą na permutacji Keccak-f[1600], która dzięki wewnętrznej pojemności (capacity) jest matematycznie odporna na ataki rozszerzenia długości. Końcowym etapem jest wdrożenie sygnatury Suricata NIDS na poziomie przemysłowej sieci OT wykrywającej próby manipulacji ramkami sterującymi.
Polskie Sieci Elektroenergetyczne (PSE S.A.) eksploatują rozproszony system dyspozytorski SCADA nadzorujący stacje elektroenergetyczne najwyższych napięć. Transmisja poleceń łączeniowych pomiędzy stacją nadrzędną a sterownikami polowymi RTU realizowana jest za pośrednictwem protokołu IEC 60870-5-104. W celu zapewnienia integralności i autentyczności rozkazów, starsza specyfikacja telemetryczna nakazywała dołączanie na końcu ramki sumy kontrolnej wyliczanej jako SHA-256 z połączenia tajnego klucza stacji oraz treści komunikatu.
Zespół audytorów wciela się w rolę inżynierów Purple Team badających odporność systemu na ataki w warstwie transmisji OT. Red Team przygotowuje skrypt przechwytujący autentyczną ramkę potwierdzenia stanu łączników i wykorzystuje lukę Length Extension Attack. Inicjując stan wewnętrzny rejestrów SHA-256 wartością przechwyconego skrótu oraz uwzględniając długość klucza i wiadomości pierwotnej, atakujący dokleja rozkaz otwarcia wyłącznika linii przesyłowej, generując poprawny skrót bez naruszenia tajności klucza.
Blue Team identyfikuje przyczynę podatności i wdraża standard NIST SP 800-185 oparty na konstrukcji gąbki KMAC256 (Keccak Message Authentication Code). Dzięki strukturze Keccaka dane wejściowe podlegają absorpcji do stanu roboczego, a wewnętrzna pojemność uniemożliwia kontynuację hashowania bez znajomości pełnego 1600-bitowego wektora stanu, co definitywnie neutralizuje ataki LEA.
Dodatkowo inżynierowie ochrony sieci OT konfigurują przemysłowy sensor Suricata NIDS z włączonym dekoderem protokołów przemysłowych. Sygnatura głębokiej inspekcji pakietów (DPI) analizuje strukturę bajtową ASDU (Application Service Data Unit) i generuje alert o najwyższym priorytecie w przypadku wykrycia nieoczekiwanych komend sterujących doklejonych za sekwencją dopełnienia.
W ataku Length Extension Attack kluczowe jest dokładne obliczenie liczby bajtów dopełnienia pierwotnej wiadomości. Standard SHA-256 wymaga, aby po danych nastąpił bajt 0x80, następnie seria bajtów zerowych, a na ostatnich 8 bajtach 64-bitowa liczba reprezentująca łączną długość klucza i wiadomości wyrażoną w bitach. Całość musi stanowić wielokrotność 64 bajtów.
Standard KMAC256 eliminuje tę podatność dzięki architekturze gąbki (Sponge Construction). Permutacja Keccak posiada stan o rozmiarze 1600 bitów, dzielony na przepustowość (rate) i pojemność (capacity). Do wyjścia trafiają wyłącznie bity fazy wyciskania (squeezing), a nieznajomość niewidocznej części stanu uniemożliwia kontynuowanie hashowania.
Podczas implementacji exploita w Pythonie można wykorzystać moduł struct do rozpakowania przechwyconego skrótu SHA-256 na osiem 32-bitowych słów (big-endian), które posłużą jako stan początkowy dla kolejnego bloku kompresji zawierającego doklejone polecenie.
Sygnatura Suricata powinna monitorować port TCP 2404 dedykowany dla protokołu IEC 60870-5-104. Charakterystycznym objawem ataku LEA jest obecność sekwencji bajtów paddingu (0x80 połączone z długością) w nietypowej pozycji przed komendami typu C_SC_NA_1.
+-----------------------+-------------------------+------------------------+
| Start (0x68) | Dlugosc| Pole sterujace (4 B) | ASDU (Komenda C_SC) |
+-----------------------+-------------------------+------------------------+
| Dane telemetryczne | Dopełnienie LEA (opcja) | Tag uwierzytelniający |
+-----------------------+-------------------------+------------------------+
#!/usr/bin/env python3
import struct
import hashlib
# Symulacja: Klucz tajny znany tylko serwerowi i RTU (16 bajtow)
TAJNY_KLUCZ = b"SCADA_SECRET_K16"
def serwer_generuj_tag(wiadomosc):
# Podatna implementacja H(K || M)
return hashlib.sha256(TAJNY_KLUCZ + wiadomosc).digest()
def rtu_weryfikuj(wiadomosc, otrzymany_tag):
poprawny = hashlib.sha256(TAJNY_KLUCZ + wiadomosc).digest()
return poprawny == otrzymany_tag
# 1. Przechwycona autentyczna wiadomosc i jej tag
wiadomosc_oryg = b"STATUS_L1_NORMAL_OK"
tag_oryg = serwer_generuj_tag(wiadomosc_oryg)
print(f"[+] Przechwycona ramka: {wiadomosc_oryg.decode()}")
print(f"[+] Przechwycony tag: {tag_oryg.hex()}")
# 2. Obliczenie paddingu Merkle-Damgard dla dlugosci klucz (16 B) + wiadomosc (19 B) = 35 B
calkowita_dlugosc = 16 + len(wiadomosc_oryg) # 35 bajtow
pad_len = (56 - (calkowita_dlugosc + 1) % 64) % 64
padding = b"\x80" + b"\x00" * pad_len + struct.pack(">Q", calkowita_dlugosc * 8)
# 3. Zlosliwe rozszerzenie: komenda otwarcia wyłacznika stacji
zlosliwy_doklejony = b";COMMAND=TRIP_BREAKER_L1;FORCE=1"
# Inicjalizacja rejestrow SHA-256 wartosciami przechwyconego tagu
h_stany = struct.unpack(">8I", tag_oryg)
# Obliczenie nowego tagu na nowym bloku (uzywajac hashpump lub logiki SHA-256)
nowa_pelna_wiadomosc = wiadomosc_oryg + padding + zlosliwy_doklejony
print(f"[+] Nowa ramka (z paddingiem): {nowa_pelna_wiadomosc}")
print("[+] Sukces LEA: Wstrzyknieto rozkaz wylaczenia linii przesylowej bez znajomosci klucza!")
#!/usr/bin/env python3
from cryptography.hazmat.primitives import hashes
# Realizacja odpornego schematu KMAC256 zgodnie z NIST SP 800-185
def kmac256_uwierzytelnij(klucz, wiadomosc, customization=b"PSE_SCADA_IEC104"):
# cSHAKE / KMAC absorbuje klucz i wiadomosc w sposob odporny na LEA
h = hashes.Hash(hashes.SHAKE256(32))
# Separacja domen i absorpcja klucza
h.update(customization)
h.update(klucz)
h.update(wiadomosc)
return h.finalize()
klucz_stacji = b"SCADA_SECRET_K16_EXTREMELY_SAFE!"
ramka = b"STATUS_L1_NORMAL_OK"
tag_kmac = kmac256_uwierzytelnij(klucz_stacji, ramka)
print(f"[+] Bezpieczny tag KMAC256 (32 bajty): {tag_kmac.hex()}")
print("[+] Odpornosc matematyczna: Architektura gabki Keccak uniemozliwia ataki LEA!")
# Przechwytywanie ruchu na dedykowanym interfejsie sieci OT
tshark -i eth1 -f "tcp port 2404" -Y "iec104" -T fields \
-e frame.number -e ip.src -e ip.dst -e iec104.type -e iec104.addr
# Eksport przechwyconych danych do pliku pcap
tshark -i eth1 -f "tcp port 2404" -w scada_traffic.pcap
alert tcp any any -> any 2404 (msg:"SCADA_OT - Podejrzenie ataku Length Extension Attack na IEC-104"; \
flow:to_server,established; \
content:"|68|"; offset:0; depth:1; \
content:"|80|"; distance:10; within:60; \
content:"TRIP_BREAKER"; nocase; distance:0; \
classtype:attempted-admin; sid:1000603; rev:1; \
metadata:created_at 2026_09_29, attack_target SCADA_RTU;)
# Uruchomienie Suricata w trybie offline na pliku testowym
suricata -r scada_traffic.pcap -c /etc/suricata/suricata.yaml -k none
# Sprawdzenie wpisów alertów w pliku fast.log
tail -n 20 /var/log/suricata/fast.log | grep "1000603"
Poniższa lista zawiera propozycje zagadnień i wniosków technicznych, które warto uwzględnić w sprawozdaniu z tego zadania:
Przykładowe wnioski (wzór do sprawozdania): Eksploatacja ataku rozszerzenia długości na autorski mechanizm uwierzytelniania w protokole IEC 60870-5-104 ujawniła krytyczną lukę w łączności sterowników stacji elektroenergetycznych. Znając jedynie legalny pakiet telemetryczny i jego skrót SHA-256, zespół audytorski dokleił złośliwe polecenie rozłączenia transformatora i wygenerował poprawny skrót uwierzytelniający bez znajomości klucza stacji. Sterownik polowy RTU bezbłędnie zweryfikował autentyczność spreparowanego rozkazu, co w warunkach rzeczywistych mogłoby doprowadzić do blackoutu sieci przesyłowej. Zastąpienie wadliwej konstrukcji standaryzowanym algorytmem KMAC256 opartym na konstrukcji gąbki Keccak całkowicie wyeliminowało ten wektor ataku dzięki ukryciu rejestrów wewnętrznych funkcji skrótu. Wdrożona modernizacja protokołu łączności dyspozytorskiej trwale zabezpieczyła infrastrukturę elektroenergetyczną przed sabotażem i spełniła rygory dyrektywy NIS2.
Zadanie opiera się na treściach Wykładu 2 (Podstawy ochrony, poufność i łańcuch zaufania), Wykładu 3 (Funkcje skrótu, integralność kodu i drzewa Merkle'a) oraz Wykładu 6 (Trendy rozwoju kryptologii, bezpieczeństwo łańcucha dostaw oprogramowania i podpisywanie artefaktów). Ćwiczenie weryfikuje kierunkowe efekty uczenia się: W1 (dogłębna znajomość wektorów ataku typu Supply Chain na automatyczne potoki CI/CD, technik zatruwania kompilacji i podmiany zależności), W3 (specyfikacja standardu poświadczeń in-toto, bezkluczowe podpisywanie w architekturze Sigstore Cosign oraz publiczne logi przejrzystości Rekor), U1 (przeprowadzenie symulacji ataku na serwer budujący z podmianą biblioteki bankowej i manipulacją plikiem skrótów), U2 (konfiguracja polityki in-toto layout, generowanie linków poświadczających oraz weryfikacja binarnej nienaruszalności), U3 (szacowanie ryzyka wg metodyki CVSS v4.0), U4 (inżynieria sygnatur Suricata NIDS wykrywających rozbieżności sum kontrolnych pobieranych bibliotek) oraz K1 (zrozumienie odpowiedzialności dostawcy oprogramowania w reżimie dyrektywy NIS 2 i rozporządzenia DORA). Wymagania normatywne obejmują wytyczne NIST SP 800-204D (Strategies for Integrating Software Supply Chain Security in DevSecOps), in-toto Framework Specification v1.0, Rozporządzenie DORA (UE 2022/2554), klasyfikację CWE-494 oraz techniki T1195.001 i T1195.002 matrycy MITRE ATT&CK.
Głównym celem zadania jest zbadanie podatności łańcucha dostaw oprogramowania (Supply Chain Attack) w automatycznych potokach kompilacji i wdrażania CI/CD systemów bankowości elektronicznej. Studenci analizują wektor ataku polegający na wstrzyknięciu złośliwego kodu do biblioteki płatniczej w trakcie etapu budowania przed wygenerowaniem oficjalnego wydania. W części ofensywnej zespół demonstruje obejście prostych weryfikacji sum kontrolnych SHA-256 poprzez modyfikację manifestu dystrybucyjnego na skompromitowanym serwerze kompilacji. Ćwiczenie uświadamia, że sama weryfikacja hasha pobieranego z tego samego źródła co binarium nie stanowi wystarczającego środka obronnego.
W części defensywnej celem jest wdrożenie kryptograficznego standardu poświadczeń pochodzenia kodu in-toto oraz bezkluczowego podpisywania artefaktów Sigstore Cosign. Studenci konfigurują układ kryptograficzny weryfikujący podpisy każdego etapu budowania oraz sprawdzają wpisy w publicznym rejestrze przejrzystości Rekor. Końcowym etapem jest opracowanie sygnatury Suricata NIDS alarmującej o rozbieżności pomiędzy deklarowaną sumą kontrolną a rzeczywistym strumieniem danych w sieci.
Krajowa Izba Rozliczeniowa (KIR S.A.) zarządza infrastrukturą rozliczeń międzybankowych Elixir i Euro Elixir. W ramach podnoszenia odporności cyfrowej zgodnie z rozporządzeniem DORA, instytucja weryfikuje bezpieczeństwo automatycznego potoku CI/CD generującego pakiety klienckie API dla banków komercyjnych. W trakcie audytu założono scenariusz, w którym adwersarz uzyskuje dostęp do serwera kompilacji Jenkins/GitLab Runner.
Zespół Red Team przeprowadza symulację ataku typu Compromised Build Pipeline: podczas kompilacji biblioteki Java/Python podmienia funkcję walidacji numerów rachunków IBAN na wersję przekierowującą ułamek procenta transakcji na rachunek atakującego. Jednocześnie skrypt atakujący przelicza sumę SHA-256 zmodyfikowanego pliku jar i nadpisuje oficjalny plik checksums.sha256 w repozytorium artefaktów Nexus, omijając elementarne kontrole wdrożeniowe.
Zespół Blue Team wdraża kryptograficzny schemat gwarancji pochodzenia kodu w oparciu o framework in-toto oraz narzędzie Sigstore Cosign. Układ ten definiuje politykę (layout), która wymaga kryptograficznych podpisów od niezależnych ról: dewelopera zatwierdzającego kod źródłowy, izolowanego środowiska budującego oraz automatycznego skanera podatności SAST. Klucze prywatne powiązane są z tożsamościami OIDC, a każdy podpis trafia do nienaruszalnego rejestru Rekor.
Dodatkowo inżynierowie wdrażają sieć monitorowania ruchu transmisyjnego z sygnaturami Suricata NIDS. Reguły DPI przechwytują pakiety pobierania artefaktów z serwera Nexus, wyliczają sumy SHA-256 w locie i porównują je z autoryzowaną bazą podpisanych metadanych in-toto, natychmiast przerywając proces wdrożenia w razie wykrycia anomalii.
Podstawowym problemem tradycyjnej weryfikacji sum kontrolnych jest brak separacji uprawnień. Jeżeli atakujący przejmie serwer dystrybucyjny, może zmodyfikować zarówno plik binarny, jak i towarzyszący mu plik sum kontrolnych. Framework in-toto rozwiązuje ten problem, wprowadzając niezależnie podpisywane metadane linków (step links) przez poszczególnych uczestników procesu.
Układ in-toto (layout) precyzyjnie definiuje reguły przepływu materiałów (inspection rules). Każdy krok rejestruje skróty kryptograficzne plików wejściowych i wyjściowych. Weryfikator sprawdza, czy pliki przekazane do kompilatora były dokładnie tymi samymi plikami, które zatwierdził deweloper swoim kluczem prywatnym.
W środowisku produkcyjnym narzędzie Sigstore Cosign pozwala na podpisywanie bez konieczności długoterminowego przechowywania kluczy na dysku (Keyless Signing). Tożsamość jest poświadczana przez token OIDC, certyfikat X.509 wystawiany przez CA Fulcio, a podpis trwale rejestrowany w dzienniku Rekor.
Sygnatura Suricata wykorzystuje silnik analizy protokołu HTTP i słowa kluczowe filestore oraz sha256, co pozwala na inspekcję w locie pobieranych archiwów i generowanie alertu, gdy hash pakietu nie znajduje się na białej liście autoryzowanych wydań.
#!/usr/bin/env python3
from in_toto.models.layout import Layout, Step
from in_toto.models.metadata import Metablock
from securesystemslib.signer import CryptoSigner
from cryptography.hazmat.primitives.asymmetric import ed25519
# Generowanie klucza Ed25519 wlasciciela projektu
owner_key = ed25519.Ed25519PrivateKey.generate()
signer = CryptoSigner(owner_key)
layout = Layout()
step_build = Step(name="kompilacja-biblioteki")
step_build.pubkeys = ["pubkey_builder_hex"]
step_build.expected_command = ["python3", "setup.py", "build"]
step_build.expected_materials = [["MATCH", "src/*", "WITH", "PRODUCTS", "FROM", "commit"]]
step_build.expected_products = [["CREATE", "dist/elixir_client.jar"]]
layout.steps.append(step_build)
metablock = Metablock(signed=layout)
metablock.sign(signer)
metablock.dump("root.layout")
print("[+] Utworzono i podpisano glowna polityke zaufania: root.layout")
#!/bin/bash
# RED TEAM: Wstrzykniecie exploita manipulujacego numerami kont
echo "[*] Wstrzykiwanie luki do zrodel podczas kompilacji..."
sed -i 's/validate_iban(account)/redirect_funds_to_attacker(account)/g' src/payment.py
# Kompilacja zatrutego pakietu
python3 -m build --wheel
# Obejscie elementarnych kontroli: Przeliczenie sumy i nadpisanie na serwerze
sha256sum dist/*.whl > dist/checksums.sha256
echo "[+] Zatrucie udane. Zaktualizowano checksums.sha256 na serwerze dystrybucyjnym!"
# Uruchomienie budowania z rejestracja wejscia/wyjscia przez in-toto
in-toto-run --step-name kompilacja-biblioteki \
--key /home/student/keys/builder_key \
--materials src/payment.py \
--products dist/elixir_client.jar \
-- python3 -m build
# Weryfikacja powstalego pliku metadanych
ls -la kompilacja-biblioteki.*.link
# Weryfikacja integralnosci calego potoku przed instalacja w banku
in-toto-verify --layout root.layout \
--layout-keys /home/student/keys/owner_pubkey.pub
# W przypadku wykrycia nieautoryzowanej modyfikacji zrodel:
# Wynik: InTotoVerificationError: Step 'kompilacja-biblioteki' failed: materials altered!
# Podpisanie wygenerowanego pakietu (eksport do rejestru)
cosign sign-blob --bundle cosign.bundle \
--output-signature elixir_client.sig \
--output-certificate elixir_client.crt \
dist/elixir_client.jar
# Weryfikacja wpisu w publicznym dzienniku przejrzystości Rekor
cosign verify-blob --bundle cosign.bundle \
--certificate-identity "builder@kir.pl" \
--certificate-oidc-issuer "https://accounts.google.com" \
dist/elixir_client.jar
alert http any any -> any any (msg:"SUPPLY_CHAIN - Wykryto pobranie pakietu o nieznanej sumie SHA-256"; \
flow:established,from_server; \
content:"/nexus/repository/maven-releases/"; http_uri; \
file.data; \
filesha256:!/etc/suricata/authorized_elixir_hashes.list; \
classtype:bad-unknown; sid:1000604; rev:1; \
metadata:created_at 2026_09_29, team BlueTeam;)
Poniższa lista zawiera propozycje zagadnień i wniosków technicznych, które warto uwzględnić w sprawozdaniu z tego zadania:
Przykładowe wnioski (wzór do sprawozdania): Symulacja ataku na środowisko CI/CD Krajowej Izby Rozliczeniowej wykazała, że kompromitacja pojedynczego węzła kompilacji pozwalała na wstrzyknięcie złośliwego kodu do biblioteki klienckiej API bez zmiany kodu źródłowego w repozytorium Git. Zastosowanie tradycyjnych sum kontrolnych pobieranych z serwera budującego okazało się bezużyteczne, gdyż proces malware zaktualizował plik sum w tym samym potoku. Wdrożenie standardu poświadczeń in-toto połączonego z bezkluczykowym podpisywaniem Sigstore Cosign całkowicie udaremniło ten atak poprzez wymuszenie weryfikacji kryptograficznego łańcucha wytwórczego w publicznym rejestrze Rekor. Każdy pakiet API musi obecnie posiadać dowód tożsamości OIDC zatwierdzony przez zaufany potok budujący, co uniemożliwia wdrożenie kodu skompilowanego na obcej maszynie. Równoległa sygnatura sieciowa w systemie Suricata gwarantuje natychmiastowe zablokowanie pobierania paczek o sumach kontrolnych niezgodnych ze skarbem metadanych in-toto.
Zadanie opiera się na treściach Wykładu 2 (Podstawy ochrony, polityki bezpieczeństwa i integralność oprogramowania), Wykładu 3 (Funkcje skrótu, podpisy cyfrowe i odciski certyfikatów X.509) oraz Wykładu 6 (Trendy rozwoju kryptologii, architektura Zero Trust w routerach brzegowych i segmentacja sieci). Ćwiczenie weryfikuje kierunkowe efekty uczenia się: W1 (znajomość wektorów ataków na oprogramowanie układowe firmware, manipulacji pakietami .npk i infekcji urządzeń sieciowych), W4 (zasady architektury Zero Trust w systemie MikroTik RouterOS v7, bezpieczna telemetria i wzajemne uwierzytelnianie mTLS), U1 (procedura bezpiecznej instalacji firmware przez Netinstall z weryfikacją kryptograficznych sum SHA-256), U2 (konfiguracja wzajemnego mTLS z przypinaniem fingerprintu SHA-256 certyfikatu klienta w RouterOS CLI), U3 (analiza ryzyka CVSS v4.0), U4 (inżynieria reguł Sigma analizujących syslog routera pod kątem ataków brute-force na API) oraz K2 (świadomość odpowiedzialności za ochronę styku sieci publicznej z infrastrukturą krytyczną). Wymagania normatywne obejmują wytyczne NIST SP 800-207 (Zero Trust Architecture), zalecenia CIS MikroTik Benchmark v1.0, wytyczne CSIRT GOV w reżimie ustawy o KSC, klasyfikację CWE-295 oraz techniki T1190 i T1110 matrycy MITRE ATT&CK.
Głównym celem zadania jest wdrożenie kompleksowego hardeningu urządzeń sieciowych MikroTik RouterOS v7 w reżimie architektury Zero Trust. Studenci analizują procedury bezpiecznego wgrywania systemu operacyjnego za pomocą narzędzia Netinstall z rygorystyczną weryfikacją sum kontrolnych SHA-256. W części analitycznej zespół bada wektory ataków na interfejsy zarządzania oraz symuluje próby wstrzyknięcia nieautoryzowanych pakietów oprogramowania. Ćwiczenie pozwala zrozumieć, że weryfikacja integralności oprogramowania układowego jest fundamentem bezpieczeństwa infrastruktury brzegowej.
W części defensywnej celem jest konfiguracja wzajemnego uwierzytelniania mTLS dla interfejsu REST API z rygorystycznym przypięciem odcisku SHA-256 certyfikatu klienta. Studenci wdrażają reguły zapory ogniowej w łańcuchu raw oraz izolują ruch zarządzający w dedykowanej instancji VRF. Końcowym etapem jest opracowanie reguły Sigma dla dzienników syslog RouterOS, która natychmiast alarmuje o próbach siłowego łamania haseł dostępowych.
Rządowa Sieć Łączności Bezpiecznej (nadzorowana przez CSIRT GOV / ABW) zarządza węzłami telekomunikacyjnymi łączącymi delegatury urzędów wojewódzkich. Po wykryciu skoordynowanych kampanii szpiegowskich ukierunkowanych na urządzenia brzegowe (np. botnety Glupteba, Meris) podjęto decyzję o przeprowadzeniu pełnego audytu bezpieczeństwa routerów MikroTik RouterOS v7 pracujących na styku sieci publicznej i rządowej.
Zespół Red Team analizuje możliwość przejęcia routera poprzez nieautoryzowaną modyfikację obrazu instalacyjnego lub atak siłowy na porty zarządzania API-SSL i Winbox. W ramach testów penetracyjnych studenci weryfikują podatność urządzeń na próby załadowania zmodyfikowanych pakietów npk pozbawionych oficjalnego podpisu cyfrowego producenta oraz symulują masowe zapytania logowania generowane z wielu adresów IP.
Zespół Blue Team wdraża procedurę instalacji czystego obrazu systemu za pośrednictwem narzędzia Netinstall przez odizolowany port Ethernet, weryfikując skrót SHA-256 pobranego pakietu z oficjalnymi skrótami publikowanymi na bezpiecznym serwerze producenta. Następnie inżynierowie rekonfigurują urządzenie zgodnie z założeniami Zero Trust: wyłączane są wszystkie nieszyfrowane usługi (telnet, ftp, http, mac-server), a zarządzanie ograniczone zostaje do dedykowanego interfejsu mTLS z przypiętym odciskiem SHA-256.
Całość telemetrii z routera przesyłana jest przez bezpieczny protokół syslog TLS do centralnego serwera SIEM. Blue Team konstruuje regułę Sigma, która analizuje sekwencje logów systemowych RouterOS i wykrywa zsynchronizowane ataki brute-force, automatycznie dodając adresy źródłowe napastników do dynamicznej czarnej listy zapory ogniowej MikroTik.
Zastosowanie narzędzia Netinstall jest jedyną w 100% skuteczną metodą usunięcia złośliwego oprogramowania (np. backdoorów instalowanych przez botnety) z urządzeń MikroTik. Netinstall formatuje partycję systemową i zapisuje strukturę plików na nowo, co wyklucza przetrwanie zmanipulowanych skryptów ukrytych w pamięci trwałej routera.
W protokole mTLS weryfikacja certyfikatu klienta odbywa się dwustronnie. Serwer RouterOS weryfikuje podpis CA na certyfikacie administratora, a przypięcie odcisku SHA-256 gwarantuje, że nawet wystawienie fałszywego certyfikatu przez skompromitowane CA pośredniczące nie pozwoli napastnikowi na zalogowanie się do urządzenia.
W łańcuchu raw zapory ogniowej pakiety są przetwarzane przed mechanizmem śledzenia połączeń (connection tracking), co pozwala na oszczędność zasobów procesora i skuteczną neutralizację ataków Denial of Service ukierunkowanych na interfejsy zarządzania.
Reguła Sigma dla systemu MikroTik powinna monitorować identyfikatory komunikatów logowania o treści "login failure for user ... from ... via api-ssl", wyzwalając alert po przekroczeniu progu 10 nieudanych prób w oknie jednej minuty.
# Pobranie oficjalnego pakietu oraz weryfikacja skrótu SHA-256
sha256sum routeros-7.16-arm.npk
# Porównanie z oficjalną sumą kontrolną producenta
echo "a1b2c3d4e5f67890abcdef1234567890abcdef1234567890abcdef1234567890 routeros-7.16-arm.npk" | sha256sum -c
# Wylaczenie niebezpiecznych uslug nieszyfrowanych
/ip service disable telnet,ftp,www,api
/ip service set api-ssl certificate=router-cert-sha256 require-client-certificate=yes tls-version=only-1.3 disabled=no
# Zablokowanie serwerow MAC i sasiadow na portach zewnetrznych
/tool mac-server set allowed-interface-list=none
/tool mac-server mac-winbox set allowed-interface-list=none
/ip neighbor discovery-settings set discover-interface-list=none
# Import certyfikatu Root CA oraz certyfikatu serwera
/certificate import file-name=root_ca.crt passphrase=""
/certificate import file-name=router_server.crt passphrase=""
# Konfiguracja uzytkownika z przypieciem odcisku SHA-256 certyfikatu klienta
/user add name=admin_sec group=full address=192.168.88.0/24 \
certificate=client_admin_cert \
comment="Administrator z wymuszonym certyfikatem SHA-256"
# Dynamiczna czarna lista w lancuchu raw
/ip firewall raw add chain=prerouting src-address-list=blacklist_bf action=drop comment="Blokada atakow brute-force"
/ip firewall filter add chain=input protocol=tcp dst-port=8729 connection-state=new \
src-address-list=api_stage3 action=add-src-to-address-list address-list=blacklist_bf address-list-timeout=1d
/ip firewall filter add chain=input protocol=tcp dst-port=8729 connection-state=new \
src-address-list=api_stage2 action=add-src-to-address-list address-list=api_stage3 address-list-timeout=1m
/ip firewall filter add chain=input protocol=tcp dst-port=8729 connection-state=new \
src-address-list=api_stage1 action=add-src-to-address-list address-list=api_stage2 address-list-timeout=1m
/ip firewall filter add chain=input protocol=tcp dst-port=8729 connection-state=new \
action=add-src-to-address-list address-list=api_stage1 address-list-timeout=1m
#!/usr/bin/env python3
import requests
ROUTER_IP = "192.168.88.1"
API_URL = f"https://{ROUTER_IP}/rest/system/resource"
# Zapytanie z bilateralnym certyfikatem mTLS
response = requests.get(
API_URL,
cert=('admin_client.crt', 'admin_client.key'),
verify='root_ca.crt'
)
print(f"[+] Status odpowiedzi REST API: {response.status_code}")
print(f"[+] Zasoby routera: {response.json()}")
title: Wykrycie Ataku Brute-Force na Interfejs API MikroTik
id: c4e1a7b8-6721-4f12-a1b2-mikrotikbf001
status: experimental
description: Wykrywa powtarzajace sie nieudane proby uwierzytelnienia na interfejsie API-SSL w routerze MikroTik
logsource:
category: firewall
product: mikrotik
detection:
selection:
message|contains:
- 'login failure for user'
- 'via api-ssl'
timeframe: 1m
condition: selection | count() > 10
fields:
- src_ip
- user
level: high
tags:
- attack.credential_access
- attack.t1110
Poniższa lista zawiera propozycje zagadnień i wniosków technicznych, które warto uwzględnić w sprawozdaniu z tego zadania:
Przykładowe wnioski (wzór do sprawozdania): Audyt i utwardzenie routerów MikroTik RouterOS v7 w formule Zero Trust pozwoliły na całkowitą eliminację podatności brzegowych wykorzystywanych przez znane botnety szpiegowskie. Przeprowadzenie czystej instalacji za pomocą narzędzia Netinstall z rygorystyczną weryfikacją sumy kontrolnej SHA-256 usunęło wszelkie pozostałości potencjalnie zmodyfikowanych pakietów jądra. Dostęp do interfejsu zarządzania został uwarunkowany zestawieniem wzajemnego tunelu mTLS z bezwzględnym przypięciem odcisku certyfikatu administracyjnego, co wyeliminowało ryzyko ataków podsłuchu i fałszowania tożsamości. Wszystkie zbędne usługi legacy zostały bezpowrotnie wyłączone, a administracja dozwolona jest wyłącznie za pośrednictwem dedykowanego tunelu WireGuard z uwierzytelnianiem kluczem asymetrycznym. Zintegrowanie dzienników zdarzeń routera z systemem SIEM za pośrednictwem reguł Sigma zapewnia pełną rozliczalność każdej zmiany reguł zapory i spełnia najwyższe wytyczne CSIRT GOV.
Zadanie opiera się na treściach Wykładu 2 (Poufność danych, funkcje jednokierunkowe i odporność poświadczeń), Wykładu 3 (Funkcje wyprowadzania klucza KDF, solenie i kryptoanaliza słownikowa) oraz Wykładu 6 (Akceleracja sprzętowa na farmach GPU/ASIC i nowoczesne pamięciochłonne funkcje skrótu). Ćwiczenie weryfikuje kierunkowe efekty uczenia się: W1 (podatność klasycznych funkcji PBKDF2 i MD5 na wysoce zrównolegloną kryptoanalizę sprzętową z wektorami SIMD), W3 (specyfikacja standardu RFC 9106 Argon2id, parametry kosztu pamięciowego m_cost, czasowego t_cost i współbieżności lanes), U1 (implementacja zoptymalizowanego skryptu kryptoanalitycznego w Pythonie symulującego atak słownikowy), U2 (wdrożenie bezpiecznego haszowania Argon2id zintegrowanego ze sprzętowym pieprzem Pepper w SoftHSM2), U3 (analiza ryzyka CVSS v4.0), U4 (inżynieria reguł Sigma analizujących dzienniki uwierzytelniania w SIEM) oraz K1 (zapewnienie odpowiedniego stopnia bezpieczeństwa poświadczeń zgodnie z art. 32 RODO). Wymagania normatywne obejmują standardy RFC 9106 (Argon2 Memory-Hard Function for Password Hashing), NIST SP 800-63B (Digital Identity Guidelines: Authentication and Lifecycle Management), Rozporządzenie RODO (art. 32), klasyfikację CWE-916 oraz techniki T1110.002 i T1003 z matrycy MITRE ATT&CK.
Głównym celem zadania jest praktyczne zbadanie podatności mechanizmów ochrony haseł na kryptoanalizę siłową realizowaną z wykorzystaniem akceleracji sprzętowej GPU i jednostek SIMD. Studenci analizują dysproporcję wydajnościową pomiędzy klasycznymi funkcjami PBKDF2/MD5 a pamięciochłonnymi algorytmami nowoczesnej kryptografii. W części ofensywnej zespół tworzy w języku Python zoptymalizowany skrypt łamiący próbki skrótów z bazy danych tożsamości. Ćwiczenie pozwala uświadomić sobie, że sam algorytm PBKDF2 bez wysokich parametrów pamięciowych nie stanowi wystarczającej bariery dla klastrów obliczeniowych.
W części defensywnej celem jest wdrożenie odpornego na ataki sprzętowe algorytmu Argon2id (RFC 9106) wzbogaconego o pieprz (Pepper) zarządzany w module SoftHSM2. Studenci optymalizują parametry kosztu pamięciowego i czasowego tak, aby maksymalnie utrudnić równoległe przeszukiwanie na kartach graficznych. Końcowym etapem jest przygotowanie reguły Sigma dla systemu SIEM, która identyfikuje próby eksfiltracji bazy skrótów i anomalie uwierzytelniania.
Ministerstwo Cyfryzacji – Krajowy Węzeł Tożsamości (login.gov.pl) obsługuje poświadczenia tożsamości cyfrowej milionów obywateli. W ramach audytu odporności na wypadek wycieku baz danych poświadczeń (Threat Modeling i testy typu Purple Teaming) zespół inżynierów bada podatność przechowywanych skrótów na kryptoanalizę siłową i ataki słownikowe prowadzone przy użyciu nowoczesnych farm procesorów graficznych (GPU) i układów ASIC.
Red Team otrzymuje zrzut testowej bazy zawierającej hasze wygenerowane za pomocą starszych wersji schematu PBKDF2-HMAC-SHA256 oraz MD5 z soleniem. Wykorzystując skrypt z akceleracją wektorową w języku Python oraz narzędzia typu hashcat, zespół demonstruje, że szybkość testowania haseł na pojedynczej stacji roboczej sięga setek milionów prób na sekundę, co pozwala na odzyskanie haseł użytkowników w ciągu kilkunastu minut.
Blue Team projektuje nową architekturę ochrony poświadczeń bazującą na standardzie RFC 9106 Argon2id. Algorytm ten wymusza alokację dużych bloków pamięci RAM (np. 64 MB na każde haszowanie), co skutecznie paraliżuje procesory graficzne poprzez wysycenie przepustowości pamięci. Dodatkowo, aby zabezpieczyć bazę przed kryptoanalizą offline w przypadku wycieku danych z bazy SQL, schemat łączy hasło z tajnym pieprzem (Pepper) generowanym i przechowywanym wewnątrz tokena SoftHSM2 PKCS#11.
W warstwie telemetrii Blue Team wdraża regułę detekcyjną Sigma analizującą zdarzenia z serwerów bazy danych oraz aplikacji uwierzytelniającej. System koreluje masowe zapytania o tabele poświadczeń z nieudanymi próbami logowania z nietypowych geolokalizacji, co pozwala na natychmiastowe wykrycie incydentu naruszenia poufności bazy danych.
Podstawową słabością PBKDF2 jest znikome zapotrzebowanie na pamięć operacyjną (zaledwie kilkadziesiąt bajtów stanu wewnętrznego). Dzięki temu procesory graficzne mogą uruchamiać dziesiątki tysięcy wątków jednocześnie, osiągając miliardy prób na sekundę. Algorytm Argon2id rozwiązuje ten problem, wypełniając wielomegabajtową macierz pamięci losowymi permutacjami, co blokuje równoległe jednostki cieniujące GPU z powodu wąskiego gardła pamięci VRAM.
Klucz pieprzu (Pepper) stanowi dodatkowy tajny składnik kryptograficzny wspólny dla całej aplikacji. Przechowywanie pieprzu wewnątrz modułu SoftHSM2 z flagami CKA_EXTRACTABLE=FALSE gwarantuje, że nawet w przypadku pełnego zrzutu bazy danych SQL przez lukę SQL Injection, napastnik nie może rozpocząć kryptoanalizy offline na własnym sprzęcie.
Dobór parametrów Argon2id powinien uwzględniać możliwości sprzętowe serwera. Zaleca się, aby czas pojedynczego haszowania wynosił od 300 do 500 milisekund dla autoryzowanego użytkownika, co w zupełności wystarcza do zapewnienia komfortu pracy, a jednocześnie uniemożliwia masowe ataki siłowe.
Reguła Sigma powinna łączyć zdarzenia audytu bazy danych (np. zapytanie SELECT z klauzulą LIMIT > 1000 na tabeli users) ze wskaźnikami telemetrii systemowej wskazującymi na nieautoryzowany zrzut danych.
#!/usr/bin/env python3
import hashlib
import time
from multiprocessing import Pool
SÓL = b"rzadowa_sol_krajowa_123"
HASLO_TEST = "Obywatel2026!"
HASH_CEL = hashlib.pbkdf2_hmac('sha256', HASLO_TEST.encode(), SÓL, 100000)
def testuj_kandydata(kandydat):
h = hashlib.pbkdf2_hmac('sha256', kandydat.encode(), SÓL, 100000)
return h == HASH_CEL
if __name__ == '__main__':
slowa = [f"Haslo{i:05d}!" for i in range(50000)]
t0 = time.perf_counter()
with Pool(8) as p:
wyniki = p.map(testuj_kandydata, slowa)
t1 = time.perf_counter()
print(f"[+] Przetestowano 50 000 hasel w czasie {t1 - t0:.2f} s ({50000/(t1-t0):.1f} haszy/s)")
print("[!] Ostrzezenie: Brak kosztu pamieciowego pozwala na latwe przyspieszenie ataku na kartach GPU!")
export SOFTHSM2_CONF=/home/student/lab6_hsm/softhsm2.conf
# Generowanie klucza pieprzu (Pepper) w tokenie HSM
pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --login --pin 12345678 \
--keygen --key-type generic:32 --label "PEPPER_ARGON2_KEY" \
--sensitive --extractable false
#!/usr/bin/env python3
import argon2
import PyKCS11
# Pobranie wartosci pieprzu lub wyliczenie HMAC pieprzu bezposrednio w HSM
ph = argon2.PasswordHasher(
time_cost=3, # 3 iteracje
memory_cost=65536, # 64 MB pamieci RAM
parallelism=4, # 4 watki robocze
hash_len=32,
salt_len=16
)
# Polaczenie hasla z pieprzem ze sprzetowego tokena
haslo_uzytkownika = "TajneHasloObywatela#2026"
pepper_hsm = b"HSM_PEPPER_INTERNAL_SECRET_32B!" # Pobierane z sesji PKCS#11
haslo_z_pieprzem = haslo_uzytkownika.encode() + pepper_hsm
hash_bezpieczny = ph.hash(haslo_z_pieprzem)
print(f"[+] Wygenerowany skrot Argon2id:\n{hash_bezpieczny}")
# Weryfikacja
poprawne = ph.verify(hash_bezpieczny, haslo_z_pieprzem)
print(f"[+] Wynik weryfikacji poświadczenia: {poprawne}")
# Testowanie wydajnosci Hashcat w trybie benchmarku dla Argon2id
hashcat -b -m 15400
# Weryfikacja drastycznego spadku wydajnosci wzgledem PBKDF2 (tryb 10900)
hashcat -b -m 10900
title: Masowy Odczyt Bazy Danych Poświadczeń Użytkowników
id: e5f2a1b9-8731-4f12-a1b2-credentialdump01
status: experimental
description: Wykrywa podejrzanie duze zapytania do tabeli haszy wskazujace na probe zrzutu bazy przed atakiem offline
logsource:
category: database
product: sql
detection:
selection:
query|contains:
- 'SELECT'
- 'password_hash'
- 'salt'
- 'FROM users'
timeframe: 30s
condition: selection | count() > 500
fields:
- client_ip
- db_user
- query
level: critical
tags:
- attack.credential_access
- attack.t1003
# Uruchomienie monitorowania pamieci RAM serwera uwierzytelniajacego
valgrind --tool=massif python3 argon2_secure.py
# Odczyt raportu alokacji pamieci
ms_print massif.out.* | head -n 30
Poniższa lista zawiera propozycje zagadnień i wniosków technicznych, które warto uwzględnić w sprawozdaniu z tego zadania:
Przykładowe wnioski (wzór do sprawozdania): Testy benchmarkingowe z wykorzystaniem klastra kart graficznych wykazały, że hasła zabezpieczone tradycyjnym algorytmem PBKDF2 z niską liczbą iteracji są łamane z prędkością setek milionów prób na sekundę. Wdrożenie hybrydowego algorytmu Argon2id z parametrami kosztu pamięciowego 64 MB oraz czterema wątkami roboczymi drastycznie obniżyło efektywność równoległych ataków GPU do zaledwie kilkudziesięciu prób na sekundę na jedno urządzenie. Dodatkowe zastosowanie kryptograficznego pieprzu zarządzanego wewnątrz modułu bezpieczeństwa HSM uniemożliwia rozpoczęcie kryptoanalizy słownikowej nawet w przypadku pełnego wycieku bazy danych użytkowników. Węzeł tożsamości login.gov.pl zyskał najwyższy poziom odporności na nowoczesne wektory łamania poświadczeń bez zauważalnego obniżenia komfortu logowania obywateli. Wdrożona reguła detekcyjna Sigma natychmiast wychwytuje i blokuje rozproszone ataki typu Credential Stuffing, chroniąc strategiczną bazę tożsamości państwowej.
Zadanie opiera się na treściach Wykładu 2 (Podstawy ochrony, nienaruszalność i niezaprzeczalność danych), Wykładu 3 (Drzewa Merkle'a, znaczniki czasu RFC 3161 TSA i rejestry nienaruszalne append-only) oraz Wykładu 6 (Kryptografia łańcuchów blokowych, protokoły consensusu i dowody kryptograficzne). Ćwiczenie weryfikuje kierunkowe efekty uczenia się: W1 (podatność centralnych baz danych logów na ataki fałszowania historii przez administratora – Equivocation / Split-View), W3 (architektura kryptograficznych rejestrów nienaruszalnych z dowodami włączenia i kotwiczeniem w publicznym blockchainie Bitcoin przez OP_RETURN), U1 (implementacja ataku rozwidlenia historii w języku Python manipulującego lokalnym łańcuchem skrótów), U2 (konstrukcja systemu podwójnego kotwiczenia z wieloma niezależnymi serwerami TSA oraz transakcją OP_RETURN), U3 (analiza ryzyka CVSS v4.0), U4 (inżynieria reguł detekcyjnych Sigma dla weryfikatorów spójności drzewa Merkle'a) oraz K1 (aspekty prawne nienaruszalności rejestrów audytowych w instytucjach finansowych wg wytycznych KNF i rozporządzenia DORA). Wymagania normatywne obejmują standardy RFC 3161 (Time-Stamp Protocol), RFC 6962 (Certificate Transparency), Rozporządzenie DORA (UE 2022/2554), klasyfikację CWE-345 oraz techniki T1565.001 i T1070 matrycy MITRE ATT&CK.
Nadrzędnym celem zadania jest zbadanie mechanizmów odporności kryptograficznych rejestrów audytowych na ataki typu Equivocation (Split-View), polegające na prezentowaniu odmiennych wersji historii różnym audytorom. Studenci analizują strukturę łańcuchów skrótów oraz drzew Merkle'a wykorzystywanych w bankowych bazach logów bezpieczeństwa. W części ofensywnej zespół tworzy w języku Python demonstrator ataku rozwidlenia rejestru, w którym złośliwy administrator podmienia wpis o naruszeniu integralności. Ćwiczenie dowodzi, że samo haszowanie lokalnych rekordów nie chroni przed fałszowaniem historii przez uprzywilejowane konta systemowe.
W części defensywnej celem jest wdrożenie architektury nienaruszalnego rejestru audytowego z podwójnym kotwiczeniem w niezależnych serwerach TSA (RFC 3161) oraz publicznym blockchainie Bitcoin. Studenci implementują mechanizm publikowania korzenia drzewa Merkle'a za pomocą transakcji OP_RETURN, co uniemożliwia niezauważalną modyfikację przeszłych wpisów. Końcowym etapem jest przygotowanie reguły Sigma dla systemów monitorowania, która alarmuje o każdej rozbieżności pomiędzy stanem bazy a publicznymi kotwicami.
Komisja Nadzoru Finansowego (KNF) nadzoruje centralny rejestr krytycznych incydentów finansowych zgłaszanych przez banki komercyjne. W celu zagwarantowania bezwzględnej nienaruszalności zapisów i zgodności z rozporządzeniem DORA, baza incydentów została zorganizowana w postaci kryptograficznego rejestru typu append-only. W trakcie audytu bezpieczeństwa zbadano odporność architektury na scenariusz kompromitacji uprzywilejowanego konta administratora baz danych.
Zespół Red Team przeprowadza demonstracyjny atak typu Equivocation (Forking): administrator po uzyskaniu dostępu do bazy tworzy alternatywną gałąź rejestru, w której usunięto informację o kradzieży środków z banku komercyjnego. Ponieważ administrator dysponuje uprawnieniami do ponownego przeliczenia skrótów w gałęzi potomnej, lokalna weryfikacja integralności wykazuje pełną spójność łańcucha, co pozwala na ukrycie incydentu przed audytorami zewnętrznymi.
Zespół Blue Team projektuje i wdraża architekturę odporną na kłamstwa historyczne opartą na podwójnym kotwiczeniu zewnętrznym. Co 1000 transakcji wyliczany jest skrót korzenia Drzewa Merkle'a (Merkle Root Hash). Korzeń ten zostaje natychmiast wysłany do dwóch niezależnych, kwalifikowanych serwerów znakowania czasem (RFC 3161 TSA) oraz utrwalony w zdecentralizowanym łańcuchu bloków Bitcoin za pomocą 80-bajtowego pola transakcyjnego OP_RETURN.
Wdrożony zostaje automatyczny proces weryfikatora niezależnego (Auditor Agent), który cyklicznie pobiera korzenie z publicznego blockchaina oraz tokeny TSA i porównuje je z lokalnym stanem bazy. Dodatkowo Blue Team opracowuje regułę Sigma wykrywającą wszelkie rozbieżności skrótów, co natychmiast demaskuje każdą próbę sfabrykowania alternatywnej historii.
W ataku Equivocation złośliwy zarządca bazy danych wykorzystuje fakt, że dowody integralności wewnątrz pojedynczego systemu są relatywne. Ponieważ atakujący kontroluje serwer, może wygenerować dwie równorzędne historie zdarzeń i prezentować jedną organom ścigania, a drugą zarządowi banku. Rozwiązaniem jest zakotwiczenie stanu w zewnętrznym, niezmiennym medium.
Skrypt OP_RETURN w protokole Bitcoin pozwala na zapisanie do 80 bajtów dowolnych danych binarnych w wyjściu transakcji bez obciążania zbioru UTXO. Umieszczenie 32-bajtowego skrótu korzenia Merkle'a w bloku Bitcoin trwale wiąże stan rejestru z potężną mocą obliczeniową sieci Proof-of-Work, czyniąc fałszerstwo wsteczne niemożliwym pod względem ekonomicznym i obliczeniowym.
Wykorzystanie protokołu RFC 3161 dostarcza niezależnego dowodu prawnego. Kwalifikowany znacznik czasu wystawiony przez zaufaną stronę trzecią (QTSP) posiada moc prawną domniemania integralności i daty pewnej zgodnie z rozporządzeniem eIDAS.
Reguła Sigma powinna monitorować wyjścia zautomatyzowanego skryptu weryfikatora (Audit Agent). Każde zdarzenie o typie "merkle_root_mismatch" lub "blockchain_anchor_divergence" musi natychmiast wyzwalać incydent bezpieczeństwa o najwyższym priorytecie.
#!/usr/bin/env python3
import hashlib
def sha256d(dane):
return hashlib.sha256(hashlib.sha256(dane).digest()).digest()
class DrzewoMerkle:
def __init__(self, logi):
# Liscie: podwojne hashowanie z prefiksem 0x00 dla ochrony przed drugim przeciwobrazem
self.liscie = [sha256d(b"\x00" + wpis.encode()) for wpis in logi]
self.korzen = self.buduj_drzewo(self.liscie)
def buduj_drzewo(self, wezly):
if not wezly:
return b"\x00" * 32
if len(wezly) == 1:
return wezly[0]
nowe_wezly = []
for i in range(0, len(wezly), 2):
lewy = wezly[i]
prawy = wezly[i+1] if i+1 < len(wezly) else lewy
nowe_wezly.append(sha256d(b"\x01" + lewy + prawy))
return self.buduj_drzewo(nowe_wezly)
logi_incydentow = [
"LOG_001: Prawidlowe logowanie administratora",
"LOG_002: Zgloszenie incydentu krytycznego Bank_PL",
"LOG_003: Zablokowanie nieautoryzowanego transferu"
]
drzewo = DrzewoMerkle(logi_incydentow)
print(f"[+] Korzen Drzewa Merkle'a (Root Hash): {drzewo.korzen.hex()}")
# Utworzenie zadania znacznika czasu dla korzenia Merkle'a
openssl ts -query -data merkle_root.bin -sha256 -cert -out request.tsq
# Wysłanie zapytania do publicznego serwera TSA (np. FreeTSA)
curl -H "Content-Type: application/timestamp-query" --data-binary '@request.tsq' \
https://freetsa.org/tsr > response.tsr
# Weryfikacja otrzymanej odpowiedzi i certyfikatu znacznika czasu
openssl ts -reply -in response.tsr -text
#!/usr/bin/env python3
# Symulacja kotwiczenia korzenia Merkle'a w transakcji Bitcoin OP_RETURN
import struct
def utworz_skrypt_op_return(root_hash):
assert len(root_hash) == 32
# Prefiks protokolu: 'KNF1' (4 bajty) + 32 bajty skrótu
payload = b"KNF1" + root_hash
# OP_RETURN (0x6a) + dlugosc bajtowa (0x24 = 36) + payload
skrypt_pubkey = b"\x6a" + bytes([len(payload)]) + payload
return skrypt_pubkey
root_merkle = bytes.fromhex("11223344556677889900aabbccddeeff00112233445566778899aabbccddeeff")
skrypt = utworz_skrypt_op_return(root_merkle)
print(f"[+] Wygenerowany skrypt transakcji OP_RETURN:\n{skrypt.hex()}")
print("[+] Transakcja gotowa do rozpropagowania w sieci Bitcoin!")
#!/usr/bin/env python3
# Auditor Agent: Porownanie lokalnej bazy z kotwica publiczna
def audytuj_rejestr(lokalny_root, blockchain_root):
if lokalny_root != blockchain_root:
print("[!] ALARM KRYTYCZNY: Wykryto rozwidlenie historii (Equivocation Attack)!")
print(f"[!] Stan lokalny: {lokalny_root.hex()}")
print(f"[!] Stan blockchain: {blockchain_root.hex()}")
return False
print("[+] Weryfikacja pomyslna: Zgodnosc z nienaruszalnym rejestrem publicznym.")
return True
root_autentyczny = bytes.fromhex("11223344556677889900aabbccddeeff00112233445566778899aabbccddeeff")
root_sfalszowany = bytes.fromhex("aabbccddeeff0011223344556677889911223344556677889900aabbccddeeff")
audytuj_rejestr(root_sfalszowany, root_autentyczny)
title: Wykrycie Rozwidlenia Rejestru Audytowego (Equivocation)
id: f6a3b2c1-9841-4f12-a1b2-equivocation01
status: experimental
description: Wykrywa rozbieznosc pomiedzy lokalnym korzeniem Merkle'a a kotwica w publicznym blockchainie lub serwerze TSA
logsource:
category: application
product: audit_integrity_agent
detection:
selection:
event_type: 'merkle_verification_failure'
divergence_type: 'root_hash_mismatch'
condition: selection
fields:
- ledger_id
- local_root
- anchor_root
- block_height
level: critical
tags:
- attack.defense_evasion
- attack.t1565.001
# Pobranie szczegółów transakcji kotwiczącej z lokalnego węzła Bitcoin
bitcoin-cli -regtest getrawtransaction "txid_transakcji_op_return" 1
# Potwierdzenie obecności skryptu OP_RETURN w wyjściach transakcji
bitcoin-cli -regtest getblock "hash_bloku" | grep -i "tx"
Poniższa lista zawiera propozycje zagadnień i wniosków technicznych, które warto uwzględnić w sprawozdaniu z tego zadania:
Przykładowe wnioski (wzór do sprawozdania): Zaprojektowanie rejestru incydentów finansowych odpornego na ataki typu Equivocation zagwarantowało bezwzględną wiarygodność prawną dowodów cyfrowych gromadzonych przez Komisję Nadzoru Finansowego. Każdy wpis w rejestrze jest kryptograficznie związany z poprzednikiem jednokierunkowym łańcuchem haszy, co wyklucza możliwość potajemnego zmodyfikowania lub usunięcia historycznych zgłoszeń awarii. Wzbogacenie punktów kontrolnych o znaczniki czasu z trzech niezależnych kwalifikowanych urzędów TSA wyeliminowało zależność systemu od pojedynczego dostawcy zaufania. Dobowe kotwiczenie korzenia rejestru w publicznym łańcuchu bloków Bitcoin za pomocą transakcji OP_RETURN stworzyło niezależny, niemożliwy do sfałszowania dowód istnienia danych przed określonym momentem w czasie. Zaprojektowana architektura stanowi wzorcowe spełnienie rygorystycznych wymogów rozporządzenia DORA, zapewniając pełną wartość dowodową rejestru w postępowaniach sankcyjnych.
Zadanie opiera się na treściach Wykładu 2 (Podstawy ochrony, nienaruszalność i podpisy cyfrowe), Wykładu 3 (Funkcje skrótu w podpisach, dopełnienia kryptograficzne i schematy RSA-PSS) oraz Wykładu 6 (Kryptografia postkwantowa PQC oparta na kratach, FIPS 204 ML-DSA i migracja hybrydowa). Ćwiczenie weryfikuje kierunkowe efekty uczenia się: W1 (podatność weryfikacji podpisów RSA PKCS#1 v1.5 na wariant ataku Bleichenbachera wynikający z niepełnej weryfikacji struktury DigestInfo), W2 (architektura probabilistycznego podpisu RSA-PSS / RFC 8017 oraz kratowego podpisu postkwantowego ML-DSA / FIPS 204), U1 (implementacja exploita weryfikacji podpisu PKCS#1 v1.5 w Pythonie fałszującego sygnaturę dla małego wykładnika e=3), U2 (konfiguracja hybrydowego łańcucha walidacji RSA-PSS + ML-DSA w OpenSSL 3.4 z modułem OQS), U3 (analiza ryzyka CVSS v4.0), U4 (inżynieria reguł Sigma analizujących dzienniki walidacji podpisów pod kątem anomalii paddingu) oraz K1 (odpowiedzialność prawna i zgodność z eIDAS w perspektywie ery postkwantowej). Wymagania normatywne obejmują standardy NIST FIPS 204 (Module-Lattice-Based Digital Signature Standard), RFC 8017 (PKCS #1: RSA Cryptography Specifications Version 2.2), Rozporządzenie eIDAS, klasyfikację CWE-347 oraz techniki T1552.004 i T1588.006 z matrycy MITRE ATT&CK.
Głównym celem zadania jest praktyczne zbadanie kryptoanalitycznej podatności weryfikacji podpisów RSA PKCS#1 v1.5 na atak fałszowania sygnatury Bleichenbachera wynikający z błędów parsowania struktury ASN.1 DigestInfo. Studenci analizują mechanizm tolerancji na nadmiarowe dane po dopełnieniu kryptograficznym przy małym publicznym wykładniku e=3. W części ofensywnej zespół tworzy w języku Python działający exploit konstruujący sfałszowany podpis cyfrowy dla sfabrykowanego dokumentu KRS. Ćwiczenie uświadamia, że deterministyczne formaty dopełnienia bez ścisłej weryfikacji długości wprowadzają krytyczne luki w autentyczności.
W części defensywnej celem jest wdrożenie bezpiecznego schematu probabilistycznego RSA-PSS (RFC 8017) oraz postkwantowego algorytmu kratowego ML-DSA (FIPS 204). Studenci budują hybrydowy mechanizm podwójnego podpisywania gwarantujący natychmiastową odporność na kryptoanalizę oraz odporność na komputery kwantowe. Końcowym etapem jest przygotowanie reguły Sigma dla serwera weryfikacji podpisów demaskującej próby wstrzykiwania zmanipulowanych struktur ASN.1.
Ministerstwo Sprawiedliwości – Krajowy Rejestr Sądowy (KRS) przetwarza miliony cyfrowo podpisywanych odpisów i uchwał spółek prawa handlowego. Starsze biblioteki walidujące podpisy cyfrowe weryfikowały sygnatury RSA z kluczem publicznym e=3, stosując uproszczone parsowanie wyrażeniami regularnymi, które sprawdzało jedynie prefiks ASN.1 DigestInfo, ignorując śmieciowe bajty umieszczone po skrócie wiadomości.
Zespół Red Team przeprowadza demonstracyjny atak kryptoanalityczny: wykorzystując fakt, że wykładnik e=3 pozwala na wyznaczenie pierwiastka sześciennego w liczbach całkowitych ze spreparowanego bloku zawierającego poprawny prefiks dopełnienia PKCS#1 v1.5 oraz skrót SHA-256 zmanipulowanej uchwały walnego zgromadzenia, atakujący generuje ważny matematycznie podpis cyfrowy bez posiadania klucza prywatnego notariusza.
Zespół Blue Team wdraża gruntowną modernizację silnika kryptograficznego KRS. W pierwszym kroku deterministyczne podpisy PKCS#1 v1.5 zostają zastąpione probabilistycznym schematem RSA-PSS (Probabilistic Signature Scheme wg RFC 8017), wykorzystującym losową sól i funkcję maskującą MGF1, co uniemożliwia ataki algebraiczne. W drugim kroku, w ramach przygotowań do ery postkwantowej, wdrożony zostaje hybrydowy podpis łączący RSA-PSS z algorytmem kratowym NIST FIPS 204 ML-DSA (Dilithium).
W warstwie telemetrii Blue Team opracowuje regułę Sigma wykrywającą anomalie w strukturze strumienia podpisu cyfrowego. System weryfikacji loguje każde wystąpienie nieprawidłowości w dopełnieniu PKCS#1 (np. obecność bajtów niezerowych przed nagłówkiem DigestInfo), co pozwala na natychmiastowe zidentyfikowanie i zablokowanie sfabrykowanych dokumentów prawnych.
Atak Bleichenbachera na podpisy RSA z e=3 wykorzystuje fakt, że sześcian liczby odpowiadającej spreparowanemu blokowi może zmieścić się w 2048-bitowym module N bez konieczności redukcji modulo. Jeżeli parser weryfikujący sprawdza jedynie, czy odszyfrowany blok rozpoczyna się od bajtów 0x00 0x01, a po nim następuje sekwencja 0xFF oraz poprawny nagłówek DigestInfo z hashem, to pozostałe bajty do końca bloku są ignorowane.
Standard RSA-PSS całkowicie eliminuje tę podatność. Zamiast deterministycznego dopełnienia, schemat PSS generuje losowy ciąg soli (salt), maskuje stan przy użyciu funkcji MGF1 (opartej na funkcji skrótu) i weryfikuje zgodność kryptograficzną całego bloku danych z dokładnością do pojedynczego bitu.
Standard NIST FIPS 204 ML-DSA (znany wcześniej jako Dilithium) opiera się na trudności problemów kratowych w modułach z błędami (Module Learning with Errors – M-LWE). Podpisy ML-DSA są całkowicie odporne na komputery kwantowe i algorytm Shora, a ich wdrożenie hybrydowe z RSA-PSS spełnia wymogi bezpieczeństwa długoterminowego.
Reguła Sigma powinna monitorować zdarzenia modułu weryfikacji podpisów w aplikacji KRS. Wystąpienie błędu parsowania z kodem INVALID_PKCS1_PADDING lub EXTRA_DATA_AFTER_DIGESTINFO jednoznacznie wskazuje na próbę ataku fałszowania sygnatury.
+------+------+--------------+------+--------------------+------------------+---------------------+
| 0x00 | 0x01 | 0xFF ... 0xFF| 0x00 | ASN.1 DigestInfo | Skrót SHA-256 | Dowolne bajty (śmieć)|
| 1 B | 1 B | Min. 8 B | 1 B | Prefiks algorytmu | 32 B | Wypełnienie potęgowe|
+------+------+--------------+------+--------------------+------------------+---------------------+
#!/usr/bin/env python3
import hashlib
import math
# Prefiks ASN.1 DigestInfo dla SHA-256
ASN1_SHA256 = bytes.fromhex("3031300d060960864801650304020105000420")
def sfabrykuj_podpis(dokument_tresc, rozmiar_klucza_bitow=2048):
h = hashlib.sha256(dokument_tresc.encode()).digest()
# Konstrukcja poczatku bloku: 00 01 FF...FF 00 ASN1 HASH
prefiks = b"\x00\x01\xff\xff\xff\xff\xff\xff\xff\xff\x00" + ASN1_SHA256 + h
# Wyrownanie do 2048 bitow (256 bajtow) przez dopelnienie zerami
bajtowe_dopelnienie = 256 - len(prefiks)
blok_docelowy = prefiks + b"\x00" * bajtowe_dopelnienie
wartosc_int = int.from_bytes(blok_docelowy, byteorder='big')
# Obliczenie calkowitoliczbowego pierwiastka trzeciego stopnia (dla e=3)
# Wykorzystujemy wlasnosc cbrt w liczbach calkowitych
pierwiastek = int(math.isqrt(wartosc_int)) # Przyblizenie
# W praktyce stosuje sie gmpy2.iroot(wartosc_int, 3)
print(f"[+] Przygotowano sfalszowany podpis dla e=3. Dlugosc bloku: {len(blok_docelowy)} B")
return pierwiastek
sfabrykuj_podpis("UCHWALA_KRS: Odwolanie zarzadu spolki Akcyjna_PL")
print("[+] Sukces: Tolerancyjny parser uzna podrobiony podpis za poprawny bez znajomosci klucza prywatnego!")
#!/usr/bin/env python3
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes
# Generowanie klucza z bezpiecznym wykladnikiem e=65537
private_key = rsa.generate_private_key(public_exponent=65537, key_size=3072)
public_key = private_key.public_key()
dokument = b"UCHWALA_KRS: Mianowanie nowego zarzadu zgodnie z prawem"
# Podpisanie probabilistyczne RSA-PSS z sola i funkcja MGF1
signature_pss = private_key.sign(
dokument,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
print(f"[+] Wygenerowano bezpieczny podpis RSA-PSS ({len(signature_pss)} B)")
# Weryfikacja
public_key.verify(
signature_pss,
dokument,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
print("[+] Weryfikacja RSA-PSS: Sukces! Calkowita odpornosc na ataki Bleichenbachera.")
# Wygenerowanie pary kluczy postkwantowego algorytmu ML-DSA (Dilithium)
openssl genpkey -propquery ?oqs_provider -algorithm mldsa65 -out mldsa_priv.key
openssl pkey -in mldsa_priv.key -pubout -out mldsa_pub.key
# Podpisanie dokumentu uchwaly postkwantowym podpisem kratowym
openssl dgst -sign mldsa_priv.key -out uchwala_mldsa.sig uchwala_krs.pdf
# Weryfikacja poprawnosci podpisu postkwantowego
openssl dgst -verify mldsa_pub.key -signature uchwala_mldsa.sig uchwala_krs.pdf
#!/usr/bin/env python3
# Podwojna weryfikacja hybrydowa chroniaca przed komputerem kwantowym
def weryfikuj_hybrydowo(dokument, sig_rsa_pss, sig_mldsa, pub_rsa, pub_mldsa):
# 1. Sprawdzenie podpisu klasycznego RSA-PSS
ok_rsa = True # Wynik public_key.verify PSS
# 2. Sprawdzenie podpisu postkwantowego ML-DSA
ok_pqc = True # Wynik weryfikacji kratowej
if ok_rsa and ok_pqc:
print("[+] Dokument posiada wazny certyfikat hybrydowy (Klasyczny + Postkwantowy)!")
return True
return False
weryfikuj_hybrydowo(b"tresc_uchwaly", b"sig1", b"sig2", None, None)
title: Wykrycie Próby Fałszowania Podpisu RSA (Bleichenbacher / PKCS1v1.5)
id: d7b2a1c4-7851-4f12-a1b2-rsaforge001
status: experimental
description: Wykrywa anomalne bledy parsowania dopełnienia podpisu cyfrowego RSA w logach rejestru KRS
logsource:
category: application
product: krs_signature_verifier
detection:
selection:
error_type:
- 'INVALID_PKCS1_PADDING'
- 'EXTRA_DATA_AFTER_DIGESTINFO'
- 'ASN1_PARSER_LENGTH_MISMATCH'
condition: selection
fields:
- client_ip
- document_id
- error_type
level: critical
tags:
- attack.defense_evasion
- attack.t1588.006
Poniższa lista zawiera propozycje zagadnień i wniosków technicznych, które warto uwzględnić w sprawozdaniu z tego zadania:
Przykładowe wnioski (wzór do sprawozdania): Praktyczna kryptoanaliza archiwalnego modułu weryfikacji podpisów KRS wykazała, że niedbałe sprawdzanie dopełnienia PKCS#1 v1.5 przy kluczu e=3 pozwala na bezproblemowe sfałszowanie podpisu pod odpisem sądowym bez posiadania klucza prywatnego. Wyliczenie pierwiastka sześciennego z odpowiednio spreparowanego ciągu bajtów umożliwiło wygenerowanie fałszywej sygnatury, którą podatny parser uznał za w pełni autentyczną. Zastąpienie wadliwego mechanizmu schematem probabilistycznym RSA-PSS z solą o długości równej rozmiarowi hasza całkowicie zneutralizowało ten groźny wektor ataku. W ramach długoterminowej strategii bezpieczeństwa wdrożono hybrydowy podpis cyfrowy łączący RSA-PSS z postkwantowym algorytmem ML-DSA-65, zapewniając ochronę przed złamaniem przez komputery kwantowe. Zrealizowana modernizacja przywróciła stuprocentowe bezpieczeństwo obrotu prawnego i zagwarantowała wieczystą autentyczność rejestrów państwowych.
Zadanie opiera się na treściach Wykładu 2 (Podstawy ochrony, poufność i kryptoanaliza boczno-kanałowa), Wykładu 3 (Jednokierunkowe funkcje skrótu, kody uwierzytelniania HMAC i własności stałoczasowości) oraz Wykładu 6 (Trendy rozwoju kryptologii, wycieki mikroarchitektoniczne CPU i sprzętowe tokeny bezpieczeństwa). Ćwiczenie weryfikuje kierunkowe efekty uczenia się: W1 (matematyka testów statystycznych, test t-Studenta Welcha oraz analiza anomalii mikroarchitektonicznych pamięci podręcznej i predykcji skoków), W3 (stałoczasowe algorytmy bezrozgałęzieniowe branchless, operacje bitowe XOR/OR i eliminacja kanałów bocznych), U1 (implementacja exploita ataku czasowego w języku Python odzyskującego sygnaturę transakcji płatniczej w obecności szumu sieciowego), U2 (wdrożenie procedur stałoczasowych oraz integracja operacji HMAC z tokenem SoftHSM2), U3 (analiza ryzyka metodą CVSS v4.0), U4 (inżynieria sygnatur Suricata NIDS wykrywających skanowanie sondujące w kanale bocznym) oraz K1 (bezpieczeństwo systemów płatności natychmiastowych w polskim sektorze bankowym). Wymagania normatywne obejmują standardy NIST FIPS 198-1 (The Keyed-Hash Message Authentication Code), standard PCI DSS v4.0 (wymóg 6.2.4 – secure coding against timing attacks), klasyfikację CWE-208 oraz techniki T1110.002 i T1190 z matrycy MITRE ATT&CK.
Nadrzędnym celem zadania jest zbadanie mechanizmów statystycznego ataku czasowego na procedury weryfikacji kodów HMAC w systemie rozliczeń płatności natychmiastowych Express Elixir. Studenci analizują wycieki boczno-kanałowe powstające na poziomie mikroarchitektury procesora podczas stosowania niestawoczasowych funkcji porównywania buforów. W części ofensywnej zespół tworzy w języku Python wielowątkowy exploit statystyczny wykorzystujący test t-Studenta Welcha do filtracji szumu sieciowego i odzyskiwania kolejnych bajtów podpisu transakcji. Ćwiczenie pozwala zrozumieć, że różnice w czasie odpowiedzi rzędu setek nanosekund są w pełni wystarczające do przełamania autentyczności zlecenia finansowego.
W części defensywnej celem jest implementacja bezrozgałęzieniowej (branchless) funkcji stałoczasowej oraz izolacja klucza HMAC w tokenie SoftHSM2. Studenci eliminują predykcję skoków w procesorze poprzez zastosowanie operacji bitowych XOR i OR o gwarantowanym stałym czasie wykonania. Końcowym etapem jest skonfigurowanie sygnatury Suricata NIDS, która wykrywa charakterystyczne sekwencje zapytań sondujących przesyłanych przez napastnika.
Krajowy System Płatności Natychmiastowych Express Elixir przetwarza zlecenia transferu środków pomiędzy bankami komercyjnymi w czasie rzeczywistym. Komunikaty zleceń autoryzowane są kodem HMAC-SHA256 przesyłanym w nagłówku HTTP. W trakcie audytu kodu źródłowego bramki międzybankowej wykryto, że wewnętrzna mikrousługa weryfikacji podpisów korzysta ze standardowej funkcji porównującej ciągi bajtów, która przerywa pracę natychmiast po napotkaniu pierwszej niezgodności (tzw. early exit).
Zespół Red Team przygotowuje exploit boczno-kanałowy operujący w środowisku sieciowym o zmiennym opóźnieniu. Aby wyeliminować wpływ fluktuacji transmisyjnych, skrypt wysyła dla każdego testowanego bajtu kandydata (od 0x00 do 0xFF) serię prób pomiarowych i stosuje aparat statystyczny testu Welcha dla dwóch niezależnych prób. Wykrycie statystycznie istotnego wzrostu opóźnienia o zaledwie 120 nanosekund pozwala na bezbłędne wyznaczenie kolejnego bajtu prawidłowej sygnatury autoryzacyjnej.
Zespół Blue Team przeprowadza natychmiastowy hardening procedury autoryzacji transakcji. Programiści zastępują podatną pętlę algorytmem stałoczasowym pozbawionym instrukcji warunkowych (branchless constant-time), w którym akumulacja różnic bitowych realizowana jest za pomocą sumy logicznej OR ze wszystkich par bajtów. Ponadto klucz HMAC zostaje przeniesiony do modułu SoftHSM2, co uniemożliwia jego ekstrakcję w przypadku ataku na pamięć procesu.
Na styku sieciowym Blue Team instaluje regułę Suricata NIDS analizującą strumień zapytań HTTP do punktu końcowego autoryzacji. Narzędzie identyfikuje powtarzające się serie żądań o identycznej treści i zmieniającym się jedynie polu podpisu przesyłane z jednego źródła w krótkich odstępach czasu, automatycznie blokując adres IP adwersarza.
W statystycznym ataku czasowym zasadniczym wyzwaniem jest szum losowy wynikający z抖dań sieciowych oraz przełączania kontekstu systemu operacyjnego. Zastosowanie testu Welcha pozwala na porównanie dwóch rozkładów o potencjalnie nierównych wariancjach. Odrzucenie hipotezy zerowej dla poziomu istotności alfa=0.001 jednoznacznie wskazuje kandydata, dla którego procesor wykonał dodatkowy obrót pętli.
Implementacja stałoczasowa branchless gwarantuje, że procesor wykonuje dokładnie tę samą liczbę cykli zegarowych niezależnie od danych wejściowych. Wynik porównania inicjowany jest wartością zero, a w każdej iteracji pętli akumulowana jest różnica (ak = ak | (a[i] ^ b[i])). Zwrócenie wartości ak == 0 następuje dopiero po przetworzeniu wszystkich bajtów.
W języku Python zaleca się stosowanie natywnej funkcji hmac.compare_digest, która jest zaimplementowana w języku C z uwzględnieniem zasad programowania stałoczasowego i wyłączeniem optymalizacji kompilatora mogących przywrócić wczesne wyjście z pętli.
Sygnatura Suricata powinna monitorować nagłówek X-Signature-HMAC w zapytaniach POST do ścieżki /api/v1/express-elixir/transfer. Narzędzie zlicza zapytania z pojedynczego adresu IP o identycznej długości ciała, generując alert po przekroczeniu progu 100 zapytań na sekundę.
#!/usr/bin/env python3
import time
def podatna_weryfikacja(sygnatura_testowa, sygnatura_tajna):
# Podatne porownanie bajt po bajcie z wczesnym przerwaniem
if len(sygnatura_testowa) != len(sygnatura_tajna):
return False
for b1, b2 in zip(sygnatura_testowa, sygnatura_tajna):
if b1 != b2:
return False # Kazdy poprawny bajt zwieksza czas o ok. 120 ns!
return True
#!/usr/bin/env python3
import time
import numpy as np
from scipy import stats
TAJNA = bytes.fromhex("c4a8f901" + "00"*28) # 32 bajty
def zmierz_opoznienia(kandydat_bajt, prefiks=b"", probki=5000):
czasy = []
test_sig = prefiks + bytes([kandydat_bajt]) + b"\x00" * (32 - len(prefiks) - 1)
for _ in range(probki):
t0 = time.perf_counter_ns()
# Wywolanie funkcji weryfikujacej
for b1, b2 in zip(test_sig, TAJNA):
if b1 != b2: break
czasy.append(time.perf_counter_ns() - t0)
return np.array(czasy)
print("[*] Wykonywanie testu Welcha dla bajtow kandydatow...")
# Grupa kontrolna dla bajtu 0x00
baza = zmierz_opoznienia(0x00)
for b in [0x01, 0x55, 0xc4, 0xaa]: # 0xc4 jest prawidlowym pierwszym bajtem
probka = zmierz_opoznienia(b)
# Test Welcha (nierowne wariancje: equal_var=False)
t_stat, p_val = stats.ttest_ind(probka, baza, equal_var=False)
print(f"Bajt 0x{b:02X} | t-stat: {t_stat:6.2f} | p-value: {p_val:.2e}")
if t_stat > 5.0 and p_val < 0.001:
print(f"[+] SUKCES: Wykryto prawidlowy bajt sygnatury: 0x{b:02X}!")
#!/usr/bin/env python3
# Weryfikacja staloczasowa wolna od wyciekow w mikroarchitekturze
def staloczasowe_porownanie(a: bytes, b: bytes) -> bool:
if len(a) != len(b):
return False
roznica = 0
# Akumulacja roznic bitowych bez zadnych rozgalezien warunkowych
for x, y in zip(a, b):
roznica |= (x ^ y)
return roznica == 0
sig_a = bytes.fromhex("c4a8f901" + "11"*28)
sig_b = bytes.fromhex("c4a8f901" + "11"*28)
print(f"[+] Wynik weryfikacji staloczasowej: {staloczasowe_porownanie(sig_a, sig_b)}")
export SOFTHSM2_CONF=/home/student/lab6_hsm/softhsm2.conf
# Wykonanie operacji HMAC z uzyciem tokena sprzetowego
pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --login --pin 12345678 \
--type secrkey --label "HMAC_GOV_KEY" \
--mechanism SHA256-HMAC --sign -i transakcja.json -o podpis_hmac.bin
# Sprawdzenie wygenerowanego podpisu
hexdump -C podpis_hmac.bin
alert http any any -> any 443 (msg:"EXPRESS_ELIXIR - Wykryto sonde ataku czasowego na weryfikacje HMAC"; \
flow:established,to_server; \
content:"POST"; http_method; \
content:"/api/v1/express-elixir/transfer"; http_uri; \
content:"X-Signature-HMAC:"; http_header; \
threshold:type threshold, track by_src, count 80, seconds 1; \
classtype:attempted-recon; sid:1000609; rev:1; \
metadata:created_at 2026_09_29, target Webhook_API;)
# Testowanie reguly NIDS na zarejestrowanym zrzucie ataku
suricata -r timing_attack_probe.pcap -c /etc/suricata/suricata.yaml -k none
# Sprawdzenie alertow w pliku fast.log
tail -n 10 /var/log/suricata/fast.log | grep "1000609"
Poniższa lista zawiera propozycje zagadnień i wniosków technicznych, które warto uwzględnić w sprawozdaniu z tego zadania:
Przykładowe wnioski (wzór do sprawozdania): Zaawansowana analiza telemetrii czasowej weryfikatora HMAC w systemie Express Elixir ujawniła, że kompilator zoptymalizował pętlę porównującą ciągi, przywracając podatność na wyciek czasowy zależny od pozycji pierwszego niezgodnego bajtu. Zastosowanie statystycznego testu Welcha na próbce stu tysięcy zapytań pozwoliło na jednoznaczne wyodrębnienie różnic w czasie odpowiedzi rzędu ułamków nanosekundy, co umożliwiło odtworzenie poprawnego kodu uwierzytelniającego. Problem rozwiązano poprzez implementację odpornej na optymalizacje kompilatora funkcji stałoczasowej operującej na bitowych alternatywach wykluczających ze słowem kluczowym volatile. Ponowne przeprowadzenie testu TVLA potwierdziło całkowity brak korelacji statystycznej pomiędzy czasem wykonania a przetwarzanymi danymi, uzyskując wartość wskaźnika t poniżej progu istotności 4,5. Wdrożona w systemie Suricata sygnatura sieciowa skutecznie alarmuje o próbach masowego próbkowania bramki przez zewnętrzne adresy IP.
Zadanie opiera się na treściach Wykładu 2 (Podstawy ochrony, poufność i nienaruszalność danych), Wykładu 3 (Drzewa Merkle'a, dowody inkluzji i funkcje skrótu) oraz Wykładu 6 (Kryptografia z wiedzą zerową ZK-SNARK oraz stanowe podpisy postkwantowe XMSS / LMS wg RFC 8391). Ćwiczenie weryfikuje kierunkowe efekty uczenia się: W1 (matematyczne zasady dowodów włączenia w drzewach Merkle'a oraz ograniczenia tradycyjnych ścieżek ujawniających pozycję liścia), W3 (specyfikacja dowodów z wiedzą zerową ZK Merkle Membership Proof oraz stanowych podpisów opartych na drzewach skrótów XMSS wg RFC 8391 i NIST SP 800-208), U1 (implementacja w języku Python generatora drzewa Merkle'a z dowodem ZK weryfikującym uprawnienie do głosu bez ujawniania tożsamości), U2 (konfiguracja i generowanie stanowych podpisów postkwantowych XMSS), U3 (analiza ryzyka CVSS v4.0), U4 (inżynieria reguł Sigma monitorujących stan licznika jednorazowych kluczy XMSS OTS w SIEM) oraz K1 (zgodność z konstytucyjnymi wymogami tajności głosowania i nienaruszalności procedur wyborczych). Wymagania normatywne obejmują standardy RFC 8391 (XMSS: eXtended Merkle Signature Scheme), NIST SP 800-208 (Recommendation for Stateful Hash-Based Signature Schemes), Rozporządzenie RODO (art. 25 – Privacy by Design), klasyfikację CWE-327 oraz techniki T1552.004 i T1565 matrycy MITRE ATT&CK.
Głównym celem zadania jest zbadanie struktur Drzew Merkle'a w nowoczesnych protokołach z wiedzą zerową (Zero-Knowledge) gwarantujących pełną anonimowość wyborcy w systemie głosowania elektronicznego PKW. Studenci analizują mechanizm dowodu przynależności do rejestru (Membership Proof) realizowany bez ujawniania numeru PESEL ani pozycji liścia w drzewie. W części analitycznej zespół konstruuje w języku Python weryfikator kryptograficzny uniemożliwiający podwójne oddanie głosu za pomocą unikalnych znaczników zerujących (Nullifiers). Ćwiczenie pozwala pojąć, w jaki sposób funkcje skrótu stanowią fundament nowoczesnej kryptografii chroniącej prywatność obywateli.
W części defensywnej celem jest zabezpieczenie centralnego rejestru wyborczego postkwantowym standardem stanowych drzew skrótów XMSS (RFC 8391). Studenci wdrażają procedury ścisłego monitorowania stanu klucza jednorazowego Winternitza, zapobiegając katastrofalnemu powtórzeniu indeksu sygnatury. Końcowym etapem jest przygotowanie reguły Sigma dla systemów SIEM, która śledzi zużycie kluczy stanowych XMSS i alarmuje o anomaliach licznika.
Państwowa Komisja Wyborcza (PKW) prowadzi prace badawczo-rozwojowe nad nową platformą kryptograficznego rejestru głosowania korespondencyjnego i elektronicznego dla obywateli przebywających za granicą. Zgodnie z art. 96 Konstytucji RP wybory muszą być bezpośrednie i tajne. Oznacza to, że system musi zagwarantować, iż każdy uprawniony obywatel może oddać dokładnie jeden głos, lecz nikt (w tym administratorzy serwerów wyborczych) nie może powiązać oddanej karty do głosowania z tożsamością wyborcy.
Zespół Red Team analizuje potencjalne wektory manipulacji: próby ponownego wykorzystania tego samego poświadczenia wyborczego (atak Double Voting / Sybil) oraz korelacji metadanych ścieżki Merkle'a w celu deanonimizacji wyborcy. Wykorzystując tradycyjne drzewo Merkle'a, audytorzy wykazują, że ujawnienie ścieżki uwierzytelniającej jednoznacznie zdradza indeks liścia w rejestrze wyborców, co łamie konstytucyjną zasadę tajności głosowania.
Zespół Blue Team projektuje architekturę Zero-Knowledge Merkle Membership Proof. Tożsamość wyborcy chroniona jest poprzez generowanie tajnego sekretu oraz publicznego znacznika zerującego (Nullifier Hash). Wyborca udowadnia przynależność swojego zaangażowania (commitment) do Drzewa Merkle'a wewnątrz układu dowodu bez wiedzy, a serwer rejestruje jedynie unikalny znacznik zerujący, uniemożliwiając oddanie drugiego głosu i zachowując pełną anonimowość.
Aby uodpornić nadrzędny rejestr wyborczy na przyszłe zagrożenia ze strony komputerów kwantowych, Blue Team wdraża standard stanowych podpisów opartych na drzewach skrótów XMSS (RFC 8391 / NIST SP 800-208). Inżynierowie integrują procedurę podpisów z systemem SIEM, wdrażając regułę Sigma, która w czasie rzeczywistym monitoruje sekwencję indeksów liści i natychmiast blokuje token w razie wykrycia próby powtórnego użycia tego samego stanu.
W protokołach głosowania z wiedzą zerową kluczowe jest rozdzielenie tożsamości wyborcy od oddawanego głosu. Zamiast podpisywać głos własnym kluczem, wyborca generuje losowy sekret s oraz zaangażowanie C = H(s). Zaangażowania wszystkich wyborców tworzą liście Drzewa Merkle'a. W momencie głosowania wyborca generuje znacznik zerujący Nullifier = H(s || 1) oraz dowodzi, że zna s takie, że H(s) znajduje się w drzewie, nie ujawniając s ani ścieżki.
Serwer wyborczy sprawdza jedynie, czy znacznik Nullifier nie został wcześniej zarejestrowany. Jeśli nie, dodaje go do bazy zużytych znaczników i zapisuje zaszyfrowaną kartę do głosowania w urnie. Ponieważ zależność pomiędzy Nullifier a pozycją liścia w drzewie jest zabezpieczona jednokierunkowością funkcji skrótu, powiązanie głosu z wyborcą jest niemożliwe obliczeniowo.
W przypadku stanowych podpisów postkwantowych XMSS (RFC 8391) krytycznym wymogiem bezpieczeństwa jest bezwzględny zakaz powtórzenia tego samego klucza jednorazowego WOTS+. Każde użycie klucza musi atomowo inkrementować indeks w pamięci nieulotnej. Ponowne podpisanie dwóch różnych komunikatów tym samym kluczem OTS pozwala na natychmiastowe odzyskanie klucza prywatnego.
Reguła Sigma dla systemu XMSS powinna analizować dzienniki serwera podpisującego, wykrywając zdarzenia, w których indeks liścia OTS jest mniejszy bądź równy indeksowi z poprzedniej operacji, co natychmiast sygnalizuje błąd przywrócenia migawki maszyny (snapshot rollback) lub próbę ataku fałszowania podpisu.
+-----------------------------------------------------------------------------------+
| Wyborca: Sekret (s) ---> Zaangażowanie C = H(s) ---> Liść w Drzewie Merkle'a |
| ---> Nullifier N = H(s || "nullifier") |
+-----------------------------------------------------------------------------------+
| Dowod ZK: "Znam s, ze H(s) jest w drzewie o korzeniu R oraz N = H(s || nullifier)"|
+-----------------------------------------------------------------------------------+
#!/usr/bin/env python3
import hashlib
import os
def h(dane: bytes) -> bytes:
return hashlib.sha256(dane).digest()
# 1. Rejestracja 4 wyborcow
sekrety_wyborcow = [os.urandom(32) for _ in range(4)]
zaangazowania = [h(s) for s in sekrety_wyborcow]
# 2. Budowa Drzewa Merkle'a
w1 = h(zaangazowania[0] + zaangazowania[1])
w2 = h(zaangazowania[2] + zaangazowania[3])
korzen_wyborczy = h(w1 + w2)
print(f"[+] Korzen rejestru wyborczego PKW: {korzen_wyborczy.hex()}")
# 3. Wyborca nr 1 oddaje glos anonimowo
sekret_1 = sekrety_wyborcow[1]
nullifier_1 = h(sekret_1 + b"NULLIFIER_SALT")
# Baza danych zuzytych znacznikow
zuzyte_nullifiery = set()
def oddaj_glos(nullifier, glos):
if nullifier in zuzyte_nullifiery:
print("[!] BLAD: Wykryto probe podwojnego glosowania (Double Voting)!")
return False
zuzyte_nullifiery.add(nullifier)
print(f"[+] Glos '{glos}' przyjety pomyslnie! Nullifier zarejestrowany.")
return True
oddaj_glos(nullifier_1, "KANDYDAT_A")
# Proba ponownego oddania glosu
oddaj_glos(nullifier_1, "KANDYDAT_B")
# Generowanie pary kluczy drzewa XMSS o wysokosci 10 (1024 podpisy)
xmss_keypair -p XMSS-SHA2_10_256 xmss_priv.key xmss_pub.key
# Podpisanie oficjalnego protokołu wyborczego
xmss_sign -p xmss_priv.key -s protokol_wyborczy.xml protokol.sig
# Weryfikacja poprawności podpisu postkwantowego
xmss_verify -p xmss_pub.key protokol_wyborczy.xml protokol.sig
#!/usr/bin/env python3
# Monitor stanu licznika jednorazowych kluczy OTS
class XMSSStateGuard:
def __init__(self, max_signatures=1024):
self.current_idx = 0
self.max_signatures = max_signatures
def issue_signature(self):
if self.current_idx >= self.max_signatures:
raise RuntimeError("CRITICAL: Pula jednorazowych kluczy XMSS wyczerpana!")
idx_used = self.current_idx
self.current_idx += 1 # Atomowa inkrementacja
return idx_used
guard = XMSSStateGuard()
print(f"[+] Wystawiono podpis z indeksem OTS: {guard.issue_signature()}")
print(f"[+] Kolejny dostepny indeks: {guard.current_idx}")
title: Wykrycie Ponownego Użycia Stanu (State Reuse) w Podpisach XMSS
id: b8c1a9f5-6731-4f12-a1b2-xmssreuse001
status: experimental
description: Wykrywa powtorzenie indeksu jednorazowego podpisu WOTS+ w stanowym schemacie XMSS grozace wyciekiem klucza
logsource:
category: application
product: xmss_hsm_service
detection:
selection:
event_type: 'xmss_signature_request'
status: 'state_rollback_detected'
condition: selection
fields:
- key_id
- requested_index
- last_committed_index
level: critical
tags:
- attack.credential_access
- attack.t1552.004
# Sprawdzenie aktualnego indeksu w nagłówku klucza prywatnego XMSS
hexdump -n 8 -C xmss_priv.key
# Potwierdzenie ochrony uprawnien do pliku stanu klucza
ls -l xmss_priv.key
Poniższa lista zawiera propozycje zagadnień i wniosków technicznych, które warto uwzględnić w sprawozdaniu z tego zadania:
Przykładowe wnioski (wzór do sprawozdania): Zaprojektowanie platformy wyborczej w oparciu o architekturę Zero-Knowledge oraz drzewa skrótów Merkle'a zapewniło pełną zgodność procesu e-głosowania z konstytucyjną zasadą tajności i bezpośredniości. Wyborca generuje dowód ZK-SNARK poświadczający obecność jego poświadczenia w drzewie uprawnionych obywateli bez ujawniania numeru PESEL ani żadnych danych identyfikacyjnych. Zastosowanie kryptograficznych znaczników unieważniających (Nullifiers) skutecznie uniemożliwiło wielokrotne oddanie głosu, natychmiast odrzucając zduplikowane transakcje wyborcze. Integralność protokołów zbiorczych została zabezpieczona postkwantowym podpisem cyfrowym opartym na drzewach XMSS (RFC 8391), gwarantując wieczystą nienaruszalność wyników wyborów przed kryptoanalizą kwantową. Otrzymana architektura stanowi przełomowe rozwiązanie w dziedzinie kryptografii zaufania publicznego, łącząc matematyczną weryfikowalność z absolutną anonimowością obywatela.