Algoritmo RC4


●   Funcionamento do RC4
    –   Vetor State (S)
         ●   256 posições
               0   1       2       3       4       5       6       7   8   9




         ●   Permutação de acordo com a chave (K)
                       K       x       x       x       x       x




                                                                               1
Algoritmo RC4


index1 = 0;
index2 = 0;
for(counter = 0; counter < 256; counter++)
{
    index2 = (key[index1] + state[counter] + index2) % 256;

    swap_byte(&state[counter], &state[index2]);
    index1 = (index1 + 1) % key_data_len;

}



                                                              2
Algoritmo RC4

●   Após a permuta é realizada a criação
    da chave de qualquer tamanho pelo
    PRNG
    inicializa-se x = y = 0


    x = (x + 1) % 256;
    y = (state[x] + y) % 256;
    swap_byte(&state[x], &state[y]);
    xorIndex = (state[x] + state[y]) % 256;
    GeneratedByte = state[xorIndex];



                                              3
Algoritmo RC4


●   Verificação do funcionamento:
●   Software wep.php
●   apresenta a chave, o vetor State e os Bytes utilizandos para
    realizar a cifragem da mensagem
●   ex:


           php wep.php normal 10:11:12:13 “teste”




                                                               4
Situação Atual



●   O WEP apresenta chaves fracas
●   artigo:
    “Weaknesses in the Key Scheduling
          Algorithm of RC4” de
       Fluhrer / Mantin / Shamir

●   Programas WEPCrack e AirSnort


                                        5
Situação Atual


index1 = 0;
index2 = 0;


for(counter = 0; counter < 256; counter++)
{
    index2 = (key[index1] + state[counter] + index2) % 256;
    swap_byte(&state[counter], &state[index2]);
    index1 = (index1 + 1) % key_data_len;

}




                                                              6
Situação Atual

●   Existem dois elementos que alteram os valores de S:
    –   Index2 (varia de acordo com a chave)
    –   Counter (contador linear)
●   Existe uma probabilidade de que um valor seja
    alterado tanto pelo Index, quanto pelo Counter




                                                          7
Situação Atual



●   Ou seja existe a probabilidade de aprox. 37% de que um valor
    seja alterado apenas por Counter
●   Para uma chave com K bytes, sendo E < K existe uma
    probabilidade de que E dependa apenas dos elementos 0..E da
    chave no vetor S


●   Ou seja, em 37% dos      casos   o   algoritmo   passa   a   ser
    equivalente a.......




                                                                   8
Situação Atual
for(counter = 0; counter < 256; counter++)
 {
    index2 = (key[index1] + state[counter] + index2) % 256;
     swap_byte(&state[counter], &state[index2]);
     index1 = (index1 + 1) % key_data_len;
}



for(counter = 0; counter < 256; counter++)
{
     index2 = (key[index1] + counter + index2) % 256;
     state[counter] = index2;
     index1 = (index1 + 1) % key_data_len;
}

                                                              9
Situação Atual

●   A probabilidade     desta afirmação estar correta
    para os elementos de State




                                                        10
Situação Atual



●   prova:
●   executar os dois algoritmos e comparar o número de colisões
    para cada elemento de State




             php wep.php prove1 8 500 norm




                                                             11
Situação Atual


●   Desta forma:


           State[E] = ΣK(E) + E(E + 1)/2

●   Onde (E) representa o somatório dos bytes de 0..E
    (inclusive) da chave K


    –   State[1] = K[0] + K[1] + 1(1 + 1)/2
    –   State[2] = K[0] + K[1] + K[2] + 2(2 + 1)/2




                                                         12
Situação Atual



●   prova:
●   verificar   se   o   valor   de   State[E]   pode   ser   obtido   pela
    fórmula




     php wep.php prove1 8 500 norm state




                                                                         13
Situação Atual



