I'm doing a school project about webapp security and vulnerabilities, and for that i've made my own very simple website with a login and a search bar.
Now, i've made the login silent on purpose, while the search bar shows output on SQL injections. So for demonstration purposes I would like to do a time-based completely blind SQL injection attack on the login... But i'm a bit stuck.
I have no idea how I can enumerate how many columns are in the table for the login query, in a time-based situation:
SELECT * FROM customer WHERE cMAIL='' AND cPWD='';
I cannot do ORDER BY n;#, since I get absolutely no error output when something goes wrong. The only way I can get any indication is through SLEEP() or BENCHMARK().
But I cannot put ORDER BY into a SELECT IF() statement. So how can I find out how many columns exist? (it makes unions impossible for me).
Thank you!
EDIT: It might be worth mentioning, the site is very unsecure on purpose (doesn't use mysqli, just mysql). Since it is just for demonstration
Okay, I found an answer to my own question:
Instead of using ORDER BY, I used SELECT and bruteforced my way to see how many columns existed:
SELECT * FROM customer WHERE cMAIL='' AND cPWD='';
Can be enumerated in the dark by doing:
SELECT * FROM customer WHERE cMAIL='' UNION SELECT null,null,null AND SLEEP(5);# AND cPWD=''
You just keep adding more nulls to the select until the database sleeps for 5 seconds. Then you know how many columns are in the given table.
Hope this can help someone else.
Related
I was presented with this question during a technical test in HackerRank, I made several attempts to answer it and even asked a friend who's much more experienced than me
This is the code we ended up submitting:
SELECT name, count(*)
FROM employee
GROUP BY name, phone, age
HAVING COUNT(*) >1;
Using dummy data, I was getting the accurate result on MySQL workbench.
Is my query wrong? is the request poorly written? How can this be solved more efficiently (if possible at all)?
Your query is nearly correct, given the explanation of the requirments. But I have to say, what a terrible example of a question for this type of problem - please do not design schemas like this for your employer!
I say nearly correct since the actual requirement is just the names of the employees, so techincally you do not need to return the count(*) to satisfy the requirments.
I am in charge of the security of several websites. Recently we bought the Acunetix WVS and performed several tests that gave positive on SQL injection. Not only am I trying to replicate these tests but I also trying to find out if it is possible to extract relevant information, given that we have a WAF/IPS deployed that mitigates the more critical SQL injections.
I am obviously not allowed to disclose the website I am currently testing on, for that I will refer to it as http://example.com.
I was able to find out that on the page http://example.com/show_results.php?group=1&query=members there are 2 queries being used to display the results. So maybe, this is related to Routed SQL Injection. I have applied several SQL injection techniques, and through the error messages I have identified that they take the form of:
SELECT 1 FROM ... WHERE group='1' LIMIT 0,1
SELECT 1,2,3,4 FROM ... WHERE group='1' AND `user_type` NOT LIKE 'colaborators' ORDER BY 'name'
Both queries are displayed on individual <div>. user_type represents the members on the URL. The first query is obviously very easy to inject. I can get the database name by simply changing the URL to:
http://example.com/show_results.php?group=1' union select database() -- - &query=
The obvious question here is: How to get the table names for instance. Something like:
GROUP_CONCAT(table_name) FROM information_schema.tables WHERE TABLE_SCHEMA=database()
This is tricky because both queries use the same group parameter, so it is not entirely Routed SQL Injection in its simplest form. Something like this:
http://example.com/show_results.php?group=1' union select database() -- -&query=members
Note the difference brom above on the query parameter. This shows me the error of The used SELECT statements have a different number of columns (obviously because both queries have a different number of columns).
I'd like to select * from 2 tables, but have each table's column name be prefixed with a string, to avoid duplicate column name collissions.
For example, I'd like to have a view like so:
CREATE VIEW view_user_info as (
SELECT
u.*,
ux.*
FROM
user u,
user_ex ux
);
where the results all had each column prefixed with the name of the table:
e.g.
user_ID
user_EMAIL
user_ex_ID
user_ex_TITLE
user_ex_SIN
etc.
I've put a sql fiddle here that has the concept, but not the correct syntax of course (if it's even possible).
I'm using MySql, but would welcome generic solutions if they exist!
EDIT: I am aware that I could alias each of the fields, as mentioned in one of the comments. That's what I'm currently doing, but I find at the start of a project I keep having to sync up my tables and views as they change. I like the views to have everything in them from each table, and then I manually select out what I need. Kind of a lazy approach, but this would allow me to iterate quicker, and only optimize when it's needed.
I find at the start of a project I keep having to sync up my tables and views as they change.
Since the thing you're trying to do is not really supported by standard SQL, and you keep modifying database structures in development, I wonder if your best approach would be to write a little script that recreates that SELECT statement for you. Maybe wrap it in a method call in the development language of your choice?
Essentially you'd need to query INFORMATION_SCHEMA for the tables and columns of interest, probably via a join, and write the results out in SQL style.
Then just run the script every time you make database structural changes that are important to you, and watch your code magically keep up.
This might have been asked before, but I can't seem to find any relevant answer anywhere.
I wrote a couple of long queries in Access (2003) a couple of weeks ago. I wanted to use those queries today and found that they are been truncated. The query starts as it should and somewhere halfway through it says AS [%$###_Alias] and the rest is missing.
Both query are only a few 100 characters long, so well below the limit allowed by Access.
The structure of both queries is like this
SELECT Some calculated fields with a few IIF statements
FROM
(
SELECT Some fields calculated with lots of IIF statement
FROM joined table
WHERE some condition
)
ORDER BY Some fields
Which I do not is particularly demanding of Access, and should certainly not cause it truncate the query in anger. So why does this happen?
Please don't slam me for putting in Japanese text now, the next part is purely for reference. One of my actual (truncated) queries looks like this:
SELECT
管理番号,
種別,
IIF(種別TYPE='', OTHER種別TYPE, IIF(種別TYPE='その他','その他' & OTHER種別TYPE,種別TYPE)) AS TYPE
FROM [
SELECT
管理番号,
IIF(建物か設備_建物,'建物',IIF(建物か設備_設備, '設備', '種別なし')) AS 種別,
IIF(建物か設備_建物,IIF(建物用途_戸建住宅,'戸建住宅',IIF(建物用途_共同住宅,'共同住宅',IIF(建物用途_教育施設,'教育施設',IIF(建物用途_庁舎,'庁舎',IIF(建物用途_事務所,'事務所',IIF(建物用途_工場,'工場',IIF(建物用途_倉庫,'倉庫',IIF(建物用途_店舗,'店舗',IIF(建物用途_物置小屋,'物置小屋',IIF(建物用途_車庫,'車庫',IIF(建物用途_農作小屋,'農作小屋',IIF(建物用途_その他,'その他')))))))))))),
IIF(建物か設備_設備,IIF(設備種別_物置,'物置',IIF(設備種別_駐車場,'駐車場',IIF([設備種別_運動場/庭等],'運動場/庭等',IIF(設備種別_電気設備等,'電気設備等',IIF(設備種別_畜舎など,'畜舎など',IIF(設備種別_ビニールハウス等,'ビニールハウス等',IIF(設備種別_その他,'その他'))))))),'')) AS 種別TYPE,
'(' & REPLACE(REPLACE(TRIM(建物用途_その他記載欄),'(',''),')','') & ')' AS OTHER種別TYPE
FROM
T_メイン INNER JOIN T対象 ON T_メイン.管理番号=T対象.調査番号]. AS [%$###_Alias];
EDIT
I rechecked both of my queries and unlike I said only one of them got truncated. The other one is intact. Extremely weird...
I've noticed that if I don't assign an alias for a subquery, Access' query designer will assign one for me. And those aliases resemble the one you cited, [%$###_Alias]. However, I've not noticed it discard any part of my SQL text when it added such an alias. So although this suggestion may be a long shot, try assigning your own alias, eg FROM ( ... ) AS sub, and see whether the query designer preserves the rest of your SQL text.
We have redirect huge internet service from domain .de to domain .com - this is discussion board (vBulletin). At the moment we need to change all phrases like "domainame.de" to "domainame.com":
Over 120 tables (posts, threads)
A lot of MySQL fields
Anyone have suggestion how do something like this? We need replace string "domainame.de" to "domainname.com" - everywhere.
What you want to do sounds dangerous, as it could hit some false-positives, and change things unintentionally. Suppose your old domain is 'acme.de' and the new one 'acme.com', and some random visitor posted the following (this is an over-simplified example):
I enjoy working with Acme.Depending on my mood.
It would be very easy to convert this to:
I enjoy working with Acme.compending on my mood.
Therefore, my suggestions, in order of preference:
Don't update the DB at all, just configure your web server to redirect the .de traffic to the .com traffic. You're less likely to make mistakes this way.
If you must update the discussion board, do it in your display logic, rather than in the database--then you'll have no chance of making irrevocable mistakes.
Write a script in perl, or your favorite text-processing language, language, which does a regex replacement on every table/field. I suggest the following strategy:
a. Do a SELECT id,<field name> FROM <table> WHERE <field name> LIKE '%domain.de%'
b. Store output in a CSV, or other format that is easy to parse.
c. Run your Regex script to change domain.de to domain.com
d. Check the output.
e. Do an UPDATE <table> SET <field>=? WHERE id=?, with the output of your script.
Do it in small chunks at first (a few tens or hundreds of posts at a time), and visually check the results before committing your changes to the database, to make sure you haven't made mistakes.
I dont know whether this might work for you but have a look at this
The following query would give you the list of tables (120 tables)
SELECT DISTINCT table_name
FROM
(
SELECT *
FROM information_schema.`COLUMNS` C
) t1
WHERE TABLE_SCHEMA='schema_name'
next
you can use UPDATE query for each table. you can achieve this using CURSORS
I am not good in cursors but I think it will help in this situation