Vulnerability is a combination punch--attack of distributed nodes-the vulnerability of early warning-the black bar safety net

ID MYHACK58:62201679682
Type myhack58
Reporter 佚名
Modified 2016-09-27T00:00:00


Distributed systems mostly rely on the message queue middleware to solve the asynchronous processing, the application of coupled problems such as Message Queuing middleware of choice in turn depends on the overall system design and implementation, message packaging, transmission, processing through the entire system, if in a certain key processing logic point appears on a security, then the entire distributed nodes are likely to be destroyed. Popular development language for almost all of the presence of the sequence of improper handling result of the command execution issues, such as the Python class of the magic method reduce() in pickle Library for deserialization of the time of the call, in PHP class magic method __wakup() will also in the instance of the deserialized when invoked, and so on. From a developer's point of view, the development of language provides the data serialization and convenient way of the instance of the object across the application delivery, program A and program B can by serialized data transfer mode to remotely access the instance object or remote method calls as in Java RMI, while standing in a security researchers perspective, this cross-Application Data transfer or call way there may be objects data tampering and the method of malicious call security risks. In the message queue implementations, the message data of the sequence of package way it becomes a time bomb, unsafe serialization mode may cause the message data has been tampered with, causing the deserialization of the data analysis after a series of security issues. Message Queuing middleware of choice is also a big problem, it is common to have the RabbitMQ And ActiveMQ And Kafka, Redis, etc., and the like Redis, this presence is not authorized to access the problem component if it is the attacker the control, you can pass components direct to the message queue to insert the data, ranging from the impact throughout the distributed nodes of the logic processing, heavy then directly insert malicious data binding deserialization problem like the node group to attack. Having said that, to summarize the above-mentioned several security issues: 1, each language exists in the sequence of the questions may directly lead to remote command execution; 2, the message queue implementation will often directly use the language's own serialization, or is similar to the encapsulated message; 3, a distributed system using message queue middleware a wide range, wherein some of the distributed framework using the like Redis that there is an unauthorized access issue in the Assembly; 4, message queues, message tampering will directly or indirectly affect to a distributed node; This 4 security issues or vulnerabilities are combined together, you can become a direct invasion and destruction of the distributed nodes of the attack method. So, whether there is truly meet to the above problem instance? Currently, it has been found Python Celery the distributed framework, there is indeed such a problem, below I will for the appeal 4 questions to Celery distributed framework as an example to illustrate how to attack the distributed nodes to fight the vulnerability combination of punches. Corny Python serialization Celery a distributed framework is composed of the Python language written, to the following better description of the problem, so here is the first simple recall Python serialization security issues. 1. A simple serialization example In Python there are so one called the pickle module is used to instance the object serialization and de-serialization, a simple example: import base64 import pickle class MyObj(object): loa = 'hello my object' t_obj = MyObj() serialized = base64. b64encode(pickle. dumps(t_obj)) print('--> pickling MyObj instance {} and Base64 it\ngot "{}"'. format(t_obj, serialized)) print('--> unpickling serialized data\with "{}"'. format(serialized)) obj = pickle. loads(base64. b64decode(serialized)) print('** unpickled object is {}'. format(obj)) print('{} -> loa = {}'. format(obj, obj. loa)) Due to the pickle module to the instance of the object to serialize when generating the binary structure of the data, the transmission time will often be Base64 encoded, which can effectively prevent the number of bytes of data lost. The above procedure is a MyObj class instance is serialized and Base64-encoded and then decoded deserialization re-get the instance of a process, run the program to give output: ! Through the screenshots you can see the sequence of the former and the serialized instance is a different object address is different, and usually deserialization to instantiate a class instance, the current operating environment must first define the type to the normal sequence, otherwise may encounter can not find the correct type cannot be deserialized, for example, will the appeal process nothing two files and before a file is used to instantiate MyObj class and its serialize and then through the Base64 encoded output, then a file is used for receiving a string of a string, which is Base64 decoding after deserialization is:

import base64 import pickle class MyObj(object): loa = 'hello my object' print(base64. b64encode(pickle. dumps(MyObj ())))

import sys import base64 import pickle print(pickle. loads(base64. b64decode(sys. argv[1]))) It is said above, on deserialization if the environment does not exist in the deserialized type is defined as not defined in MyObj class, then in pairs the output results for the deserialization will fail, error message prompt cannot find the MyObj is: ! 2. Trick so that the deserialization becomes dangerous Seemingly deserialization does not instantiate any objects of the operating environment dependent but there is then some tricks can be achieved deserialize to arbitrary code execution effect. If a class defines reduce() function, then the examples of anti-serialized when pickle by reduce() function to look for the correct re-the class instantiation process. (reduce() function detailed documentation reference For example, here I in MyObj class defines reduce() function:

...class MyObj(object): loa = 'hello my object' def reduce(self): return (str, ('replaced by reduce() method', ))... Then performed on a section of the program process, it will directly give the output: ! There is no longer error message is because MyObj in sequence of time, the re-constructed class of processes to write into the serialized data, the pickle in the deserialize of the time will follow the reconstruction process to perform the appropriate action here is to use the built-in str function to operate the parameter ‘replaced by reduce() method’ and return, so successfully deserialized and output the string.

[1] [2] [3] [4] [5] [6] next