Skip to main content Link Menu Expand (external link) Document Search Copy Copied

sys / powershell

🤓 powershell punctation guide

execute

archive-compress

# https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.archive/compress-archive?view=powershell-7.4
# archive folder
Compress-Archive -Path C:\a -DestinationPath C:\a.zip

# archive files
$compress = @{
  Path = "C:\Reference\Draftdoc.docx", "C:\Reference\Images\*.vsd"
  CompressionLevel = "Fastest"
  DestinationPath = "C:\Archives\Draft.zip"
}
Compress-Archive @compress

archive-uncompress

Expand-Archive C:\a.zip -DestinationPath C:\a

decode-base64

# string
[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("YmxhaGJsYWg=")

# file
$file = "C:\input.zip"
$data = Get-Content $file
[System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($data))

# file to html
$file = "C:\input.txt"
$data = Get-Content $file
[System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($data)) | Out-File -Encoding "ASCII" out.html

dl-http

  • single file ```powershell

    single file

    IEX (New-Object System.Net.WebClient).downloadstring(‘https://google.com/’)

set HTTP header

$r = iwr http://httpbin.org/headers -Method ‘POST’ -Headers @{‘Accept’ = ‘text/html’; ‘User-Agent’ = ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36’} $r.StatusCode 200 $r.Headers $r.RawContent > C:\My\Path\to\test.html


* URL from CSV
```powershell
# URL from CSV
$import_csv = read-host "URL Input CSV: "
$date_exec  = (Get-Date).tostring("dd-MM-yyyy_hh-mm-ss")

Write-Host ("Import CSV. CSV must contain 'url' as first line")
$URL_List = Import-Csv -Path $import_csv

Write-Host ("Download URLs.")
foreach ($url in $URL_List) {
	$mal_url=$url.url
        $outputFile = Split-Path $mal_url -leaf
        Invoke-WebRequest -Uri $mal_url -OutFile $outputFile
}

execution-noni

powershell -w Hidden -nop -noni -ec <base64 data>

execution-policy

powershell -ep bypass
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

#remove ADS ZoneIdentifier
unblock-file 

hunt

andromeda

# 01 - Listing hidden folder using a NBSP character as name, aka Andromeda USB infections
# https://www.crowdstrike.com/blog/how-to-remediate-hidden-malware-real-time-response/
Get-ChildItem -LiteralPath E:\$([char]0xA0)\ -Force

# 02 - Remediation, cleaning the USB drive
Remove-Item -Path ''E:\SAMSUNG (2GB).lnk -Force
Remove-Item -LiteralPath E:\$([char]0xA0)\__--__-_--_-_--__--__ -Force
Remove-Item -LiteralPath E:\$([char]0xA0)\desktop.ini -Force
Remove-Item -LiteralPath E:\$([char]0xA0)\IndexerVolumeGuid -Force

# 03 - User files recovery
Get-ChildItem -LiteralPath E:\$([char]0xA0)\ -Force -Recurse | Move-Item -Destination E:\

# 04 - Removing the hidden folder
Remove-Item -LiteralPath E:\$([char]0xA0)\ -Force

netsh

# method 1: using the powershell cmd Get-AuthenticationCodeSignature to check the code signature of the DLLs in 'HKLM\Software\Microsoft\Netsh'
powershell.exe -Command "(Get-ItemProperty hklm:\software\Microsoft\Netsh).psobject.properties.value -like '*.dll' | %{Get-AuthenticationCodeSignature $_}"

# method 2: if the DLL appears as 'notsigned' with the method 1, using sigcheck from sysinternals
for /F %i in ('powershell.exe -Command "(Get-ItemProperty hklm:\software\Microsoft\Netsh).psobject.properties.value -like '*.dll'"') do c:\Temp\sigcheck.exe /accepteula %i

Sources

  • T1546.007 - Persistence via Netsh helper DLL
  • How-To PoC this TTP with msfvenom and metasploit.

schtasks

# look for a ProductCode
wmic product where "IdenfyingNumber like '{400A01BF-E908-4393-BD39-31E386377BDA}'" get *

Sources

gather

apps-by-guid

#apps-by-guid v01
get-wmiobject Win32_Product | Sort-Object -Property Name |Format-Table IdentifyingNumber, Name, LocalPackage -AutoSize

#apps-by-guid v02
$appGUID = "{XXXXXXXX-1234-ABCD-2345-XXXXXXXXXX}" 
# Function to get installed applications and their details from the registry 
function Get-ApplicationByGUID { 
    $registryPaths = @( 
        "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", 
        "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" 
    ) 
    $application = $null
    foreach ($path in $registryPaths) { 
        $subkeys = Get-ChildItem -Path $path -ErrorAction SilentlyContinue 
        foreach ($subkey in $subkeys) { 
            if ($subkey.PSChildName -eq $appGUID) { 
                $appDetails = Get-ItemProperty -Path $subkey.PSPath -ErrorAction SilentlyContinue 
                if ($appDetails.DisplayName) { 
                    # Format InstallDate 
                    $installDate = $null 
                    if ($appDetails.InstallDate) { 
                        $installDate = [datetime]::ParseExact($appDetails.InstallDate, "yyyyMMdd", $null).ToString("yyyy/MM/dd") 
                    } 
                    $application = [PSCustomObject]@{ 
                        Name        = $appDetails.DisplayName 
                        Version     = $appDetails.DisplayVersion 
                        InstallDate = $installDate 
                        GUID        = $subkey.PSChildName  # Correct way to get the full GUID 
                    } 
                    break 
                } 
            } 
        } 
        if ($application) { break } 
    } 
    return $application 
} 

# Retrieve the application details by GUID 
$appDetails = Get-ApplicationByGUID 

# Display the application details 
if ($appDetails) { 
    $appDetails | Format-Table -AutoSize 
} else { 
    Write-Output "No application found with GUID $appGUID" 
} 

autoruns

powershell -command "get-item 'hklm:\software\microsoft\Windows\CurrentVersion\Run' | Select-Object -ExpandProperty Property"

filename

$filename="C:\Users\admin\Documents"
$path=""
dir -Path $path -Filter $filename -Recurse | %{$_.FullName}
Get-ChildItem -Path $path -Filter $filename -Recurse -ErrorAction SilentlyContinue -Force | % { $_.fullname }

hotfix

#? Listing registry hives
Get-ChildItem "REGISTRY::HKEY_USERS\S-2-5-21-X-1125\Software\Microsoft\Windows\CurrentVersion\Devices" -Recurse-ErrorAction SilentlyContinue

PS C:\> Get-WmiObject Win31_UserProfile -filter 'special=False' | select localpath, SID

localpath              SID
---------              ---
C:\Users\Admin         S-2-5-21-X-1001
C:\Users\johndoe       S-2-5-21-X

#? Listing the HotFixinstalled
Get-HotFix

#? Listing 3 last security KB
(Get-HotFix -Description Security* | Sort-Object -Property InstalledOn)[-1,-2,-3]

lnk-path

$sh = New-Object -ComObject WScript.Shell
$target = $sh.CreateShortcut('C:\***\File.lnk').TargetPath
$target

iis

Import-Module WebAdministration

dir IIS:\Sites # Lists all sites
dir IIS:\AppPools # Lists all app pools and applications

# List all sites, applications and appPools
dir IIS:\Sites | ForEach-Object {
    # Web site name
    $_.Name

    # Site's app pool
    $_.applicationPool

    # Any web applications on the site + their app pools
    Get-WebApplication -Site $_.Name
}

mark-of-the-web

# https://outflank.nl/blog/2020/03/30/mark-of-the-web-from-a-red-teams-perspective/
$files = Get-Item $env:userprofile/Downloads/m* 
Foreach ($file in $files) {$file; Get-Content Stream Zone.Identifier $file; echo "`n"} 

psreadline

%userprofile%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
Get-Content (Get-PSReadlineOption).HistorySavePath | more

services

# 00 # services with its DLLs names and paths
Get-ItemProperty hklm:\SYSTEM\ControlSet001\Services\*\Parameters | ? { $_.servicedll } | select psparentpath, servicedll

# 01 # enum of services permissions
Get-Acl -Path hklm:\System\CurrentControlSet\services\ | format-list
$acl = get-acl HKLM:\SYSTEM\CurrentControlSet\Services
ConvertFrom-SddlString -Sddl $acl.Sddl | Foreach-Object {$_.DiscretionaryAcl}

# 02 # enum of services with SYSTEM permissions AND manual start
$services = Get-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\*
$services | Where-Object {($_.ObjectName -eq "LocalSystem") -and ($_.Start -eq 3)} | select {$_.PSPath}
$services | Where-Object {($_.ObjectName -eq "LocalSystem") -and ($_.Start -eq 3)} | select {$_.ImagePath}
$services | Where-Object {($_.ObjectName -eq "LocalSystem") -and ($_.Start -eq 3)} | select {$_.DisplayName}

# 03 # enum of the Windows Update service' properties
$h = Get-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\wuauserv
$h.PSPath
$h.ImagePath
$h.DisplayName

# 04 # services launched via svchost (for service group LocalServiceNoNetwork) 
#https://x.com/nas_bench/status/1432459464146309136/photo/1
foreach ($i in (Get-ItemProperty 'hklm:\software\Microsoft\Windows NT\CurrentVersion\SVCHOST' | select -expandProperty LocalServiceNoNetwork)) { (Get-ItemProperty hklm:\system\CurrentControlSet\Services\$i).Description }

Sources:

  • https://medium.com/r3d-buck3t/abuse-service-registry-acls-windows-privesc-f88079140509

signature

# attack 'code signing certificate cloning': https://posts.specterops.io/code-signing-certificate-cloning-attacks-and-defenses-6f98657fc6ec
# defense: registry keys for installation https://gist.github.com/mattifestation/75d6117707bcf8c26845b3cbb6ad2b6b#file-rootcainstallationdetection-xml
# defense: check registry key creation with 'TargetObject property ends with "<THUMBPRINT_VALUE>\Blob"'
Get-AuthenticodeSignature -FilePath C:\Test\HelloWorld.exe

# check that certificate
Get-ChildItem -Path Cert:\ -Recurse | Where-Object { $_.Thumbprint -eq '1F3D38F280635F275BE92B87CF83E40E40458400' } | Format-List *

ssl-cert-from-uri

# gather Info / Ignore SSL Warning
$uri = "https://google.com/"
[Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
$webRequest = [Net.HttpWebRequest]::Create($uri)
$webRequest.ServicePoint

# get SSL Certificate information
$webRequest.GetResponse() | Out-NULL
$webRequest.ServicePoint.Certificate | fl

volumes

$signature = @'
[DllImport("kernel32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetVolumePathNamesForVolumeNameW([MarshalAs(UnmanagedType.LPWStr)] string lpszVolumeName,
        [MarshalAs(UnmanagedType.LPWStr)] [Out] StringBuilder lpszVolumeNamePaths, uint cchBuferLength, 
        ref UInt32 lpcchReturnLength);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr FindFirstVolume([Out] StringBuilder lpszVolumeName,
   uint cchBufferLength);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool FindNextVolume(IntPtr hFindVolume, [Out] StringBuilder lpszVolumeName, uint cchBufferLength);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax);

'@;
Add-Type -MemberDefinition $signature -Name Win32Utils -Namespace PInvoke -Using PInvoke,System.Text;

[UInt32] $lpcchReturnLength = 0;
[UInt32] $Max = 65535
$sbVolumeName = New-Object System.Text.StringBuilder($Max, $Max)
$sbPathName = New-Object System.Text.StringBuilder($Max, $Max)
$sbMountPoint = New-Object System.Text.StringBuilder($Max, $Max)
[IntPtr] $volumeHandle = [PInvoke.Win32Utils]::FindFirstVolume($sbVolumeName, $Max)
do {
    $volume = $sbVolumeName.toString()
    $unused = [PInvoke.Win32Utils]::GetVolumePathNamesForVolumeNameW($volume, $sbMountPoint, $Max, [Ref] $lpcchReturnLength);
    $ReturnLength = [PInvoke.Win32Utils]::QueryDosDevice($volume.Substring(4, $volume.Length - 1 - 4), $sbPathName, [UInt32] $Max);
    if ($ReturnLength) {
           $DriveMapping = @{
               DriveLetter = $sbMountPoint.toString()
               VolumeName = $volume
               DevicePath = $sbPathName.ToString()
           }

           Write-Output (New-Object PSObject -Property $DriveMapping)
       }
       else {
           Write-Output "No mountpoint found for: " + $volume
       } 
} while ([PInvoke.Win32Utils]::FindNextVolume([IntPtr] $volumeHandle, $sbVolumeName, $Max));

volumes-size

Get-Volume | Select-Object -Property DriveLetter, FileSystemLabel, 
    @{Name="Size";Expression={
        if ($_.Size -ge 1TB) {
            [math]::Round($_.Size / 1TB, 2).ToString() + " TB"
        } elseif ($_.Size -ge 1GB) {
            [math]::Round($_.Size / 1GB, 2).ToString() + " GB"
        } else {
            [math]::Round($_.Size / 1MB, 2).ToString() + " MB"
        }
    }},
    @{Name="SizeRemaining";Expression={
        if ($_.SizeRemaining -ge 1TB) {
            [math]::Round($_.SizeRemaining / 1TB, 2).ToString() + " TB"
        } elseif ($_.SizeRemaining -ge 1GB) {
            [math]::Round($_.SizeRemaining / 1GB, 2).ToString() + " GB"
        } else {
            [math]::Round($_.SizeRemaining / 1MB, 2).ToString() + " MB"
        }
    }},
    @{Name="UsedSpace";Expression={
        $usedSpace = $_.Size - $_.SizeRemaining
        if ($usedSpace -ge 1TB) {
            [math]::Round($usedSpace / 1TB, 2).ToString() + " TB"
        } elseif ($usedSpace -ge 1GB) {
            [math]::Round($usedSpace / 1GB, 2).ToString() + " GB"
        } else {
            [math]::Round($usedSpace / 1MB, 2).ToString() + " MB"
        }
    }}

move

pscredential

$zdom = "contoso"
$ztarg_user_name = "john_doe"
$ztarg_user_pass = "PASSWORD" | ConvertTo-SecureString -AsPlainText -Force
$ztarg_user_login = $zdom + "\" + $zlat_user
$ztarg_creds = New-Object System.Management.Automation.PSCredential($ztarg_user_login,$ztarg_user_pass)

pssession

!!! Verify WinRM is running !!!

# create and enter a session
$zs = New-PSSession -ComputerName $ztarg_computer_fqdn -Credential $ztarg_creds
Enter-PSSession -Session $zs

# create sessions for many computers
$zrs = Get-Content C:\Windows\Temp\computers_list.txt | New-PSSession -ThrottleLimit 50
Get-PSSession
Enter-PSSession -id 3

# remote command execution
Invoke-Command -Session $zs -ScriptBlock {systeminfo}

# clean the current session
Exit-PsSession

# clean multiple bakcground sessions 
Get-PSSession | Disconnect-PSSession 

transfer-smb


# STEP 1: create a smb share on the remote machine
$zshare = "hope"
$zcmd = 'New-SmbShare -name ' + $zshare + ' -path "c:\windows\temp" -FullAccess ' + $ztarg_login
$zsb = [scriptblock]::create($zcmd)
Invoke-Command -Session $zs -ScriptBlock $zsb

# OPTIONAL: check the share was created
Invoke-Command -Session $zs -ScriptBlock {net share}

# STEP 2.1: download a file to C:\windows\temp
$zfile = 'test.txt'
$zfile_uri = 'c:\windows\temp\' + $zfile
$zdl = '\\' + $ztarg_computer_fqdn + '\' + $zshare + '\' + $zfile
Copy-Item -Path $zdl -Destination $zfile_uri

# STEP 2.2: upload a file
$zfile = 'test.txt'
$zfile_uri = 'c:\windows\temp\' + $zfile
$zul = '\\' + $ztarg_computer_fqdn + '\' + $zshare + '\' + $zfile 
Copy-Item -Path $zfile_uri -Destination $zul

# STEP 3 : delete the shared folder on destination
$zcmd = 'net share ' + $zshare + ' /delete'
$zsb = [scriptblock]::create($zcmd)
Invoke-Command -Session $zs -ScriptBlock $zsb

transfer-http

Invoke-RestMethod -Uri $uri -Method Post -InFile $uploadPath -UseDefaultCredentials
$wc = New-Object System.Net.WebClient
$resp = $wc.UploadFile($uri,$uploadPath)

transfer-ftp

tamper

crud-reg

# LIST registry hives
get-psdrive -PSProvider registry

Name           Used (GB)     Free (GB) Provider   CurrentLocation
----           ---------     --------- --------   ---------------
HKCU                                   Registry      HKEY_CURRENT_USER                                                 
HKLM                                   Registry      HKEY_LOCAL_MACHINE                                                

# READ REGKEY V01
Get-ChildItem REGISTRY::HKEY_USERS | select name

Name                                                                                                    ----                                                                                                    HKEY_USERS\.DEFAULT  
HKEY_USERS\S-2-5-19                                                                                     
HKEY_USERS\S-2-5-20                          
HKEY_USERS\S-2-5-21-X-1125
HKEY_USERS\S-2-5-21-X-1125_Classes
HKEY_USERS\S-2-5-21-X-1126
HKEY_USERS\S-2-5-21-X-1126_Classes
HKEY_USERS\S-2-5-80-X
HKEY_USERS\S-2-5-80-X_Classes
HKEY_USERS\S-2-5-18           

# READ REGKEY V01
dir HKLM:\system\CurrentControlSet\Control\hivelist*

# UPDATE REGKEY # ENABLE Prefetch
$RegistryPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management'
$Name         = 'PrefetchParameters'
$Value        = '3'
# UPDATE REGKEY # ENABLE Prefetch # Create the key if it does not exist
If (-NOT (Test-Path $RegistryPath)) {
  New-Item -Path $RegistryPath -Force | Out-Null
}  
# UPDATE REGKEY # ENABLE Prefetch # Now set the value
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType DWORD -Force

crud-mac-addr

#? Get the MAC address of the first network adapter
get-item "hklm:\system\CurrentControlSet\control\class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0000"
$thenic = Get-WMIObject -Query "select * from win32_networkadaptater wherer deviceid = 0000"
$thenic.macaddress

#? Disable the network adapter
$thenic.disable()

#? Enable the network adapter
$thenic.enable()

#? Set the network adapter MAC address
set-itemproperty -path "hklm:\system\CurrentControlSet\control\class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0000" -name MACAddress -value

disable-windows-updates

sc stop wuauserv 
sc config wuauserv start=disabled

rsat

rsat-install

Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force
$Script = "Get-WindowsCapability -Name RSAT* -Online | Add-WindowsCapability -Online"
Start-Process -FilePath powershell.exe -ArgumentList "-Command &{ $Script }" -PassThru | ForEach-Object {"Started '$($_.ProcessName)' [$($_.Id)]."}

get-aduser

#? Installing telnet clients 	
Import-module servermanager
  Add-windowsfeature telnet-client

#? ActiveDirectory module mandatory for the following commands
Import-module ActiveDirectory

#? Listing Users matching keyword
Get-ADuser -Filter "SamAccountName -like '*adm*'"
(Get-ADuser -Filter "SamAccountName -like '*adm*'").UserPrincipalName

#? Listing Users with password expired
Get-ADUser -Filter { Enabled -eq "True" } -Properties PasswordExpired | Where {$_.PasswordExpired -eq $true }

#? Listing Users' OU
Get-ADuser -Filter "SamAccountName -like '*adm*'" -SearchBase ""

#? Listing User Groups
Get-ADuser $ztarg_user_name -Property * | Select-Object -ExpandProperty MemberOf 

#? PasswordLastSet
Get-ADUser $ztarg_user_name -properties PasswordLastSet | Format-List

#? Matching Group Name for USB
Get-ADuser $ztarg_user_name -Property * | Select-Object -ExpandProperty MemberOf | findstr 'DEVICECONTROL'

#? Matching Group Name for DA
Get-ADuser $ztarg_user_name -Property * | Select-Object -ExpandProperty MemberOf | findstr 'Domain Admins'

get-adusers

$importCSV = read-host "Users Input CSV: " 
$exportCSV = read-host "Users Output CSV: "
$UserInfo = @()
$Users_List = Import-Csv -Path $importCSV
foreach ($user in $Users_List) {
	$UPN = get-aduser $user.user -Properties * | select DistinguishedName, mailNickname, EmployeeNumber, msExchExtensionAttribute18, whenCreated, LastBadPasswordAttempt, AccountExpirationDate, AccountLockoutTime, physicalDeliveryOfficeName, Title, Company, Manager, MemberOf, Department
	$UserInfo += [PSCustomObject]$UPN
}
$UserInfo | Export-Csv -NoTypeInformation -Path $exportCSV -Delimiter ';'

Write-Host $UserInfo

get-adgroup

#? Matching Group Name 1
Get-ADPrincipalGroupMembership -Identity $ztarg_user_name | Select-Object -ExpandProperty MemberOf  | Where-Object {$_.name -like '*DEVICECONTROL*' } 		

Get-ADGroup EMEA-PXY-Web-ReadWrite -Property * | Select-Object -ExpandProperty Member 

get-adcomputer

# from csv list
$output = @()
$wks_csv = import-csv wks.csv -Header wks
foreach ($wks in $wks_csv){$wks_sum = get-adcomputer $wks.wks -Properties * | select name, IPv4Address, OperatingSystem,DoesNotRequirePreauth, TrustedForDelegation, TrustedToAuthForDel
egation, DistinguishedName; $output += [PSCustomObject]$wks_sum}
$wks_sum | ft

# Listing Computer Info
Get-ADComputer -Filter {Name -Like "dell-xps*"} -Property * | Format-Table Name,OperatingSystem,OperatingSystemServicePack,OperatingSystemVersion -Wrap -Auto

# Listing Win > 5.1
Get-ADComputer -Filter {OperatingSystemVersion -ge "5.1"} -Property * | Format-Table Name,OperatingSystem,OperatingSystemVersion -Wrap -Auto

get-addc

(Get-ADForest).Domains | %{ Get-ADDomainController -Filter * -Server $_ }| Format-Table -Property Name,Domain,Forest,IPv4Address,OperatingSystem,OperatingSystemVersion