Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GSoC] SQLi library with support to MySQL (and MariaDB) #13596

Merged
merged 36 commits into from
Jul 10, 2020

Conversation

red0xff
Copy link
Contributor

@red0xff red0xff commented Jun 11, 2020

What is it

This pull request adds an SQL injection library to the metasploit framework, to make it easier for module writers to exploit these vulnerabilities, supports the MySQL database management system for now (support for others will be added).

Features

  • Wrappers around the most common queries (version, current user, table names, column names of a given table, data from a table ...)
  • Boolean-based and Time-based blind injections
  • Support for cases when only a part of the query results is returned (truncated results)
  • Encoders that are easy to use (predefined ones, base64 or hex for example), or define (an encoder is a Hash, the encoder part is a string like to_base64(^DATA^), where ^DATA^ will be replaced with the data to encode, and decoder is a Ruby proc, that will decode the data).
  • An option to automatically get strings replaced with hexadecimal constants (to get around character filtering in some cases)

(data is casted to Binary already, to make sure it works on other character sets, substr returns a one-byte character, but sometimes, the encoding on the web application is different, or some unprintable characters are filtered on the output, see the OpenEMR example).

Test modules

I rewrote two metasploit modules to use the new library, they are working exactly as the original ones, except the changes:

  • auxiliary/sqli/openemr/openemr_sqli_dump.rb : query result truncated to 31 bytes, can contain non-ascii characters:
    • Table enumeration is now done only in the openemr database only ( where table_schema=database() added to the condition when enumerating table names), let me know if I should change that.
    • lang_definitions table added to skiptables, it's a large (>4mb) table that contains the strings in different languages.
    • base64 encoder is now used (see (1) for the reason)
      For testing, you can use this docker-compose.yml
  • exploits/linux/http/eyesofnetwork_autodiscovery_rce.rb : time-based SQL injection.
    • No changes
      Tested on Eyesofnetwork 5.1
      (1) :
sqli.run_sql('select 0x61c3') # no "\xc3" byte returned, only 'a'
sqli.run_sql("select '<abcdefghijklmnopqrstuvwxyz01234'") # &lt; returned for <, and 30 other characters, which means, decoding &lt; is necessary to get 31 characters

Results can also include a comma, using base64 (or dealing with these issues is necessary to get correct results).

Feedback

Any feedback is much appreciated, I am working on implementing a similar interface to sqlite, but if there is a feature request, or something should be changed, I'll be more than happy to make changes that can make the library better / more useful for module writers.

@jmartin-tech jmartin-tech self-assigned this Jun 11, 2020
@h00die
Copy link
Contributor

h00die commented Jun 11, 2020

I think the wiki would be a good place to add examples of how to use this. However, i'm not sure you have permissions to add a page to the wiki. Maybe a markdown in a comment or something for the time being?
maybe add an example_webapp_sqli.rb would be another good case?

Edit: oh oh oh!!! Here's what would be cool... use sqlmap and show it's output, then how you'd code that into the example_webapp_sqli, that way you give a real world example (maybe a hackme type app has multiple sqli types that can be shown).

This would give an easy roadmap to devs on how to take the most popular sqli tool and use it in msf.

@jmartin-tech
Copy link
Contributor

I like the idea of a usage guide with walk thru on how an exploit might be developed. For now adding that as a markdown file in documentation in separate branch might give a place to start on that. I can check with the team on where the longer term location for something like that should be.

@h00die
Copy link
Contributor

h00die commented Jun 11, 2020

Other ideas, I think if you include/require *sqli, it should load in advanced options like sleepdelay with preset values. I think this is a more fluid way for users so they can do set sleepdelay 15. This gets it out of being something set by the developer and into the hands of the user to judge for themselves since its hard to predict timing of internal networks vs VPN+far flung servers over the internet.

Copy link
Contributor

@jmartin-tech jmartin-tech left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the through refactor. Still working thru some test runs to validate module changes here.

