OWASP Testing Guide
  • Foreword by Eoin Keary
  • Frontispiece
  • Introduction
  • The OWASP Testing Framework
    • The Web Security Testing Framework
    • Penetration Testing Methodologies
  • Web Application Security Testing
    • Introduction and Objectives
    • Information Gathering
      • Conduct Search Engine Discovery Reconnaissance for Information Leakage (WSTG-INFO-01)
      • Fingerprint Web Server (WSTG-INFO-02)
      • Review Webserver Metafiles for Information Leakage (WSTG-INFO-03)
      • Enumerate Applications on Webserver (WSTG-INFO-04)
      • Review Webpage Content for Information Leakage (WSTG-INFO-05)
      • Identify Application Entry Points (WSTG-INFO-06)
      • Map Execution Paths Through Application (WSTG-INFO-07)
      • Fingerprint Web Application Framework (WSTG-INFO-08)
      • Fingerprint Web Application (WSTG-INFO-09)
      • Map Application Architecture (WSTG-INFO-10)
    • Configuration and Deployment Management Testing
      • Test Network Infrastructure Configuration (WSTG-CONF-01)
      • Test Application Platform Configuration (WSTG-CONF-02)
      • Test File Extensions Handling for Sensitive Information (WSTG-CONF-03)
      • Review Old Backup and Unreferenced Files for Sensitive Information (WSTG-CONF-04)
      • Enumerate Infrastructure and Application Admin Interfaces (WSTG-CONF-05)
      • Test HTTP Methods (WSTG-CONF-06)
      • Test HTTP Strict Transport Security (WSTG-CONF-07)
      • Test RIA Cross Domain Policy (WSTG-CONF-08)
      • Test File Permission (WSTG-CONF-09)
      • Test for Subdomain Takeover (WSTG-CONF-10)
      • Test Cloud Storage (WSTG-CONF-11)
      • Testing for Content Security Policy (WSTG-CONF-12)
    • Identity Management Testing
      • Test Role Definitions (WSTG-IDNT-01)
      • Test User Registration Process (WSTG-IDNT-02)
      • Test Account Provisioning Process (WSTG-IDNT-03)
      • Testing for Account Enumeration and Guessable User Account (WSTG-IDNT-04)
      • Testing for Weak or Unenforced Username Policy (WSTG-IDNT-05)
    • Authentication Testing
      • Testing for Credentials Transported over an Encrypted Channel (WSTG-ATHN-01)
      • Testing for Default Credentials (WSTG-ATHN-02)
      • Testing for Weak Lock Out Mechanism (WSTG-ATHN-03)
      • Testing for Bypassing Authentication Schema (WSTG-ATHN-04)
      • Testing for Vulnerable Remember Password (WSTG-ATHN-05)
      • Testing for Browser Cache Weaknesses (WSTG-ATHN-06)
      • Testing for Weak Password Policy (WSTG-ATHN-07)
      • Testing for Weak Security Question Answer (WSTG-ATHN-08)
      • Testing for Weak Password Change or Reset Functionalities (WSTG-ATHN-09)
      • Testing for Weaker Authentication in Alternative Channel (WSTG-ATHN-10)
      • Testing Multi-Factor Authentication (MFA) (WSTG-AUTH-11)
    • Authorization Testing
      • Testing Directory Traversal File Include (WSTG-ATHZ-01)
      • Testing for Bypassing Authorization Schema (WSTG-ATHZ-02)
      • Testing for Privilege Escalation (WSTG-ATHZ-03)
      • Testing for Insecure Direct Object References (WSTG-ATHZ-04)
      • Testing for OAuth Authorization Server Weaknesses
      • Testing for OAuth Client Weaknesses
      • Testing for OAuth Weaknesses (WSTG-ATHZ-05)
    • Session Management Testing
      • Testing for Session Management Schema (WSTG-SESS-01)
      • Testing for Cookies Attributes (WSTG-SESS-02)
      • Testing for Session Fixation (WSTG-SESS-03)
      • Testing for Exposed Session Variables (WSTG-SESS-04)
      • Testing for Cross Site Request Forgery (WSTG-SESS-05)
      • Testing for Logout Functionality (WSTG-SESS-06)
      • Testing Session Timeout (WSTG-SESS-07)
      • Testing for Session Puzzling (WSTG-SESS-08)
      • Testing for Session Hijacking (WSTG-SESS-09)
      • Testing JSON Web Tokens (WSTG-SESS-10)
    • Input Validation Testing
      • Testing for Reflected Cross Site Scripting (WSTG-INPV-01)
      • Testing for Stored Cross Site Scripting (WSTG-INPV-02)
      • Testing for HTTP Verb Tampering (WSTG-INPV-03)
      • Testing for HTTP Parameter Pollution (WSTG-INPV-04)
      • Testing for Oracle
      • Testing for MySQL
      • Testing for SQL Server
      • Testing PostgreSQL
      • Testing for MS Access
      • Testing for NoSQL Injection
      • Testing for ORM Injection
      • Testing for Client-side
      • Testing for SQL Injection (WSTG-INPV-05)
      • Testing for LDAP Injection (WSTG-INPV-06)
      • Testing for XML Injection (WSTG-INPV-07)
      • Testing for SSI Injection (WSTG-INPV-08)
      • Testing for XPath Injection (WSTG-INPV-09)
      • Testing for IMAP SMTP Injection (WSTG-INPV-10)
      • Testing for File Inclusion
      • Testing for Code Injection (WSTG-INPV-11)
      • Testing for Command Injection (WSTG-INPV-12)
      • Testing for Buffer Overflow (WSTG-INPV-13)
      • Testing for Format String Injection (WSTG-INPV-13)
      • Testing for Incubated Vulnerability (WSTG-INPV-14)
      • Testing for HTTP Splitting Smuggling (WSTG-INPV-15)
      • Testing for HTTP Incoming Requests (WSTG-INPV-16)
      • Testing for Host Header Injection (WSTG-INPV-17)
      • Testing for Server-side Template Injection (WSTG-INPV-18)
      • Testing for Server-Side Request Forgery (WSTG-INPV-19)
      • Testing for Mass Assignment (WSTG-INPV-20)
    • Testing for Error Handling
      • Testing for Improper Error Handling (WSTG-ERRH-01)
      • Testing for Stack Traces (WSTG-ERRH-02)
    • Testing for Weak Cryptography
      • Testing for Weak Transport Layer Security (WSTG-CRYP-01)
      • Testing for Padding Oracle (WSTG-CRYP-02)
      • Testing for Sensitive Information Sent via Unencrypted Channels (WSTG-CRYP-03)
      • Testing for Weak Encryption (WSTG-CRYP-04)
    • Business Logic Testing
      • Introduction to Business Logic
      • Test Business Logic Data Validation (WSTG-BUSL-01)
      • Test Ability to Forge Requests (WSTG-BUSL-02)
      • Test Integrity Checks (WSTG-BUSL-03)
      • Test for Process Timing (WSTG-BUSL-04)
      • Test Number of Times a Function Can Be Used Limits (WSTG-BUSL-05)
      • Testing for the Circumvention of Work Flows (WSTG-BUSL-06)
      • Test Defenses Against Application Misuse (WSTG-BUSL-07)
      • Test Upload of Unexpected File Types (WSTG-BUSL-08)
      • Test Upload of Malicious Files (WSTG-BUSL-09)
      • Test Payment Functionality (WSTG-BUSL-10)
    • Client-Side Testing
      • Testing for Self DOM Based Cross-Site Scripting
      • Testing for DOM-Based Cross Site Scripting (WSTG-CLNT-01)
      • Testing for JavaScript Execution (WSTG-CLNT-02)
      • Testing for HTML Injection (WSTG-CLNT-03)
      • Testing for Client-side URL Redirect (WSTG-CLNT-04)
      • Testing for CSS Injection (WSTG-CLNT-05)
      • Testing for Client-side Resource Manipulation (WSTG-CLNT-06)
      • Testing Cross Origin Resource Sharing (WSTG-CLNT-07)
      • Testing for Cross Site Flashing (WSTG-CLNT-08)
      • Testing for Clickjacking (WSTG-CLNT-09)
      • Testing WebSockets (WSTG-CLNT-10)
      • Testing Web Messaging (WSTG-CLNT-11)
      • Testing Browser Storage (WSTG-CLNT-12)
      • Testing for Cross Site Script Inclusion (WSTG-CLNT-13)
      • Testing for Reverse Tabnabbing (WSTG-CLNT-14)
    • API Testing
      • Testing GraphQL (WSTG-APIT-01)
  • Reporting
    • Reporting
    • Vulnerability Naming Schemes
  • Appendix
    • Testing Tools Resource
    • Suggested Reading
    • Fuzz Vectors
    • Encoded Injection
    • History
    • Leveraging Dev Tools
  • Testing Checklist
  • Table of Contents
  • REST Assessment Cheat Sheet
  • API Testing
Powered by GitBook
On this page
  • Summary
  • How to Test
  • The Single Quotes Problem
  • Multiple Mixed Queries
  • Information Gathering
  • Attack Vectors
  • Standard SQL Injection Attack
  • Out of Band SQL Injection
  • Blind SQL Injection
  • Tools
  • References
  • Whitepapers
  • Case Studies
  1. Web Application Security Testing
  2. Input Validation Testing

Testing for MySQL

PreviousTesting for OracleNextTesting for SQL Server

Last updated 2 years ago

Summary

vulnerabilities occur whenever input is used in the construction of a SQL query without being adequately constrained or sanitized. The use of dynamic SQL (the construction of SQL queries by concatenation of strings) opens the door to these vulnerabilities. SQL injection allows an attacker to access the SQL servers. It allows for the execution of SQL code under the privileges of the user used to connect to the database.

MySQL server has a few particularities so that some exploits need to be specially customized for this application. That's the subject of this section.

How to Test

When an SQL injection vulnerability is found in an application backed by a MySQL database, there are a number of attacks that could be performed depending on the MySQL version and user privileges on DBMS.

MySQL comes with at least four versions which are used in production worldwide, 3.23.x, 4.0.x, 4.1.x and 5.0.x. Every version has a set of features proportional to version number.

  • From Version 4.0: UNION

  • From Version 4.1: Subqueries

  • From Version 5.0: Stored procedures, Stored functions and the view named INFORMATION_SCHEMA

  • From Version 5.0.2: Triggers

