Objective
PHP is a common open source scripting language, with its syntax mixed with C,java and the syntax of excellent languages such as Perl. In addition, it provides a wide range of function libraries for developers to use. However, if used improperly, PHP also poses a very large security risk to the application.
In this article, we will delve into some of the problems that often arise in PHP applications, especially when we use the "= =" (comparison operator) for string comparisons, some security issues may arise. Although there have been a lot of recent articles around this topic has been discussed, but I decided from the "black box test" point of view, discuss how to use this problem to penetrate and attack the target. First, I will analyze the root cause of the problem so that we can understand its working mechanism more deeply so that we are able to avoid this security problem as much as possible.
Description of the problem
In 2011, the official PHP vulnerability tracking system found that when strings and numbers were compared, there were some very strange phenomena in the program. From a security standpoint, this problem is not actually a security issue. For example, you can see the following code:
In fact, this occurs when you are working with a comparison operator such as "= =". The problem in the example above is not a vulnerability because it is a feature called "type Conversion" provided by PHP. Essentially, when we use a specific comparison operator (e.g. = =,!=, <>), PHP first tries to determine the type of data that is involved in the comparison. But such a type conversion mechanism would have the potential to result in a large discrepancy between the results of the calculations and the results we expect, as well as a very serious security problem. Security research experts wrote in the full disclosure report of the issue: this type of conversion mechanism will likely lead to elevated privileges and even make the program's password verification process unsafe.
Gynvael wrote a classic article on this topic, the PHP equals operator "= =" covers a wide range of data types, we provide you with a more complete list of comparative reference, and gives some examples, the details are as follows:
As you can see, when we use "= =" to compare these numeric strings, the actual size of the numbers in the string is a part of the comparison, which is a very interesting question from a security standpoint. In this case, you can use the scientific notation to represent a number and place it in a string, and PHP will automatically treat it as a numeric type. We get this type of output because PHP uses a hash algorithm (usually a hexadecimal numeric representation) for processing. For example, if a number is 0, PHP will automatically convert its type, but its value will always be 0, during a loose comparison. For a given hash algorithm, the password is likely to become replaceable. For example, when the hash value of a password is converted to a number represented by the scientific notation, it is possible to match the other password hashes exactly. As a result, even a completely different password may be validated by the system. But interestingly, when some of the numbers used in the scientific notation are compared, the results may surprise you:
Consider this problem from the angle of "black box test"
From the point of view of static analysis, these security problems seem to be a little common. But if we look at these issues from a black box perspective, what can we get? For any user account in the application, if the application uses the most current hash hashing algorithm (such as SHA1 and MD5) to process the password, And you use a loose comparison of PHP when you verify the password hash, then there is a risk of security problems. We can now consider a typical penetration test where you can create a normal account, set the password to one of the passwords similar to the hash value, and then use the other password for the login operation. Obviously, the security of the system depends entirely on the hashing algorithm you are using. So, let's say you don't use the "Salt" value in the hash algorithm, you have to use at least two different hashing algorithms to handle the password.
Now, before we go into the combination of these passwords, we should also consider the one o'clock-the requirement of the password. Because before we analyze these passwords and hashing algorithms, we first have to make sure that the initial password we set is compounded by the requirement of password complexity, otherwise our analysis and research will have no meaning. So we have to make sure that our password is at least eight characters long, that the password contains uppercase and lowercase letters, numbers, and at least one special character: as follows:
Import random import Hashlib import re import string import sys
Prof = Re.compile ("^0+ed*[ubbcodeplace_1]quot;) # You can also Consider:re.compile (" ^d*e0+[ubbcod Eplace_1]quot) prefix = string.lower (sys.argv[1]) + '! ' +string.upper (sys.argv[1]) + '%s ' num=0 while True:
Num+=1 B = hashlib.sha256 (prefix% num). Hexdigest () if (b[0]== ' 0 ' and Prof.match (b)): Print (PREFIX+STR (num), b) for this purpose, I wrote a python script, and although I didn't do everything I could to optimize the performance of this script, with the help of the PyPy compiler, this well-written script could run stably in all of the CPU cores available to my AMD FX8350. In addition, I used the hash function in the Hashlib library, and to avoid encountering the Python Gil process synchronization problem, I also generated a separate process to process the password data. Not only that, I also used a very complex technique to generate a different prefix for each password, as shown in the preceding code.
Analysis results
After one hours of analysis, I got the SHA1 value of four passwords. To my surprise, it takes less time to get the MD5 value of four passwords.
The results of the password are very similar, as shown in the following example:
You can select two passwords to compare and compare the results as follows:
If you can't get the results as shown in the above figure, then you should feel lucky. You can try to bundle the username and password together, and then use a hash algorithm with a "salt" value to compute. You only need to modify a small number of code to achieve, click "Here" to get the modified script.
Solution
PHP provides us with a solution, and if you want to Bihachi values, you should use the password_verify () or hash_equals () two functions. They make a rigorous comparison of the data and exclude some other interference factors. But please note that the hash_equals () function can also be used for string comparisons.
Analysis conclusion
While our analysis steps are a bit too complex to execute, from the perspective of black box testing, the approach we describe may provide some valuable information. If a password in an application uses such a validation mechanism, the security problems it poses will outweigh the problems of the PHP data type conversion itself.
The problem is much more than that.
The impact of this problem is much more than that. Attackers can add these passwords to the dictionary file and then brute-force attack attacks on all users in the application. Furthermore, if there are unsafe factors in the application's password recovery mechanism, an attacker may also have an unlimited number of attacks on the target account until the attack succeeds.