Clean code, easy to develop code, … Does the programmer know about safe code ??? (Part 2)

Tram Ho

As promised at the end of part 1 , in this part 2 I will talk about the flaws: PHP Type Juggling, Hard Coded, Processing important data at Client side, Using insecure random number generator, … .

I will still take the challenges in the Secure Coding CTF as an analysis example. It is convenient to have a visual example, and continue to write up for challenges.

Now let’s continue with Secure Coding

3. PHP Type Junggling

The typle junggling vulnerability occurs because PHP supports two methods of comparison: Loose comparisons and Strict comparisons.

Absolute comparison is used with 3 equal signs === . This type of comparison only returns TRUE when two variables are compared with the same data type and value .

Relative comparison is used with 2 equal signs == . This type of comparison is more flexible, but also creates holes that the programmer is not aware of. This is because when doing a comparison, PHP will try to return 2 variables to a common data type. If 2 variables are compared the same in terms of both data type and value , the absolute comparison is done.

However, when the data types of two variables are different, during the conversion to common data types, their values ​​may be changed. This can produce undesirable results bias. If this can be exploited, the attacker has the ability to:

  • Pass some authentication steps
  • Change the flow of the program as desired
  • Causes the program to have a logic error.

3.1. Example 1: Junggling 1


We just need to pay attention to the PHP code in the source file is:

In the code, the password is specified as a string: 999 . But if we enter 999, then when we encounter the first if, the === comparison will immediately change our input to =P To echo out the flag, we need to bypass the first if and get to the second if, or in other words, find an input that satisfies the following two conditions simultaneously:

  • It can’t be 999
  • A relative comparison of the string 999 must return FALSE

To make it easy to find the matching input, we should look at the 3 comparison tables in the PHP comparison documentation

I have marked it on the relative comparison table to make it easier:

Comparing string 1 is similar when comparing string 999 so I have circled the whole line in blue. TRUE probabilities are the direction we need to find to satisfy the second if paragraph. In which, the case that is circled out should be eliminated because this case will be blocked at the first if (“1” == “1” returns TRUE and “1” === “1” also returns TRUE).

Note: when reading the value from GET request, our input is just a string, so it will not be able to pass a boolean value. Then there is only 1 most viable option, which is to compare a number with a string. With this option, it will be clearer to see how PHP handles the variable type when doing the comparison in the table below.

So when doing a comparison of 2 strings with each other, PHP will convert all the number to a number, and then perform a comparison between 2 numbers together.

=> Need to find a string that is different from 999 , but when converted to a natural number, the value must be = 999.

=> That string is 0999 :

  • 0999 === 999 => FALSE
  • 0999 == 999 => TRUE

3.2. Example 2: Junggling 2


This time the PHP code compares as follows:

This time, to get the flag, we need to input input so that strcmp($_GET['password'], $actualPass) returns 0. I have circled the cells as shown below because strcmp only returns 4 types of values: <0 , 0,> 0 and null.

To pass validation we need the strcmp function to return 0 or null . We can only find a way to make strcmp return null, because we don’t know the password, we can’t make strcmp return 0.

When we read the document about the PHP strcmp function, we easily see that there are a number of cases where strcmp returns null.

Where, when comparing a string to an array, strcmp returns null. Which we can enter an array by changing ?password= to ?password[]=

In short, there are cases where programmers can only use relative comparison. But if possible, always use absolute comparison. Even when it appears harmless, relative comparisons can still mislead the logic of the code because of the potential for unpredictable results.

4. Hard Coded

Hard coded is an error caused by the programmer to reveal important information in the code. When this code is somehow exposed and a bad guy can use this information to attack. Depending on the importance of the information, the consequences can range from nothing to very serious effects.

For example the case gets $ 4000 bounty on this hackerone . Starbuck revealed JumpCloud API key in public repo on Github. If you search on github, sometimes you will find some API keys hard-coded in public repos.