It should be noted that for MySQL versions before 4.0.x, only Boolean or time-based Blind Injection attacks could be used, since the subquery functionality or UNION statements were not implemented.

From now on, we will assume that there is a classic SQL injection vulnerability, which can be triggered by a request similar to the one described in the Section on .

http://www.example.com/page.php?id=2

The Single Quotes Problem

Before taking advantage of MySQL features, it has to be taken in consideration how strings could be represented in a statement, as often web applications escape single quotes.

MySQL quote escaping is the following:

'A string with \'quotes\''

That is, MySQL interprets escaped apostrophes \' as characters and not as metacharacters.

So if the application, to work properly, needs to use constant strings, two cases are to be differentiated:

  1. Web app escapes single quotes ' => \'

  2. Web app does not escape single quotes ' => '

Under MySQL, there is a standard way to bypass the need of single quotes, having a constant string to be declared without the need for single quotes.

Let's suppose we want to know the value of a field named password in a record, with a condition like the following:

  1. password like 'A%'

  2. The ASCII values in a concatenated hex: password LIKE 0x4125

  3. The char() function: password LIKE CHAR(65,37)

Multiple Mixed Queries

MySQL library connectors do not support multiple queries separated by ; so there's no way to inject multiple non-homogeneous SQL commands inside a single SQL injection vulnerability like in Microsoft SQL Server.

For example the following injection will result in an error:

1 ; update tablename set code='javascript code' where 1 --

Information Gathering

Fingerprinting MySQL

Example:

1 /*! and 1=0 */

If MySQL is present, the clause inside the comment block will be interpreted.

Version

There are three ways to gain this information:

  1. By using the global variable @@version

  2. By using comment fingerprinting with a version number /*!40110 and 1=0*/

which means

if(version >= 4.1.10)
   add 'and 1=0' to the query.

These are equivalent as the result is the same.

In band injection:

