[WikiDyd] [TitleIndex] [WordIndex

Cel zajęć

Ćwiczenia z wykorzystaniem algorytmów kryptograficznych funkcji jednokierunkowych (hash) do ochrony bazy haseł. Poznanie zasad ataku systematycznego przeszukiwania (brute-force).

Wprowadzenie

Jedną z najstarszych funkcji jednokierunkowych używanych w systemach POSIX była systemowa funkcja crypt(), która wykorzystuje algorytm DES. Obecnie jest zastępowana przez bezpieczniejsze algorytmy, jednak wciąż wiele programów korzysta właśnie z tej funkcji.

Przykładem może być program htpasswd z pakietu Apache, który służy do zarządzania prostą bazą użykowników. Baza przechowywana jest w pliku tekstowym, w którym poszczególne linie definiują kolejnych użytkowników. Hasła użytkowników są chronione przy pomocy kryptograficznej funkcji jednokierunkowej.

Przykładowe wywołanie funkcji crypt() z poziomu języka Python.

import sys
import crypt
import string
import random

password = sys.argv[1]

#sol stala
salt = 'ab'

#sol losowana
#salt = ''.join(random.sample(string.ascii_letters, 2))

protected_password = crypt.crypt(password, salt)
print protected_password 

Innym zastosowaniem jednokierunkowych funkcji skrótu jest kontrola spójności plików (MAC). Program md5sum (standardowo dostępny w systemach uniksopodobnych, w systemach BSD jest podobny program md5) jest właśnie do tego przeznaczony, oblicza sumy kontrolne i może sprawdzić, czy zmieniły się one w stosunku do wcześniej zapisanych.

Przykładowe wywołanie funkcji realizujących algorytm MD5:

import sys
import hashlib
md5  = hashlib.md5( sys.argv[1] )
print md5.digest()
print md5.hexdigest()

Format pliku sum kontrolnych dla plików (md5sum) jest dosyć prosty. Każda linia zawiera sumę md5 i ścieżkę dostępu do pliku np. :

0044f6a93aa14142974d45d62eb0636c  sciezka/dostepu/do/pliku.xxx

Ataki na funkcje jednokierunkowe

Metoda systematycznego przeszukiwania, inaczej zwana metodą brutalnej siły (ang. brute force) to jeden z najprostszych ataków na wszelkiego rodzaju zabezpieczenia. Polega ona na ślepym przeszukiwaniu przestrzeni klucza w celu znalezienia tego właściwego. Łatwą obroną przed tego typu atakiem jest rozszerzenie przestrzeni, a tym samym wydłużenie czasu potrzebnego do jej przeszukania.

Jednym z najbardziej znanych programów realizujących ten atak jest John the Ripper. W ramach ćwiczenia będziemy korzystać ze znacznie prostrzego przykładu. Przykładowy skrypt realizujący atak na hasło o długości trzech znaków, składające się z samych małych liter, ukryte za pomocą funkcji crypt():

import sys, string, crypt
passwd = sys.argv[1]
chars = string.ascii_letters
for a in chars:
        for b in chars:
                for c in chars:
                        trial = a+b+c
                        crypted = crypt.crypt( trial, passwd)
                        if crypted == passwd:
                                print "Haslo zlamane: "+trial
                                break
print "Nie udalo sie"

Ataki przez kolizje to grupa metod, których celem jest naruszenie bezpieczeństwa jednokierunkowych funkcji skrótu. Wykorzystanie paradoksu urodzinowego może być wykorzystane do zwiększenia prawdopodobieństwa kolizji. Współczesne algorytmy MD5, SHA, mają na tyle długie wartości funkcji skrótu, że znalezienie kolizji jest bardzo czasochłonne. Można sobie jednak wyobrazić algorytm łatwiejszy do złamania, zaimplementujmy go pod funkcja trivial_hash().

def trivial_hash(dane):
        hash = 0
        for znak in dane:
                hash += ord(znak)
        return hash % 999

Nasze badania nad atakami przed kolizje ograniczymy do ataków na funkcje trivial_hash.

Potrzebna wiedza

Do realizacji zadań na zajęciach wymagane są:

Dodatkowe informacje

Dodatkowych informacji należy szukać w materiałach oraz literaturze prezentowanej na wykładzie. Tematyka jest bardzo dobrze opracowana w Wikipedii.

Hasła dla Google: brute force attack, cryptographic hash function, htpasswd, md5sum, crypt function, unix password

Przykładowe zadania

  1. Napisz program korzystający z bazy wygenerowanej przez program htpasswd. Celem programu jest sprawdzenie, czy użytkownik o podanym identyfikatorze i haśle jest w pliku bazy.

  2. Napisz program umożliwiający zmianę hasła użytkownika w bazie programu htpasswd.

  3. Napisz program umożliwiający dodawanie nowych użytkowników do bazy programu htpasswd.

  4. Przy pomocy wywołania bibliotecznej funkcji md5() odtwórz działanie programu md5sum.

  5. Przy pomocy wywołania bibliotecznej funkcji md5() odtwórz działanie polecenia md5sum -c, czyli kontrole spójności plików.

  6. Korzystając z polecania time sprawdź wydajność dowolnej implementacji algorytmu łamania haseł metodą brutalnej siły i oszacuj czas maksymalny czas potrzebny do złamania haseł różnej długości i składający się z małych liter i dużych liter.

  7. Napisz program zgadujący hasła ukryte za pomocą funkcji crypt(), przechowywane w bazie programu htpasswd. Przyjmij założenie, że hasła są trzy znakowe i składają się z samych małych liter.

  8. Przygotuj dwa dokumenty, których funkcje skrótu trivial_hash() bedą identyczne, a treść różna. Wykorzystaj paradoks urodzinowy.

  9. Napisz program szukający kolizji z określoną wartością funkcji skrótu trivial_hash() poprzez modyfikacje 'białych' znaków.

  10. Porównaj wydajność programu "John the Ripper", z pythonowym skryptem do łamania haseł.

2015-09-23 06:44