Why SQL injection UNION attack does not work? - mysql

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.

Related

Insert statement usage in SQL injection

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.

(SQL) Union combination with additional data

I use a database program called Agility by WiSys at my job. I had an unusual occurrence where part the data I needed was found in one column of a specific table and the rest was in another column in another table.
I used a UNION to combine these tables, but I have found that I cannot add any more data needed for the rest of my report. When I do, I receive a Error Message stating: All queries combined using a UNION, INTERSECT OR EXCEPT operator must have an equal number of expressions in their target lists.
Basically, the UNION works as needed, I have combined my data into one column, however, I cannot call any additional data needed in the query because the UNION prevents that data from being called.
Here is my query without the additional data I need:
SELECT table1_sql.UnionColumn1,
FROM table1_sql
UNION
SELECT table2_sql.UnionColumn2 AS CombinedColumn
FROM table2_sql
ORDER BY CombinedColumn
I need to have the UNION with these extra columns in my report as well:
SELECT table1_sql.UnionColumn1,
table1_sql.ExtraColumn1,
table1_sql.ExtraColumn2,
table1_sql.ExtraColumn3,
table1_sql.ExtraColumn4
FROM table1_sql
UNION
SELECT table2_sql.UnionColumn2 AS CombinedColumn
FROM table2_sql
ORDER BY CombinedColumn
An example of the data that I am trying to retrieve would be:
Example Data Where Order_No is the data that I want to join via UNION and everything else is data that is also needed but not allowed with a UNION.
The program Agility is not as robust as other programs, so I am somewhat limited in my ability to complete this reports using alternatives to UNION. Please advice.
The error message is telling you the complete story. When using a union BOTH queries MUST have the same number of columns. You can work with it by simply adding some hard coded NULLS.
SELECT table1_sql.UnionColumn1,
table1_sql.ExtraColumn1,
table1_sql.ExtraColumn2,
table1_sql.ExtraColumn3,
table1_sql.ExtraColumn4
FROM table1_sql
UNION
SELECT table2_sql.UnionColumn2 AS CombinedColumn
, NULL
, NULL
, NULL
, NULL
FROM table2_sql
ORDER BY CombinedColumn
Please note you will have to order by UnionColumn1 because the column names in the second query are not the name of the columns in the final result set. Only the names from the first query.

Union query to combine results of 3 tables

I am relatively new to coding so please have patience.
I am trying to combine data from 3 tables. I have managed to get some data back but it isn't what i need. Please see my example below.
select oid, rrnhs, idnam, idfnam, dte1, ta
as 'access type' from person
left join
(select fk_oid, min(dte), dte1, ta
from
((Select fk_oid,min(accessdate) as dte, accessdate1 as dte1, accesstype as ta
from vascularpdaccess
where isnull(accesstype)=false group by fk_oid)
union
(Select fk_oid, min(hpdate) as dte, hpdate as dte1, HPACCE as ta
from hdtreatment
where isnull(hptype)=false group by fk_oid)) as bla
group by fk_oid) as access
on person.oid=access.fk_oid
where person.rrnhs in (1000010000, 2000020000, 3000030000)
My understanding with a union is that the columns have to be of the same data type but i have two problems. The first is that accesstype and hpacce combine in to a the same column as expected, but i dont want to actually see the hpacce data (dont know if this is even possible).
Secondly, the idea of the query is to pull back a patients 'accesstype' date at the first date of hpdate.
I dont know if this even makes sens to you guys but hoping someone can help..y'all are usually pretty nifty!
Thanks in advance!
Mikey
All queries need to have the same number of columns in the SELECT statement. It looks like you first query has the max number of columns, so you will need to "pad" the other to have the same number of columns. You can use NULL as col to create the column with all null values.
To answer the question (I think) you were asking... for a UNION or UNION ALL set operation, you are correct: the number of columns and the datatypes of the columns returned must match.
But it is possible to return a literal as an expression in the SELECT list. For example, if you don't want to return the value of HPACCE column, you can replace that with a literal or a NULL. (If that column is character datatype (we can't tell from the information provided in the question), you could use (for example) a literal empty string '' AS ta in place of HPACCE AS ta.
SELECT fk_oid
, MIN(HPDATE) AS dte
, hpdate AS dte1
, NULL AS ta
-- -------------------- ^^^^
FROM hdtreatment
Some other notes:
The predicate ISNULL(foo)=FALSE can be more simply expressed as foo IS NOT NULL.
The UNION set operator will remove duplicate rows. If that's not necessary, you could use a UNION ALL set operator.
The subsequent GROUP BY fk_oid operation on the inline view bla is going to collapse rows; but it's indeterminate which row the values from dte1 and ta will be from. (i.e. there is no guarantee those values will be from the row that had the "minimum" value of dte.) Other databases will throw an exception/error with this statement, along the lines of "non-aggregate in SELECT list not in GROUP BY". But this is allowed (without error or warning) by a MySQL specific extension to GROUP BY behavior. (We can get MySQL to behave like other databases and throw an error of we specify a value for sql_mode that includes ONLY_FULL_GROUP_BY (?).)
The predicate on the outer query doesn't get pushed down into the inline view bla. The view bla is going to materialized for every fk_oid, and that could be a performance issue on large sets.
Also, qualifying all column references would make the statement easier to read. And, that will also insulate the statement from throwing an "ambiguous column" error in the future, when a column named (e.g.) ta or dte1 is added to the person table.

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

Striping of results from MySQL UNION

I am trying to conceptualize how to set up UNION of 3 tables that will allow for ordering in a striping fashion.
Top 5 from the UNION of Tables A,B,C
with results ordered like so:
A
B
C
A
B
C
....
Is this sort of thing possibe with SQL and more specifically MySQL?
Personally, I would pull the three queries out separately, and then process through them in your favourite programming language. The queries should run faster like this, as they would not be so complex.
It should be possible using only SQL though, by adding a couple of columns to your output for each of the three queries, and then wrapping the whole lot in an outer select such as;
SELECT * FROM ( <PUT THE FULL UNION HERE> ) ORDER BY table_name, row_count
You'd need to alter each of the queries like this;
##rowCount=0;
SELECT 'A' AS table_name, (##rowCount+1) AS row_count, <remaining fields>
FROM table_A;
Now, I'm not totally sure of the syntax for the incrementing row counter, but I've seen it done elsewhere (probably on StackOverflow somewhere), so maybe someone else can help with that part? (Or you may find the answer by searching this site...)