Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
PowerShell-scripts, zoals andere programmeertalen, kunnen kwetsbaar zijn voor injectieaanvallen. Een injectieaanval treedt op wanneer een gebruiker invoer levert aan een kwetsbare functie die extra opdrachten bevat. De kwetsbare functie voert de extra opdrachten uit, wat een ernstig beveiligingsprobleem kan zijn. Een kwaadwillende gebruiker kan bijvoorbeeld misbruik maken van de kwetsbare functie om willekeurige code uit te voeren op een externe computer, waardoor deze computer mogelijk in gevaar komt en toegang krijgt tot andere computers in het netwerk.
Zodra u op de hoogte bent van het probleem, zijn er verschillende manieren om te beschermen tegen injectieaanvallen.
Voorbeeld van kwetsbare code
PowerShell-code-injectieproblemen omvatten gebruikersinvoer die scriptcode bevat. De gebruikersinvoer wordt toegevoegd aan een kwetsbaar script waar het wordt geparseerd en uitgevoerd door PowerShell.
function Get-ProcessById
{
param ($ProcId)
Invoke-Expression -Command "Get-Process -Id $ProcId"
}
De Get-ProcessById
functie zoekt een lokaal proces op met de id-waarde. Er wordt een $ProcId
parameterargument van elk type gebruikt. De $ProcId
wordt vervolgens geconverteerd naar een tekenreeks en ingevoegd in een ander script dat wordt geparseerd en uitgevoerd met behulp van de Invoke-Expression
cmdlet. Deze functie werkt prima wanneer een geldig proces-id-geheel getal wordt doorgegeven.
Get-ProcessById $PID
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
97 50.09 132.72 1.20 12528 3 pwsh
De $ProcId
parameter geeft echter geen type op. Hiermee wordt elke willekeurige tekenreekswaarde geaccepteerd die andere opdrachten kan bevatten.
Get-ProcessById "$PID; Write-Host 'pwnd!'"
In dit voorbeeld heeft functie het proces dat is geïdentificeerd, correct opgehaald $PID
, maar ook het geïnjecteerde script uitgevoerd Write-Host 'pwnd!'
.
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
92 45.66 122.52 1.06 21736 3 pwsh
pwnd!
Manieren om te beschermen tegen injectieaanvallen
De zijn verschillende manieren om te beschermen tegen een injectieaanval.
Getypte invoer gebruiken
U kunt een type opgeven voor het $ProcId
argument.
function Get-ProcessById
{
param ([int] $ProcId)
Invoke-Expression -Command "Get-Process -Id $ProcId"
}
Get-ProcessById "$PID; Write-Host 'pwnd!'"
Get-ProcessById:
Line |
7 | Get-ProcessById "$PID; Write-Host 'pwnd!'"
| ~~~~~~~~~~~~~~~~~~~~~~~~~
| Cannot process argument transformation on parameter 'ProcId'. Cannot convert value
"8064; Write-Host 'pwnd!'" to type "System.Int32". Error: "The input string '8064; Write-Host 'pwnd!'
was not in a correct format."
Hier is de $ProcId
invoerparameter beperkt tot een geheel getaltype, dus er treedt een fout op wanneer een tekenreeks wordt doorgegeven die niet kan worden geconverteerd naar een geheel getal.
Niet gebruiken Invoke-Expression
In plaats van Invoke-Expression
te gebruiken, roep direct Get-Process
aan, en laat de parameterbinder van PowerShell de invoer valideren.
function Get-ProcessById
{
param ($ProcId)
Get-Process -Id $ProcId
}
Get-ProcessById "$PID; Write-Host 'pwnd!'"
Get-Process:
Line |
5 | Get-Process -Id $ProcId
| ~~~~~~~
| Cannot bind parameter 'Id'. Cannot convert value "8064; Write-Host 'pwnd!'" to type
"System.Int32". Error: "The input string '8064; Write-Host 'pwnd!' was not in a correct
format."
Als best practice moet u het gebruik Invoke-Expression
vermijden, met name bij het verwerken van gebruikersinvoer.
Invoke-Expression
is gevaarlijk omdat het elke tekenreeksinhoud die u opgeeft parseert en uitvoert, waardoor het kwetsbaar is voor injectieaanvallen. Het is beter om te vertrouwen op PowerShell-parameterbinding.
Tekenreeksen verpakken in enkele aanhalingstekens
Er zijn echter momenten waarop het gebruik Invoke-Expression
onvermijdelijk is en u ook invoer van gebruikersreeksen moet verwerken. U kunt gebruikersinvoer veilig verwerken met enkele aanhalingstekens rond elke tekenreeksinvoervariabele. Het enkele aanhalingsteken zorgt ervoor dat de PowerShell-parser de gebruikersinvoer als één letterlijke tekenreeks behandelt.
function Get-ProcessById
{
param ($ProcId)
Invoke-Expression -Command "Get-Process -Id '$ProcId'"
}
Get-ProcessById "$PID; Write-Host 'pwnd!'"
Get-Process: Cannot bind parameter 'Id'. Cannot convert value "8064; Write-Host " to type
"System.Int32". Error: "The input string '8064; Write-Host' was not in a correct format."
Deze versie van de functie is echter nog niet volledig veilig tegen injectieaanvallen. Een kwaadwillende gebruiker kan nog steeds enkele aanhalingstekens gebruiken in hun invoer om code in te voeren.
Get-ProcessById "$PID'; Write-Host 'pwnd!';'"
In dit voorbeeld worden enkele aanhalingstekens in de invoer van de gebruiker gebruikt om te forceren dat de functie drie afzonderlijke instructies uitvoert, waarvan een willekeurige code is die door de gebruiker is geïnjecteerd.
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
97 46.08 183.10 1.08 2524 3 pwsh
pwnd!
Gebruik de EscapeSingleQuotedStringContent()
-methode
Als u de gebruiker wilt beschermen tegen het invoegen van hun eigen enkele aanhalingstekens om gebruik te maken van de functie, moet u de EscapeSingleQuotedStringContent()
API gebruiken. Dit is een statische openbare methode van de klasse PowerShell System.Management.Automation.Language.CodeGeneration . Deze methode maakt de invoer van de gebruiker veilig door enkele aanhalingsteken in de gebruikersinvoer te escapen.
function Get-ProcessById
{
param ($ProcId)
$ProcIdClean = [System.Management.Automation.Language.CodeGeneration]::
EscapeSingleQuotedStringContent("$ProcId")
Invoke-Expression -Command "Get-Process -Id '$ProcIdClean'"
}
Get-ProcessById "$PID'; Write-Host 'pwnd!';'"
Get-Process: Cannot bind parameter 'Id'. Cannot convert value "8064'; Write-Host 'pwnd!';'" to type
"System.Int32". Error: "The input string '8064'; Write-Host 'pwnd!';'' was not in a correct format."
Zie EscapeSingleQuotedStringContent()voor meer informatie.
Kwetsbare code detecteren met Injection Hunter
Injection Hunter is een module geschreven door Lee Holmes die PowerShell Script Analyzer-regels bevat voor het detecteren van beveiligingsproblemen met code-injectie. Gebruik een van de volgende opdrachten om de module te installeren vanuit de PowerShell Gallery:
# Use PowerShellGet v2.x
Install-Module InjectionHunter
# Use PowerShellGet v3.x
Install-PSResource InjectionHunter
U kunt dit gebruiken om beveiligingsanalyses te automatiseren tijdens builds, processen voor continue integratie, implementaties en andere scenario's.
$RulePath = (Get-Module -List InjectionHunter).Path
Invoke-ScriptAnalyzer -CustomRulePath $RulePath -Path .\Invoke-Dangerous.ps1
RuleName Severity ScriptName Line Message
-------- -------- ---------- ---- -------
InjectionRisk.InvokeExpression Warning Invoke-Dan 3 Possible script injection risk via the
gerous.ps1 Invoke-Expression cmdlet. Untrusted input can cause
arbitrary PowerShell expressions to be run.
Variables may be used directly for dynamic parameter
arguments, splatting can be used for dynamic
parameter names, and the invocation operator can be
used for dynamic command names. If content escaping
is truly needed, PowerShell has several valid quote
characters, so [System.Management.Automation.Languag
e.CodeGeneration]::Escape* should be used.
Zie PSScriptAnalyzer voor meer informatie.