Java serialization Remote Command Execution detection ModSecurity rules
In 2015 a interesting article published by Foxglove Security team put a vulnerability that exploited Java serialization on the spotlight, which was present in the Apache commons library, such library is present in many different, the exploitation using a tool as ysoserial was really easy.
Even if the main goal of this site is to promote positive security filtering writing a few rules to prevent the exploitation of vulnerabilities such as this (often hidden in the applications inherited from libraries or frameworks) can be convenient and fast to deploy without having to wait for the next patch cycle or a new application build.
Burpsuite is a web application proxy that have a couple of extensions to help identifying and exploiting java deserialization vulnerabilities (Java Deserialization Scanner only for pro version and the Java Serial Killer extensions), the tools can be used for testing the applications and the WAF rules to block such kind of attacks.
A recent vulnerability CVE-2017-9805 in Apache Struts may also be addressed the same way, black listing some keywords is helpful .
ModSecurity Rules
These rules assume that a request body processor is parsing the request into ARGS, XML or REQUEST_BODY variables is in use (URLENCODED, XML, JSON), if that is not the case the rules will not fire at all (no body processor or MULTIPART body processor).
# [ Java serialization vulnerability/Apache Commons (CVE-2015-4852) ] # # Detect exploitation of "Java serialization" vulnerability in Apache commons library. # # Based on rules by @spartantri. # https://spartantri.com/ModSecurity/?p=44 # # https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/ # https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet # SecStreamInBodyInspection On # Potential false positives with random fields, the anomaly level is set low to avoid blocking request SecRule STREAM_INPUT_BODY "@rx (\xac\xed\x00\x05)" \ "msg:'Magic bytes Detected, probable java serialization in use',\ phase:request,\ rev:'1',\ ver:'OWASP_CRS/3.1.0',\ maturity:'7',\ accuracy:'7',\ pass,\ id:932178,\ tag:'application-multi',\ tag:'language-java',\ tag:'platform-multi',\ tag:'attack-rce',\ tag:'OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION',\ tag:'WASCTC/WASC-31',\ tag:'OWASP_TOP_10/A1',\ tag:'PCI/6.5.2',\ severity:'NOTICE',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rce_score=+%{tx.notice_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RCE-%{matched_var_name}=%{tx.0},\ setvar:tx.ysoserial_2000=1" # Looking for possibly RCE vulnerable java classes if magic bytes were detected, # anomaly score set to warning as both conditions may indicate a possibly vulnerable application SecRule &TX:ysoserial_2000 "!@eq 0" \ "msg:'Probable java serialization containing vulnerable java class in use',\ phase:request,\ rev:'1',\ ver:'OWASP_CRS/3.1.0',\ maturity:'7',\ accuracy:'7',\ block,\ id:932179,\ tag:'application-multi',\ tag:'language-java',\ tag:'platform-multi',\ tag:'attack-rce',\ tag:'OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION',\ tag:'WASCTC/WASC-31',\ tag:'OWASP_TOP_10/A1',\ tag:'PCI/6.5.2',\ severity:'WARNING',\ chain" SecRule ARGS|XML|REQUEST_BODY "@rx (CloneTransformer|ForClosure|InstantiateFactory|InstantiateTransformer|InvokerTransformer|PrototypeCloneFactory|PrototypeSerializationFactory|WhileClosure)" \ "t:none,\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rce_score=+%{tx.warning_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RCE-%{matched_var_name}=%{tx.0},\ setvar:tx.ysoserial_2001=1" # Magic bytes detected and payload included possibly RCE vulnerable classess detected and process execution methods detected # anomaly score set to critical, the request attempt to perform RCE. SecRule &TX:ysoserial_2000 "!@eq 0" \ "msg:'Remote Command Execution: Java serialization (CVE-2015-5842)',\ phase:request,\ rev:'1',\ ver:'OWASP_CRS/3.1.0',\ maturity:'7',\ accuracy:'7',\ block,\ id:932180,\ tag:'application-multi',\ tag:'language-java',\ tag:'platform-multi',\ tag:'attack-rce',\ tag:'OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION',\ tag:'WASCTC/WASC-31',\ tag:'OWASP_TOP_10/A1',\ tag:'PCI/6.5.2',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ severity:'CRITICAL',\ chain" SecRule ARGS|XML|REQUEST_BODY "(runtime|processbuilder)" \ "t:none,t:lowercase,\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rce_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RCE-%{matched_var_name}=%{tx.0}" # Generic rule to detect processbuilder or runtime calls, if any of thos is found and the same target contains # java. unmarshaller or base64data to trigger a potential payload execution # tested with https://www.exploit-db.com/exploits/42627/ SecRule ARGS|XML:/*|REQUEST_BODY|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML "@rx (?:runtime|processbuilder)" \ "msg:'Remote Command Execution: Java process spawn (CVE-2017-9805)',\ phase:request,\ rev:'1',\ ver:'OWASP_CRS/3.1.0',\ maturity:'7',\ accuracy:'7',\ t:none,t:lowercase,\ block,\ id:932181,\ tag:'application-multi',\ tag:'language-java',\ tag:'platform-multi',\ tag:'attack-rce',\ tag:'OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION',\ tag:'WASCTC/WASC-31',\ tag:'OWASP_TOP_10/A1',\ tag:'PCI/6.5.2',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ severity:'CRITICAL',\ ,t:none,t:lowercase,\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rce_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RCE-%{matched_var_name}=%{tx.0},\ chain" SecRule MATCHED_VAR "@rx (?:unmarshaller|base64data|java\.)"
Sample rule output caused by ysoserial payloads
ysoserial payload generation
$ java -jar ysoserial-master-v0.0.5-g52383a1-6.jar CommonsCollections1 "ping spartantri.com" ��sr2sun.reflect.annotation.AnnotationInvocationHandlerU���~�L java.util.Mapxrjava.lang.reflect.Proxy�'� �C�Lht%Ljava/lang/reflect/InvocationHandler;xpsq~sr*org.apache.commons.collections.map.LazyMapn唂�y�Lfactoryt,Lorg/apache/commiTransformerst-[Lorg/apache/commons/collections/Transformer;xpur-[Lorg.apache.commons.collections.Transformer;�V*��4�xpsr;org.apache.commons.collections.functors.ConstantTransformerXv�A��L iConstanttLjava/lang/Object;xpvrjava.lang.Runtimexpsr:org.apache.commons.collections.functors.InvokerTransformer���k{|�8[iArgst[Ljava/lang/Object;L iMethodNametLjava/lang/String;[ iParamTypest[Ljava/lang/Class;xpur[Ljava.lang.Object;��X�s)lxpt getRuntimeur[Ljava.lang.Class;���Z�xpt getMethoduq~vrjava.lang.String���8z;�Bxpvq~sq~uq~puq~tinvokeuq~vrjava.lang.Objectxpvq~sq~ur[Ljava.lang.String;��V��{Gxptping spartantri.comtexecuq~q~#sq~srjava.lang.Integer⠤���8Ivaluexrjava.lang.Number��� ���xpsrjava.util.HashMap���`�F
Auditlog output
tail -1 /var/log/apache2/modsec_audit.log |jq '.audit_data.error_messages' [ "[file \"apache2_util.c\"] [line 273] [level 3] [client 127.0.0.1] ModSecurity: Warning. Pattern match \"test\" at REQUEST_HEADERS:content-type. [file \"/usr/share/modsecurity-crs/owasp-crs.load\"] [line \"23\"] [id \"147\"] [hostname \"localhost\"] [uri \"/index.html\"] [unique_id \"WbG6838AAQEAAB4C4-gAAAAB\"]", "[file \"apache2_util.c\"] [line 273] [level 3] [client 127.0.0.1] ModSecurity: Warning. Pattern match \"(\\\\\\\\\\\\\\\\xac\\\\\\\\\\\\\\\\xed\\\\\\\\\\\\\\\\x00\\\\\\\\\\\\\\\\x05)\" at STREAM_INPUT_BODY. [file \"/usr/share/modsecurity-crs/owasp-crs.load\"] [line \"47\"] [id \"932178\"] [rev \"1\"] [msg \"Magic bytes Detected, probable java serialization in use\"] [severity \"NOTICE\"] [ver \"OWASP_CRS/3.1.0\"] [maturity \"7\"] [accuracy \"7\"] [tag \"application-multi\"] [tag \"language-java\"] [tag \"platform-multi\"] [tag \"attack-rce\"] [tag \"OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION\"] [tag \"WASCTC/WASC-31\"] [tag \"OWASP_TOP_10/A1\"] [tag \"PCI/6.5.2\"] [hostname \"localhost\"] [uri \"/index.html\"] [unique_id \"WbG6838AAQEAAB4C4-gAAAAB\"]", "[file \"apache2_util.c\"] [line 273] [level 3] [client 127.0.0.1] ModSecurity: Warning. Pattern match \"(CloneTransformer|ForClosure|InstantiateFactory|InstantiateTransformer|InvokerTransformer|PrototypeCloneFactory|PrototypeSerializationFactory|WhileClosure)\" at ARGS:payload. [file \"/usr/share/modsecurity-crs/owasp-crs.load\"] [line \"69\"] [id \"932179\"] [rev \"1\"] [msg \"Probable java serialization containing vulnerable java class in use\"] [severity \"WARNING\"] [ver \"OWASP_CRS/3.1.0\"] [maturity \"7\"] [accuracy \"7\"] [tag \"application-multi\"] [tag \"language-java\"] [tag \"platform-multi\"] [tag \"attack-rce\"] [tag \"OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION\"] [tag \"WASCTC/WASC-31\"] [tag \"OWASP_TOP_10/A1\"] [tag \"PCI/6.5.2\"] [hostname \"localhost\"] [uri \"/index.html\"] [unique_id \"WbG6838AAQEAAB4C4-gAAAAB\"]", "[file \"apache2_util.c\"] [line 273] [level 3] [client 127.0.0.1] ModSecurity: Warning. Pattern match \"(CloneTransformer|ForClosure|InstantiateFactory|InstantiateTransformer|InvokerTransformer|PrototypeCloneFactory|PrototypeSerializationFactory|WhileClosure)\" at REQUEST_BODY. [file \"/usr/share/modsecurity-crs/owasp-crs.load\"] [line \"69\"] [id \"932179\"] [rev \"1\"] [msg \"Probable java serialization containing vulnerable java class in use\"] [severity \"WARNING\"] [ver \"OWASP_CRS/3.1.0\"] [maturity \"7\"] [accuracy \"7\"] [tag \"application-multi\"] [tag \"language-java\"] [tag \"platform-multi\"] [tag \"attack-rce\"] [tag \"OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION\"] [tag \"WASCTC/WASC-31\"] [tag \"OWASP_TOP_10/A1\"] [tag \"PCI/6.5.2\"] [hostname \"localhost\"] [uri \"/index.html\"] [unique_id \"WbG6838AAQEAAB4C4-gAAAAB\"]", "[file \"apache2_util.c\"] [line 273] [level 3] [client 127.0.0.1] ModSecurity: Warning. Pattern match \"(runtime|processbuilder)\" at REQUEST_BODY. [file \"/usr/share/modsecurity-crs/owasp-crs.load\"] [line \"99\"] [id \"932180\"] [rev \"1\"] [msg \"Remote Command Execution: Java serialization (CVE-2015-5842)\"] [data \"Matched Data: found within REQUEST_BODY: payload=\\\\\\\\xac\\\\\\\\xed\\\\\\\\x00\\\\\\\\x05sr\\\\\\\\x00\\\\\\\\x17java.util.priorityqueue\\\\\\\\x94\\\\\\\\xda0\\\\\\\\xb4\\\\\\\\xfb?\\\\\\\\x82\\\\\\\\xb1\\\\\\\\x03\\\\\\\\x00\\\\\\\\x02i\\\\\\\\x00\\\\\\\\x04sizel\\\\\\\\x00\\\\\\\\x0acomparatort\\\\\\\\x00\\\\\\\\x16ljava/util/comparator;xp\\\\\\\\x00\\\\\\\\x00\\\\\\\\x00\\\\\\\\x02sr\\\\\\\\x00borg.apache.commons.collections4.comparators.transformingcomparator/\\\\\\\\xf9\\\\\\\\x84\\\\\\\\xf0+\\\\\\\\xb1\\\\\\\\x08\\\\\\\\xcc\\\\\\\\x02\\\\\\\\x00\\\\\\\\x02l\\\\\\\\x00\\\\\\\\x09decoratedq\\\\\\\\x00~\\\\\\\\x00\\\\\\\\x01l\\\\\\\\x00\\\\\\\\x0btransformert\\\\\\\\x00-lorg/apache/commons/collections4/transformer;xpsr\\\\\\\\x00@org.apache.commons.collections4.comparators.comparablecomparator\\\\\\\\xfb...\"] [severity \"CRITICAL\"] [ver \"OWASP_CRS/3.1.0\"] [maturity \"7\"] [accuracy \"7\"] [tag \"application-multi\"] [tag \"language-java\"] [tag \"platform-multi\"] [tag \"attack-rce\"] [tag \"OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION\"] [tag \"WASCTC/WASC-31\"] [tag \"OWASP_TOP_10/A1\"] [tag \"PCI/6.5.2\"] [hostname \"localhost\"] [uri \"/index.html\"] [unique_id \"WbG6838AAQEAAB4C4-gAAAAB\"]" ]
Conclusion
Filtering requests such as this to allow only well known serilized requests while blocking malicious requests can be very complicated as there are many different elements. It will also be difficult to make the standard CRS to pass but with a little bit of additional details to identify possible RCE and vulnerable classes the false positive rates reduces dramatically and still have a descent protection against common tools.
The rules listed here are designed for standard attacks, other variants produced by Burpsuite “Deserialization Scanner” extension can use multiple types of encoding such as base64, asciihex, base64gzip and gzip.