SQL Injection using Unicode Characters

Davuluri Lahari Rama Sai
5 min readJul 8, 2020

--

Is your application not responding for normal SQL Injection payloads? Your application might be using character encoding.

I found this vulnerability while performing penetration testing for an e-learning application that uses Moodle as LMS in the background. Moodle LMS uses Unicode by default, for content transformation which also helps for data sanitization. These filters could be bypassed to achieve a successful SQL Injection exploit.

I would say that; this is not a usual SQL Injection case. This is because, you can never figure out a proof that there is an issue with the back-end query, as random characters do not work. For example, single-quote (‘), double-hyphen for commenting (- -), other comments (//, /*), equals (=), etc. Instead, Unicode characters like single quote ('), double-hyphen (--), other comments (//, /*), braces (()), equals to (=), etc. works with the current scenario, which might not impact another application that uses a different set of Unicode characters for their backend code.

Now, let me walkthrough the approach I followed to find this vulnerability.

Step 1: Observed the application cookies.

Cookies play an important role to disclose details about an application’s background. Here, I found a few interesting cookies with names as below:

These cookies clearly states that the application uses Moodle LMS in the background.

Moodle LMS

Moodle is a free and open-source learning management system (LMS) written in PHP. Moodle is used by developers to create a private learning space online, full of engaging activities and materials, providing the Administrator with the complete control of all the data management including how the Managers, Instructors and Learners of the application are on-boarded into the system.

Step 2: Access Moodle Administration.

Try to access the Moodle Administration page by following the folder structure of Moodle Site. For this application, the moodle site administration is present in “/moodle7102/” directory, including the SiteId (eg: 7102) of the application. This could usually be just “/moodle/” in a default case.

Environment of the application disclosed was:

Moodle version 1.9.11
Unicode is enabled
Database — mssql — version 13.0.5426.0
PHP version 5.2.5

Step 3: Enumerate Unicode Characters

As disclosed in the Moodle Administration Environment, we got to know that the application uses Unicode. The Unicode Standard provides a unique number for every character, independent of the platform, device, application or language.

Hence, when you pass in a Unicode character to a Non-Unicode data type (like char, varchar), SQL implicitly converts the Unicode character to its closest resembling Non-Unicode homoglyph.

Validating Vulnerable Parameter

To validate if the input field/parameter is vulnerable to SQL Injection, observe the below payload(s) that I used:

Search Field Value: %%’%%%%v___
Material Fetched: You’ve been Hacked

Here, we have given multiple ‘%’ (and/or ‘_’) characters which were ignored by the application and responded with the record having ‘v in its name. This concludes that the single quote (‘) we provided is no more working to break the query.

To enumerate what type of Unicode characters will be helpful for constructing valid payload for the application, the single-quote (‘) in UTF-8, UTF-16, and UTF-32 can be given in the text box or parameter to check if any Database Error Pattern is found.

Search Field Value: test
Material Fetched: 0 results

We finally achieved a Database Error using UTF-8 encoded single-quote (‘). We can now proceed with using UTF-8 characters from the global character table to construct the payload.

These could also be enumerated from the application depending on the application behaviour, including delimiters like space to achieve great accuracy. The encoded payload can be provided directly as it is, for the intercepted request in a proxy tool, such as Burp Suite.

Step 4: Construct the payload

Unless In-Band SQL Injection(Union-based and Error-based) failed, Inferential will not be in picture. In this case, the errors returned by the application were not that helpful as, not much Information Disclosure was happening. To try for union-based SQL Injection, UNION command did not display output for our query in the response.

Hence, let’s construct a basic Blind SQL Injection boolean payload for MSSQL payload to verify.

' AND 1=1-- (TRUE Statement)
' AND 1=0-- (FALSE Statement)

Or a simple time-based SQL payload as below:

' WAITFOR DELAY '0:0:15'-- (sleep for 15 seconds)

That’s all! Proceed further to exploit entire database and dump data.

Here is an example, where I was able to validate database name of the DB Server. As the current database is MSSQL, below is how I constructed the payload. I have masked the DB name for privacy issues, but please note that the same unicode characters should be used in the entire payload including spaces.

Clap and share, if you like. Comment for any other help or thoughts.
Happy Hacking :)

--

--