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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 

# 

# This software is provided under under a slightly modified version 

# of the Apache Software License. See the accompanying LICENSE file 

# for more information. 

# 

# Description: 

# WPS packets 

# 

# Author: 

# Aureliano Calvo 

 

 

import array 

import struct 

 

from impacket.helper import ProtocolPacket, Byte, Bit 

from functools import reduce 

 

 

class ArrayBuilder(object): 

 

def from_ary(self, ary): 

return ary 

 

def to_ary(self, value): 

return array.array("B", value) 

 

class ByteBuilder(object): 

 

def from_ary(self, ary): 

return ary[0] 

 

def to_ary(self, value): 

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

 

class StringBuilder(object): 

def from_ary(self, ary): 

return ary.tostring() 

 

def to_ary(self, value): 

return array.array('B', value) 

 

class NumBuilder(object): 

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

 

def __init__(self, size): 

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

self.size = size 

 

def from_ary(self, ary): 

52 ↛ 53line 52 didn't jump to line 53, because the condition on line 52 was never true if len(ary) != self.size: 

raise Exception("Expected %s size but got %s" % (self.size, len(ary))) 

return reduce( lambda ac, x: ac * 256 + x, ary, 0) 

 

def to_ary(self, value0): 

value = value0 

rv = array.array('B') 

for _ in range(self.size): 

value, mod = divmod(value, 256) 

rv.append(mod) 

 

63 ↛ 64line 63 didn't jump to line 64, because the condition on line 63 was never true if value != 0: 

raise Exception("%s is too big. Max size: %s" % (value0, self.size)) 

 

rv.reverse() 

return rv 

 

class TLVContainer(object): 

 

def builder(self, kind): 

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

 

def from_ary(self, ary): 

i = 0 

while i<len(ary): 

kind = self.ary2n(ary, i) 

length = self.ary2n(ary, i+2) 

i+=4 

value = ary[i:i+length] 

self.elems.append((kind, value)) 

i += length 

 

return self 

 

def __init__(self, builders, default_builder = ArrayBuilder(), descs=None): 

self.builders = builders 

self.default_builder = default_builder 

self.elems = [] 

self.descs = descs or {} 

 

def append(self, kind, value): 

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

 

def __iter__(self): 

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

 

def all(self, kind): 

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

 

def __contains__(self, kind): 

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

 

def first(self, kind): 

return self.all(kind)[0] 

 

def to_ary(self): 

ary = array.array('B') 

for k,v in self.elems: 

ary.extend(self.n2ary(k)) 

ary.extend(self.n2ary(len(v))) 

ary.extend(v) 

 

return ary 

 

 

def get_packet(self): 

return self.to_ary().tostring() 

 

def set_parent(self, my_parent): 

self.__parent = my_parent 

 

def parent(self): 

return self.__parent 

 

def n2ary(self, n): 

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

 

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

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

 

def __repr__(self): 

def desc(kind): 

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

 

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

 

def child(self): 

return None 

 

class SCElem(object): 

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

 

AP_CHANNEL = 0x1001 

ASSOCIATION_STATE = 0x1002 

AUTHENTICATION_TYPE = 0x1003 

AUTHENTICATION_TYPE_FLAGS = 0x1004 

AUTHENTICATOR = 0x1005 

CONFIG_METHODS = 0x1008 

CONFIGURATION_ERROR = 0x1009 

CONFIRMATION_URL4 = 0x100A 

CONFIRMATION_URL6 = 0x100B 

CONNECTION_TYPE = 0X100C 

CONNECTION_TYPE_FLAGS = 0X100D 

CREDENTIAL = 0X100E 

DEVICE_NAME = 0x1011 

DEVICE_PASSWORD_ID = 0x1012 

E_HASH1 = 0x1014 

E_HASH2 = 0x1015 

E_SNONCE1 = 0x1016 

E_SNONCE2 = 0x1017 

ENCRYPTED_SETTINGS = 0x1018 

ENCRYPTION_TYPE = 0X100F 

ENCRYPTION_TYPE_FLAGS = 0x1010 

ENROLLEE_NONCE = 0x101A 

FEATURE_ID = 0x101B 

IDENTITY = 0X101C 

INDENTITY_PROOF = 0X101D 

KEY_WRAP_AUTHENTICATOR = 0x101E 

KEY_IDENTIFIER = 0X101F 

MAC_ADDRESS = 0x1020 

MANUFACTURER = 0x1021 

MESSAGE_TYPE = 0x1022 

MODEL_NAME = 0x1023 

MODEL_NUMBER = 0x1024 

NETWORK_INDEX = 0x1026 

NETWORK_KEY = 0x1027 

NETWORK_KEY_INDEX = 0x1028 

NEW_DEVICE_NAME = 0x1029 

NEW_PASSWORD = 0x102A 

