Insert statement usage in SQL injection - mysql

I'm working through an SQL injection tutorial. I don't understand one aspect of an SQL statement which is used determine where the different columns in the table will be displayed on the web page and then used to execute statements. A previous SQL injection statement has been used to determine the number of columns in the table, which is 6. The SQL statement is
SELECT * FROM TableName Where id=12 union all select 1,2,3,4,5,6
I've researched the SELECT and UNION ALL statements and haven't been able to work out what is actually going on. My thinking is that the numbers in the 2nd select statement respresent the column numbers.
The second statement used to get the values from the table is:
SELECT * FROM TableName Where id=12 union all select 1,2,3,4,user(),6
What does the select 1,2,3,4,5,6 and select 1,2,3,4, user(),6 component of the SQL injection query actually do?

They are not column numbers but values. Assuming you can somehow inject the statement you now need something to do with it. The first example counts the columns. theUNION will fail when there are not enough columns. By adding more columns to the UNION eventually the statement will execute. Now you know how many columns there are.
The second one is injecting the user into the return result set. Assuming the result set gets displayed on the screen for some reason, you now have a user name (or service account name) with which to execute more statements on your database, escalate privileges or make service calls.
It's doing something like that. Without knowing more it's hard to know what exactly.

Related

Why SQL injection UNION attack does not work?

I am trying to get the table names and other relevant information with sql injection. The idea was to use a sqli union attack, to get that information from information_schema and then get the content of the tables.
To achieve that, I fisrt try to get the number of columns the query was returning this way:
?parameter=111 or 1=1 union select NULL,NULL,NULL,NULL--
I reached the conclusion that the query was returning 4 columns(all of them are strings), and the next step would be to get that information like this
?parameter=111 or 1=1 union select group_concat(table_name),2,3,4 from information_schema.tables where table_schema=database()
But this does not work, if I remove the where clause it does not work either, or with other tables.
Is like when I add the "from" it stops working.
Why is this? How can I get the table names?
PD: I also tried
?parameter=111 or 1=1 0>ASCII(substring(SELECT table_name from information_schema.tables,1,1))
but it always return false, regardless the value of what value I compare it to.

Is sql IN clause with single parameter the same as a query for single column?

In case I only provide a single value, are the following sql statements equivalent (eg in terms of performance)?
SELECT * FROM mytable where lastname IN(:lastnames);
SELECT * FROM mytable where lastname = :lastname;
Background: I have service that should serve a list, and a service that serves a single result. Now I thought why creating two database query endpoints, if I could achieve the same thing with just one query (means: also a single result could be queried by using the IN clause).
i tried it on my mariaDB database on a small table with hundred of records and the query with IN is a bit slower than the first one (which is to be expected) but we are talking of 0.02 sec difference
Assuming your db's engine is optimised and would check if there is one value inside the IN parameters and "convert" it to an equal/do the correct operation it would still be technically longer than just a written equal.
Also see this about IN performance.
Use This Query.
It May Be Solve Your Problem.
SELECT * FROM mytable where lastname IN(SELECT lastname FROM mytable where lastname = :lastname);

Select Left(columnA,2) or right(columnA,1)

Is there a way in MySql to use an either or in a select column. For instance
select left(columnA,2) or right(columnA,1) as columnAlias, sum(columnB)
from table
where ((left(columnA,2) in ('aa','bb','cc')) or (right(columnA,1) in ('a,','b','c')))
group by columnAlias
what I have is a table where either the first 2 characters of the column or the last character of the column indicates the facility. I need to sum the values by facility. A union gets me part way there then I could loop through the resulting dataset and sum things up in the code (or do a stored proc to return the sums), but I am wondering if there is a way to just get it from the query.
I've tried using the union query as an on the fly temp table and doing the select and group on that but if there are no records returned from either of the select statments then it throws a "column columnA cannot be null error.
Also tried with the syntax above, but not getting the results I am expecting. Any other ways to do this through the query?
using a CASE would prob be your best bet here.
http://dev.mysql.com/doc/refman/5.0/en/case-statement.html

How to select one parameter from a SQL query which yields a no. of parameter?

I am having a sql query
select devices.id, devices.type_designator_id, devices.color, devices.status,
devices.device_build, users.username
from devices,users
where
devices.user_id=users.id and devices.user_id=1608
ORDER BY devices.id;
Now it will give me 6 output from two tables devices and users.
Now I want to extract only one output from above query (without changing the anything) type_designator_id, to put it as a parameter for next sql query with different table.
Say new table is Type_designators with a parameter name id, which is same as the type_designator_id from the previous query.
You could consider creating a view defined by the query you've shown above, and using that view in your new query.

How to make a variable LIMIT in a query, using MYSQL

I'm trying to build a query with a variable limit. As far as I know I cannot do something like select * from table limit my_variable;, but I've read on the internet about a workaround:
SET SQL_SELECT_LIMIT = variable;
I have to write this syntax before the query I want to apply the LIMIT in. This works fine if I write a SELECT query after that code line, but it does not work if I write the following code instead:
INSERT INTO table
SELECT * FROM table1;
It will insert every record of the table1 in table2, instead of inserting the quantity of records specified in the first code line I wrote in this post.
How can I accomplish this?
Using prepared statements to dynamically compose SQL queries.