I am investigating in SQL injection and having a difficulty at hiding payload in hex, hope someone can advise.
For example, the injection:
select name from user where id= ? --> this where I want to inject
I want to make the query like:( just for example only)
select name from user where id= 1 union select 1,2,3
In order to hide my payload, I would like to convert "1 union select 1,2,3" into hexadecimal as below:
select name from products where id=X'3120756E696F6E2073656C65637420313233';
select name from products where id=0x3120756E696F6E2073656C65637420313233;
However, somehow mysql does not interpret my hex into the original string, but consider it as a number which is not logic in my point of view. Anyone can help me with this?
Thanks.
It's perfectly logical for MySQL to interpret both 0x3120... and X'3120...' as hexadecimal literal expressions in both cases, and to interpret as a number, string, or blob, as context dictates.
The parser would not under any circumstance interpret such expressions ambiguously, any more than it would misinterpret something like this:
WHERE id = '1 UNION ALL SELECT ...'
It's unambiguously a literal string expression, the same as the two examples provided.
https://dev.mysql.com/doc/refman/5.6/en/hexadecimal-literals.html
I am not inclined to assist anyone with advice on how to exploit a SQL injection vulnerability. Using urlencoding would allow you to pass something like %31%20%75%6E... which is really no clever exploit at all, only a different way of encoding a URL for presentation at an already-vulnerable interface and would serve no advanced purpose. Either it's properly written, or it's already vulnerable without such a tactic, and such an encoding wouldn't change that except maybe in rare cases.
Related
I have an JSON string stored in the database and I need to SQL COUNT based on the WHERE condition that is in the JSON string. I need it to work on the MYSQL 5.5.
The only solution that I found and could work is to use the REGEXP function in the SQL query.
Here is my JSON string stored in the custom_data column:
{"language_display":["1","2","3"],"quantity":1500,"meta_display:":["1","2","3"]}
https://regex101.com/r/G8gfzj/1
I now need to create a SQL sentence:
SELECT COUNT(..) WHERE custom_data REGEXP '[HELP_HERE]'
The condition that I look for is that the language_display has to be either 1, 2 or 3... or whatever value I will define when I create the SQL sentence.
So far I came here with the REGEX expression, but it does not work:
(?:\"language_display\":\[(?:"1")\])
Where 1 is replaced with the value that I look for. I could in general look also for "1" (with quotes), but it will also be found in the meta_display array, that will have different values.
I am not good with REGEX! Any suggestions?
I used the following regex to get matches on your test string
\"language_display\":\[(:?\"[0-9]\"\,)*?\"3\"(:?\,\"[0-9]\")*?\]
https://regex101.com/ is a free online regex tester, it seems to work great. Start small and work big.
Sorry it doesn't work for you. It must be failing on the non greedy '*?' perhaps try without the '?'
Have a look at how to serialize this data, with an eye to serializing the language display fields.
How to store a list in a column of a database table
Even if you were to get your idea working it will be slow as fvck. Better off to process through each row once and generate something more easily searched via sql. Even a field containing the comma separated list would be better.
select name from movies where id = 1; gives me
name
----------
How the 'A' Stole Christmas
How would I select in order to get
name
----------
How the \'A\' Stole Christmas
I can use replace(title,'\'','\\\'') which turns ugly since I need to do it twice one for single & double quote, Curious to know if there is cleaner approach
Struggling with escaping characters is a sign that you may be unnecessarily converting strings manually as data flows through different systems. The question I would ask is whether it is necessary to have escaped strings for your requirements.
When constructing and executing your queries you should use bind variables which removes the need to quote strings to build up your Sql queries and minimizes the risk of Sql injection security issues.
See http://php.net/manual/en/mysqli-stmt.bind-param.php
Once you have Sql results in a variable or PHP structure it is often better to find functions/libraries such as JSON functions described at https://coderwall.com/p/p2kumg/json_encode-vs-serialize-with-php-arrays
And of course there's http://www.w3schools.com/php/func_string_addslashes.asp as mentioned by D4V1D as a comment.
Edit ...
There also appears to be a Mysql QUOTE() function that does what you are asking.
See http://www.w3resource.com/mysql/string-functions/mysql-quote-function.php
I'm developing a Java desktop application that connects with a database, and I would like to know the next. It results that as far as I know, Prepared Statements avoid SQL injections while you don't make a direct concatenation with user data, but today I figured out that it doesn't escape String regex (like '%' from the LIKE operator,) due that it just escapes characters that could break up the String itself and alter the query. So, if user does:
Search = "%Dogs"; // User input
Query = "SELECT * FROM Table WHERE Field LIKE ?";
blah.setString(1, Search);
It will return all the rows that contains 'Dogs' at the beginning by injection.
Now I ask:
1-) Is this something bad / dangerous viewing from a global point?
2-) Is there a full list of Regex that Mysql could use from inside a String? if so, can you please share it with me?
Thank you.
If the user uses such meta characters in their search, the results may or may not be catastrophic, but a search for %% could be bad. A valid search for %Dogs may also not return the results the user was expecting which affects their experience.
LIKE only offers two meta characters, so you can escape them both on your own when acquired from users (simply using something akin to Search = Search.replaceAll("%", "\\\\%")).
I have an InnoDB database table of 12 character codes which often need to be entered by a user.
Occasionally, a user will enter the code incorrectly (for example typing a lower case L instead of a 1 etc).
I'm trying to write a query that will find similar codes to the one they have entered but using LIKE '%code%' gives me way too many results, many of which contain only one matching character.
Is there a way to perform a more detailed check?
Edit - Case sensitive not required.
Any advice appreciated.
Thanks.
Have a look at soundex. Commonly misspelled strings have the same soundex code, so you can query for:
where soundex(Code) like soundex(UserInput)
use without wildcard % for that
SELECT `code` FROM table where code LIKE 'user_input'
thi wil also check the space
SELECT 'a' = 'a ', return 1 whereas SELCET 'a' LIKE 'a ' return 0
reference
In postgresql, it's possible to use "Dollar-Quoted String Constants" to avoid escaping single quotes in constant strings:
Without Dollar-Quoted String Constants:
'Jeff''s table'
With Dollar-Quoted String Constants:
$$Jeff's table$$
Is there a MySQL equivalent?
On edit: I'm not looking for a way to sanitize inputs, I'm looking for a way to make queries that generate sql easier to read.
No, because it doesn't really work. An attacker just addes a pair of dollar signs to their injection attempt instead.
The correct way to handle this is a system that uses real query parameters, such that the parameter values are never substituted directly into a query string. This is also generally better for performance because the db can do a better job caching the execution plan you don't end up building string dynamically, which tends to be slow in modern languages.
Not having excess concatenation statements greatly improves the readability of the code, as well. Instead of this:
sql = "SELECT * FROM MyTable WHERE Column1=$$" + somevarialbe + "$$ AND Column2=$$" + OtherVariable";
it's just this:
sql = "SELECT * FROM MyTable wHERE Column1=#Value1 AND Column2=#Value2";
Hmm... Okay, I can see some limited utility for this feature now.
Imagine a ticket tracking system with a stored procedure to get open tickets. You might actually hard-code the literal 'open' into the where clause of the query. Not that this would be a good design — ticket status should be in a table with it's own key, so that you'd hardcode the key rather than the text. But it plants the seed for something valid and more-complicated.
You can enclose your string in double quotes instead, e.g.
"Jeff's table"
Note: If this doesn't work, it means that you've got ANSI_QUOTES SQL mode turned on. The MySQL docs say:
If the ANSI_QUOTES SQL mode is enabled, string literals can be quoted only within single quotation marks because a string quoted within double quotation marks is interpreted as an identifier.