OOB_DEVICE_PASSWORD = 0X102C 

OS_VERSION= 0X102D 

POWER_LEVEL = 0X102F 

PSK_CURRENT = 0x1030 

PSK_MAX = 0x1031 

PUBLIC_KEY = 0x1032 

RADIO_ENABLED = 0x1033 

REBOOT = 0x1034 

REGISTRAR_CURRENT = 0x1035 

REGISTRAR_ESTABLISHED = 0x1036 

REGISTRAR_LIST = 0x1037 

REGISTRAR_MAX = 0x1038 

REGISTRAR_NONCE = 0x1039 

REQUEST_TYPE = 0x103A 

RESPONSE_TYPE = 0x103B 

RF_BANDS = 0X103C 

R_HASH1 = 0X103D 

R_HASH2 = 0X103E 

R_SNONCE1 = 0X103F 

R_SNONCE2 = 0x1040 

SELECTED_REGISTRAR = 0x1041 

SERIAL_NUMBER = 0x1042 

WPS_STATE = 0x1044 

SSID = 0x1045 

TOTAL_NETWORKS = 0x1046 

UUID_E = 0x1047 

UUID_R = 0x1048 

VENDOR_EXTENSION = 0x1049 

VERSION = 0x104A 

X_509_CERTIFICATE_REQUEST = 0x104B 

X_509_CERTIFICATE = 0x104C 

EAP_IDENTITY = 0x104D 

MESSAGE_COUNTER = 0x104E 

PUBLIC_KEY_HASH = 0x104F 

REKEY_KEY = 0x1050 

KEY_LIFETIME = 0x1051 

PERMITTED_CONFIG_METHODS = 0x1052 

SELECTED_REGISTRAR_CONFIG_METHODS= 0x1053 

PRIMARY_DEVICE_TYPE = 0x1054 

SECONDARY_DEVICE_TYPE_LIST = 0x1055 

PORTABLE_DEVICE = 0x1056 

AP_SETUP_LOCKED = 0x1057 

APPLICATION_EXTENSION = 0x1058 

EAP_TYPE = 0x1059 

INITIALIZATION_VECTOR = 0x1060 

KEY_PROVIDED_AUTOMATICALLY = 0x1061 

_802_1X_ENABLED = 0x1062 

APP_SESSION_KEY = 0x1063 

WEP_TRANSMIT_KEY = 0x1064 

 

class MessageType(object): 

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

 

BEACON = 0x01 

PROBE_REQUEST = 0x02 

PROBE_RESPONSE = 0x03 

M1 = 0x04 

M2 = 0x05 

M2D = 0x06 

M3 = 0x07 

M4 = 0x08 

M5 = 0x09 

M6 = 0x0A 

M7 = 0x0B 

M8 = 0x0C 

WSC_ACK = 0x0D 

WSC_NACK = 0x0E 

WSC_DONE = 0x0F 

 

class AuthTypeFlag(object): 

OPEN = 0x0001 

WPAPSK = 0x0002 

SHARED = 0x0004 

WPA = 0x0008 

WPA2 = 0x0010 

WPA2PSK = 0x0020 

 

AuthTypeFlag_ALL = AuthTypeFlag.OPEN | \ 

AuthTypeFlag.WPAPSK | \ 

AuthTypeFlag.SHARED | \ 

AuthTypeFlag.WPA | \ 

AuthTypeFlag.WPA2 | \ 

AuthTypeFlag.WPA2PSK 

 

class EncryptionTypeFlag(object): 

NONE = 0x0001 

WEP = 0x0002 

TKIP = 0x0004 

AES = 0x0008 

 

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

 

class ConnectionTypeFlag(object): 

ESS = 0x01 

IBSS = 0x02 

 

class ConfigMethod(object): 

USBA = 0x0001 

ETHERNET = 0x0002 

LABEL = 0x0004 

DISPLAY = 0x0008 

EXT_NFC_TOKEN = 0x0010 

INT_NFC_TOKEN = 0x0020 

NFC_INTERFACE = 0x0040 

PUSHBUTTON = 0x0080 

KEYPAD = 0x0100 

 

 

class OpCode(object): 

WSC_START = 0x01 

WSC_ACK = 0x02 

WSC_NACK = 0x03 

WSC_MSG = 0x04 

WSC_DONE = 0x05 

WSC_FRAG_ACK = 0x06 

 

class AssocState(object): 

NOT_ASSOC = 0 

CONN_SUCCESS = 1 

CFG_FAILURE = 2 

FAILURE = 3, 

IP_FAILURE = 4 

 

class ConfigError(object): 

NO_ERROR = 0 

OOB_IFACE_READ_ERROR = 1 

DECRYPTION_CRC_FAILURE = 2 

_24_CHAN_NOT_SUPPORTED = 3 

