What does # mean in sql? - mysql

Does anyone know what something like OR 1# means in the context of mysql injection?

It is MySQL's version of the line comment delimiter. In standard SQL, the line comment delimiter is --.
-- This is a standard SQL comment.
# This is a MySQL comment.
So in the context of SQL injection, if the attacker knows you're using MySQL he may use it to abruptly terminate the malicious SQL statement, causing MySQL to ignore whatever is behind the # and execute only the stuff that comes before it. This is only effective against single-line SQL statements, however. Here's an example:
Input:
Username: fake' OR 1#
Password: pass
Resultant SQL:
SELECT * FROM users WHERE username = 'fake' OR 1#' AND password = 'pass'
Which is executed as this, which returns every row:
SELECT * FROM users WHERE username = 'fake' OR 1

This is the start of a comment. It means that anything after that will be skipped by the parser.

Related

Mysql query breaking when sent as GET parameter

I am testing out a blind boolean SQL injection endpoint in a course and am having some issues figuring out where my payload is going wrong.
I have tested the below in the mysql shell on the target box and it works.
GRANT/**/ALL/**/ON/**/*.*/**/TO/**/root#localhost;
But when I submit it in the q GET param I am getting an error in the application.
php?q=off')/**/or/**/GRANT/**/ALL/**/ON/**/*.*/**/TO/**/root#localhost%23
I tested a basic boolean statement with '1'='1' instead and it works fine so I am assuming there is something wrong with my actual query in the context of the URL.
q=off')/**/or/**/'1'='1'%23
I have tried the payload url encoded as well but still with the same issues.
Any idea what might be causing this?
Using SQL injection to combine a partial expression like
OR '1'='1' as part of some other query works because there are many ways to append extra expression syntax to an existing SQL query that already has a WHERE clause.
For example, it's easy to see in the below example how the additional expression can be appended to the first query, and it's still a legal expression.
SELECT * FROM mytable WHERE col1 = 'off'
SELECT * FROM mytable WHERE col1 = 'off' OR '1'='1' -- '
But GRANT is a statement on its own. It cannot be appended to another query like that. There's no way to combine GRANT with a SELECT statement.
SELECT * FROM mytable WHERE col1 = 'off' OR GRANT ALL ON *.* TO ...
That's just not a legal SQL query. You can study the online syntax reference for SELECT and other types of statements.
SQL injection works by tricking the app into executing one SQL statement with different syntax than the original intended SQL statement. But it can't make invalid syntax work!

Function that removes characters that can cause SQL injection

I need to use dynamic SQL in a stored procedure.
That dynamic SQL will create SQL object, therefore I cannot parameterize it and execute it with sp_executesql.
Is there some SQL function which will check the stored procedure parameter variable and tell me if there are some illegal characters? Or remove them or there is a list of these characters?
Something like
DECLARE #variable = 'password OR 1=1'
IF IsSqlInjectionPossible(#variable)
BEGIN
RAISERROR('Illegal input characters',16,1)
RETURN
END
or
SET #variable = removePossibleSqlInjection(#variable)
How do you do that?
Is there some SQL function which will check the stored procedure parameter variable and tell me if there are some illegal characters ?
There is no such function and it just cannot be
Simply because there are NO "characters that can cause sql injection". All characters used in injection are perfectly legal. Your idea of SQL injection is wrong. It is not something alien to the query, like a virus or a bacteria, but just regular SQL. So all you can do is to forbade characters that are used in SQL queries, which will make this function effectively wipe your query.
What character from 'password OR 1=1' statement you consider illegal?
Let us consider you have a form where users can ask for public data of their friends. Let us suppose further that the form posts an ID and you use that as a numeric value in your query:
select public_details
from users
where ID = 5
ID is a value you get from the user. It is not safe at all to allow users to choose the ID they are searching for, but let us ignore that for now for the sake of the example. Now if the user sends a post as follows
5 or 1=1
There is no illegal character, not even apostrophe. The problem is therefore that this is a business-logic issue and should be addressed at application level.

You have an error in your SQL syntax near '<!

Trying to relocate a Wordpress DB and are running in to this issue all the time.
Been trying all the normal stuff to get it working optimizing, repairing etc and also try to import it with several tools (Sequel pro etc ) and over ssh.
Have the issue occurring over several tables and can see that other's have had the same. Because i can't import any copy i would need some expertise advice how to solve this either in phpmyadmin or ssh.
Error message is
#mysql -u -p db < /tmp/file.sql
> ERROR 1064 (42000) at line 109088: You have an error in your SQL
> syntax; check the manual that corresponds to your MySQL server version
> for the right syntax to use near '<!
> <div class="error"><h1>Error</h1> <p><strong>SQL query:</strong> <a href=' at line 1
Don't really know how to approach it because i find this all over the DB
like
<image:caption><![CDATA
Any advice?
Since "all the normal stuff" isn't working...
I'm going to take a guess, you are a running something to "copy" the contents of a database table, or you're doing some sort of "dump" or "export" that creates SQL statements.
And the SQL statements that are running against the target are throwing an error.
We can't tell (from where we're sitting and what we're seeing) what it is you are actually doing, we're just guessing.
The two most likely possibilities:
Whatever tool you are using isn't expecting that the column values being copied might contain values that need to be "escaped" if that value is incorporated in the text of a SQL statement. For example, suppose I have a column value like this:
I'd like a pony
and If I grab that value and I naively stick that into the text of a SQL statement, without regard for any characters it might contain, e.g.
INSERT INTO foo (bar) VALUES ('I'd like a pony');
If I try to execute that statement, MySQL is going to throw a syntax error. MySQL is going to see a string literal with a value of 'I' (the single quote that is part of the string is now being seen as the end of the string literal. MySQL is going to flag a syntax error on what follows d like a pony.
When we take a value and build a SQL statement from it, we have to properly escape the values. In this example, the insert statement to reproduce that string value could look like this:
INSERT INTO foo (bar) VALUES ('I''d like a pony');
^^
If this is what's happening, you can be thankful that the column values didn't include something more nefarious...
Robert'); DROP TABLE students; --
But without seeing the actual SQL statement that is being executed, this is just a guess at what is causing the issue.
Is there some kind of guide or some instructions that you are following to "relocate a Wordpress DB" which documents "all the normal stuff" that you are doing?
FOLLOWUP
Question was edited to add this information:
mysql -u -p db < /tmp/file.sql
What's important here is the contents of file.sql.
The problem is most likely in the part of "all the normal stuff" is producing that file. That part is effectively broken because it's not expecting that an extracted column value can contain a single quote character, and is not properly escaping the value before it's incorporated into the text of a SQL INSERT statement.

How do I write an SQL query that fails?

I need this query for testing exception handling, so I would prefer that the query is not schema dependent. I am looking for something like SELECT 1; but of course that doesn't fail.
I am using Java and MySQL but I hope to find answers that doesn't depend on programming languages and/or RDBMSs.
What about "SELECT 1/0" for starters?
You could put an invalid token into the query
select doesnotexist.* from something_else
Or of course, what you should do is mock out the method and have it throw the exception during your test.
there are tons of ways to make a query fail, like mispelling a field, or selecting from non existing tables. for example:
SELECT some_fake_field FROM table_that_doesnt_exists
One way to trigger a failure is to call a stored procedure with the wrong number of parameters. Another similar idea is to write an update/insert statement with the wrong number of arguments...
More ideas here:
How to raise an error within a MySQL function
Any old syntax error will do... like an unterminated string
select 'bob
To get 1/0 to raise an error in MySQL, you need to set sql_mode to ERROR_FOR_DIVISION_BY_ZERO.
Try this:
SET sql_mode = 'ERROR_FOR_DIVISION_BY_ZERO';
SELECT 1/0;
If this sql_mode isn't set, MySQL will return a NULL instead of an error.
You can check what your current settings are with the following:
SELECT ##GLOBAL.sql_mode;
SELECT ##SESSION.sql_mode;

How to use MySQL user-variables with ADO.NET

MySQL SQL commands can contain user variables that start with '#'.
The MySQL ADO.NET connector also uses '#' for command parameters.
Is there a way to escape the '#' character so I can use a user-variable in an SQL statement sent to MySQL via ADO.NET?
I'm trying to do something like this:
UPDATE company
SET next_job_id = #jobid:=next_job_id+1
WHERE company_id = #companyid;
SELECT #jobid;
Where #jobid is a MySQL user variable and #companyid is a parameter.
It's a connection string option - "Allow User Variables=true"
When set to true, parameters are prefixed with '?'.
Update: I've written up more on this, including how to get this to work with ADO.NET and Subsonic. See Here.