●   Exemplo de chave fraca – permite a descoberta do
    segredo a partir do vetor de permutação devido a
    relação entre chaves prévias e vetor State


    –   Exemplo de previsão simples no caso em que S[1] = 1
         ●   K[0] + K[1] = 0 (chave fraca), implicando:
         ●   S[2] = K[2] + 2 (2+1) / 2 = K[2] + 3




                                                              14
Situação Atual



●   prova:
●   gerar as chaves com K[0] = 0 e K[1] = 0




     php wep.php prove1 8 500 weak state




                                              15
Situação Atual

●   Após a permuta é realizada a criação
    da chave de qualquer tamanho pelo
    PRNG
    inicializa-se x = y = 0
    x = (x + 1) % 256;
    y = (state[x] + y) % 256;
    swap_byte(&state[x], &state[y]);
    xorIndex = (state[x] + state[y]) % 256;
    GeneratedByte = state[xorIndex];




                                              16
Situação Atual


●   Considerando uma situação onde State[1]=1
     –   ou seja, K[0]=K[1]=0




    x = (0 + 1) % 256;                   /* x == 1 */
    y = (state[1] + 0) % 256;            /* y == 1 */
    swap_byte(&state[1], &state[1]);     /* no effect */
    xorIndex = (state[1] + state[1]);    /* xorIndex = 2 */
    GeneratedByte = state[2]




                                                              17
Situação Atual

●   Sempre que State[1] = 1, a alteração realizada pelo PRNG
    torna-se previsível
    –   É realizado um XOR entre o texto claro e State[2]
    –   Ao descobrir State[2], o atacante pode sugerir um K[2]
        provável
                State[2] = K[2] + 3, quando State[1]=1


●   prova:


          php wep.php normal 00:00:12:82
                      “teste”


                                                            18
Situação Atual

●   prova:
●   para encontrar novas chaves com State[1]=1
     –   1000 tentativas (aleatório)
     –   chave com tam=5


             php wep.php find_weak 1000 5




                                                 19
Quebra do WEP


●       No wep, o IV representa os primeiros 3 bytes do segredo
        compartilhado (K) = K[0], K[1], K[2]


●       O LLC adiciona sempre o mesmo cabeçalho (0xaa), primeiro
        byte a ser cifrado (texto claro)


    ●   O atacante pode, então recriar os primeiros passos
        da permuta de State a partir do IV utilizado




                                                              20
Quebra do WEP



●   Resumindo, o atacante possui:
    –   IV = K[0], K[1], K[2]
    –   Precisa descobrir S[3] para descobrir/sugerir K[3],
        pois


           S[3] = K[0] + K[1] + K[2] + K[3] + 3(3 + 1)/2




                                                           21
Quebra do WEP



●    Sempre que S[1] = 0 e S[0] = n o primeiro byte será
     cifrado por S[n], pois:

    x = (x + 1) % 256;                        x = 1
    y = (state[x] + y) % 256;                 y = (state[1]) = 0
    swap_byte(&state[x], &state[y]);          state[1] <-> state [0]
    xorIndex = (state[x] + state[y]) % 256;   xorIndex = (state[1] +
                                              state[0]) = state[1]
    GeneratedByte = state[xorIndex];          GeneratedByte = state[1]




                                                                         22
Quebra do WEP

●   prova:
●   para encontrar novas chaves com State[1]=0
     –   1000 tentativas (aleatório)
     –   chave com tam=5


             php wep.php find_weak 1000 5

●   utiliza-se a chave encontrada no RC4
●   o valor apontado por State[0] será o índice em State para o
    valor utilizado na cifragem


    php wep.php normal 50:233:61:247:240
                 "ola mundo"
                                                             23
Quebra do WEP


●   Se (S[1] + S[S[1]] = 3) então o texto será cifrado
    por S[3]
    –   Descoberta de S[3]
         ●   S[3] = texto_cifrado XOR 0xaa

    –   Inversão do processo de permutação do RC4
         ●   S[3] = K[0] + K[1] + K[2] + K[3] + 3(3 + 1)/2

●   O   mesmo    é   feito    para     K[4],   ...   Ou      seja
    (S[1]+S[S[1]]=4) ... .... ....




                                                               24
Quebra do WEP

●   Exemplo:
php wep.php normal 4:29:74:3:228 “teste”


KEY: 4:29:74:3:228<- objetivo
State:
S[0]=3 S[1]=0 S[2]=110 S[3]=116 S[4]=197 S[5]=38...
RC4 KEY:116:79:90:205:73


O atacante possui os valores iniciais da chave
IV[0]=K[0]=4 IV[1]=K[1]=29 IV[2]=K[2]=74




                                                      25
Quebra do WEP

●   Para obter K[3]:
IV[0]=K[0]=4 IV[1]=K[1]=29 IV[2]=K[2]=74
S[3]=116 (obtém realizando um XOR entre 0xaa e o valor
         do primeiro byte do pacote capturado)


S[3] = 4 + 29 + 74 + K[3] + 3 x (3+1)/2
K[3] =   116 – 4 – 29 – 74 – 6   = 3


                       K[3] = 3




                                                    26
Quebra do WEP


●   Próximo passo:
     –   Encontrar uma situação onde S[1]=0 e S[0]=4 com
         chave fraca, ou seja, que:




    S[4] = K[0] + K[1] + K[2] + K[3] + K[4] + 4(4+1)/2


                            ...




                                                         27
Quebra do WEP


●   Exemplo 2:
php wep.php normal 26:55:29:50:43 “teste”


KEY: 26:55:29:50:43<- objetivo
State:
S[0]=3 S[1]=0 S[2]=10 S[3]=166 S[4]=213 S[5]=218...


RC4 KEY:166:198:122:220:59




                                                      28
Quebra do WEP


●   Para obter K[3]:
IV[0]=K[0]=26 IV[1]=K[1]=55 IV[2]=K[2]=29
S[3]=166 (obtém realizando um XOR entre 0xaa e o valor
         do primeiro byte do pacotecapturado)


K[3] =   166 – 26 – 55 – 29 – 6   = 50


                       K[3] = 50

                       ... ... ...


                                                    29