1 AND 1=0 UNION SELECT @@version /*

Inferential injection:

1 AND @@version like '4.0%'

The response would contain something to the lines of:

5.0.22-log

Login User

There are two kinds of users MySQL Server relies upon.

There is some difference between 1 and 2. The main one is that an anonymous user could connect (if allowed) with any name, but the MySQL internal user is an empty name (''). Another difference is that a stored procedure or a stored function are executed as the creator user, if not declared elsewhere. This can be known by using CURRENT_USER.

In band injection:

1 AND 1=0 UNION SELECT USER()

Inferential injection:

1 AND USER() like 'root%'

The response would contain something to the lines of:

user@hostname

Database Name in Use

There is the native function DATABASE()

In band injection:

1 AND 1=0 UNION SELECT DATABASE()

Inferential injection:

1 AND DATABASE() like 'db%'

Expected Result, A string like this:

dbname

INFORMATION_SCHEMA

Tables_in_INFORMATION_SCHEMA
DESCRIPTION

SCHEMATA

All databases the user has (at least) SELECT_priv

SCHEMA_PRIVILEGES

The privileges the user has for each DB

TABLES

All tables the user has (at least) SELECT_priv

TABLE_PRIVILEGES

The privileges the user has for each table

COLUMNS

All columns the user has (at least) SELECT_priv

COLUMN_PRIVILEGES

The privileges the user has for each column

VIEWS

All columns the user has (at least) SELECT_priv

ROUTINES

Procedures and functions (needs EXECUTE_priv)

TRIGGERS

Triggers (needs INSERT_priv)

USER_PRIVILEGES

Privileges connected User has

All of this information could be extracted by using known techniques as described in SQL Injection section.

Attack Vectors

Write in a File

If the connected user has FILE privileges and single quotes are not escaped, the into outfile clause can be used to export query results in a file.

Select * from table into outfile '/tmp/file'

Note: there is no way to bypass single quotes surrounding a filename. So if there's some sanitization on single quotes like escape \' there will be no way to use the into outfile clause.

This kind of attack could be used as an out-of-band technique to gain information about the results of a query or to write a file which could be executed inside the web server directory.

Example:

1 limit 1 into outfile '/var/www/root/test.jsp' FIELDS ENCLOSED BY '//' LINES TERMINATED BY '\n<%jsp code here%>';

Results are stored in a file with rw-rw-rw privileges owned by MySQL user and group.

Where /var/www/root/test.jsp will contain:

//field values// <%jsp code here%>

Read from a File

load_file is a native function that can read a file when allowed by the file system permissions. If a connected user has FILE privileges, it could be used to get the files' content. Single quotes escape sanitization can by bypassed by using previously described techniques.

load_file('filename')

The whole file will be available for exporting by using standard techniques.

Standard SQL Injection Attack

In a standard SQL injection you can have results displayed directly in a page as normal output or as a MySQL error. By using already mentioned SQL Injection attacks and the already described MySQL features, direct SQL injection could be easily accomplished at a level depth depending primarily on the MySQL version the pentester is facing.

Out of Band SQL Injection

Blind SQL Injection

For blind SQL injection, there is a set of useful function natively provided by MySQL server.

  • String Length:

    • LENGTH(str)

  • Extract a substring from a given string:

    • SUBSTRING(string, offset, #chars_returned)

  • Time based Blind Injection:

    • BENCHMARK and SLEEP BENCHMARK(#ofcycles,action_to_be_performed) The benchmark function could be used to perform timing attacks when blind injection by boolean values does not yield any results. See. SLEEP() (MySQL > 5.0.x) for an alternative on benchmark.

Tools

References

Whitepapers

Case Studies

Of course, the first thing to know is if there's MySQL DBMS as a back end database. MySQL server has a feature that is used to let other DBMS ignore a clause in MySQL dialect. When a comment block '/**/' contains an exclamation mark '/*! sql here*/' it is interpreted by MySQL, and is considered as a normal comment block by other DBMS as explained in .

By using the function

: the user connected to the MySQL Server.

: the internal user who is executing the query.

From MySQL 5.0 a view named was created. It allows us to get all the information about databases, tables, and columns, as well as procedures and functions.

A good attack is to know the results by forcing a function/procedure or the server itself to throw an error. A list of errors thrown by MySQL and in particular native functions could be found on .

Out of band injection could be accomplished by using the clause.

For a complete list, refer to the

SQL Injection
Testing for SQL Injection
MySQL manual
VERSION()
USER()
CURRENT_USER()
INFORMATION_SCHEMA
MySQL Manual
MySQL manual
Francois Larouche: Multiple DBMS SQL Injection tool
Reversing.org - sqlbftools
Bernardo Damele A. G.: sqlmap, automatic SQL injection tool
Muhaimin Dzulfakar: MySqloit, MySql Injection takeover tool
Chris Anley: "Hackproofing MySQL"
Zeelock: Blind Injection in MySQL Databases
into outfile