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

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