Key Value -------- FilePath notepad ArgumentList {c:\test}
PS> sudo ping 127.0.0.1-n1
Key Value -------- FilePath ping ArgumentList {127.0.0.1, -n, 1}
Now that the sudo function body works, in part 2 we look at the actual implantation of running commands elevated. 现在,sudo 函数体能正常工作,在第二部分中,我们将学习实际注入一个函数并提升权限。
# path to a digitally signed file (adjust path to an existing signed ps1 file): $Path = "$env:temp\test.ps1" $Status = Get-AuthenticodeSignature-FilePath$Path | Select-Object-Property * $Status
结果类似这样:
SignerCertificate : [Subject]
CN=MyPowerShellCode
[Issuer]
CN=MyPowerShellCode
[Serial Number]
1B98E986A1D7BCB245034A0225381CA4
[Not Before]
01.05.2022 17:39:56
[Not After]
01.05.2027 17:49:56
[Thumbprint]
F4C1F9978D564E143D554F3679746B3A79E1FF87
TimeStamperCertificate :
Status : UnknownError
StatusMessage : A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider
Path : C:\Users\tobia\AppData\Local\Temp\test.ps1
SignatureType : Authenticode
IsOSBinary : False
# digitally sign this file (adjust path to an existing ps1 file): $Path = "$env:temp\test.ps1"
# adjust this path to point to a valid code signing certificate: $CertPath = 'Cert:\CurrentUser\my\F4C1F9978D564E143D554F3679746B3A79E1FF87'
# if it does not exist, create a dummy file $exists = Test-Path-Path$Path if ($exists-eq$false) { 'Hello World!' | Set-Content-Path$Path-Encoding UTF8 }
# read a code signing certificate to use for signing: $myCert = Get-Item-Path$CertPath
# add a digital signature to a PS script file: Set-AuthenticodeSignature-FilePath$Path-Certificate$myCert
# show changes inside script file: notepad $Path
运行此代码时,在 $Path 中指定的脚本文件将打开并显示添加到脚本底部的数字签名:
Hello World!
# SIG # Begin signature block
# MIIFcAYJKoZIhvcNAQcCoIIFYTCCBV0CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU4QK+x7NLicgrIdzN+Nvxqbuq
# Qv2gggMKMIIDBjCCAe6gAwIBAgIQG5jphqHXvLJFA0oCJTgcpDANBgkqhkiG9w0B
...
# hiding errors: $ErrorActionPreference = 'SilentlyContinue' # telling all cmdlets to use a private variable for error logging: $PSDefaultParameterValues.Add('*:ErrorVariable', '+myErrors') # initializing the variable: $myErrors = $null
# do stuff: Stop-Service-Name Spooler dir c:\gibtsnichtabc
# check errors at end USING PRIVATE VARIABLE: $myErrors.Count $myErrors | Out-GridView
# the ID you picked when saving the options: $id = 5388
# the name of the reg value that stores your choices: $flag = "StateFlags$id"
# the location where user choices are stored: $path = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\*"
# get all subkeys where your user choice was enabled: Get-Item-Path$path | Where-Object { $_.Property -contains$flag } # contains your registry value (StateFlags5388) Where-Object { $_.GetValue($flag) -gt0 } # your registry value contains a number greater than 0
Get-PnpDevice-Class Bluetooth | Where-Object HardwareID -match'DEV_' | Select-Object FriendlyName, $Address | Where-Object Address | Out-GridView-Title'Select Bluetooth Device to Remove'-OutputMode Single
functionUnpair-Bluetooth { # take a UInt64 either directly or as part of an object with a property # named "DeviceAddress" or "Address" param ( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] [Alias('Address')] [UInt64] $DeviceAddress )
# tell PowerShell the location of the internal Windows API # and define a static helper function named "Unpair" that takes care # of creating the needed arguments: begin { Add-Type-Namespace"Devices"-Name'Bluetooth'-MemberDefinition' [DllImport("BluetoothAPIs.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)] [return: MarshalAs(UnmanagedType.U4)] static extern UInt32 BluetoothRemoveDevice(IntPtr pAddress); public static UInt32 Unpair(UInt64 BTAddress) { GCHandle pinnedAddr = GCHandle.Alloc(BTAddress, GCHandleType.Pinned); IntPtr pAddress = pinnedAddr.AddrOfPinnedObject(); UInt32 result = BluetoothRemoveDevice(pAddress); pinnedAddr.Free(); return result; }' }
# do this for every object that was piped into this function: process { $result = [Devices.Bluetooth]::Unpair($DeviceAddress) [PSCustomObject]@{ Success = $result-eq0 ReturnValue = $result } } }