I have encountered this error in practice. It is in the source code of an android application that still hardcodes the staging server address with basic authen. Even the primary account can still log into the staging environment.

Example: Sloth


The login information in the code was revealed as follows:

  • Reveal username on line 58:

  • Reveal the admin password hash on line 29:

Not only exposing login information, this case is also a vulnerability in using insecure hashes due to password hashing using the MD5 algorithm. Just using online tools, anyone can find the root password.

With the login information as admin / sunshine, we can login and get the flag

In addition to this example, in the git log disclosure example in Part 1 I mentioned hard coded credentials as well but later removed it from the code.

In a nutshell, there is only one way to avoid revealing important information, which is to be very careful with each hard-coded information. Make sure that this information has no value to help attack the system to hard code it. Minimize the hard code.

5. Process important data at Client Side

This error occurs because the programmer performs some data processing functions at the client, then just upload the results to the server. This can somewhat reduce the work Server has to do, but just need to know how to use the basic Burp Suite, we can easily block and fix the request before sending it.

Suppose the case is as follows: Trong năm Covid thứ 2, trường X triển khai hệ thống làm bài kiểm tra trắc nghiệm online cho học sinh. Sau khi học sinh bấm nút "NỘP BÀI" thì ở phía Client sẽ đối chiếu đáp án và chấm điểm luôn, rồi gửi điểm lên Server để lưu kết quả lại. Tôi là học sinh Z học lớp 1F, với tài năng của 1 script kiddie chính hiệu, tôi đã bật burp suite lên và chặn request, sửa điểm bài thi từ 2.5 thành 10. Cuối năm học, không ngoài dự đoán tôi đã đứng đầu trường.

Through the case of học sinh Z above, it can be seen that it is very dangerous when we process important data at Client Side.

Example: Client Destroyer


The Client Destroyer article has 1 PHP code and 1 JS code:

  • PHP:

  • JS:

In the PHP code, we know that the password is , but the password is still incorrect when entered. This happens because the below JS snippet, it will remove all dots . go.

But since this script is written right in the php file, we can use Chrome Dev Tools to fix the validate () function. Just F12 => Console tab => copy and paste the above JavaScript code but delete the line input = input.replaceAll (“.”, “”); go => Enter to execute function override.

Then we can enter the password and get the flag.

Thus, to ensure the system works properly, with important functions, only input from the user should be sent to the server for processing.

6. Using unsafe random number generator

The problem with insecure random number generators is often referred to with the Java programming language. Java generic level 2 random number generating library is java.util.Random and

Both libraries above are capable of generating random numbers, but is considered True Random (Random Number Genarator – RNG) and java.util.Random is not appreciated, is considered Pseudo Random – pseudorandom (pseudo random Number genarator – PRNG).

As I understand, it is possible to determine the randomness of the number generator by evaluating 2 factors:

  • Random generation algorithm
  • The seed algorithm

Regarding the randomization algorithm, I am not good at algorithms to be able to comment. As for the seed, I do know a little bit. Seed is one parameter from which from this seed the random generation algorithm can generate sequences of random numbers. With identical seeds, the generated sequence of random numbers will be identical in both the value of each element and their order.

RNG algorithms are recommended for products that require high security not only because of a good generation algorithm, but also the way the seeding algorithm is complexed to ensure seed values ​​are random and non-existent. at 2 seed the same.

For example: Thunderstruck


It is still required to log in to get the flag, the user name is admin, and the password is generated by the generateSecurePassword () function. But this function is not safe at all:

The above function generates a password by randomly taking 1 number in the range 0 -> 20, then through a series of calculations to create a password. With such a small number, only about 20 passwords can be generated. We just need to try running the algorithm with values ​​from 0 -> 19, then try in turn the generated passwords.

And seed = 19 will generate the correct password 867281 .

I would like to end part 2 here. In the next part I will mainly mention OS Command Injection vulnerability.

Share the news now

Source : Viblo