May 17, 2017

SAP Customers: Make sure your SAPJVM is up to date!

Summary

Code White have already an impressive publication record on Java Deserialization. This post is dedicated to a vulnerability in SAP NetWeaver Java. We could reach remote code execution through the p4 protocol and the Jdk7u21 gadget with certain engines and certain versions of the SAP JVM.

We would like to emphasize the big threat unauthenticated RCE poses to a SAP NetWeaver Java. An attacker with a remote shell can read out the secure storage, access the database, create a local NetWeaver user with administrative privileges, in other words, fully compromise the host. Unfortunately, this list is far from being complete. An SAP landscape is usually a network of tightly
connected servers and services. It wouldn’t be unusual that the database of the server stores technical users with high privileges for other SAP systems, be it NetWeaver ABAP or others. Once the attacker gets hold of credentials for those users she can extend her foothold in the organization and eventually compromise the entire SAP landscape.

We tested our exploit successfully on 7.20, 7.30 and 7.40 machines, for detailed version numbers see below. When contacted, SAP Product Security Response told us they published 3 notes (see [7], [8] and [9]) about updates fixing the problems (already in June 2013) with SAP JVM versions 1.5.0_086, 1.6.0_052 and 1.7.0_009 (we tested on earlier versions, see below). In addition SAP have recently adopted JDK JEP 290 (a Java enhancement that allows to filter incoming serialized data). However, neither do these three notes mention Java Deserialization nor is it obvious to the reader they relate to security in any other way.

Due to missing access to the SAP Service Marketplace we’re unable to make any statement about the aforementioned SAP JVM versions. We could only analyze the latest available SAP JVM from tools.hana.ondemand.com (see [6]) which contained a fix for the problem.

Details

In his RuhrSec Infiltrate 2016 talk, Code White’s former employee Matthias Kaiser already talked about SAP NetWeaver Java being vulnerable [2]. The work described here is completely independent of his research.
The natural entry point in this area is the p4 protocol. We found a p4 test client on SAP Collaboration Network and sniffed the traffic. One doesn’t need to wait long until a serialized object is sent over the wire:

00000000  76 31                                            v1
00000002  18 23 70 23 34 4e 6f 6e  65 3a 31 32 37 2e 30 2e .#p#4Non e:127.0.
00000012  31 2e 31 3a 35 39 32 35  36                      1.1:5925 6

    00000000  76 31 19 23 70 23 34 4e  6f 6e 65 3a 31 30 2e 30 v1.#p#4N one:10.0
    00000010  2e 31 2e 31 38 34 3a 35  30 30 30 34             .1.184:5 0004

0000001B  00 00 11 00 00 00 00 00  00 00 ff ff ff ff 00 00 ........ ........
0000002B  00 00 00 00 00 00 0a 00  63 00 6f 00 63 00 72    ........ c.o.c.r

    0000001C  00 00 75 00 00 00 ff ff  ff ff 9e 06 60 00 00 00 ..u..... ....`...
    0000002C  00 00 00 00 00 00 0b 9e  06 60 00 f7 25 e4 05 00 ........ .`..%...
    0000003C  00 00 00 00 00 00 00 98  9c 0e 2a 00 4e 00 6f 00 ........ ..*.N.o.
    0000004C  6e 00 65 00 3a 00 31 00  30 00 2e 00 31 00 30 00 n.e.:.1. 0...1.0.
    0000005C  2e 00 31 00 30 00 2e 00  31 00 30 00 3a 00 35 00 ..1.0... 1.0.:.5.
    0000006C  30 00 30 00 30 00 34 00  3a 00 4e 00 6f 00 6e 00 0.0.0.4. :.N.o.n.
    0000007C  65 00 3a 00 31 00 30 00  2e 00 30 00 2e 00 31 00 e.:.1.0. ..0...1.
    0000008C  2e 00 31 00 38 00 34 00  3a 00 35 00 30 00 30 00 ..1.8.4. :.5.0.0.
    0000009C  30 00 34                                         0.4

