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

12

13

14 import array

15 import struct

16

17 from impacket.ImpactPacket import array_tobytes

18 from impacket.helper import ProtocolPacket, Byte, Bit

19 from functools import reduce

20

21

22 class ArrayBuilder(object):

23

24 def from_ary(self, ary):

25 return ary

26

27 def to_ary(self, value):

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

29

30 class ByteBuilder(object):

31

32 def from_ary(self, ary):

33 return ary[0]

34

35 def to_ary(self, value):

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

37

38 class StringBuilder(object):

39 def from_ary(self, ary):

40 return array_tobytes(ary)

41

42 def to_ary(self, value):

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

44

45 class NumBuilder(object):

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

47

48 def __init__(self, size):

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

50 self.size = size

51

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)

56

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)

63

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

66

67 rv.reverse()

68 return rv

69

70 class TLVContainer(object):

71

72 def builder(self, kind):

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

74

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

84

85 return self

86

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

92

93 def append(self, kind, value):

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

95

96 def __iter__(self):

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

98

99 def all(self, kind):

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

101

102 def __contains__(self, kind):

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

104

105 def first(self, kind):

106 return self.all(kind)[0]

107

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)

114

115 return ary

116

117

118 def get_packet(self):

119 return array_tobytes(self.to_ary())

120

121 def set_parent(self, my_parent):

122 self.__parent = my_parent

123

124 def parent(self):

125 return self.__parent

126

127 def n2ary(self, n):

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

129

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

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

132

133 def __repr__(self):

134 def desc(kind):

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

136

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

138

139 def child(self):

140 return None

141

142 class SCElem(object):

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

144

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

231

232 class MessageType(object):

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

234

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

250

251 class AuthTypeFlag(object):

252 OPEN = 0x0001

253 WPAPSK = 0x0002

254 SHARED = 0x0004

255 WPA = 0x0008

256 WPA2 = 0x0010

257 WPA2PSK = 0x0020

258

259 AuthTypeFlag_ALL = AuthTypeFlag.OPEN | \

260 AuthTypeFlag.WPAPSK | \

261 AuthTypeFlag.SHARED | \

262 AuthTypeFlag.WPA | \

263 AuthTypeFlag.WPA2 | \

264 AuthTypeFlag.WPA2PSK

265

266 class EncryptionTypeFlag(object):

267 NONE = 0x0001

268 WEP = 0x0002

269 TKIP = 0x0004

270 AES = 0x0008

271

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

273

274 class ConnectionTypeFlag(object):

275 ESS = 0x01

276 IBSS = 0x02

277

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

288

289

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

297

298 class AssocState(object):

299 NOT_ASSOC = 0

300 CONN_SUCCESS = 1

301 CFG_FAILURE = 2

302 FAILURE = 3,

303 IP_FAILURE = 4

304

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

325

326 class DevicePasswordId(object):

327 DEFAULT = 0x0000

328 USER_SPECIFIED = 0x0001

329 MACHINE_SPECIFIED = 0x0002

330 REKEY = 0x0003

331 PUSHBUTTON = 0x0004

332 REGISTRAR_SPECIFIED = 0x0005

333

334 class WpsState(object):

335 NOT_CONFIGURED = 0x01

336 CONFIGURED = 0x02

337

338

339 class SimpleConfig(ProtocolPacket):

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

341

342 header_size = 2

343 tail_size = 0

344

345 op_code = Byte(0)

346 flags = Byte(1)

347 more_fragments = Bit(1, 0)

348 length_field = Bit(1,1)

349

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

369

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

382

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

397

398 }

399

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 )