Hide keyboard shortcuts

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 

16import array 

17import struct 

18 

19from impacket.ImpactPacket import array_tobytes 

20from impacket.helper import ProtocolPacket, Byte, Bit 

21from functools import reduce 

22 

23 

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

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

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

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

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

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

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

253class AuthTypeFlag(object): 

254 OPEN = 0x0001 

255 WPAPSK = 0x0002 

256 SHARED = 0x0004 

257 WPA = 0x0008 

258 WPA2 = 0x0010 

259 WPA2PSK = 0x0020 

260 

261AuthTypeFlag_ALL = AuthTypeFlag.OPEN | \ 

262 AuthTypeFlag.WPAPSK | \ 

263 AuthTypeFlag.SHARED | \ 

264 AuthTypeFlag.WPA | \ 

265 AuthTypeFlag.WPA2 | \ 

266 AuthTypeFlag.WPA2PSK 

267 

268class EncryptionTypeFlag(object): 

269 NONE = 0x0001 

270 WEP = 0x0002 

271 TKIP = 0x0004 

272 AES = 0x0008 

273 

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

275 

276class ConnectionTypeFlag(object): 

277 ESS = 0x01 

278 IBSS = 0x02 

279 

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 

290 

291 

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 

299 

300class AssocState(object): 

301 NOT_ASSOC = 0 

302 CONN_SUCCESS = 1 

303 CFG_FAILURE = 2 

304 FAILURE = 3, 

305 IP_FAILURE = 4 

306 

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 

327 

328class DevicePasswordId(object): 

329 DEFAULT = 0x0000 

330 USER_SPECIFIED = 0x0001 

331 MACHINE_SPECIFIED = 0x0002 

332 REKEY = 0x0003 

333 PUSHBUTTON = 0x0004 

334 REGISTRAR_SPECIFIED = 0x0005 

335 

336class WpsState(object): 

337 NOT_CONFIGURED = 0x01 

338 CONFIGURED = 0x02 

339 

340 

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