Войти

Показать полную графическую версию : [решено] Восстановление пароля от wifi точки доступа


jkadaba
27-08-2017, 07:52
На просторах инета видел как это можно сделать с помощью команды netsh, но этот способ меня не устраивает по двум причинам. Если не экспортировать данные в xml, данные выводимые netsh локализависимы, мне же нужно чтобы одинаково хорошо работало в системе как с русской локалью, так с какой-либо другой (английской, немецкой, да хоть с китайской). Если же экспортировать предварительно данные в xml, проблема с локалью отпадает, но возникает проблема временного файла. Отсюда вопрос, существуют ли альтернативные способы решения задачи?

Kazun
27-08-2017, 10:45
Использовать WinApi - https://msdn.microsoft.com/en-us/library/windows/desktop/aa816369(v=vs.85).aspx

https://blogs.technet.microsoft.com/heyscriptingguy/2017/01/13/view-passwords-of-wireless-profiles-without-using-netsh-exe/

https://msdnshared.blob.core.windows.net/media/2017/01/4-HSG-011317.png

greg zakharov
27-08-2017, 12:19
Использовать WinApi
WLAN API по своей сути обращается к профилю хранящемуся на жестком диске виде обычного xml-документа ($env:allusersprofile\Microsoft\Wlansvc\Profiles\Interfaces\{interface_GUID}\{profile_GUID}.xml) в случае Windows >= 6.x или же к разделу реестра HKLM\SOFTWARE\Microsoft\WZCSVC\Parameters\Interfaces\{interface_GUID}), причем в последнем случае данные представлены в бинарном виде. Но так как упомянался netsh, речь скорее о первом случае, то есть Windows < 6.x отметаем и фокусируемся на xml. Пароль в xml хранится в узле keyMaterials в зашифрованном виде, расшифровать его можно, например, так:
#requires -RunAsAdministrator
<#
Author: greg zakharov
License: BSD 3-Clause
Dependencies: none

This code is hardcoded alternative for
netsh wlan show profile name="PROFILE" key=clear
#>
function Set-Delegate {
[CmdletBinding()]
param(
[Parameter(Mandatory, Position=0)]
[ValidateScript({$_ -ne [IntPtr]::Zero})]
[IntPtr]$ProcAddress,

[Parameter(Mandatory, Position=1)]
[ValidateNotNull()]
[Type]$Prototype,

[Parameter(Position=2)]
[ValidateNotNullOrEmpty()]
[Runtime.InteropServices.CallingConvention]
$CallingConvention = 'StdCall'
)

$method = $Prototype.GetMethod('Invoke')
$returntype, $paramtypes = $method.ReturnType, $method.GetParameters().ParameterType
$holder = New-Object Reflection.Emit.DynamicMethod(
'Invoke', $returntype, $(if (!$paramtypes) { $null } else { $paramtypes }), $Prototype
)
$il = $holder.GetILGenerator()

if ($paramtypes) {
(0..($paramtypes.Length - 1)).ForEach{$il.Emit([Reflection.Emit.OpCodes]::Ldarg, $_)}
}

switch ([IntPtr]::Size) {
4 { $il.Emit([Reflection.Emit.OpCodes]::Ldc_I4, $ProcAddress.ToInt32()) }
8 { $il.Emit([Reflection.Emit.OpCodes]::Ldc_I8, $ProcAddress.ToInt64()) }
}
$il.EmitCalli(
[Reflection.Emit.OpCodes]::Calli, $CallingConvention, $returntype,
$(if (!$paramtypes) { $null } else { $paramtypes })
)
$il.Emit([Reflection.Emit.OpCodes]::Ret)

$holder.CreateDelegate($Prototype)
}

function New-Delegate {
[CmdletBinding()]
param(
[Parameter(Mandatory, Position=0)]
[ValidateNotNullOrEmpty()]
[String]$Module,

[Parameter(Mandatory, Position=1)]
[ValidateNotNull()]
[Hashtable]$Signature
)

begin {
function private:Get-ProcAddress {
[OutputType([Hashtable])]
param(
[Parameter(Mandatory, Position=0)]
[ValidateNotNullOrEmpty()]
[String]$Module,

[Parameter(Mandatory, Position=1)]
[ValidateNotNull()]
[String[]]$Function
)

begin {
[Object].Assembly.GetType('Microsoft.Win32.Win32Native').GetMethods(
[Reflection.BindingFlags]'Static, NonPublic'
).Where{$_.Name -cmatch '\AGet(ProcA|ModuleH)'}.ForEach{ Set-Variable $_.Name $_ }

if (($mod = $GetModuleHandle.Invoke($null, @($Module))) -eq [IntPtr]::Zero) {
throw New-Object InvalidOperationException('Could not find specified module.')
}
}
process {}
end {
$table = @{}
$Function.ForEach{ if (($$ = $GetProcAddress.Invoke(
$null, @($mod, $_)
)) -ne [IntPtr]::Zero) { $table.$_ = $$ } }
$table
}
}
}
process {}
end {
$scope, $fname = @{}, (Get-ProcAddress $Module $Signature.Keys)
$fname.Keys.ForEach{ $scope.$_ = Set-Delegate $fname.$_ $Signature.$_ }
$scope
}
}

