Skip to content

Commit

Permalink
fix wifi problem
Browse files Browse the repository at this point in the history
  • Loading branch information
AlessandroZ committed Mar 18, 2018
1 parent 9c70f02 commit c6e72c2
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 54 deletions.
3 changes: 2 additions & 1 deletion Windows/lazagne/config/constant.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class constant():
st = None # standart output
drive = u'C'
dpapi = None
dpapi_hash = None
lsa_secrets = None
user_password = None
wifi_password = False # Check if the module as already be done
module_to_exec_at_end = []
27 changes: 27 additions & 0 deletions Windows/lazagne/config/dpapi_structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
from lazagne.config.write_output import print_debug
from lazagne.config.constant import *
import traceback
import ctypes
import os
from lazagne.softwares.windows.lsa_secrets import LSASecrets

class Decrypt_DPAPI():
def __init__(self, password=None, pwdhash=None):
Expand Down Expand Up @@ -43,6 +45,22 @@ def __init__(self, password=None, pwdhash=None):
for r in self.umkp.try_credential_hash(self.sid, pwdhash=pwdhash.decode('hex')):
print_debug('INFO', r)

# System Information

if ctypes.windll.shell32.IsUserAnAdmin() != 0: # Need admin priv
if not constant.lsa_secrets:
# Retrieve LSA secrets
LSASecrets().run()

if constant.lsa_secrets:
masterkeydir = u'C:\\Windows\\System32\\Microsoft\\Protect\\S-1-5-18\\User'
if os.path.exists(masterkeydir):
self.smkp = MasterKeyPool()
self.smkp.load_directory(masterkeydir)
self.smkp.add_system_credential(constant.lsa_secrets['DPAPI_SYSTEM'])
for r in self.smkp.try_system_credential():
print_debug('INFO', r)

