CVE-2016-8027
An exploitable blind sql injection vulnerability exists within McAfee’s ePolicy Orchestrator 5.3.0 that is accessible without authentication. A specially crafted HTTP post can allow an aggressor to alter a sql query which can result in disclosure of information within the database or impersonation of an agent. An attacker can use any HTTP client to trigger this vulnerability.
McAfee’s ePolicy Orchestrator 5.3.0
http://www.mcafee.com/us/products/epolicy-orchestrator.aspx(http://www.mcafee.com/us/products/epolicy-orchestrator.aspx)
8.2 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:L
McAfee’s ePolicy Orchestrator is a centralized security management suite that is used to manage antivirus and policies within the enterprise. These types of software are also known as an HBSS or Host-based Security System. It is used to manage a number of agents which are deployed in the enterprise and can be used to enforce defenses and software policies in a scalable manner.
McAfee’s ePolicy Orchestrator is composed of a number of components. This consists of a load-balancer which is driven by Apache and extended via custom modules. The Console itself which is based on Tomcat, and is used by staff to manage the entirety of the software. The last component are the agents themselves which are deployed on each client machine. The agents communicate over a proprietary protocol known as SPIPE to Apache which is then forwarded to the Console. This specific vulnerability is located within the application server and is reachable over SPIPE or via the Console directly.
Within the Tomcat server component, which may be reachable on port 8443 in most configurations, are a number of servlets which serve as the management component of the application. The DataChannel servlet is actually mapped to a POST request received against “https://
Once the POST request is received by the EPODataChannelServlet class, the following code will be executed. When calling the ProcessIncomingMessage function, this will eventually call the EPOBaseDataChannelData.unpackLittleEndian_DataPacket method. This method will decode a structure from the POST’s content which contains the message type, it’s origin, and most importantly the Agent’s GUID as well as some other fields. Afterwards this object will then get passed to the EPODataChannelMessagingService.receiveAgentMessage method.
com.mcafee.epo.dataChannel.servlet.EPODataChannelServlet:49
protected void doPost(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse)
throws ServletException, IOException
{
...
try
{
BeanFactory localBeanFactory = (BeanFactory)getServletContext().getAttribute("beanFactory");
EPODataChannelReceiveAction localEPODataChannelReceiveAction = (EPODataChannelReceiveAction)localBeanFactory.getBean("epo.dataChannel.action");
localEPODataChannelReceiveAction.ProcessIncomingMessage(paramHttpServletRequest, paramHttpServletResponse); // \
}
\
byte[] arrayOfByte = readBytesFromRequest(paramHttpServletRequest); // XXX: reads bytes from POST request
try
{
EPOBaseDataChannelData localEPOBaseDataChannelData = EPOBaseDataChannelData.unpackLittleEndian_DataPacket(arrayOfByte); // XXX: Decodes bytes into an object
boolean bool = this.m_service.receiveAgentMessage(localEPOBaseDataChannelData); // XXX
if (!bool) {
m_log.error("could not process incoming message");
}
}
The EPODataChannelMessagingService.receiveAgentMesage method will then forward the object containing the unpacked data to the DataChannelMessagingServiceInternal.receiveAgentMessage method. This method will check to see that the Agent GUID in the packet is defined, and then call the EPOComputerService.getByAgentGUIDNoUserCheck method using the AgentGUID as its only argument.
com.mcafee.epo.dataChannel.service.DataChannelMessageServiceInternal:325
public boolean receiveAgentMessage(EPOBaseDataChannelData paramEPOBaseDataChannelData)
throws EPODataChannelException
{
if (paramEPOBaseDataChannelData == null) {
throw new EPODataChannelException("Empty message received");
}
String str = paramEPOBaseDataChannelData.getMessageType();
if ((str == null) || (str.length() < 1)) {
throw new EPODataChannelException("Invalid length of message type received");
}
...
localConnection = getDatabase().getConnection(localOrionUser);
localOrionUser = getUserForMessage(localConnection, paramEPOBaseDataChannelData); // \
\
private OrionUser getUserForMessage(Connection paramConnection, EPOBaseDataChannelData paramEPOBaseDataChannelData)
{
OrionUser localOrionUser = getUserLoader().getDefaultTenantSystemUser();
try
{
String str = paramEPOBaseDataChannelData.getAgentGUID(); // XXX: from POST request
if ((str != null) && (str.length() > 0))
{
EPOComputer localEPOComputer = getComputerService().getByAgentGUIDNoUserCheck(paramConnection, str); // XXX
In the EPOComputerService class, the getByAgentGUIDNoUserCheck method is contains the sql injection vulnerability. This method will simply take the provided Agent GUID and use it to build a query using the EPOComputerDataMapper class which will then be executed over the jdbc connection.
com.mcafee.epo.core.services.EPOComputerServiceInternal:159
public EPOComputer getByAgentGUIDNoUserCheck(Connection paramConnection, String paramString)
throws SQLException
{
if ("N/A".equals(paramString)) {
return null;
}
String str = getComputerMapper().getSelectSql(false) + "where (AgentGUID = '" + paramString + "')"; // XXX
List localList = getComputerMapper().getByQuery(paramConnection, str);
if ((localList == null) || (localList.isEmpty())) {
return null;
}
EPOComputer localEPOComputer = (EPOComputer)localList.get(0);
loadLdapPropsForComputer(paramConnection, localEPOComputer);
return localEPOComputer;
}
This results in the EPOComputerDatabaseMapper class building a query that looks like the following.
select AutoID, Type, NodeName, ParentID, AgentPlatform, ResortEnabled, AgentGUID, SequenceErrorCount, SequenceErrorCountLastUpdate, SuperAgent, TenantId from [EPOLeafNode] where (AgentGUID = '%s')
In some configurations, the console may not be directly reachable by an agent. The method by which an agent communicates to the console, however, is through the Apache based load balancer using a proprietary protocol known as SPIPE. This can be reached via the uri “https://
.text:54609BBC loc_54609BBC: ; CODE XREF: epo_handler_9a60+D0j
.text:54609BBC 0B0 6A 06 push 6 ; size_t
.text:54609BBE 0B4 68 0C DA 60 54 push offset str./spipe ; "/spipe"
.text:54609BC3 0B8 8B 86 E0 00 00 00 mov eax, [esi+0E0h]
.text:54609BC9 0B8 50 push eax ; char *
.text:54609BCA 0BC FF 15 E8 C1 60 54 call ds:strncmp ; [library] MSVCR100.dll
.text:54609BD0 0BC 83 C4 0C add esp, 0Ch
...
.text:54609C1D loc_54609C1D: ; CODE XREF: epo_handler_9a60+17Aj
.text:54609C1D 0B0 8B 46 4C mov eax, [esi+4Ch]
.text:54609C20 0B0 83 F8 02 cmp eax, 2
.text:54609C23 0B0 74 72 jz short loc_54609C97
...
.text:54609C97 loc_54609C97: ; CODE XREF: epo_handler_9a60+1C3j
.text:54609C97 0B0 E8 E4 05 00 00 call epoStart_a280
.text:54609C9C 0B0 8B D8 mov ebx, eax
...
.text:54609F02 0B0 8D 8D 78 FF FF FF lea ecx, [ebp+lv_apacheObject?_88] ; [object] gvtbl_f25c
.text:54609F08 0B0 E8 23 06 00 00 call mod_epo_ProcessPostRequest_a530 ; [completed] 0x0
.text:54609F0D 0B0 89 45 A8 mov [ebp+lv_result_58], eax
This function is simply responsible for checking that the Content-Length of the POST request is larger than 0xea bytes and will then proceed to call into the NAIMSERV.DLL library which contains the majority of the SPIPE implementation. This size represents the header of the SPIPE protocol.
.text:5460A74C loc_5460A74C: ; CODE XREF: mod_epo_ProcessPostRequest_a530+1D5j
.text:5460A74C 0C0 B9 EA 00 00 00 mov ecx, 0EAh
.text:5460A751 0C0 3B CB cmp ecx, ebx
.text:5460A753 0C0 1B D2 sbb edx, edx
.text:5460A755 0C0 F7 DA neg edx
.text:5460A757 0C0 89 55 8C mov [ebp+var_74], edx
.text:5460A75A 0C0 75 47 jnz short loc_5460A7A3
...
.text:5460A7A3 0C0 A1 84 26 61 54 mov eax, gpf_naimserv(?)_12684 ; [external] naimserv.dll!ProcessPostRequest_fe40
.text:5460A7A8 0C0 85 C0 test eax, eax
.text:5460A7AA 0C0 74 10 jz short error(noProcessPostRequestEntryPoint)_a7bc
.text:5460A7AC
.text:5460A7AC 0C0 56 push esi
.text:5460A7AD 0C4 53 push ebx
.text:5460A7AE 0C8 57 push edi
.text:5460A7AF 0CC FF D0 call eax ; gpf_naimserv(?)_12684
.text:5460A7B1 0C0 89 45 94 mov [ebp+lv_httpStatus_6c], eax
NAIMSERV.DLL registers a couple of callbacks, one of which is responsible for processing the POST request. Eventually after some checks, the module will encounter the following code which will xor all the bytes in the POST’s content with the byte 0xAA. Immediately after decoding, the application will process the header and store it into an object which is used to determine the version of the SPIPE package as well as store extra data that’s interpreted as a list of key/value pairs. The version of the SPIPE package can be one of the following values: 0x40000001, 0x50000001, or 0x60000001.
.text:54C0FEE5 1110 8D 95 DC EF FF FF lea edx, [ebp+lv_supports2048bitRsa_1024]
.text:54C0FEEB 1110 52 push edx
.text:54C0FEEC 1114 8B 45 0C mov eax, [ebp+av_contentLength_4]
.text:54C0FEEF 1114 50 push eax
.text:54C0FEF0 1118 E8 AB 0D 05 00 call sub_54C60CA0 ; [synopsis] xor's every byte in content with 0xaa
.text:54C0FEF5 1118 83 C4 08 add esp, 8
...
.text:54C0FF97 1110 8D 8D D0 FD FF FF lea ecx, [ebp+lvo_string_230]
.text:54C0FF9D 1110 51 push ecx
.text:54C0FF9E 1114 8B 55 0C mov edx, [ebp+av_contentLength_4]
.text:54C0FFA1 1114 52 push edx
.text:54C0FFA2 1118 8D 95 B4 FD FF FF lea edx, [ebp+lvo_string_24c]
.text:54C0FFA8 1118 8B B5 C8 EF FF FF mov esi, [ebp+lp_content_1038]
.text:54C0FFAE 1118 8B CE mov ecx, esi
.text:54C0FFB0 1118 E8 DB 8A 01 00 call sub_54C28A90 ; [input] %ecx=packetData?,%edx=v_string
.text:54C0FFB0 ; [synopsis] checks the packet header for the minimum Spipe version and a few other things.
.text:54C0FFB0 ; [output] %eax=v_headerResult
If a version 4 packet is used, then the application will use the DES3 algorithm to decrypt the extra data. Version 6, however relies on using SSL. Within this same function, the library will extract the SupportedSPIPEVersion string which could be “4.0”, “5.0”, or “6.0”.
.text:54C1024E 1110 8B 45 0C mov eax, [ebp+av_contentLength_4]
.text:54C10251 1110 50 push eax
.text:54C10252 1114 8B D6 mov edx, esi
.text:54C10254 1114 8D 85 D0 F6 FF FF lea eax, [ebp+lvo_spipeExtraDataObject_930]
.text:54C1025A 1114 E8 C1 70 00 00 call sub_54C17320 ; [note] stored to 271(%eax) and 0x400 bytes in size
.text:54C1025A ; [input] %edx=postData,%eax=someObject
.text:54C1025A ; [synopsis] extracts from an epo packet the string for "SupportedSPIPEVersion"
...
.text:54C102D8 1110 8B 45 0C mov eax, [ebp+av_contentLength_4]
.text:54C102DB 1110 50 push eax
.text:54C102DC 1114 8B D6 mov edx, esi
.text:54C102DE 1114 8D 85 D0 F6 FF FF lea eax, [ebp+lvo_spipeExtraDataObject_930]
.text:54C102E4 1114 E8 C7 6D 00 00 call sub_54C170B0 ; [note] stored to 1f0(%eax) and 0x81 bytes in size
.text:54C102E4 ; [synopsis] extracts from an epo packet the string for "ServerKeyHash".
.text:54C102E9 1110 89 85 D4 EF FF FF mov [ebp+lp_extraPacketRequest_102c], eax
...
.text:54C10445 1110 8B 45 0C mov eax, [ebp+av_contentLength_4]
.text:54C10448 1110 50 push eax
.text:54C10449 1114 8B D6 mov edx, esi
.text:54C1044B 1114 8D 85 D0 F6 FF FF lea eax, [ebp+lvo_spipeExtraDataObject_930]
.text:54C10451 1114 E8 2A 6C 00 00 call sub_54C17080 ; [note] stored to 671(%eax) and 0x40 bytes in size
.text:54C10451 ; [synopsis] extracts from an epo packet the string for "TenantId"
Afterwards, the module will then use these values to locate the Agent’s public key. This public key will be used to verify that the SPIPE package has not been tampered with. Once this is done, then the application will check the Server’s key against the value of the “ServerKeyHash” field provided in the packet. A few more checks later and the module will finally encounter the function responsible for actually handling the Agent’s request.
.text:54C10683 1110 8B BD C8 EF FF FF mov edi, [ebp+lp_content_1038]
.text:54C10689 1110 8D 4F 16 lea ecx, [edi+16h] ; lpString
.text:54C1068C 1110 89 8D D0 EF FF FF mov [ebp+lp_tenantIdString?_1030], ecx
.text:54C10692 1110 8D 95 A0 EF FF FF lea edx, [ebp+lv_databaseId_1060]
.text:54C10698 1110 52 push edx ; int
.text:54C10699 1114 8D 85 A4 EF FF FF lea eax, [ebp+lv_105C]
.text:54C1069F 1114 50 push eax ; int
.text:54C106A0 1118 8D 95 9C EF FF FF lea edx, [ebp+lv_size_1064]
.text:54C106A6 1118 52 push edx ; int
.text:54C106A7 111C 8D 85 EC FD FF FF lea eax, [ebp+lv_buffer(512)?_214]
.text:54C106AD 111C 50 push eax ; int
.text:54C106AE 1120 E8 3D 10 01 00 call GetAgentPublicKey_216f0
...
.text:54C10754 1110 8B 95 C4 EF FF FF mov edx, [ebp+var_103C]
.text:54C1075A 1110 52 push edx
.text:54C1075B 1114 8B 45 0C mov eax, [ebp+av_contentLength_4]
.text:54C1075E 1114 50 push eax
.text:54C1075F 1118 8D 95 CC EF FF FF lea edx, [ebp+var_1034]
.text:54C10765 1118 8B CF mov ecx, edi
.text:54C10767 1118 E8 34 06 05 00 call VerifySignedKeyPkgSignature_60da0
.text:54C1076C 1118 83 C4 08 add esp, 8
.text:54C1076F 1110 89 85 E8 EF FF FF mov [ebp+lv_flag?_1018], eax
...
.text:54C107E3 1110 8B 55 0C mov edx, [ebp+av_contentLength_4]
.text:54C107E6 1110 52 push edx
.text:54C107E7 1114 8B D7 mov edx, edi
.text:54C107E9 1114 8D 8D D0 F6 FF FF lea ecx, [ebp+lvo_spipeExtraDataObject_930]
.text:54C107EF 1114 E8 7C 5F 00 00 call CEPODataPackage::Buffer2Data_16770
...
.text:54C10CE3 1110 8B 8D CC EF FF FF mov ecx, [ebp+var_1034]
.text:54C10CE9 1110 51 push ecx
.text:54C10CEA 1114 8B 95 A4 EF FF FF mov edx, [ebp+lv_105C]
.text:54C10CF0 1114 52 push edx
.text:54C10CF1 1118 8D 95 EC EF FF FF lea edx, [ebp+lv_someSPIPEObject_1014]
.text:54C10CF7 1118 8D 8D D0 F6 FF FF lea ecx, [ebp+lvo_spipeExtraDataObject_930]
.text:54C10CFD 1118 E8 0E 0F 01 00 call AgentRequestHandler_21c10 ; [input] %ecx=spipeExtraObject
Inside the AgentRequestHandler function, the application will then check the PackageType field from the packet in order to determine how to handle an Agent’s request. When encountering the following function, the library will populate the object at @ebp-0x17d8 with values from the packet. One of these is the Agent’s GUID.
.text:54C22107 187C 8B C1 mov eax, ecx
.text:54C22109 187C 8B 95 14 E8 FF FF mov edx, [ebp+var_17EC]
.text:54C2210F 187C 52 push edx
.text:54C22110 1880 50 push eax
.text:54C22111 1884 8D B5 28 E8 FF FF lea esi, [ebp+lv_agentInfoObject_17D8]
.text:54C22117 1884 8B CF mov ecx, edi
.text:54C22119 1884 E8 32 E5 02 00 call server_GetAgentInfoFromSPIPE_50650 ; [input] %ecx=p_someObject,%esi=p_giantDestinationObject
.text:54C22119 ; [synopsis] fetches a bunch of attributes from %ecx and writes them to the object at %esi
.text:54C2211E 1884 83 C4 08 add esp, 8
.text:54C22121 187C 8B F0 mov esi, eax
.text:54C22123 187C 89 B5 1C E8 FF FF mov [ebp+lp_agentInfo_17E4], esi ; [alias] v_flag?
After extracting the GUID from the package, the library will then execute the following code which ensures that the GUID isn’t contained in a blacklist. After this is done, the library will check the sequence number and then enter a series of loops that will check which “PackageType” is being requested. If the package type specified by the agent is “MsgUpload”, then the application will call a function, server_OnMsgUpload, which will forward the data to the application server.
.text:54C2222D 187C C6 45 FC 02 mov byte ptr [ebp+var_4], 2
.text:54C22231 187C 8D 85 50 FF FF FF lea eax, [ebp+lp_guidString?_B0]
.text:54C22237 187C 50 push eax
.text:54C22238 1880 B8 DC D2 E1 54 mov eax, offset dword_54E1D2DC
.text:54C2223D 1880 E8 BE AA 0F 00 call sub_54D1CD00
.text:54C22242 187C 8A D8 mov bl, al
...
.text:54C22334 187C 8D 9D 28 E8 FF FF lea ebx, [ebp+lv_agentInfoObject_17D8]
.text:54C2233A 187C E8 81 2A 02 00 call servdal_ProcessAgentReportedSequenceNumber_44dc0 ; [input] %ebx=p_agentInfoObject
.text:54C2233A ; [synopsis] validates the sequence number for an agentInfoObject and logs it
.text:54C2233F 187C 89 85 24 E8 FF FF mov [ebp+var_17DC], eax
...
.text:54C2278F compare(MsgUpload)_2278f: ; CODE XREF: AgentRequestHandler_21c10+B62j
.text:54C2278F 187C B9 F8 55 DB 54 mov ecx, offset str.MsgUpload ; "MsgUpload"
.text:54C22794 187C 8D 85 6C FF FF FF lea eax, [ebp+lv_packageTypeString?_94]
.text:54C2279A 187C 8D 9B 00 00 00 00 lea ebx, [ebx+0]
...
.text:54C227CF 187C 8D 95 28 E8 FF FF lea edx, [ebp+lv_agentInfoObject_17D8] ; [XXX] calls server_onMsgUpload
.text:54C227D5 187C 52 push edx
.text:54C227D6 1880 8B D3 mov edx, ebx
.text:54C227D8 1880 8B 8D 20 E8 FF FF mov ecx, [ebp+lv_spipeExtraObject_17E0]
.text:54C227DE 1880 E8 FD 01 03 00 call server_OnMsgUpload_529e0 ; [input] %ecx=packetData?
This function will tokenize data provided by the agent, and then enter the following loop which forwards the data directly to the application server using the ForwardDataChannelMessageToJava function.
.text:54C52ACE loop_tokens_52ace: ; CODE XREF: server_OnMsgUpload_529e0+3BAj
.text:54C52ACE 128 8B 44 24 28 mov eax, [esp+124h+lp_@ecx_fc]
.text:54C52AD2 128 50 push eax ; int
.text:54C52AD3 12C 8D 7C 24 14 lea edi, [esp+128h+lv_size_114]
.text:54C52AD7 12C 33 D2 xor edx, edx
.text:54C52AD9 12C 8B CE mov ecx, esi ; void *
.text:54C52ADB 12C 89 5C 24 14 mov [esp+128h+lv_size_114], ebx
.text:54C52ADF 12C E8 3C 7D 00 00 call sub_54C5A820 ; [input] %edx=p_destBuffer
...
.text:54C52C99 128 56 push esi
.text:54C52C9A 12C 8B 74 24 1C mov esi, [esp+128h+lp_dataChannelContent_10c]
.text:54C52C9E 12C E8 5D EB FF FF call ForwardDataChannelMessageToJava_51800 ; [input] %esi=content
.text:54C52CA3 12C 83 C4 04 add esp, 4
...
.text:54C52D82 continue_tokens_52d82: ; CODE XREF: server_OnMsgUpload_529e0+36Cj
.text:54C52D82 128 8D 44 24 2C lea eax, [esp+124h+lv_Context_f8]
.text:54C52D86 128 50 push eax ; Context
.text:54C52D87 12C 68 C4 9F DB 54 push offset str., ; ","
.text:54C52D8C 130 53 push ebx ; Str
.text:54C52D8D 134 FF 15 3C 45 DA 54 call ds:strtok_s
.text:54C52D93 134 8B F0 mov esi, eax
.text:54C52D95 134 83 C4 0C add esp, 0Ch
.text:54C52D98 128 3B F3 cmp esi, ebx
.text:54C52D9A 128 0F 85 2E FD FF FF jnz loop_tokens_52ace
The ForwardDataChannelMessageToJava function will simply take the input that was extracted from the Agent’s request, and then forward it to the “/dcRedirect/dataChannelMsg.dc” resource that’s located directly on the application server component.
.text:54C51847 0F0 8D 8D 34 FF FF FF lea ecx, [ebp+lvo_secureHttp_cc]
.text:54C5184D 0F0 FF 15 60 4B DA 54 call ds:CSecureHttp::CSecureHttp(void)
.text:54C51853
.text:54C51853 0F0 89 7D FC mov [ebp+var_4], edi
.text:54C51856 0F0 8B 4D 08 mov ecx, [ebp+av_size_14]
.text:54C51859 0F0 8D 85 30 FF FF FF lea eax, [ebp+ap_resultHeaders_18]
.text:54C5185F 0F0 50 push eax ; ap_resultHeaders_18
.text:54C51860 0F4 A1 78 CB E1 54 mov eax, gp_dataChannelObject_21cb78
.text:54C51865 0F4 51 push ecx ; av_optionalDataLength_14
.text:54C51866 0F8 56 push esi ; ap_optionalData_10
.text:54C51867 0FC 68 64 9E DB 54 push offset gv_request(mimetype)_1b9e64 ; "application/octet-stream"
.text:54C5186C 100 89 BD 30 FF FF FF mov [ebp+ap_resultHeaders_18], edi
.text:54C51872 100 8B 90 5C 02 00 00 mov edx, [eax+25Ch]
.text:54C51878 100 52 push edx ; av_nServerPort_8
.text:54C51879 104 05 70 02 00 00 add eax, 270h
.text:54C5187E 104 50 push eax ; ap_serverName_4
.text:54C5187F 108 68 98 9E DB 54 push offset gv_request(dataChannelMsg)_1b9e98 ; "/dcRedirect/dataChannelMsg.dc"
.text:54C51884 10C 8D 8D 34 FF FF FF lea ecx, [ebp+lvo_secureHttp_cc] ; this
.text:54C5188A 10C FF 15 68 4B DA 54 call ds:CSecureHttp::PostSecureHttpRequest(wchar_t const *,wchar_t const *,int,wchar_t const *,void const *,uint,ulong &)
The POST request that is made to the application server is made to the DataChannel servlet. The servlet implement’s the Data Channel which has the following format.
[0] <class pint.uint16_t> getHeaderSize ???
[2] <class pint.uint16_t> version ???
[4] <class pint.uint32_t> m_expiration ???
[8] <class pint.uint32_t> CorrelationID ???
[c] <class pint.uint8_t> getFlag ???
[0] <class StringPacket> m_originNameBytes ???
[0] <class StringPacket> m_messageTypeBytes ???
[0] <class StringPacket> m_agentGUIDBytes ???
[0] <class Data> m_data ???
A StringPacket structure is a byte which defines the number of bytes that define a string.
<class StringPacket>
[0] <class pint.uint8_t> size ???
[1] <class dyn.block(size)> data ???
A Data structure is similar to a StringPacket except it uses a uint32_t to define the length of the data.
<class Data>
[0] <class pint.uint32_t> size ???
[4] <class dyn.block(size)> data ???
In the proof-of-concept, the following packet is POSTed. The only requirements of this packet are that the version is set to 1, the m_messageTypeBytes is larger than one character in length, and the m_data field contains at least one byte of data. If all of these fields are valid, then the m_agentGUIDBytes can contain up to 256 characters used for the sql injection.
<class DataPacket>
[0] <instance pint.uint16_t 'getHeaderSize'> 0x004e (78)
[2] <instance pint.uint16_t 'version'> 0x0001 (1)
[4] <instance pint.uint32_t 'm_expiration'> 0x00000000 (0)
[8] <instance pint.uint32_t 'CorrelationID'> 0x00000000 (0)
[c] <instance pint.uint8_t 'getFlag'> 0x07 (7)
[d] <instance StringPacket 'm_originNameBytes'> "\x10\x58\x58\x58\x4f\x52\x49\x47\x49\x4e\x4e\x41\x4d\x45\x58\x58\x58"
[1e] <instance StringPacket 'm_messageTypeBytes'> "\x11\x58\x58\x58\x4d\x45\x53\x53\x41\x47\x45\x54\x59\x50\x45\x58\x58\x58"
[30] <instance StringPacket 'm_agentGUIDBytes'> "\x0f\x58\x58\x58\x41\x47\x45\x4e\x54\x47\x55\x49\x44\x58\x58\x58"
[40] <instance Data 'm_data'> "\x0a\x00\x00\x00\x58\x58\x58\x44\x41\x54\x41\x58\x58\x58"
To ensure that an attacker does not have direct access to the vulnerability and instead has to use just SPIPE as an agent, verify that port 8443 that the McAfee ePolicy Orchestrator Console is bound to is inaccessible by ePolicy Orchestrator’s agents and can only by accessed by Administrators.
2016-11-04 - Vendor Disclosure
2017-02-01 - Public Release
Discovered by a member of the Talos Vulnerability Development Team.