function Get-WlanProfiles {
if (!($ifaces = (Get-ChildItem "$(
$env:allusersprofile
)\Microsoft\Wlansvc\Profiles\Interfaces" -ErrorAction 0).FullName)) {
throw 'WLAN profile(s) has not been found'
}

$profiles = @{}
$ifaces.ForEach{Get-ChildItem $_}.FullName.ForEach{
[xml]$xml = Get-Content $_
$key = $xml.WLANProfile.MSM.security.sharedKey.keyMaterial
$profiles[$xml.WLANProfile.name] = [Linq.Enumerable]::Range(
0, $key.Length
).Where{$_ % 2 -eq 0}.ForEach{[Convert]::ToByte($key.Substring($_, 2), 16)}
}
$profiles
}

function Unprotect-WlanProfiles {
begin {
[Regex].Assembly.GetType('Microsoft.Win32.NativeMethods').GetMethods().Where{
$_.Name -cmatch '\AOpenProc.*' # OpenProcess and OpenProcessToken
}.ForEach{ Set-Variable $_.Name $_ }

$ntdll = New-Delegate ntdll -Signature @{ # SeDebugPrivilege = 20
RtlAdjustPrivilege = [Func[UInt32, Boolean, Boolean, Text.StringBuilder, Int32]]
RtlGetNtVersionNumbers = [Action[[Byte[]], [Byte[]], [Byte[]]]]
}

$advapi32 = New-Delegate advapi32 -Signature @{
ImpersonateLoggedOnUser = [Func[IntPtr, Boolean]]
RevertToSelf = [Func[Boolean]]
}

$CloseHandle = [Object].Assembly.GetType('Microsoft.Win32.Win32Native').GetMethod(
'CloseHandle', [Reflection.BindingFlags]'Static, NonPublic'
)
}
process {
('mj', 'mn', 'bl').ForEach{ Set-Variable $_ ([Byte[]]@(0, 0, 0, 0)) }
$ntdll.RtlGetNtVersionNumbers.Invoke($mj, $mn, $bl)
$mj, $mn, $bl = ($mj, $mn, $bl).ForEach{ [BitConverter]::ToUInt32($_, 0) }

if ($mj -le 6) {
throw 'This requires Windows Vista or higher'
}
}
end {
$enabled = New-Object Text.StringBuilder
if ($ntdll.RtlAdjustPrivilege.Invoke(20, $true, $false, $enabled) -ne 0) {
throw 'Could not take SeDebugPrivilege for current host'
}

try {
if (($sph = $OpenProcess.Invoke($null, @(0x2000000, $false, (
Get-Process winlogon
).Id))).IsInvalid) { throw 'OpenProcess failed' }

$hrf, $tkn = (New-Object Runtime.InteropServices.HandleRef(
(New-Object IntPtr), $sph.DangerousGetHandle()
)), [IntPtr]::Zero
if (!$OpenProcessToken.Invoke($null, ($par = [Object[]]@($hrf, 0x2000000, $tkn)))) {
throw 'OpenProcessToken failed'
}

if (!$advapi32.ImpersonateLoggedOnUser.Invoke($par[2])) {
throw 'ImpersonateLoggedOnUser failed'
}

Add-Type -AssemblyName System.Security
($profiles = Get-WlanProfiles).Keys.ForEach{
New-Object PSObject -Property @{
SSID = $_
Password = [Text.Encoding]::Default.GetString(
[Security.Cryptography.ProtectedData]::Unprotect(
$profiles.$_, $null, [Security.Cryptography.DataProtectionScope]::LocalMachine
)
)
} | Select-Object SSID, Password
}
}
catch { $_ }
finally {
[void]$advapi32.RevertToSelf.Invoke()
[void]$CloseHandle.Invoke($null, @($par[2]))
if ($sph) { $sph.Dispose() }
}
}
}
Этот пример требует прав администратора, но может со временем перепишу его, что это требование станет необязательным.
Оригинальный код (https://github.com/gregzakh/ps5/blob/master/Scripts/Unprotect-WlanProfiles.ps1)

jkadaba
28-08-2017, 12:16
Спасибо, ребят! Буду разбираться.




© OSzone.net 2001-2012