Quebra wep

  • 1.
    Algoritmo RC4 ● Funcionamento do RC4 – Vetor State (S) ● 256 posições 0 1 2 3 4 5 6 7 8 9 ● Permutação de acordo com a chave (K) K x x x x x 1
  • 2.
    Algoritmo RC4 index1 =0; index2 = 0; for(counter = 0; counter < 256; counter++) { index2 = (key[index1] + state[counter] + index2) % 256; swap_byte(&state[counter], &state[index2]); index1 = (index1 + 1) % key_data_len; } 2
  • 3.
    Algoritmo RC4 ● Após a permuta é realizada a criação da chave de qualquer tamanho pelo PRNG inicializa-se x = y = 0 x = (x + 1) % 256; y = (state[x] + y) % 256; swap_byte(&state[x], &state[y]); xorIndex = (state[x] + state[y]) % 256; GeneratedByte = state[xorIndex]; 3
  • 4.
    Algoritmo RC4 ● Verificação do funcionamento: ● Software wep.php ● apresenta a chave, o vetor State e os Bytes utilizandos para realizar a cifragem da mensagem ● ex: php wep.php normal 10:11:12:13 “teste” 4
  • 5.
    Situação Atual ● O WEP apresenta chaves fracas ● artigo: “Weaknesses in the Key Scheduling Algorithm of RC4” de Fluhrer / Mantin / Shamir ● Programas WEPCrack e AirSnort 5
  • 6.
    Situação Atual index1 =0; index2 = 0; for(counter = 0; counter < 256; counter++) { index2 = (key[index1] + state[counter] + index2) % 256; swap_byte(&state[counter], &state[index2]); index1 = (index1 + 1) % key_data_len; } 6
  • 7.
    Situação Atual ● Existem dois elementos que alteram os valores de S: – Index2 (varia de acordo com a chave) – Counter (contador linear) ● Existe uma probabilidade de que um valor seja alterado tanto pelo Index, quanto pelo Counter 7
  • 8.
    Situação Atual ● Ou seja existe a probabilidade de aprox. 37% de que um valor seja alterado apenas por Counter ● Para uma chave com K bytes, sendo E < K existe uma probabilidade de que E dependa apenas dos elementos 0..E da chave no vetor S ● Ou seja, em 37% dos casos o algoritmo passa a ser equivalente a....... 8
  • 9.
    Situação Atual for(counter =0; counter < 256; counter++) { index2 = (key[index1] + state[counter] + index2) % 256; swap_byte(&state[counter], &state[index2]); index1 = (index1 + 1) % key_data_len; } for(counter = 0; counter < 256; counter++) { index2 = (key[index1] + counter + index2) % 256; state[counter] = index2; index1 = (index1 + 1) % key_data_len; } 9
  • 10.
    Situação Atual ● A probabilidade desta afirmação estar correta para os elementos de State 10
  • 11.
    Situação Atual ● prova: ● executar os dois algoritmos e comparar o número de colisões para cada elemento de State php wep.php prove1 8 500 norm 11
  • 12.
    Situação Atual ● Desta forma: State[E] = ΣK(E) + E(E + 1)/2 ● Onde (E) representa o somatório dos bytes de 0..E (inclusive) da chave K – State[1] = K[0] + K[1] + 1(1 + 1)/2 – State[2] = K[0] + K[1] + K[2] + 2(2 + 1)/2 12
  • 13.
    Situação Atual ● prova: ● verificar se o valor de State[E] pode ser obtido pela fórmula php wep.php prove1 8 500 norm state 13
  • 14.
    Situação Atual ● Exemplo de chave fraca – permite a descoberta do segredo a partir do vetor de permutação devido a relação entre chaves prévias e vetor State – Exemplo de previsão simples no caso em que S[1] = 1 ● K[0] + K[1] = 0 (chave fraca), implicando: ● S[2] = K[2] + 2 (2+1) / 2 = K[2] + 3 14
  • 15.
    Situação Atual ● prova: ● gerar as chaves com K[0] = 0 e K[1] = 0 php wep.php prove1 8 500 weak state 15
  • 16.
    Situação Atual ● Após a permuta é realizada a criação da chave de qualquer tamanho pelo PRNG inicializa-se x = y = 0 x = (x + 1) % 256; y = (state[x] + y) % 256; swap_byte(&state[x], &state[y]); xorIndex = (state[x] + state[y]) % 256; GeneratedByte = state[xorIndex]; 16
  • 17.
    Situação Atual ● Considerando uma situação onde State[1]=1 – ou seja, K[0]=K[1]=0 x = (0 + 1) % 256; /* x == 1 */ y = (state[1] + 0) % 256; /* y == 1 */ swap_byte(&state[1], &state[1]); /* no effect */ xorIndex = (state[1] + state[1]); /* xorIndex = 2 */ GeneratedByte = state[2] 17
  • 18.
    Situação Atual ● Sempre que State[1] = 1, a alteração realizada pelo PRNG torna-se previsível – É realizado um XOR entre o texto claro e State[2] – Ao descobrir State[2], o atacante pode sugerir um K[2] provável State[2] = K[2] + 3, quando State[1]=1 ● prova: php wep.php normal 00:00:12:82 “teste” 18
  • 19.
    Situação Atual ● prova: ● para encontrar novas chaves com State[1]=1 – 1000 tentativas (aleatório) – chave com tam=5 php wep.php find_weak 1000 5 19
  • 20.
    Quebra do WEP ● No wep, o IV representa os primeiros 3 bytes do segredo compartilhado (K) = K[0], K[1], K[2] ● O LLC adiciona sempre o mesmo cabeçalho (0xaa), primeiro byte a ser cifrado (texto claro) ● O atacante pode, então recriar os primeiros passos da permuta de State a partir do IV utilizado 20
  • 21.
    Quebra do WEP ● Resumindo, o atacante possui: – IV = K[0], K[1], K[2] – Precisa descobrir S[3] para descobrir/sugerir K[3], pois S[3] = K[0] + K[1] + K[2] + K[3] + 3(3 + 1)/2 21
  • 22.
    Quebra do WEP ● Sempre que S[1] = 0 e S[0] = n o primeiro byte será cifrado por S[n], pois: x = (x + 1) % 256; x = 1 y = (state[x] + y) % 256; y = (state[1]) = 0 swap_byte(&state[x], &state[y]); state[1] <-> state [0] xorIndex = (state[x] + state[y]) % 256; xorIndex = (state[1] + state[0]) = state[1] GeneratedByte = state[xorIndex]; GeneratedByte = state[1] 22
  • 23.
    Quebra do WEP ● prova: ● para encontrar novas chaves com State[1]=0 – 1000 tentativas (aleatório) – chave com tam=5 php wep.php find_weak 1000 5 ● utiliza-se a chave encontrada no RC4 ● o valor apontado por State[0] será o índice em State para o valor utilizado na cifragem php wep.php normal 50:233:61:247:240 "ola mundo" 23
  • 24.
    Quebra do WEP ● Se (S[1] + S[S[1]] = 3) então o texto será cifrado por S[3] – Descoberta de S[3] ● S[3] = texto_cifrado XOR 0xaa – Inversão do processo de permutação do RC4 ● S[3] = K[0] + K[1] + K[2] + K[3] + 3(3 + 1)/2 ● O mesmo é feito para K[4], ... Ou seja (S[1]+S[S[1]]=4) ... .... .... 24
  • 25.
    Quebra do WEP ● Exemplo: php wep.php normal 4:29:74:3:228 “teste” KEY: 4:29:74:3:228<- objetivo State: S[0]=3 S[1]=0 S[2]=110 S[3]=116 S[4]=197 S[5]=38... RC4 KEY:116:79:90:205:73 O atacante possui os valores iniciais da chave IV[0]=K[0]=4 IV[1]=K[1]=29 IV[2]=K[2]=74 25
  • 26.
    Quebra do WEP ● Para obter K[3]: IV[0]=K[0]=4 IV[1]=K[1]=29 IV[2]=K[2]=74 S[3]=116 (obtém realizando um XOR entre 0xaa e o valor do primeiro byte do pacote capturado) S[3] = 4 + 29 + 74 + K[3] + 3 x (3+1)/2 K[3] = 116 – 4 – 29 – 74 – 6 = 3 K[3] = 3 26
  • 27.
    Quebra do WEP ● Próximo passo: – Encontrar uma situação onde S[1]=0 e S[0]=4 com chave fraca, ou seja, que: S[4] = K[0] + K[1] + K[2] + K[3] + K[4] + 4(4+1)/2 ... 27
  • 28.
    Quebra do WEP ● Exemplo 2: php wep.php normal 26:55:29:50:43 “teste” KEY: 26:55:29:50:43<- objetivo State: S[0]=3 S[1]=0 S[2]=10 S[3]=166 S[4]=213 S[5]=218... RC4 KEY:166:198:122:220:59 28
  • 29.
    Quebra do WEP ● Para obter K[3]: IV[0]=K[0]=26 IV[1]=K[1]=55 IV[2]=K[2]=29 S[3]=166 (obtém realizando um XOR entre 0xaa e o valor do primeiro byte do pacotecapturado) K[3] = 166 – 26 – 55 – 29 – 6 = 50 K[3] = 50 ... ... ... 29