I am not sure if this is the best section to post this thread, but I think this issue can be interesting for some people.
If the topic doesn't fit this section, feel free to move it elsewhere. : P
This issue affects most of TP-Link routers (their ESSID is usually TP-LINK_XXXXXX), and has nothing to do with the firmware. The problem is the key generation in the EasySetupAssistant. Using WPA2, the assistant generates random passwords of length 10, with 32 possible characters (2-9; A-Z without 'I' or 'O'). If someone tried to break this password with a speed 20.000 keys/sec. (this speed can be easily achieved with a desktop computer and GPU acceleration), he would need 3210 / 20000 = 1785.1 years to break it. So the system is apparently secure. The problem is that the assistant is using a linear congruential generator with seeds of 32 bits to generate the characters of the key. That is, there are 232 possible keys in the key set. Here is the code (Python) of the generator:
Hmmm, not exactly... The seeds are NOT random.
chars = "2345678923456789ABCDEFGHJKLMNPQRSTUVWXYZ"
def gen(seed, length): #length=10 for WPA/WPA2, length=13 for WEP
key = ""
for i in range(length):
seed = (seed)*0x343FD + 0x269EC3
key += chars[((seed >> 0x10) & 0x7FFF) % 0x28]
The seed is obtained by transforming the 64-bit output of KERNEL32.GetSystemTimeAsFileTime into a 32-bit unsigned integer, which is in practice just a number that increases on 1 each second based on the UTC time at the moment of generating the key. Here is the code in Python of that function:
Since we can predict the values of the seeds between two dates, we can reduce the cases from 2^31 to the seconds elapsed between two dates. Let me explain, suppose we know one AP was installed during 2012, regardless of the month, day, etc... Thanks to this method we know we have to check only the keys corresponding to seeds that lie between 0x4EFFA3AD and 0x50E22700. That is:
dt = t1 - datetime.datetime(1601, 1, 1, 0, 0, 0)
t = dt.days*86400 + dt.seconds*100 + dt.microseconds*10
tA = (t/2**32 + 0xFE624E21)
tB = (t%2**32 + 0x2AC18000) % (1<<32)
if tA >= (1<<32):
tA += 1
tA %= 1<<32
r = (tA % 0x989680) * (2**32)
r = ((r + tB) / 0x989680) % (2**31)
There are around 365*24*60*60 = 31536000 seconds in a year (which is more or less 0x50E22700 - 0x4EFFA3AD). Therefore, we have only to check 31536000 keys. That is really easy: we can do it in 26 minutes with GPU acceleration or in 5 hours using only the CPU. Notice that regarding the computing time, this would be the worst case possible. If some attacker knew that a router was recently installed, he could break the password in a few minutes or even seconds!
print genSeed(datetime.datetime(2012, 1, 1, 0, 0, 0)) #0x4EFFA3AD
print genSeed(datetime.datetime(2013, 1, 1, 0, 0, 0)) #0x50E22700
Vulnerable TP-Link Routers: (Any wireless router made by TP-Link since 2010, I guess)
TL-W8151N (V1, V3)
TL-WA730RE (V1, V2*)
TL-WA830RE (V1, V2*)
TL-WR740N (V1, V2, V3, V4)
TL-WR741ND (V1, V2, V3*,V4)
TL-WR841N (V1*,V5, V7, V8)
TL-WR841ND (V3, V5, V7, V8*)
TL-WR940N (V1, V2)
TL-WR941ND (V2, V3, V4, V5)
TD-W8951NB (V3*,V4, V5)
TD-W8951ND (V1, V3, V4, V5)
TD-W8960N (V1, V3, V4)
TD-W8961NB (V1, V2, V3*)
*Possibly vulnerable. I could not download the assistant to verify it.
Download tool: http://www.mediafire.com/?gor6b9b63nu6020
Here is the program to generate dictionaries for cracking these routers. It has been tested by other people, and we managed to crack the WPA2 password of 3 TP-Link APs. Of course these tests were made with our own routers. Tell me what you think about this program, feel free to post your "success stories", and report any bugs you found, please.
I have included versions for Windows and Linux as well as the source code of the program. Run the program TPLink-GenKeysFinal and follow the instructions. At the moment it is useless to specify the BSSID since I haven't focused on the list of release dates yet. My suggestion is to use the default arguments until we got the complete list of release dates for each router. If you know certainly the model of the AP, then pass the release date of the router to the program in the format --start DD/MM/YYYY.
I have also included some utilities I made to test this vulnerability. If you are interested about the details of this issue, you should take a look at them and read all I wrote on my blog about this [ES]. I don't really want to rewrite everything in English since I guess many of you are not really interested in reading all this information, but I hope Google Translator can make this a bit more understandable.