Skip to content

[FEATURE REQUEST] Server Filesystem Enumeration using SQL injection #2908

@edgarolijar

Description

@edgarolijar

Tools

SQLMAP is a powerful tool (with overwhelming amount of features), but there is currently no real functionality to perform servers's file system enumeration via SQL injection (e.g. MySQL's load_file(...)). If you want to scan web folder, then tools like DirBuster already exist and do their job very well, but if you want to enumerate server's internal structure by using SQL injection, then ... there is currently only such a tool which is called SqlNuke and is written in ruby (and not python =( ) and isn't far so mature tool as sqlmap is (ok there is also a Metasploit tool, but it's still not cool enough: https://digi.ninja/metasploit/mysql_file_enum.php).

meme

Why SQLMAP?

Why is sqlmap so perfect to solve this task? Because it has already all the necessary functionality to make an SQL injection in very different ways (cookies & headers, POST & GET requests, payload suffix, prefix, time based, blind, union based, stacked, SQL injection type recognition and payload generation and and and ... - you know how much it is ;)). So why not just add another cool option to contribute to the glory of this great tool!

There are several possible scenarios, where it might be useful

1. File privilege is on, but it's impossible to write file to any world-viewable folder

  1. All world-viewable folders are protected -> still possible to write to "non-public" folders (we can also check if the file exists if we are able to write to some non-public folder from the outside, but if we try to create file with specific name we'll fail because MySQL's into outfile can't overwrite files)
  2. MySQL's into outfile requires quotes or doublequotes (load_file(...) can still work with HEX), which are e.g. blocked.

2. File priv is on: We can read and write files, but we just don't know DocumentRoot's location and need to bruteforce it. Quotes aren't blocked.

  1. "Spammer 4ever"-style: try to write a file with special payload (easier detection in the next step, if it's a right file) (MySQL: into outfile) and then try to read it back (MySQL: load_file(...)). Problem: Some folders might be still protected, or there might be a rare case with file collision (MySQL's into outfile can't overwrite existing files)(file names must be carefully chosen to avoid possible collisions).
    After such "attack" we definitely will need to clean up the server xD so a list with tested paths would be useful...
  2. We know how our script in the DocumentRoot is called (e.g. index.pl), so we will try to bruteforce DocumentRoot (maybe we have some minimal information leak found, where we see relative path like use lib qw(../../../service/lib); and then later in the code use Foo::Engine; (e.g. leaked perl code)) by using bugs (read below) or dictionary-based or pure bruteforce. (consider the case where we can't find DocumentRoot via php bugs (or similar) or google search or in log files or in database itself - we just d-o-n't have it =()

Note

  1. MySQL's load_file() works with HEX-encoded or quoted string and works also with relative paths, e.g.: load_file("../../../../Apache/htdocs/path/file.php") (current working directory on MySQL is @@datadir (default path is /var/lib/mysql))
    (https://websec.wordpress.com/2007/11/17/mysql-table-and-column-names/)
  2. Stacked queries ";" are disabled by default, so I'm considering here the most common case where we can use subqueries (nested queries) only
  3. I use MySQL only as example here

Suggestions

  1. Fixed list with default/common file paths of config files
    /etc/passwd
    /etc/init.d/apache/httpd.conf
    /etc/init.d/apache2/httpd.conf
    ...
    -> https://wiki.apache.org/httpd/DistrosDefaultLayout
    -> nginx, Apache, lighttpd, Apache Tomcat, Jetty, ...
    -> possibility to use own lists
  2. Dictionary based search or pure bruteforce
    {variable_path}{fixed_filename} OR {fixed}{variable}{fixed}
    Example: /var/www/{variable}/htdocs/index.php
    Where {variable} might be from a wordlist or be just bruteforced (only lower-case chars OR only upper-case chars OR only numbers OR upper-case + lower case OR ... etc)
    And don't forget about "ugly" file or folder names. Example /var/www/java_1.6/file.txt, so we need to bruteforce only the java version in this folder name: {fixed}{java_{0..9}[1].{0...9}[1]}{fixed}
  3. Using cool bugs on specific MySQL versions:
    https://securityweekly.com/2013/01/18/mysql-file-system-enumeration/
    -> Instead of enumerating file names we can use this bug to enumerate directories
    -> Windows MySQL 4.1.7, 5.5.29, Linux MySQL 5.5.25, ... (and maybe other versions?)(maybe there are similar bugs on other DBMSs?) - btw is there a CVE for this bug?!

Not so important question

Does SQLMAP use any of known *SQL's bugs which you can find in the CVE-list?
And again, just for example MySQL: https://www.cvedetails.com/vulnerability-list.php?vendor_id=185

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions