How does union select statement output vulnerable columns - sql

Consider a SQL vulnerable site.
Let the number of columns in the query be 3.
So the statement goes, www.test.com?php.id=-1' union select 1,2,3 --+-
My understanding of this statement is like this.
There are 2 statements
Union is used to join both statements.
(-) is used to null the value of the first statement.
' is used to break the query and input a second statement and --+- is used to comment out the rest of the statement.
Upon inputting this statement, The website displays 2 and 3 as vulnerable columns.
What I don't get is that how a select statement displays the vulnerable columns.

Suppose your back-end code did something like:
sql = "SELECT UserId, UserName, Password from Users where UserID = " + id + " AND password = '" + password + "'"
So it would only return results if the User ID and password matched.
Then "injecting" the code above would result in a SQL statement of
SELECT UserId, UserName, Password from Users
where UserID = -1 union select 1,2,3 --+- AND password = 'anything'
Presumably the UI might then display 1 and 2 in the "username" and "password" fields, identifying them as "vulnerable"
It's a technique used to determine how SQL statements are built in back-end code in order to define a true SQL injection attack to retrieve sensitive data.

Related

SQL Server, using or statement condition

I am using a query which its searching inside a table for two conditions. I will give an example:
Select *
from Customers
where mobile= '" + textboxt1.Text + "' or Phone = '" + textboxt1.Text + "'
The query returns me the first row which mobile or phone numbers is equal with my textbox1.Text.
I need to set a condition: start looking "entire table" for find the first 'or' statement(mobile). If there is not exist any result then go and search again entire table using the second or condition (Phone).
Is there any easy way which i can write my query? Or do I need to use a case for this?
Assuming that not more than one record in the table would match on mobile, and that not more than one record would match on the phone (which seems relevant given your description of your use case), you could use top 1 and conditional ordering:
select top 1 *
from Customers
where mobile= #textboxt1 or phone = #textboxt2
order by case when mobile= #textboxt1 then 0 else 1 end
If a record matches on mobile, the conditional ordering clause will put it in first position, and top 1 will eliminate the (possible) other record matching on phone. Else, the (only) matching record on phone will be retained.
Note: don't trust user input. Use prepared statement and query parameters at all times. I modified the query so it uses parameters (#textboxt1, #textboxt2).
You can sometimes improve performance by choosing a UNION instead of an OR.
SELECT TOP 1 * FROM (
SELECT *, 0 Ordinal
FROM Customers
WHERE mobile = #number
UNION ALL
SELECT *, 1 Ordinal
FROM Customers
WHERE phone = #number
) t
ORDER BY Ordinal

SQL Injection Method

The Injection Procedures are :
SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1;
But, My Question Is how the injection query is working in the sql?
its when you have your query as string in your code, something like this
Query = "SELECT UserId, Name, Password FROM Users WHERE UserId = '" + sUserID + "'"
So you pass sUserID = "ABC' OR 1=1;"
this will be translated like
SELECT UserId, Name, Password FROM Users WHERE UserId = 'ABC' OR 1=1
Since the condition 1=1 is always true, adding it at the end of a WHERE statement renders it irrelevant, and always true, as if the WHERE statement does not exist at all. Thus, the query is always executed, regardless of any other conditions added to the WHERE statement.
In the example you provided, If you allow your users to write down their own userID, they can write 105 or 1=1 in the input fields or in a website's URL address, and since or 1=1 makes UserId=105 useless, and the query will always select the data, hence the SQL injection.

Case statement is not working on query

I am working on jasper report.I have a table named user I have 2 parameters internal,external .When I use internal then my query needs to show the users where username LIKE '%_#__%.__%' and when I use external then my query needs to show the users where username NOT LIKE '%_#__%.__%'.Like when internal then report will show 2,3,4,5 no row and when external then report will show only one row..My query is
SELECT case
when $P{internal} = 'internal' then
id end as cid,
designation,division_name,pin_no,username FROM application_user where username LIKE
'%_#__%.__%'
else
id end as cid,
designation,division_name,pin_no,username FROM application_user where username NOT LIKE
'%_#__%.__%'
but it is not working
Please let me know If i'm not clear
Projection statements cannot be parameterised in SQL directly (but you can in Dynamic SQL, obviously).
Your test expression should be evaluated in the WHERE block, not SELECT. The SQL you posted is not valid and won't run, so I'm curious how you're getting the results you're seeing.
Try this:
SELECT
id AS cid,
designation,
division_name,
pin_no,
username
FROM
application_user
WHERE
( $P{internal} = 'internal' AND username LIKE '%_#__%.__%' )
OR
( $P{internal} <> 'internal' AND username NOT LIKE '%_#__%.__%' )
Note that this will not necessarily result in the best runtime execution plan because of the different effective query "shape" depending on the parameter value. Ideally you should have two different queries selected by your application code which have the different username predicates.

Oracle 11g Concat function error

I'm encountering this error:
ORA-00904: "LASTNAME": invalid identifier
When trying to make a report using concat function.
Here is the query:
SELECT 'Full Name','User Name', 'Email' FROM Dual
UNION ALL
SELECT distinct concat(concat(firstname, ' '), lastname), username, Email
FROM
(
select distinct concat(concat(firstname, ' '), lastname), username, Email
from sas_aclentry, sas_usergroup
where sas_aclentry.userkey = sas_usergroup.userkey
and objecttype in (16,3,4,101,14,102) and productkey = 1 and type = 1 and privilege !=0 and isdeleted = 0 and STATUS IN (0, 32)
UNION
select distinct concat(concat(firstname, ' '), lastname), username, Email
from sas_objecttree
join sas_usergroup on sas_usergroup.userkey = sas_objecttree.childkey
where isdeleted = 0 and STATUS IN (0, 32)
and parentkey in (
select distinct sas_aclentry.userkey
from sas_aclentry
join sas_usergroup on sas_usergroup.userkey = sas_aclentry.userkey
where objecttype in (16,3,4,101,14,102) and productkey = 1 and type = 2 and privilege !=0 and isdeleted = 0)
)
WHERE UPPER(Email) LIKE '%SAS%';
Wandered on google but could not find any way to make this works.
Please help.
Appreciate any input.
Will
The error seems to be that your outer query tries to select lastname from the derived table, which does not expose any column with that name. I'm guessing you meant to alias the concated column in the derived table and select that.
Try changing the beginning of the query to this:
SELECT 'Full Name','User Name', 'Email' FROM Dual
UNION ALL
SELECT fullname, username, Email
FROM
(
select distinct firstname || ' ' || lastname as fullname, username, Email
With some databases concat can take more than two arguments, I'm not sure this is true for Oracle though, but you should be able to use the concatenation operator || and change your nested concat functions to this:
firstname || ' ' || lastname as fullname
which makes the code a bit cleaner. (I would also try to be consistent in the use of explicit joins - in the derived table you use implicit joins for the first query and explicit for the second).
There are many mistakes in this query, besides what has already been pointed out (you are selecting "lastname" from a subquery whose projection does not contain a column by that name).
When you do a UNION, the first term of the union must have column names or aliases, which will be used for all the terms of the union. It does not suffice to select three strings from dual (which are probably meant to be used as headers), you must also give each of them an alias. For example, select 'Full Name' as fullname, ... from dual. Alternatively, you may leave the select... from dual for later in the union.
The fact that the "column headers" are shown at the top of the query does not mean they will be at the top of the result set. If you want them to show up at the top of your results, you must use an ORDER BY clause (which probably also means you will need to be able to order by something).
In the "problem" part of the Union, the select with a subquery, with the names and concatenations, you concatenate in the subquery, and then in the select list of the outer query you concatenate again (and supposedly the same three columns that the subquery concatenated already). This will not produce the result you wanted even if there were no syntax errors. What you probably want to do is to do the concatenation in the subquery (and best to use the || operator which may be used repeatedly, instead of concat() which is limited in Oracle); alias the result of the concatenation as fullname, and select fullname in the outer query.
After you fix these issues, others may come to the front; I (we) am/are not able to test, since you didn't provide any test inputs. Please follow up / write back if you need more help. Good luck!

incorrect syntax error near ,

I have recently changed my database from access to a .mdf and now I am having problems getting my code to work.
One of the problems im having is this error "incorrect syntax near ,".
I have tried different ways to try fix this for example putting brackets in, moving the comma, putting spaces in, taking spaces out but I just cant get it.
I would be so grateful if anyone could help me.
My code is:
SqlStr = "INSERT INTO UserTimeStamp ('username', 'id') SELECT ('username', 'id') FROM Staff WHERE password = '" & passwordTB.Text & "'"
Assuming you're looking for username and id columns, then that's not proper SQL syntax.
The main issues are that you're column names are enclosed in single quotes and in parentheses in your select. Try changing it to this:
SqlStr = "INSERT INTO UserTimeStamp (username, id) SELECT username, id FROM Staff WHERE password = '" & passwordTB.Text & "'"
That will get sent off to SQL like this:
INSERT INTO UserTimeStamp (username, id)
SELECT username, id
FROM Staff
WHERE password = 'some password'
There are a number of issues I potentially see.
Column names shouldn't be quoted, i.e. INTO UserTimeStamp('username','id') should be INTO UserTimeStamp(username, id)
Column fields, unless literal strings, shouldn't be quoted either. i.e. SELECT ('username','id') should be SELECT username, id.
You are putting yourself at risk for T-SQL injection by quoting your parameter like that. You should consider using a stored procedure, or use a well tested function to secure your parameters if you are doing ad-hoc queries.
SqlStr = "INSERT INTO UserTimeStamp (username, id) SELECT username, id FROM Staff WHERE password = " + MyQuoteFunction(passwordDB.Text);
Try wrapping column names in square brackets like so:
INSERT INTO employee ([FirstName],[LastName]) SELECT [FirstName],[LastName] FROM Employee where [id] = 1
Edit: Also drop the parentheses surrounding the selected fields.