Coverage for /root/GitHubProjects/impacket/impacket/wps.py : 94%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved.
2#
3# This software is provided under under a slightly modified version
4# of the Apache Software License. See the accompanying LICENSE file
5# for more information.
6#
7# Description:
8# WPS packets
9#
10# Author:
11# Aureliano Calvo
14import array
15import struct
17from impacket.ImpactPacket import array_tobytes
18from impacket.helper import ProtocolPacket, Byte, Bit
19from functools import reduce
22class ArrayBuilder(object):
24 def from_ary(self, ary):
25 return ary
27 def to_ary(self, value):
28 return array.array("B", value)
30class ByteBuilder(object):
32 def from_ary(self, ary):
33 return ary[0]
35 def to_ary(self, value):
36 return array.array('B', [value])
38class StringBuilder(object):
39 def from_ary(self, ary):
40 return array_tobytes(ary)
42 def to_ary(self, value):
43 return array.array('B', value)
45class NumBuilder(object):
46 """Converts back and forth between arrays and numbers in network byte-order"""
48 def __init__(self, size):
49 """size: number of bytes in the field"""
50 self.size = size
52 def from_ary(self, ary):
53 if len(ary) != self.size: 53 ↛ 54line 53 didn't jump to line 54, because the condition on line 53 was never true
54 raise Exception("Expected %s size but got %s" % (self.size, len(ary)))
55 return reduce( lambda ac, x: ac * 256 + x, ary, 0)
57 def to_ary(self, value0):
58 value = value0
59 rv = array.array('B')
60 for _ in range(self.size):
61 value, mod = divmod(value, 256)
62 rv.append(mod)
64 if value != 0: 64 ↛ 65line 64 didn't jump to line 65, because the condition on line 64 was never true
65 raise Exception("%s is too big. Max size: %s" % (value0, self.size))
67 rv.reverse()
68 return rv
70class TLVContainer(object):
72 def builder(self, kind):
73 return self.builders.get(kind, self.default_builder)
75 def from_ary(self, ary):
76 i = 0
77 while i<len(ary):
78 kind = self.ary2n(ary, i)
79 length = self.ary2n(ary, i+2)
80 i+=4
81 value = ary[i:i+length]
82 self.elems.append((kind, value))
83 i += length
85 return self
87 def __init__(self, builders, default_builder = ArrayBuilder(), descs=None):
88 self.builders = builders
89 self.default_builder = default_builder
90 self.elems = []
91 self.descs = descs or {}
93 def append(self, kind, value):
94 self.elems.append((kind, self.builder(kind).to_ary(value)))
96 def __iter__(self):
97 return ((k, self.builder(k).from_ary(v)) for k,v in self.elems)
99 def all(self, kind):
100 return [e[1] for e in self if e[0] == kind]
102 def __contains__(self, kind):
103 return len(self.all(kind)) != 0
105 def first(self, kind):
106 return self.all(kind)[0]
108 def to_ary(self):
109 ary = array.array('B')
110 for k,v in self.elems:
111 ary.extend(self.n2ary(k))
112 ary.extend(self.n2ary(len(v)))
113 ary.extend(v)
115 return ary
118 def get_packet(self):
119 return array_tobytes(self.to_ary())
121 def set_parent(self, my_parent):
122 self.__parent = my_parent
124 def parent(self):
125 return self.__parent
127 def n2ary(self, n):
128 return array.array("B", struct.pack(">H",n))
130 def ary2n(self, ary, i=0):
131 return struct.unpack(">H", array_tobytes(ary[i:i+2]))[0]
133 def __repr__(self):
134 def desc(kind):
135 return self.descs[kind] if kind in self.descs else kind
137 return "<TLVContainer %s>" % repr([(desc(k), self.builder(k).from_ary(v)) for (k,v) in self.elems])
139 def child(self):
140 return None
142class SCElem(object):
143 #Data elements as defined in section 11 of the WPS 1.0h spec.
145 AP_CHANNEL = 0x1001
146 ASSOCIATION_STATE = 0x1002
147 AUTHENTICATION_TYPE = 0x1003
148 AUTHENTICATION_TYPE_FLAGS = 0x1004
149 AUTHENTICATOR = 0x1005
150 CONFIG_METHODS = 0x1008
151 CONFIGURATION_ERROR = 0x1009
152 CONFIRMATION_URL4 = 0x100A
153 CONFIRMATION_URL6 = 0x100B
154 CONNECTION_TYPE = 0X100C
155 CONNECTION_TYPE_FLAGS = 0X100D
156 CREDENTIAL = 0X100E
157 DEVICE_NAME = 0x1011
158 DEVICE_PASSWORD_ID = 0x1012
159 E_HASH1 = 0x1014
160 E_HASH2 = 0x1015
161 E_SNONCE1 = 0x1016
162 E_SNONCE2 = 0x1017
163 ENCRYPTED_SETTINGS = 0x1018
164 ENCRYPTION_TYPE = 0X100F
165 ENCRYPTION_TYPE_FLAGS = 0x1010
166 ENROLLEE_NONCE = 0x101A
167 FEATURE_ID = 0x101B
168 IDENTITY = 0X101C
169 INDENTITY_PROOF = 0X101D
170 KEY_WRAP_AUTHENTICATOR = 0x101E
171 KEY_IDENTIFIER = 0X101F
172 MAC_ADDRESS = 0x1020
173 MANUFACTURER = 0x1021
174 MESSAGE_TYPE = 0x1022
175 MODEL_NAME = 0x1023
176 MODEL_NUMBER = 0x1024
177 NETWORK_INDEX = 0x1026
178 NETWORK_KEY = 0x1027
179 NETWORK_KEY_INDEX = 0x1028
180 NEW_DEVICE_NAME = 0x1029
181 NEW_PASSWORD = 0x102A
182 OOB_DEVICE_PASSWORD = 0X102C
183 OS_VERSION= 0X102D
184 POWER_LEVEL = 0X102F
185 PSK_CURRENT = 0x1030
186 PSK_MAX = 0x1031
187 PUBLIC_KEY = 0x1032
188 RADIO_ENABLED = 0x1033
189 REBOOT = 0x1034
190 REGISTRAR_CURRENT = 0x1035
191 REGISTRAR_ESTABLISHED = 0x1036
192 REGISTRAR_LIST = 0x1037
193 REGISTRAR_MAX = 0x1038
194 REGISTRAR_NONCE = 0x1039
195 REQUEST_TYPE = 0x103A
196 RESPONSE_TYPE = 0x103B
197 RF_BANDS = 0X103C
198 R_HASH1 = 0X103D
199 R_HASH2 = 0X103E
200 R_SNONCE1 = 0X103F
201 R_SNONCE2 = 0x1040
202 SELECTED_REGISTRAR = 0x1041
203 SERIAL_NUMBER = 0x1042
204 WPS_STATE = 0x1044
205 SSID = 0x1045
206 TOTAL_NETWORKS = 0x1046
207 UUID_E = 0x1047
208 UUID_R = 0x1048
209 VENDOR_EXTENSION = 0x1049
210 VERSION = 0x104A
211 X_509_CERTIFICATE_REQUEST = 0x104B
212 X_509_CERTIFICATE = 0x104C
213 EAP_IDENTITY = 0x104D
214 MESSAGE_COUNTER = 0x104E
215 PUBLIC_KEY_HASH = 0x104F
216 REKEY_KEY = 0x1050
217 KEY_LIFETIME = 0x1051
218 PERMITTED_CONFIG_METHODS = 0x1052
219 SELECTED_REGISTRAR_CONFIG_METHODS= 0x1053
220 PRIMARY_DEVICE_TYPE = 0x1054
221 SECONDARY_DEVICE_TYPE_LIST = 0x1055
222 PORTABLE_DEVICE = 0x1056
223 AP_SETUP_LOCKED = 0x1057
224 APPLICATION_EXTENSION = 0x1058
225 EAP_TYPE = 0x1059
226 INITIALIZATION_VECTOR = 0x1060
227 KEY_PROVIDED_AUTOMATICALLY = 0x1061
228 _802_1X_ENABLED = 0x1062
229 APP_SESSION_KEY = 0x1063
230 WEP_TRANSMIT_KEY = 0x1064
232class MessageType(object):
233 """Message types according to WPS 1.0h spec, section 11"""
235 BEACON = 0x01
236 PROBE_REQUEST = 0x02
237 PROBE_RESPONSE = 0x03
238 M1 = 0x04
239 M2 = 0x05
240 M2D = 0x06
241 M3 = 0x07
242 M4 = 0x08
243 M5 = 0x09
244 M6 = 0x0A
245 M7 = 0x0B
246 M8 = 0x0C
247 WSC_ACK = 0x0D
248 WSC_NACK = 0x0E
249 WSC_DONE = 0x0F
251class AuthTypeFlag(object):
252 OPEN = 0x0001
253 WPAPSK = 0x0002
254 SHARED = 0x0004
255 WPA = 0x0008
256 WPA2 = 0x0010
257 WPA2PSK = 0x0020
259AuthTypeFlag_ALL = AuthTypeFlag.OPEN | \
260 AuthTypeFlag.WPAPSK | \
261 AuthTypeFlag.SHARED | \
262 AuthTypeFlag.WPA | \
263 AuthTypeFlag.WPA2 | \
264 AuthTypeFlag.WPA2PSK
266class EncryptionTypeFlag(object):
267 NONE = 0x0001
268 WEP = 0x0002
269 TKIP = 0x0004
270 AES = 0x0008
272EncryptionTypeFlag_ALL = EncryptionTypeFlag.NONE | EncryptionTypeFlag.WEP | EncryptionTypeFlag.TKIP | EncryptionTypeFlag.AES
274class ConnectionTypeFlag(object):
275 ESS = 0x01
276 IBSS = 0x02
278class ConfigMethod(object):
279 USBA = 0x0001
280 ETHERNET = 0x0002
281 LABEL = 0x0004
282 DISPLAY = 0x0008
283 EXT_NFC_TOKEN = 0x0010
284 INT_NFC_TOKEN = 0x0020
285 NFC_INTERFACE = 0x0040
286 PUSHBUTTON = 0x0080
287 KEYPAD = 0x0100
290class OpCode(object):
291 WSC_START = 0x01
292 WSC_ACK = 0x02
293 WSC_NACK = 0x03
294 WSC_MSG = 0x04
295 WSC_DONE = 0x05
296 WSC_FRAG_ACK = 0x06
298class AssocState(object):
299 NOT_ASSOC = 0
300 CONN_SUCCESS = 1
301 CFG_FAILURE = 2
302 FAILURE = 3,
303 IP_FAILURE = 4
305class ConfigError(object):
306 NO_ERROR = 0
307 OOB_IFACE_READ_ERROR = 1
308 DECRYPTION_CRC_FAILURE = 2
309 _24_CHAN_NOT_SUPPORTED = 3
310 _50_CHAN_NOT_SUPPORTED = 4
311 SIGNAL_TOO_WEAK = 5
312 NETWORK_AUTH_FAILURE = 6
313 NETWORK_ASSOC_FAILURE = 7
314 NO_DHCP_RESPONSE = 8
315 FAILED_DHCP_CONFIG = 9
316 IP_ADDR_CONFLICT = 10
317 NO_CONN_TO_REGISTRAR = 11
318 MULTIPLE_PBC_DETECTED = 12
319 ROGUE_SUSPECTED = 13
320 DEVICE_BUSY = 14
321 SETUP_LOCKED = 15
322 MSG_TIMEOUT = 16
323 REG_SESS_TIMEOUT = 17
324 DEV_PASSWORD_AUTH_FAILURE = 18
326class DevicePasswordId(object):
327 DEFAULT = 0x0000
328 USER_SPECIFIED = 0x0001
329 MACHINE_SPECIFIED = 0x0002
330 REKEY = 0x0003
331 PUSHBUTTON = 0x0004
332 REGISTRAR_SPECIFIED = 0x0005
334class WpsState(object):
335 NOT_CONFIGURED = 0x01
336 CONFIGURED = 0x02
339class SimpleConfig(ProtocolPacket):
340 "For now, it supports Simple configs with the bits more_fragments and length_field not set"
342 header_size = 2
343 tail_size = 0
345 op_code = Byte(0)
346 flags = Byte(1)
347 more_fragments = Bit(1, 0)
348 length_field = Bit(1,1)
350 BUILDERS = {
351 SCElem.CONNECTION_TYPE: ByteBuilder(),
352 SCElem.CONNECTION_TYPE_FLAGS: ByteBuilder(),
353 SCElem.VERSION: ByteBuilder(),
354 SCElem.MESSAGE_TYPE: ByteBuilder(),
355 SCElem.NETWORK_INDEX: ByteBuilder(),
356 SCElem.NETWORK_KEY_INDEX: ByteBuilder(),
357 SCElem.POWER_LEVEL: ByteBuilder(),
358 SCElem.PSK_CURRENT: ByteBuilder(),
359 SCElem.PSK_MAX: ByteBuilder(),
360 SCElem.REGISTRAR_CURRENT: ByteBuilder(),
361 SCElem.REGISTRAR_MAX: ByteBuilder(),
362 SCElem.REQUEST_TYPE: ByteBuilder(),
363 SCElem.RESPONSE_TYPE: ByteBuilder(),
364 SCElem.RF_BANDS: ByteBuilder(),
365 SCElem.WPS_STATE: ByteBuilder(),
366 SCElem.TOTAL_NETWORKS: ByteBuilder(),
367 SCElem.VERSION: ByteBuilder(),
368 SCElem.WEP_TRANSMIT_KEY: ByteBuilder(),
370 SCElem.CONFIRMATION_URL4: StringBuilder(),
371 SCElem.CONFIRMATION_URL6: StringBuilder(),
372 SCElem.DEVICE_NAME: StringBuilder(),
373 SCElem.IDENTITY: StringBuilder(),
374 SCElem.MANUFACTURER: StringBuilder(),
375 SCElem.MODEL_NAME: StringBuilder(),
376 SCElem.MODEL_NUMBER: StringBuilder(),
377 SCElem.NEW_DEVICE_NAME: StringBuilder(),
378 SCElem.NEW_PASSWORD: StringBuilder(),
379 SCElem.SERIAL_NUMBER: StringBuilder(),
380 SCElem.EAP_IDENTITY: StringBuilder(),
381 SCElem.NETWORK_KEY: StringBuilder(),
383 SCElem.AP_CHANNEL: NumBuilder(2),
384 SCElem.ASSOCIATION_STATE: NumBuilder(2),
385 SCElem.AUTHENTICATION_TYPE: NumBuilder(2),
386 SCElem.AUTHENTICATION_TYPE_FLAGS: NumBuilder(2),
387 SCElem.CONFIG_METHODS: NumBuilder(2),
388 SCElem.CONFIGURATION_ERROR: NumBuilder(2),
389 SCElem.DEVICE_PASSWORD_ID: NumBuilder(2),
390 SCElem.ENCRYPTION_TYPE: NumBuilder(2),
391 SCElem.ENCRYPTION_TYPE_FLAGS: NumBuilder(2),
392 SCElem.MESSAGE_COUNTER: NumBuilder(8),
393 SCElem.KEY_LIFETIME: NumBuilder(4),
394 SCElem.PERMITTED_CONFIG_METHODS: NumBuilder(2),
395 SCElem.SELECTED_REGISTRAR_CONFIG_METHODS: NumBuilder(2),
396 SCElem.PUBLIC_KEY: NumBuilder(192),
398 }
400 @classmethod
401 def build_tlv_container(cls):
402 return TLVContainer(
403 builders=SimpleConfig.BUILDERS,
404 descs = dict( (v,k) for (k,v) in SCElem.__dict__.items() )
405 )