Skip to content

Instantly share code, notes, and snippets.

@mgreen27
Created July 22, 2018 12:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mgreen27/441dac7d2034cb0f13844e4f82c2387b to your computer and use it in GitHub Desktop.
Save mgreen27/441dac7d2034cb0f13844e4f82c2387b to your computer and use it in GitHub Desktop.
Parse CLSID COM objects from Registry
<#
.SYNOPSIS
Invoke-CLSIDParser.ps1 parses COM CLSID entries from HKEY_LOCAL_MACHINE and HKEY_USERS registry hives.
Name: Invoke-CLSIDParser.ps1
Version: 0.1
Author: Matt Green (@mgreen27)
.DESCRIPTION
Researchers have recently written about several use cases for code execution and persistance utilising COM (Component Object Model) hijacking.
This script enables enumeration of all COM CLSID objects, enabling analysis and detection of these techniques.
This script can list SYSTEM, USER or a specific SID
.EXAMPLE
Invoke-CLSIDParser.ps1
Lists all COM CLSID.
.EXAMPLE
Invoke-CLSIDParser.ps1 -System
Lists all SYSTEM COM CLSID.
.EXAMPLE
Invoke-CLSIDParser.ps1 -User
Lists all USER COM CLSID.
.EXAMPLE
Invoke-CLSIDParser.ps1 -Sid <SID>
Lists all COM CLSID associated to the User SID referenced.
.NOTES
References:
https://bohops.com/2018/06/28/abusing-com-registry-structure-clsid-localserver32-inprocserver32/
https://www.youtube.com/watch?v=mkvGcf63_9k&feature=youtu.be
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory = $False)][Switch]$System,
[Parameter(Mandatory = $False)][Switch]$User,
[Parameter(Mandatory = $False)][String]$Sid = $Null
)
$System = $PSBoundParameters.ContainsKey('System')
$User = $PSBoundParameters.ContainsKey('User')
If (!($System) -And !($User) -And !($Sid)) {
$System = $True
$User = $True
}
If ($System){
Get-ChildItem -Path HKLM:\SOFTWARE\Classes\CLSID -Depth 1 | Where-Object {(Split-Path $_.name -Leaf) -eq "LocalServer32" -or (Split-Path $_.name -Leaf) -eq "InprocServer32"} | ForEach-Object {
# Setting up object for nicest output format
$Output = "" | Select Name, CLSID, Type, Value, Key
$Output.CLSID = Split-Path $_.PSParentPath -Leaf
$Output.Type = $_.PSChildName
$Output.Name = (Get-ItemProperty -Path HKLM:\SOFTWARE\Classes\CLSID\$($Output.CLSID) -Name "(Default)" -ErrorAction SilentlyContinue).("(Default)")
$Output.Value = (Get-ItemProperty -Path HKLM:\SOFTWARE\Classes\CLSID\$($Output.CLSID)\$($Output.Type) -Name "(Default)" -ErrorAction SilentlyContinue).("(Default)")
$Output.Key = $_.Name
$Output
}
}
If ($User){
$Sids = (Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Profilelist").Name | ForEach-Object {Split-Path $_ -Leaf}
$Sids | Foreach-object {Get-ChildItem -Path REGISTRY::HKEY_USERS\$_\SOFTWARE\Classes\CLSID -Depth 1 -ErrorAction SilentlyContinue} | Where-Object {(Split-Path $_.name -Leaf) -eq "LocalServer32" -or (Split-Path $_.name -Leaf) -eq "InprocServer32"} | ForEach-Object {
# Setting up object for nicest output format
$Output = "" | Select Name, CLSID, Type, Value, Key
$Output.CLSID = Split-Path $_.PSParentPath -Leaf
$Output.Type = $_.PSChildName
$Output.Name = (Get-ItemProperty -Path REGISTRY::$(Split-Path $_.Name) -Name "(Default)" -ErrorAction SilentlyContinue).("(Default)")
$Output.Value = (Get-ItemProperty -Path REGISTRY::$_ -Name "(Default)" -ErrorAction SilentlyContinue).("(Default)")
$Output.Key = $_.Name
$Output
}
}
If ($Sid){
Try{
Get-ChildItem -Path REGISTRY::HKEY_USERS\$Sid\SOFTWARE\Classes\CLSID -Depth 1 -ErrorAction Stop | Where-Object {(Split-Path $_.name -Leaf) -eq "LocalServer32" -or (Split-Path $_.name -Leaf) -eq "InprocServer32"} | ForEach-Object {
# Setting up object for nicest output format
$Output = "" | Select Name, CLSID, Type, Value, Key
$Output.CLSID = Split-Path $_.PSParentPath -Leaf
$Output.Type = $_.PSChildName
$Output.Name = (Get-ItemProperty -Path REGISTRY::$(Split-Path $_.Name) -Name "(Default)" -ErrorAction SilentlyContinue).("(Default)")
$Output.Value = (Get-ItemProperty -Path REGISTRY::$_ -Name "(Default)" -ErrorAction SilentlyContinue).("(Default)")
$Output.Key = $_.Name
$Output
}
}
Catch{
"Invoke-CLSIDParser Error: User SID does not exist. Please check format - e.g S-1-5-21-1866233333-1870853333-1579133333-1000"
}
}
[gc]::Collect()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment