DoS via Password Strength Checker Function
Greetings, Hope y’all good and fine!
Recently, I found a very unique vulnerability and after reporting and a fix has been implemented, I was able to find another trick to hit the same vulnerability again.
The vulnerability is Denial of Service
But first let’s take a look of what DoS is:
A DOS most often happens when an application contains either functional or architectural flaws that allow for remote interactions to consume large quantities of the host system’s resources, which can lead to the system locking-up or otherwise failing to deliver content.
Case I
I was testing on a website the registration page and precisely the password parameter, There’s few attack vectors could happen here.
Let’s imagine what happens when a user enter the password, The password get hashed and saved in the database and there’s few process and checks happens before that, We will get to that in a moment.
So SQL injection is probably the first thing comes to mind when testing password in sign up page, But the website was hashing the password before inserting it into the database as we imagined.
Since there’s a hash process happens we can also try to send long password string and the hashing process will result in CPU and memory exhaustion if the string was very long and saved in the database. But the website was limiting the password to 255 characters only.
But I noticed a very interesting function which is a password complexity check! and it was implemented on the server side.
What is password complexity check?
It’s an algorithmic method to check how strong the password is by using common password wordlists and other methods one of them is l33t speak, which will comes very handy and you’ll know why later.
Now, I know that the website is using a password complexity check and it was implemented server side and most importantly this function is put before the password length limit!
So the attack vector was very clear for me from this point,
An algorithm takes user input and process it against patterns so when we put a very long password string it will probably can’t go without entering some sort of search complexity problem and that exactly what happened when entering long password string! Which cause computing resources to be drained in the process.
I started testing this with entering a long password string (500 Bytes) and the server took around 5 seconds to come back with the response. And then increased the password string to 1000 Bytes and as expected the server took around 23 seconds to reply back with a response, and the more password strings is the more web server takes time to respond ultimately causing a 504 Gateway Timeout error from the reverse proxy.
I wrote a detailed report along with a PoC and submitted the report to the program.
The program was very fast It only took them less than 10 minutes to respond few hours to fix the issue!
They fixed the issue by simply making the password complexity check happens after the password length limit which was 255 Characters which is reasonable limit for passwords generated by password managers apps.
Case II
After couple of weeks, I decided to come back to the same vulnerability and do further investigation and research.
While I was doing so I learnt more about the algorithm, the rate of growths and time complexity of the algorithm is a O(n^2), What that means? in plain English this means that this algorithm is affected by the user input and takes more time to complete the computation and considered quite slow algorithms (If the user input array has 1 element it will do 1 operation, if it has 10 elements it will do 100 operations, and so on) and also the reason for this rate that every single substring of the password is being checked by the algorithm.
So great so far. Now, how someone can take advantage of that keep in mind that we are only limited by 255 characters as a password length limit!
The answer is in the l33t speak language, as I mentioned earlier that this will comes in handy later!
What is leet speak? It is the use of substitution of a word’s letters with numbers or special characters (1337 = Leet)
The algorithm reaches the most of its time complexity when using l33t speak. How so? When user input a l33t speak string, the algorithm needs to convert that to normal plain English and then makes more pattern match and checks all substring of the password and checks it against big wordlists.
Meaning more process time meaning more time. Hence the longer the string the longer CPU consumption it takes!.
It’s time to put the theory to the test!
Collecting some l33t speak characters i.e:
1
4|)V4|\|C3D l3e+ $peA|< i$ whEn J00 +4lK L1K3 t|-|15. t0 u|\|d3r$+@|\|D jOo |\/|u5+ be lEET. 1f J00 4r3 NO+ lEe+ jOO C@|\|N0T 5p3A|< 0r ReAd +|-|I5
And use it as a password!, And Violla It took sometime until response from the server came back.
Now maximizing the server pain and make the password string as long as the maximum size allowed = 255 character and sending this password string,
Abracadabra!! the server couldn’t handle the request and didn’t respond at all until the reverse proxy spitted out 504 Gateway Timeout error.
Finally wrote the report and submitted it to the program.