_50_CHAN_NOT_SUPPORTED = 4 

SIGNAL_TOO_WEAK = 5 

NETWORK_AUTH_FAILURE = 6 

NETWORK_ASSOC_FAILURE = 7 

NO_DHCP_RESPONSE = 8 

FAILED_DHCP_CONFIG = 9 

IP_ADDR_CONFLICT = 10 

NO_CONN_TO_REGISTRAR = 11 

MULTIPLE_PBC_DETECTED = 12 

ROGUE_SUSPECTED = 13 

DEVICE_BUSY = 14 

SETUP_LOCKED = 15 

MSG_TIMEOUT = 16 

REG_SESS_TIMEOUT = 17 

DEV_PASSWORD_AUTH_FAILURE = 18 

 

class DevicePasswordId(object): 

DEFAULT = 0x0000 

USER_SPECIFIED = 0x0001 

MACHINE_SPECIFIED = 0x0002 

REKEY = 0x0003 

PUSHBUTTON = 0x0004 

REGISTRAR_SPECIFIED = 0x0005 

 

class WpsState(object): 

NOT_CONFIGURED = 0x01 

CONFIGURED = 0x02 

 

 

class SimpleConfig(ProtocolPacket): 

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

 

header_size = 2 

tail_size = 0 

 

op_code = Byte(0) 

flags = Byte(1) 

more_fragments = Bit(1, 0) 

length_field = Bit(1,1) 

 

BUILDERS = { 

SCElem.CONNECTION_TYPE: ByteBuilder(), 

SCElem.CONNECTION_TYPE_FLAGS: ByteBuilder(), 

SCElem.VERSION: ByteBuilder(), 

SCElem.MESSAGE_TYPE: ByteBuilder(), 

SCElem.NETWORK_INDEX: ByteBuilder(), 

SCElem.NETWORK_KEY_INDEX: ByteBuilder(), 

SCElem.POWER_LEVEL: ByteBuilder(), 

SCElem.PSK_CURRENT: ByteBuilder(), 

SCElem.PSK_MAX: ByteBuilder(), 

SCElem.REGISTRAR_CURRENT: ByteBuilder(), 

SCElem.REGISTRAR_MAX: ByteBuilder(), 

SCElem.REQUEST_TYPE: ByteBuilder(), 

SCElem.RESPONSE_TYPE: ByteBuilder(), 

SCElem.RF_BANDS: ByteBuilder(), 

SCElem.WPS_STATE: ByteBuilder(), 

SCElem.TOTAL_NETWORKS: ByteBuilder(), 

SCElem.VERSION: ByteBuilder(), 

SCElem.WEP_TRANSMIT_KEY: ByteBuilder(), 

 

SCElem.CONFIRMATION_URL4: StringBuilder(), 

SCElem.CONFIRMATION_URL6: StringBuilder(), 

SCElem.DEVICE_NAME: StringBuilder(), 

SCElem.IDENTITY: StringBuilder(), 

SCElem.MANUFACTURER: StringBuilder(), 

SCElem.MODEL_NAME: StringBuilder(), 

SCElem.MODEL_NUMBER: StringBuilder(), 

SCElem.NEW_DEVICE_NAME: StringBuilder(), 

SCElem.NEW_PASSWORD: StringBuilder(), 

SCElem.SERIAL_NUMBER: StringBuilder(), 

SCElem.EAP_IDENTITY: StringBuilder(), 

SCElem.NETWORK_KEY: StringBuilder(), 

 

SCElem.AP_CHANNEL: NumBuilder(2), 

SCElem.ASSOCIATION_STATE: NumBuilder(2), 

SCElem.AUTHENTICATION_TYPE: NumBuilder(2), 

SCElem.AUTHENTICATION_TYPE_FLAGS: NumBuilder(2), 

SCElem.CONFIG_METHODS: NumBuilder(2), 

SCElem.CONFIGURATION_ERROR: NumBuilder(2), 

SCElem.DEVICE_PASSWORD_ID: NumBuilder(2), 

SCElem.ENCRYPTION_TYPE: NumBuilder(2), 

SCElem.ENCRYPTION_TYPE_FLAGS: NumBuilder(2), 

SCElem.MESSAGE_COUNTER: NumBuilder(8), 

SCElem.KEY_LIFETIME: NumBuilder(4), 

SCElem.PERMITTED_CONFIG_METHODS: NumBuilder(2), 

SCElem.SELECTED_REGISTRAR_CONFIG_METHODS: NumBuilder(2), 

SCElem.PUBLIC_KEY: NumBuilder(192), 

 

} 

 

@classmethod 

def build_tlv_container(cls): 

return TLVContainer( 

builders=SimpleConfig.BUILDERS, 

descs = dict( (v,k) for (k,v) in SCElem.__dict__.items() ) 

)