The vulnerability description is one thing, but trying to find a vulnerability and deal with it is a whole different matter. There are dozens, if not hundreds, special deliberately vulnerable web applications. If you search for “Purposely Vulnerable App» in you favorite search engine, you will find more than a dozen links.
In the following series of articles we will learn about vulnerabilities in OWASP Top 10, and as a polygon I will also use such deliberately vulnerable application. In my case it will be OWASP Mutillidae II. It’s not the best option out there, but the vulnerabilities are structured exactly as we need for educational purposes. Plus I’m very used to it.
Give me your hand
So the first vulnerability is Injection. In the OWASP Mutillidae II there are several options, and we will start with the simplest «SQLi Extract Data» > «User Info (Sql)».
Here’s the usual authentication form that you interact with every day:
We have no login, no password, nothing. Well, let’s register on this site. I’ll create a user named «blowzero273» with password «123»:
Great! We have created an account, and we see the message “1 Rows Inserted” hinting that a string has been added to the table in the account database.
Now let’s login with our new account. Successful, excellent!
When we work with a web page, we always need to remember that our interaction is not limited with the content of the page. There is also an address string, in which we can notice a lot of interesting:
For example, we can see that the password is passed in clear text. This is bad, as traffic can be intercepted, but perhaps it’s not such a catastrophe, traffic can be wrapped in TLS.
Let’s try to replace the password directly in the string, for example, replace this piece:
The password, of course, is now incorrect and we have received a corresponding error. And this is really bad! Bad, because with the help of thc-hydra that I was talking about here we can break this password. It takes a lot of time, but it’s quite possible.
But since we don’t have that much time, let’s try something else. Add an apostrophe character to our wrong password. Now:
Will turn into:
Now we have a full error:
There is nothing wrong with errors. How else do you diagnose a malfunction if we do not see the feedback from the application? But such errors should not be visible to users and intruders!
Now we see that when we click the «Send» button, in the background the following query is executed:
SELECT * FROM accounts WHERE username='belowzero273' AND password='12345'
Our web application does not filter the data that the user enters, and we can break the request with our additional apostrophe. Now that we know what this query looks like in the background, we have to figure out how to change it to get the information we need from the database.
Note that there is a function in the query and, i.e. both variables should be correct, because it is a combination of login and password. Quite logical, right?
Let’s doing a little more on this request:
SELECT * FROM accounts WHERE (username='belowzero273' AND password='12345') OR 1=’1
We have added a condition that is always true: 1 = 1. And the request will be executed in two cases – we have guessed the combination of login and password or 1 = 1. Well, 1=1 is always true =) It turns out that you can specify the following as a password
' or 1='1
The apostrophe at the end of the string is no longer needed, the logic of the web application will put it in the end for us. Boom! And we’ve got all the accounts from the database:
Cool, now we have logins and passwords for everyone who is registered in this application. And even worse, the passwords here are in the clear text.
What’s wrong with that? Well, the fact that most people use one and same logins (email addresses for example) and passwords for all web sites. And by registering on this single vulnerable site, they might lose access to all of them.
You can experiment with this vulnerability, such as looking for an administrator password. For this purpose we will enter the following as a login:
admin' or 1='1
we are looking for an entry in the database, where the login is “admin”, and the password is any.
Password not found!
Passwords are not always kept in clear text, but this doesn’t mean that authentication is done securely. Take a look at second example In OWASP Mutillidae II «SQLi Bypass Authentication»> «Login».
Authentication can be bypassed if you generate the appropriate query. Just recently we created an account belowzero273, and now let’s specify this string as a login:
' or ('a' = 'a' and username='belowzero273') --
Here we check the known correct condition «a = A», and login is belowzero273, as well as chop the rest of the request using “–”.
Click Enter and we’re in. Although we have no idea what the password is.
Why so simple?
Sometimes customers ask if is it easy to bypass the authentication on our site? I usually answer with a question: “How do you know it didn’t happened yet?” Injections are on the top of the rating for a reason as they have disastrous consequences.
In practice, of course, everything is a bit more complicated than in these examples, but these are basic examples to understand a deeper problem.
That’s it for now, we’ll continue next time.