def check_credentials(self, passwords):
if self.umkp:
for password in passwords:
Expand Down Expand Up @@ -97,3 +115,12 @@ def get_cleartext_password(self):
"""
if self.umkp:
return self.umkp.get_cleartext_password()

def decrypt_wifi_blob(self, key_material):
"""
Decrypt wifi password
"""
if self.smkp:
blob = DPAPIBlob(key_material.decode('hex'))
ok, msg = blob.decrypt_encrypted_blob(mkp=self.smkp)
return self.manage_response(ok, msg)
122 changes: 72 additions & 50 deletions Windows/lazagne/softwares/wifi/wifi.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from lazagne.config.write_output import print_debug
from lazagne.config.moduleInfo import ModuleInfo
from lazagne.config.dpapi_structure import *
from lazagne.config.winstructure import *
from lazagne.config.constant import *
import xml.etree.cElementTree as ET
Expand All @@ -11,61 +12,82 @@
class Wifi(ModuleInfo):
def __init__(self):
ModuleInfo.__init__(self, 'Wifi', 'wifi', dpapi_used=True)

def decrypt_using_lsa_secret(self, key):
"""
Needs admin priv but will work with all systems
"""
if not constant.dpapi:
constant.dpapi = Decrypt_DPAPI(password=constant.user_password)
return constant.dpapi.decrypt_wifi_blob(key)

def decrypt_using_netsh(self, ssid):
"""
Does not need admin priv but would work only with english and french systems
"""
print_debug('DEBUG', u'[!] Try using netsh method')
process = Popen(['netsh.exe', 'wlan', 'show', 'profile', '{SSID}'.format(SSID=ssid), 'key=clear'], stdout=PIPE, stderr=PIPE)
stdout, stderr = process.communicate()
for st in stdout.split('\n'):
if 'key content' in st.lower() or 'contenu de la cl' in st.lower():
password = st.split(':')[1].strip()
return passwords


def run(self, software_name=None):

directory = os.path.join(constant.profile['ALLUSERSPROFILE'], u'Microsoft\Wlansvc\Profiles\Interfaces')
if not constant.wifi_password:
dpapi = constant.dpapi if constant.dpapi is not None else Decrypt_DPAPI(password=constant.user_password)

# for windows Vista or higher
if os.path.exists(directory):
interfaces_dir = os.path.join(constant.profile['ALLUSERSPROFILE'], u'Microsoft\Wlansvc\Profiles\Interfaces')

passwordFound = False
rep = []
pwdFound = []
for repository in os.listdir(directory):
if os.path.isdir(directory + os.sep + repository):

rep = directory + os.sep + repository
for file in os.listdir(rep):
values = {}
if os.path.isfile(rep + os.sep + file):
f = rep + os.sep + file
tree = ET.ElementTree(file=f)
root = tree.getroot()
xmlns = root.tag.split("}")[0] + '}'

iterate = False
for elem in tree.iter():
if elem.tag.endswith('SSID'):
for w in elem:
if w.tag == xmlns + 'name':
values['SSID'] = w.text
# for windows Vista or higher
if os.path.exists(interfaces_dir):

repository = []
pwdFound = []

for wifi_dir in os.listdir(interfaces_dir):
if os.path.isdir(os.path.join(interfaces_dir, wifi_dir)):

repository = os.path.join(interfaces_dir, wifi_dir)
for file in os.listdir(repository):
values = {}
if os.path.isfile(os.path.join(repository, file)):
f = os.path.join(repository, file)
tree = ET.ElementTree(file=f)
root = tree.getroot()
xmlns = root.tag.split("}")[0] + '}'

if elem.tag.endswith('authentication'):
values['Authentication'] = elem.text
for elem in tree.iter():
if elem.tag.endswith('SSID'):
for w in elem:
if w.tag == xmlns + 'name':
values['SSID'] = w.text

if elem.tag.endswith('protected'):
values['Protected'] = elem.text

if elem.tag.endswith('keyMaterial'):
key = elem.text
try:
binary_string = binascii.unhexlify(key)
if elem.tag.endswith('authentication'):
values['Authentication'] = elem.text

# need to have system privilege, to use this technic
password = Win32CryptUnprotectData(binary_string)
if not password:
print_debug('DEBUG', u'[!] Try using netsh method')
process = Popen(['netsh.exe', 'wlan', 'show', 'profile', '{SSID}'.format(SSID=values['SSID']), 'key=clear'], stdout=PIPE, stderr=PIPE)
stdout, stderr = process.communicate()
st = stdout.split('-------------')[4].split('\n')[6]
password = st.split(':')[1].strip()

values['Password'] = password
passwordFound = True
except:
values['INFO'] = '[!] Password not found.'

if values and values['Authentication'] != 'open':
pwdFound.append(values)
return pwdFound
if elem.tag.endswith('protected'):
values['Protected'] = elem.text

if elem.tag.endswith('keyMaterial'):
key = elem.text
try:
password = self.decrypt_using_lsa_secret(key=key)
if not password:
password = self.decrypt_using_netsh(ssid=values['SSID'])

if password:
values['Password'] = password
else:
values['INFO'] = '[!] Password not found.'
except Exception, e:
print e
values['INFO'] = '[!] Password not found.'

if values and values['Authentication'] != 'open':
pwdFound.append(values)

constant.wifi_password = True
return pwdFound
21 changes: 18 additions & 3 deletions Windows/lazagne/softwares/windows/lsa_secrets.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import tempfile
import random
import string
import struct
import os

class LSASecrets(ModuleInfo):
Expand All @@ -31,18 +32,32 @@ def run_cmd(self, cmdline):
info = subprocess.STARTUPINFO()
info.dwFlags = sub.STARTF_USESHOWWINDOW
info.wShowWindow = sub.SW_HIDE
p = subprocess.Popen(command, startupinfo=info, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, universal_newlines=True)
results, _ = p.communicate()
p = subprocess.Popen(command, startupinfo=info, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, universal_newlines=True)
results, _ = p.communicate()

def run(self, software_name=None):

# DPAPI structure could compute lsa secrets as well, so do not do it again
if constant.lsa_secrets:
return ['__LSASecrets__', constant.lsa_secrets]

if self.save_hives():

isVistaOrHigher = False
if float(get_os_version()) >= 6.0:
isVistaOrHigher = True

# get LSA Secrets
# Get LSA Secrets
secrets = get_file_secrets(constant.hives['system'], constant.hives['security'], isVistaOrHigher)
if secrets:

# Clear DPAPI master key
clear = secrets['DPAPI_SYSTEM']
size = struct.unpack_from("<L", clear)[0]
secrets['DPAPI_SYSTEM'] = clear[16:16+44]

# Keep value to be reused in other module (e.g wifi)
constant.lsa_secrets = secrets

pwdFound = ['__LSASecrets__', secrets]
return pwdFound

0 comments on commit c6e72c2

Please sign in to comment.