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

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

## 272 statements

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#

15

16 import array

17 import struct

18

19 from impacket.ImpactPacket import array_tobytes

20 from impacket.helper import ProtocolPacket, Byte, Bit

21 from functools import reduce

22

23

24 class ArrayBuilder(object):

25

26 def from_ary(self, ary):

27 return ary

28

29 def to_ary(self, value):

30 return array.array("B", value)

31

32 class ByteBuilder(object):

33

34 def from_ary(self, ary):

35 return ary[0]

36

37 def to_ary(self, value):

38 return array.array('B', [value])

39

40 class StringBuilder(object):

41 def from_ary(self, ary):

42 return array_tobytes(ary)

43

44 def to_ary(self, value):

45 return array.array('B', value)

46

47 class NumBuilder(object):

48 """Converts back and forth between arrays and numbers in network byte-order"""

49

50 def __init__(self, size):

51 """size: number of bytes in the field"""

52 self.size = size

53

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)

58

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)

65

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))

68

69 rv.reverse()

70 return rv

71

72 class TLVContainer(object):

73

74 def builder(self, kind):

75 return self.builders.get(kind, self.default_builder)

76

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

86

87 return self

88

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 {}

94

95 def append(self, kind, value):

96 self.elems.append((kind, self.builder(kind).to_ary(value)))

97

98 def __iter__(self):

99 return ((k, self.builder(k).from_ary(v)) for k,v in self.elems)

100

101 def all(self, kind):

102 return [e[1] for e in self if e[0] == kind]

103

104 def __contains__(self, kind):

105 return len(self.all(kind)) != 0

106

107 def first(self, kind):

108 return self.all(kind)[0]

109

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)

116

117 return ary

118

119

120 def get_packet(self):

121 return array_tobytes(self.to_ary())

122

123 def set_parent(self, my_parent):

124 self.__parent = my_parent

125

126 def parent(self):

127 return self.__parent

128

129 def n2ary(self, n):

130 return array.array("B", struct.pack(">H",n))

131

132 def ary2n(self, ary, i=0):

133 return struct.unpack(">H", array_tobytes(ary[i: i+2]))[0]

134

135 def __repr__(self):

136 def desc(kind):

137 return self.descs[kind] if kind in self.descs else kind

138

139 return "<TLVContainer %s>" % repr([(desc(k), self.builder(k).from_ary(v)) for (k,v) in self.elems])

140

141 def child(self):

142 return None

143

144 class SCElem(object):

145 #Data elements as defined in section 11 of the WPS 1.0h spec.

146

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

233

234 class MessageType(object):

235 """Message types according to WPS 1.0h spec, section 11"""

236

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

252

253 class AuthTypeFlag(object):

254 OPEN = 0x0001

255 WPAPSK = 0x0002

256 SHARED = 0x0004

257 WPA = 0x0008

258 WPA2 = 0x0010

259 WPA2PSK = 0x0020

260

261 AuthTypeFlag_ALL = AuthTypeFlag.OPEN | \

262 AuthTypeFlag.WPAPSK | \

263 AuthTypeFlag.SHARED | \

264 AuthTypeFlag.WPA | \

265 AuthTypeFlag.WPA2 | \

266 AuthTypeFlag.WPA2PSK

267

268 class EncryptionTypeFlag(object):

269 NONE = 0x0001

270 WEP = 0x0002

271 TKIP = 0x0004

272 AES = 0x0008

273

274 EncryptionTypeFlag_ALL = EncryptionTypeFlag.NONE | EncryptionTypeFlag.WEP | EncryptionTypeFlag.TKIP | EncryptionTypeFlag.AES

275

276 class ConnectionTypeFlag(object):

277 ESS = 0x01

278 IBSS = 0x02

279

280 class 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

290

291

292 class 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

299

300 class AssocState(object):

301 NOT_ASSOC = 0

302 CONN_SUCCESS = 1

303 CFG_FAILURE = 2

304 FAILURE = 3,

305 IP_FAILURE = 4

306

307 class 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

327

328 class DevicePasswordId(object):

329 DEFAULT = 0x0000

330 USER_SPECIFIED = 0x0001

331 MACHINE_SPECIFIED = 0x0002

332 REKEY = 0x0003

333 PUSHBUTTON = 0x0004

334 REGISTRAR_SPECIFIED = 0x0005

335

336 class WpsState(object):

337 NOT_CONFIGURED = 0x01

338 CONFIGURED = 0x02

339

340

341 class SimpleConfig(ProtocolPacket):

342 "For now, it supports Simple configs with the bits more_fragments and length_field not set"

343

344 header_size = 2

345 tail_size = 0

346

347 op_code = Byte(0)

348 flags = Byte(1)

349 more_fragments = Bit(1, 0)

350 length_field = Bit(1,1)

351

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(),

371

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(),

384

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),

399

400 }

401

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 )