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

14import array 

15import struct 

16 

17from impacket.ImpactPacket import array_tobytes 

18from impacket.helper import ProtocolPacket, Byte, Bit 

19from functools import reduce 

20 

21 

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

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

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

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

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

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

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

251class AuthTypeFlag(object): 

252 OPEN = 0x0001 

253 WPAPSK = 0x0002 

254 SHARED = 0x0004 

255 WPA = 0x0008 

256 WPA2 = 0x0010 

257 WPA2PSK = 0x0020 

258 

259AuthTypeFlag_ALL = AuthTypeFlag.OPEN | \ 

260 AuthTypeFlag.WPAPSK | \ 

261 AuthTypeFlag.SHARED | \ 

262 AuthTypeFlag.WPA | \ 

263 AuthTypeFlag.WPA2 | \ 

264 AuthTypeFlag.WPA2PSK 

265 

266class EncryptionTypeFlag(object): 

267 NONE = 0x0001 

268 WEP = 0x0002 

269 TKIP = 0x0004 

270 AES = 0x0008 

271 

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

273 

274class ConnectionTypeFlag(object): 

275 ESS = 0x01 

276 IBSS = 0x02 

277 

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 

288 

289 

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 

297 

298class AssocState(object): 

299 NOT_ASSOC = 0 

300 CONN_SUCCESS = 1 

301 CFG_FAILURE = 2 

302 FAILURE = 3, 

303 IP_FAILURE = 4 

304 

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 

325 

326class DevicePasswordId(object): 

327 DEFAULT = 0x0000 

328 USER_SPECIFIED = 0x0001 

329 MACHINE_SPECIFIED = 0x0002 

330 REKEY = 0x0003 

331 PUSHBUTTON = 0x0004 

332 REGISTRAR_SPECIFIED = 0x0005 

333 

334class WpsState(object): 

335 NOT_CONFIGURED = 0x01 

336 CONFIGURED = 0x02 

337 

338 

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