Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Восстановление пароля от wifi точки доступа (http://forum.oszone.net/showthread.php?t=329351)

jkadaba 27-08-2017 07:52 2760905

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

Kazun 27-08-2017 10:45 2760914

Использовать WinApi - https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

https://blogs.technet.microsoft.com/...ing-netsh-exe/


greg zakharov 27-08-2017 12:19 2760923

Цитата:

Цитата Kazun
Использовать 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() }
    }
  }
}

Этот пример требует прав администратора, но может со временем перепишу его, что это требование станет необязательным.
Оригинальный код

jkadaba 28-08-2017 12:16 2761111

Спасибо, ребят! Буду разбираться.


Время: 22:50.

Время: 22:50.
© OSzone.net 2001-