The calls to puts & print are a concern. We had previously discussed that you wanted to use print_status and there were issues with access to datastore['VERBOSE'], I will test out some options and provide a suggestion on that shortly.

In the mean time please look into code reuse ideas I have suggested in comments.

lib/msf/core/exploit/sqli.rb Outdated Show resolved Hide resolved
lib/msf/core/exploit/sqli.rb Outdated Show resolved Hide resolved
lib/msf/core/exploit/sqli/mysqli.rb Outdated Show resolved Hide resolved
lib/msf/core/exploit/sqli/mysqli.rb Outdated Show resolved Hide resolved
lib/msf/core/exploit/sqli.rb Outdated Show resolved Hide resolved
lib/msf/core/exploit/sqli/mysqli/boolean_based_blind.rb Outdated Show resolved Hide resolved
lib/msf/core/exploit/sqli/mysqli/boolean_based_blind.rb Outdated Show resolved Hide resolved
lib/msf/core/exploit/sqli/mysqli/time_based_blind.rb Outdated Show resolved Hide resolved
lib/msf/core/exploit/sqli/mysqli/time_based_blind.rb Outdated Show resolved Hide resolved
lib/msf/core/exploit/sqli/mysqli.rb Show resolved Hide resolved
Copy link
Contributor

@jmartin-tech jmartin-tech left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor adjustments.

modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb Outdated Show resolved Hide resolved
lib/msf/core/exploit/sqli.rb Outdated Show resolved Hide resolved
lib/msf/core/exploit/sqli/mysqli/common.rb Outdated Show resolved Hide resolved
# @param output_charset [Range] The range of characters to expect in the output, optional
# @return [String] The query results
#
def run_sql(query, output_charset = nil)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def run_sql(query, output_charset = nil)
def run_sql(query, output_charset: nil)

Prefer named optional arguments.

Also note that the run_sql has 2 signatures, can that be avoided?

def run_sql(query)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the different signatures, having output_charset in non-blind injections is useless, they are primarly there to save time and requests, also, run_sql is not the method users should use to dump data from a table, dump_table_fields and other high-level enumeration methods are there for that, it's a lower-level method to be used when we need to run custom queries, or we only care about one thing, and want to retrieve it fast (session_id for example in eyesofnetwork).

I could rename it, make it blind_run_sql, and make run_sql call it with output_charset being nil, if that has advantages, please let me know (for me, different signatures with optional additional options are okay).

@ccondon-r7 ccondon-r7 added GSoC Google Summer of Code project PRs and removed GSoC Google Summer of Code project PRs labels Jun 27, 2020
@jmartin-tech jmartin-tech merged commit c61f34e into rapid7:master Jul 10, 2020
@jmartin-tech
Copy link
Contributor

jmartin-tech commented Jul 10, 2020

Release Notes

A new SQL injection library was added to the Metasploit Framework, making it easier for module writers to exploit SQLi vulnerabilities. The library currently supports the MySQL database management system, and existing modules exploits/linux/http/eyesofnetwork_autodiscovery_rce and auxiliary/sqli/openemr/openemr_sqli_dump have been updated to take advantage of the new library capabilities.

@pbarry-r7 pbarry-r7 added the rn-enhancement release notes enhancement label Jul 21, 2020
@hastalamuerte
Copy link

I think the wiki would be a good place to add examples of how to use this. However, i'm not sure you have permissions to add a page to the wiki. Maybe a markdown in a comment or something for the time being?
maybe add an example_webapp_sqli.rb would be another good case?

Edit: oh oh oh!!! Here's what would be cool... use sqlmap and show it's output, then how you'd code that into the example_webapp_sqli, that way you give a real world example (maybe a hackme type app has multiple sqli types that can be shown).

This would give an easy roadmap to devs on how to take the most popular sqli tool and use it in msf.

Expirience of sqlmap will be very helpfull! (maybe whole integrating in framework (hope in pro version too)
Wait wor wiki page of that module.

Thank you Rapid7, your products are best!

@wvu wvu added the library label May 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature library rn-enhancement release notes enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants