Generating Phone Numbers

by Samuel A. Bancroft

It's no secret that many people use their phone number as a Wi-Fi (WPA/WPA2) network passphrase.  Two factors contribute to this.

Firstly, WPA/WPA2 requires a passphrase that is 8 to 63 ASCII characters long.  A phone number, being 10 characters long, is simple to remember and to type.

Secondly, oftentimes ISPs will configure the home's wireless network to use WPA/WPA2 using the customer's phone number as the passphrase.  Customers infrequently change it.

WPA/WPA2's shared-keys can be brute-forced, but the time involved is a major obstacle.  A dictionary attack is more practical and a phone number dictionary attack may be the most practical of all due to its high yields and simplicity.

Many people use wordlist generators such as Crunch, a wordlist generator that produces large word/number lists with specific patterns, to create a "phone number" dictionary using the pattern: [AREA CODE]%%%%%%% 1

Others create scripts to do something similar to the pattern above.2

This method of creating a phone number list is inefficient and ignorant.

Example for Area Code 920:

$ crunch 10 10 -t 920%%%%%%% -o 920.txt
Crunch will now generate the following amount of data: 110000000 bytes
104 MB
0 GB
0 TB
0 PB
Crunch will now generate the following number of lines: 10000000

crunch: 100% completed generating output
$ head 920.txt
9200000000
9200000001
9200000002
9200000003
9200000004
9200000005
9200000006
9200000007
9200000008
9200000009
$ tail 920.txt
9209999990
9209999991
9209999992
9209999993
9209999994
9209999995
9209999996
9209999997
9209999998
9209999999

The North American Numbering Plan (NANP) is a telephone numbering plan created by AT&T in 1947 and put into operation in 1951.  It serves 20 North American countries. 3  The NANP dictates the rules for area codes, exchange numbers/prefixes, etc.  For example, exchange numbers ranging from 000-199 are not used within the NANP plan.

Knowing this, we can see that generating numbers using a scheme such as [AREA CODE]%%%%%%% creates a lot of waste.  Just knowing that the NANP does not use prefixes 000-199 means that the above scheme will create 10,000 numbers per invalid prefix for a total of two million invalid phone numbers.

There is another consideration.

Various prefixes within a valid range are not used and this varies throughout different area codes.  To illustrate, area code 906 (Marquette, Michigan) contains 305 valid prefixes while area code 212 (New York, New York) contains 778 valid prefixes.  If we use the Crunch scheme we discussed for area code 906, we would produce 10 million numbers while only 3.05 million numbers are valid for this area code.  As can be seen, about seven million invalid numbers would have been created.

Below I have included a Python script that will generate every valid phone number within a specified area code.

It accomplishes this by scraping valid prefixes from www.allareacodes.com and producing valid phone numbers from it.  The numbers are saved in a text file.  Take look at the Bash script f0ne.sh by DERV if you are looking for something with more bells and whistles. 4

Help save the planet - do not generate millions of invalid numbers.

import urllib.request
import re

def main():

   ac = input('Enter the area code to compute: ')
   url = 'http://www.allareacodes.com/%s' % ac
   body = requestPage(url)

   # Find the region we are intreasted in.
   findStart = re.search(r'Area Code ' + ac + ' Prefixes', body)
   findEnd = re.search(r'Most Searched Numbers', body)

   try:
       startSpan = findStart.span()[1]
       endSpan = findEnd.span()[0]
   except AttributeError:
       print('Error: Area code is not valid.')
       quit()

   getPrefix = re.findall(r'\(\d{3}\) \d{3}', body[startSpan:endSpan])
   prefix = cleanList(getPrefix) # Removes '(305) '

   makeFile(ac, prefix)

def requestPage(url):
   req = urllib.request.Request(url)
   response = urllib.request.urlopen(req)
   return response.read().decode('utf-8')

def cleanList(getPrefix):
   prefix = []
   for fix in getPrefix:
       prefix.append(fix[6:])
   return prefix

def makeFile(ac, prefix):
   textFile = open('%s_numbers' % ac, 'w')

   for x in prefix:
       for i in range(10000):
           textFile.write('%s%s%s\n' % (ac, x, str(i).zfill(4)))

   textFile.close()
   print('Done. Area code %s had %s prefixes' % (ac, len(prefix)))

if __name__ == '__main__':
   main()

References

  1. Generate 10-Digit Phone Numbers Using Crunch in Backtrack
  2. Phone Number Dictionary File for Cracking WPA and WPA2
  3. North American Numbering Plan Administrator
  4. f0ne.sh  U.S. phone number generator shell script by DERV

Code: generate.py

Return to $2600 Index