0000003A  00 00 16 00 00 00 9e 06  60 00 ff ff ff ff fe 00 ........ `.......
0000004A  00 00 00 00 00 00 14 00  00 00 00 00 00 00 00 00 ........ ........
0000005A  98 9c 0e 2a                                      ...*
0000005E  00 00 75 00 00 00 9e 06  60 00 ff ff ff ff 01 00 ..u..... `.......
0000006E  00 00 00 00 00 00 00 00  00 00 00 00 20 00 00 67 ........ .... ..g
0000007E  00 65 00 74 00 43 00 6c  00 61 00 73 00 73 00 42 .e.t.C.l .a.s.s.B
0000008E  00 79 00 4e 00 61 00 6d  00 65 00 28 00 6a 00 61 .y.N.a.m .e.(.j.a
0000009E  00 76 00 61 00 2e 00 6c  00 61 00 6e 00 67 00 2e .v.a...l .a.n.g..
000000AE  00 53 00 74 00 72 00 69  00 6e 00 67 00 29 00 00 .S.t.r.i .n.g.)..
000000BE  00 00 00 00 00 00 98 9c  0e 2a ac ed 00 05 74 00 ........ .*....t.
000000CE  12 43 6c 69 65 6e 74 49  44 50 72 6f 70 61 67 61 .ClientI DPropaga
000000DE  74 6f 72                                         tor
  


The highlighted part is just the java.lang.String object “ClientIDPropagator”.

Now our plan was to replace this serialized object by a ysoserial payload. Therefore, we needed to find out how the length of such a message block is encoded.

When we look at offset 0000005E, for instance, the 00 00 75 00 looks like 2 header null bytes and then a length in little endian format. Hex 75 is 117, but the total length of the last block is 8*16+3 = 131. If one looks at the blocks the client sent before (at offset 0000001B and 0000003A) one can easily spot that the real length of the block is always 14 more than what is actually sent. This lead to the first conclusion: a message block consists of 2 null bytes, 2 bytes length of the payload in little endian format, then 10 bytes of some (not understood) header information, then the payload:

When running the test client several times and by spotting the messages carefully enough one can see that the payload and header aren’t static: They use 2 4-bytes words sent in the second reply from
the server:


That was enough to set up a first small python program: Send the corresponding byte arrays in the right order, read the replies from the network, set the 4 byte words accordingly and replace “ClientIDPropagator” by the ysoserial Jdk7u21 gadget.

Unfortunately, this didn’t work out at first. A bit later we realized that SAP NetWeaver Java obviously didn’t serialize with the plain vanilla Java ObjectOutputStream but with a custom serializer. After twisting and tweaking a bit we were finally successful. Details are left to the reader ;-)

To demonstrate how dangerous this is we have published a disarmed exploit on github [5]. Instead of using a payload that writes a simple file to the current directory (e.g. cw98653.txt with contents "VULNERABLE"), like we did, an attacker can also add bytecode that runs Runtime.getRuntime().exec("rm -rf *") or establish a remote shell on the system and thereby compromise the system or in the worst case even parts of the SAP landscape.

We could successfully verify this exploit on the following systems:
  •  SAP Application Server Java 7.20 with SAPJVM 1.6.0_07 (build 007)
  •  SAP Application Server Java 7.30 with SAPJVM 1.6.0_23 (build 034)
  •  SAP Application Server Java 7.40 with SAPJVM 1.6.0_43 (build 048)
After SAP Product Security’s response, we downloaded SAPJVM 1.6.0_141 build 99 from [6] and indeed, the AnnotationInvocationHandler, which is at the core of theJdk7u21 gadget exploits, was patched. So, with that version, the JdkGadget cannot be used anymore for exploitation.

However, since staying up-to-date with modern software product release cycles is a big challenge for customers and the corresponding SAP notes do not explicitely bring the reader’s attention to a severe security vulnerability, we’d like to raise awareness that not updating the SAP JVM can expose their SAP systems to serious threats.

Mitigation

  •  Block p4 on your firewall
  •  Make sure your SAP JVM is up-to-date

References

  1. https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkinsopennms-
    and-your-application-have-in-common-this-vulnerability/
  2. http://codewhitesec.blogspot.de/2016/04/infiltrate16-slidedeck-java-deserialization.html
  3. https://github.com/frohoff/ysoserial
  4. https://cal.sap.com/
  5. https://github.com/codewhitesec/sap-p4-java-deserialization-exploit
  6. https://tools.hana.ondemand.com/additional/sapjvm-6.1.099-linux-x64.zip
  7. SAP Note 1875035 (available to customers since June, 2013) for SAP JVM 5
  8. SAP Note 1875026 (available to customers since June, 2013) for SAP JVM 6
  9. SAP Note 1875042 (available to customers since June, 2013) for SAP JVM 7
  10. SAP note 2443673 from April 2017