How can I: Generate a 40/64 bit WEP key in Python?

So, for several months now I hit my head against the wall of this problem, partly because it is a collateral interest, and partly because I suck programming. I searched and explored everything online, but had no luck (except for one small success, see below), so I thought I could ask experts.

What I'm trying to do is that, as the name suggests, generate 40/64 bits of the WEP key from the passphrase in accordance with the de facto standard. (A site like http://www.powerdog.com/wepkey.cgi gives the expected outputs.) I have already written parts of the script that take input and write it to a file; one of the inputs will be a passphrase sanitized in lowercase.

For the longest time, I had no idea what the defacto standard was, and even more so how to implement it. I finally stumbled upon a paper ( http://www.lava.net/~newsham/wlan/WEP_password_cracker.pdf ) that sheds as much light as I had in this question (page 18 has corresponding bits). Apparently, the code phrase is "mapped to a 32-bit value with XOR", the result of which is then used as the seed for a "linear congruent PRNG (which of several PRNGs of Python matches this description, I know), and then several bits are taken from this result The result: I have no idea how to implement this, since the description is rather vague.

I need help writing a generator in Python, as well as understanding how the key is generated. In other words, I need code to turn jackson into 09F38AF593. (And please don't tell me jackson = 09F38AF593; print (jackson))

I am not a very programmer, so explanations are also appreciated.

(Yes, I know that WEP is not safe.)

+4
source share
2 answers

This C code that you contacted would be very useful for inclusion in the question ;-) In any case, I went ahead and translated it into Python. Before you read this, let me say that I highly recommend you try it yourself and use my transcription as a guide. Translating algorithms from one programming language to another is usually a great practice when you want to improve your skills in one or both languages. Even if you do not know C, if you are familiar enough with Python to write programs in it, you should be able to get the gist of C code, as there are many similarities.

In any case, on the code.

import itertools, operator 

First, a pseudo-random number generator, which was identified in the view as a linear congruent generator . This type of PRNG is a general algorithm that can be "customized" by selecting the specific values a , c and m (the variables mentioned in the Wikipedia article). The following is an implementation of a generalized linear congruent generator:

 def prng(x, a, c, m): while True: x = (a * x + c) % m yield x 

(hope you could come up with this yourself)

Now for the actual function:

 def pass_to_key(passphrase): 

The first step in the process is a hash (or "card") containing the passphrase provided to the 32-bit number. The WEP algorithm does this by creating a set of 4 bytes (thus 4 * 8 = 32 bits) that are initialized to zero.

  bits = [0,0,0,0] 

It goes through the string and XOR each character with one of the bytes; in particular, the character i is XOR'd in byte i % 4 .

  for i, c in enumerate(passphrase): bits[i & 3] ^= ord(c) 

Then these four bytes are combined together to form one 32-bit value. (Alternatively, I could write code to save them as a 32-bit number from the beginning)

  val = reduce(operator.__or__, (b << 8*i for (i,b) in enumerate(bits))) 

This 32-bit value is used as the seed for a linear congruent generator with specific values ​​that you can see in the code. As the original developer calculated these numbers, I have no idea.

  keys = [] 

A linear congruent generator can produce up to 32 bits of output at a time. (In C, this is a data type restriction; in Python, I had to artificially apply it). I need 20 bytes to generate 4 40-bit (5-byte) WEP keys, so I will repeat PRNG 20 times,

  for i, b in enumerate(itertools.islice(prng(val, 0x343fd, 0x269ec3, 1<<32), 20)): 

and from each number, take only the third byte on the right (bit 16-23):

  keys.append((b >> 16) & 0xff) 

Why the third? Well, the bits on the upper end (4 on the right) tend not to change much, and those on the lower end can be predictable for many values ​​of PRNG constants.

Subsequently, all that remains is to print the created bytes in groups of 5.

  print ('%02x:%02x:%02x:%02x:%02x\n'*4) % tuple(keys) 
+5
source

I'm not sure what the β€œde facto standard” this website is talking about, but I'm sure router manufacturers are implementing their own methods. It doesn't matter how you do it if the same input always leads to the same result; this is a convenience, so WEP users can remember the passphrase instead of the actual hexadecimal key. Even the method in PDF that you published is pretty much ambiguous; it uses undefined PRNG (and each type of PRNG is going to give a different result) and takes "one byte" from each result without specifying which one. If you are trying to reverse engineer a specific router method, indicate what is in the message and we could find out how it works, but there is no standard method

+1
source

Source: https://habr.com/ru/post/1310637/


All Articles