This article mainly introduces the PHP forced conversion type and security risks of Remote Management plug-ins. For more information, see
This article mainly introduces the PHP forced conversion type and security risks of Remote Management plug-ins. For more information, see
The Remote Management plug-in is currently widely used by WordPress site administrators. It allows users to perform the same operations on multiple sites at the same time, such as updating to the latest release version or installing the plug-in. However, to implement these operations, the client plug-in must grant the remote user great permissions. Therefore, it is very important to ensure the communication security between the management server and the client plug-in and not be forged by attackers. This article analyzes several available plug-ins. using their vulnerabilities, attackers can even completely compromise the websites running these plug-ins.
ManageWP, InfiniteWP, and CMS Commander
These three services share the same basic code of the client plug-in (originally the ManageWp implementation, and then the other two have adjusted it ), therefore, they all have the signature Bypass Vulnerability and cause remote code execution.
The Management Server registers the private key of a client plug-in to calculate the message authentication code for each message, rather than requiring the user to provide administrator creden( (MAC, we usually see it as the MAC address of the hardware. Here is the Message Authentication Code ). A message digest is generated when a message uses the message digest algorithm of the shared key. The MAC is then sent along with the message. After receiving the message, the receiver uses the shared key to calculate the received message, generate MAC2, and then compare it with MAC1. The message digest is used to verify the authenticity and integrity of messages (everyone who has learned cryptography should know about it). This is a good way to ensure communication security, however, the implementation defects of the client plug-ins of these three services lead to serious vulnerabilities.
A message that is authenticated by helper. class. php is as follows:
// $ Signature is the MAC sent with the message // $ data is part of the message if (md5 ($ data. $ this-> get_random_signature () ==$ signature) {// valid message}
Using non-strict equals means that the type "spoofing" [type conversion] will occur before the comparison. The output of the md5 () function is always a string, but if $ signature is changed to an integer, the type conversion that occurs during the comparison is easy to forge a matching MAC. For example, if the actual MAC address starts with "0" or a non-numeric character, then 0 can match. If it is "1xxx", then integer 1 can match, and so on. (This is actually a feature of php, and of course there will be other languages. When a string and a number are not strictly equal to each other, if the first character is a number, it will be converted to the corresponding integer for comparison. If it is not a 0-9 character, it will be treated as 0, php.net official description: if you compare a number with a string or a string that involves the content of a number, the string is converted to a value and compared to a value ).
Convert a string to a numeric value:
When a string is taken as a value, the result and type are as follows:
If the string does not contain '.', 'E', or 'e' and Its numeric value is within the integer Range (defined by PHP_INT_MAX), the string is treated as an integer. All other cases are taken as float values.
The starting part of the string determines its value. This value is used if the string starts with a valid value. Otherwise, the value is 0 (0 ). A valid value is an optional positive or negative number followed by one or more numbers (which may have a decimal point) and then an optional index. The index is composed of one or more numbers following 'E' or 'e.
<? Phpvar_dump (0 = "a"); // 0 = 0-> truevar_dump ("1" = "01 "); // 1 = 1-> truevar_dump ("10" = "1e1"); // 10 = 10-> truevar_dump (100 = "1e2 "); // 100 = 100-> truevar_dump ('abcdefg' = 0); // true var_dump ('1abcdef' = 1 ); // true var_dump ('2abcdef '= 2); // true?>
Unfortunately, attackers can provide an integer as the signature. In init. php, the input request will be decoded using base64_decode (), and the result will be deserialized. The use of Unserialize () means that the type of input data can be controlled. A forged serialized message is as follows:
A: 4: {s: 9: "signature"; I: 0; s: 2: "id"; I: 100000; s: 6: "action"; s: 16: "execute_php_code"; s: 6: "params"; a: 2: {s: 8: "username"; s: 5: "admin"; s: 4: "code"; s: 25: "exec ('touch/tmp/owned ');";}}
This message uses an integer 0 as the signature, and then executes arbitrary PHP code using the execute_php_code provided by the plug-in.
$ Signature = 0; // $ data is the action concatenated with the message ID $ data = 'execute _ php_code '. 100000; if (md5 ($ data. $ this-> get_random_signature () = $ signature) {// valid message if the output of // md5 () doesn't start with a digit}
This spoofed example may not be used directly. First, the key value of the id must be greater than the value of the previous valid message. (The added Message ID is used to prevent replay attacks. Today, requests are both forged, there is also replay, which reminds me of CSRF, Cross-Site Request Forgery, is there a man-in-the-middle attack?), followed by an integer used to match the signature, these two requirements can be broken through brute force cracking.
For I from 100,000 to 100,500: for j from 0 to 9: submit request with id I and signature j
The above pseudo code tries to send a message with a large ID worthy of false, and matches each ID with a single digital fingerprint ten times (as mentioned earlier, for a string, only one number can be matched during comparison. Here, it is from 0-9 because it can be encountered in every situation ).
This defect can be fixed by using the full equal operator [=] and checking the passed fingerprint. These plug-in services are repaired by using the strict equal-all operator (php.net Description: a = B, then a and B are equal, and the types are also equal; a = B. After the type conversion occurs, determine whether the value is equal ).
There are other problems, but they have not taken any action yet. First, this approach is flawed (the key is appended to $ data and then HMAC (Hash-based Message Authentication Code, generate a message digest as the output using one key and one message as the input ). Second, only the action and Message ID used for the operation are used to create a signature. This means that an active network attacker can change the parameters in the message and the signature is still valid (for example, changing the execute_php_code message to execute arbitrary code ). For protection, MAC should contain the entire message.
(Note that the MD5-based message digest is backward. If possible, these plug-ins use openssl_verify (); * ** the Openssl 1.0.f heartbleed vulnerability announced on February 4, is known as a century-level vulnerability ***)
WORPIT
Worpit is another remote management service, but it uses a client plug-in built from scratch. It also has a forced type conversion vulnerability that allows attackers to log on with administrator privileges.
This plug-in provides a Remote Administrator Logon method. Only Woprit can be used to pass the temporary token value that can be configured by the system. This plugin checks whether the token value provided in the request matches the value stored in the database.
If ($ _ GET ['Token']! = $ OWpHelper-> getTransient ('worpit _ login_token') {die ('worpiterror: Invalid token ');}