2

I'm trying to implement the FMS attack on WEP. I understand that the attack takes advantage of the probability of parts of the RC4 sbox not changing to create "known" sbox states to reverse engineer the key. With many samples, the correct key octet should appear more often than noise.

The value that should add to the frequency count is:

enter image description here

where (I think; the notation is not properly defined)

  • B starts at 0
  • P.out is the outputted keystream byte
  • S is the Sbox
  • j is the "pointer" used in the RC4 key scheduling algorithm

In my code, I am generating 6 million data packets: a constant root key and constant plaintext to simulate constant header, and then encrypting with RC4(IV + root_key).encrypt(plaintext), without discarding the first 256 octets). The (IV, encrypted_data) pairs are run through the get_key function:

uint8_t RC4_ksa(const std::string & k, std::array <uint8_t, 256> & s, const uint16_t octets = 256){
    for(uint16_t i = 0; i < 256; i++){
        s[i] = i;
    }

    uint8_t j = 0;
    for(uint16_t i = 0; i < octets; i++){
        j = (j + s[i] + k[i % k.size()]);
        std::swap(s[i], s[j]);
    }

    return j;
}

std::string get_key(const uint8_t keylen, const std::vector <std::pair <std::string, std::string> > & captured){
    std::string rkey = "";               // root key to build
    const std::string & pt = header;     // "plaintext" with constant header

    // recreate root key one octet at a time
    for(uint8_t i = 3; i < keylen; i++){
        // vote counter for current octet
        std::array <unsigned int, 256> votes;
        votes.fill(0);

        uint8_t most = 0;                // most probable index/octet value

        // get vote from each "captured" ciphertext
        for(std::pair <std::string, std::string> const & c : captured){
            const std::string & IV = c.first;

            // IV should be of form (i = root key index + 3, 255, some value)
            if ((static_cast<uint8_t> (IV[0]) != i) ||
                (static_cast<uint8_t> (IV[1]) != 0xff)){
                continue; // skip this data
            }

            const std::string & ct = c.second;
            const std::string key = IV + rkey;

            // find current packet's vote
            std::array <uint8_t, 256> sbox;           // SBox after simulating; fill with RC4_ksa
            uint8_t j = RC4_ksa(key, sbox, i);        // simulate using key in KSA, up to known octets only

            uint8_t keybytestream = pt[i - 3] ^ ct[i - 3];

            // S^-1[keybytestream]
            uint16_t sinv;
            for(sinv = 0; sinv < 256; sinv++){
                if (sbox[sinv] == keybytestream){
                    break;
                }
            }

            // get mapping
            uint8_t ki = sinv - j - sbox[i];

            // add to tally and keep track of which tally is highest
            votes[ki]++;
            if (votes[ki] > votes[most]){
                most = ki;
            }
        }

        // select highest voted value as next key octet
        rkey += std::string(1, most);
    }

    return rkey;
}

I am getting keys that are completely incorrect. I feel that the error is probably a one-off error or something silly like that, but I have asked two people to look at this, and neither person has managed to figure out what is wrong.

Is there something that is blatantly wrong? If not, what is not-so-obviously wrong?

calccrypto
  • 8,583
  • 21
  • 68
  • 99
  • 2
    This might help: [wep fms filetype:c](http://www.google.com/#q=wep+fms+filetype:c) if you don't get an answer that meets your expectations. – jww Sep 14 '14 at 15:57
  • 1
    Perhaps http://security.stackexchange.com/ could be a better choice for this one – Marco A. Sep 14 '14 at 21:24
  • @MarcoA. Nope. Since this is a coding question, it would be off-topic at sites like Security.SE or Crypto.SE. Besides that, something tells me that no one at those sites will be very motivated to help build an “attack” tool. All in all, I would say [@jww gave the most constructive hint](http://stackoverflow.com/questions/25791102/fms-attack-on-wep-in-c#comment40419093_25791102) OP can get… especially, since this question boils down to a ***“why doesn’t this code work”*** question. (The later could be fixed if OP would edit the question accordingly, making the question less **off-topic**.) – e-sushi Sep 14 '14 at 21:41
  • @e-sushi I was sort of hoping that since this code isn't too long and not too trivial (or too long and complex), people might be willing to look at it. – calccrypto Sep 14 '14 at 22:28

0 Answers0