I was scanning a site when the following vulnerability popped up: CGI Generic SQL Injection
nessus sais that An attacker may exploit this flaw to bypass authentication, read confidential data, modify the remote database, or even take control of the remote operating system.
So i continued reading and found out that the vulnerability sits in this piece of code:
Using the POST HTTP method, Nessus found that :
The following resources may be vulnerable to SQL injection :
The '_codeTextBox' parameter of the /LoginTeacherForm.aspx CGI :
/LoginTeacherForm.aspx [loginButton=Login&_VIEWSTATE=dDwtMTU2NDIxMDkwN
Ts7Pg%3d%3d&btnChangePassword=Wijzig%20Pincode&_pinCodeTextBox=&_codeTex
tBox='+convert(int,convert(varchar,0x7b5d))+']
-------- output --------
Exception Details: System.Data.SqlClient.SqlException: String or
binary data would be truncated.
The statement has been terminated.
But i'm wondering how an attacker can exploit this vulnerability, because when i paste that piece of code it just give me the error.
So my question is how would an attack be able to actually hack into the site and bypass login etc. (Educational purpose only of course)
It looks like a false positive caused by the Nessus request causing your page to insert too long a string into a field. Nessus has detected the error was a SQL server error and has said that it may be a SQL injection vulnerability.
To test yourself try the request with _codeTextBox= set to a single quote to see if you still get a SqlException. If so amend this to two single quotes and if the error then goes away you are probably vulnerable.
The error System.Data.SqlClient.SqlException indicates an error in your SQL query statement. This implies that value stored in the _codeTextBox parameter is not validated or otherwised sanitized before being put into the query.
This would have varying implications depending on the query and logic surrounding its return value. It is impossible to determine the worst case scenario without a thorough understanding of the web application. Suffice it to say, this issue should be fixed by the developer. Fortunately, it is usually easy to fix once identified.
In this case, it looks like the _codeTextBox parameter is being passed to the convert function. I doubt anyone could exploit this. But, this indicates insecure coding practices that probably appear in other areas that Nessus is not aware of. Read below for more info.
I see this most often when the programmer simply concatenates the values with the SQL query string:
Unsafe Example (java) (Source OWASP)
String query = "SELECT account_balance FROM user_data WHERE user_name = "
+ request.getParameter("customerName");
try {
Statement statement = connection.createStatement( … );
ResultSet results = statement.executeQuery( query );
}
Since the value simply gets appended to the end of the query, the user can change query to do something nefarious like login as any user or view all transactions. In the above example, the user could change the customer name parameter to something like '' or 1=1 or worse.
Expected query:
SELECT account_balance FROM user_data WHERE user_name = someuser
Bad query:
SELECT account_balance FROM user_data WHERE user_name = '' OR 1=1
OWASP recommends the following defensive measures. Your situation will dictate what is appropriate:
Primary Defenses:
Use of Prepared Statements (Parameterized Queries)
Use of Stored Procedures
Escaping all User Supplied Input
Additional Defenses:
Also Enforce: Least Privilege
Also Perform: White List Input Validation
You really need to check out OWASP's site and read more about SQL injection.
Related
Under the authorization of my friend, I am testing his website against potential vulnerabilities.
I was trying to find if I was able to inject a SQL query into a POST request parameter hi' or 1=1 --:
query=hi'%20or%201%3d1%20--
I found that the document prints out:
<div class="error">index job,query: syntax error, unexpected '-' near '-'</div>
while with ' or 0=0 -- I get:
<div class="error">index job,query: syntax error, unexpected '|' near ' | 0=0) --'</div>
does this mean that it's vulnerable to SQL Injection? If yes, how can I make it print server system data (like information, etc.)? By the way, if the string is correct it gets redirected to another webpage (I think that's why SQLMap tells me the parameter is not SQL-injectable).
EDIT: I can see the query works just if the URL gets redirected, but I won't see the query output. If the URL doesn't get redirected, I can see these SQL query errors. I'm trying to see how to get the output and do something more useful to attack the website, or even make it detectable from sqlmap.
The current command I'm using is sqlmap -r thework.txt -p query --dbs. thework.txt contains the full valid POST request.
SQL injection isn't only about malicious attacks that read data or change data on your site.
The majority of SQL injections are simply errors like the one you saw. They might not even be malicious. What if you have an SQL injection vulnerability that simply causes an error when someone wants to register their last name as "O'Reilly"? The user is well-intentioned, but your site breaks when they use their real name.
That's reason enough to detect and fix cases of SQL injection in your code.
You didn't post your code that builds the SQL query from this input, so what you have shown is only circumstantial evidence. But I do infer that you are copying a GET input into your SQL query without proper escaping or the preferred method, using a query parameter.
Wish I had 50 reps so I could put this in comments. But yes the site is most likely vulnerable. To be sure ask your friend to allow you to run an initial exploit.
sqlmap.py -u < Target Address> --dbs
If you successfully pull up the data base you have found the vulnerability or at least have confirmed there is a vulnerability.
I'm doing some webpentesting exercises and there is this one task saying that I need to make a new account with this name and this password by using SQL injection. On the web page there is a text input username and another text input 'password'. I can enter whatever characters I want inside the username text-input but inside the password text input I need to type a specific injection.
I know I need to inject insert query but the thing is I don't know the table name. In order to insert a new user I need to know the table name so I'm wondering how can I make the web showing me an error with tablename revealed.
The error showing should be like:
Unexpected end of command in statement [SELECT * FROM (tablename) WHERE...]
I tried to enter with just one character (maybe >1 chars are required) inside the password field to make the error show or even delete the parameter text input password. But it just won't show the SQL syntax error.
So the question is: How can I make use of the exploit to make the web page view the SQL syntax error with table name revealed?
And why doesn't injection work on username field but it does on password field?
The first thing is understand the difference between "application" errors (for example, "the user doesn't exist") and execution errors, in which the application fails itself, like the "Unexpected end of command" you mention. The first case is not usually a problem from the security point of view (unless the application is very badly programmed), the second one is what could allow hacking.
A well programmed web application should ideally only have application errors, but the more realistic approach is cope with unexpected execution errors in way that don't make it vulnerable. Also, application should process any user input in a way that don't cause an execution error.
It seems that they are teaching you the most flagrant case that allows SQL injection, apps than don't do any processing to user input (so it's very easy put text in an input field that cause an execution error), and that don't cope with execution errors (in this case, showing the internal execution message to the user).
A common mistake in web applications is constructing the SQL query with string concatenation, so the simplest way of make it fail is using the string delimiter (') in a field, causing the string value to end prematurely. In an sloppy web app it would cause an execution error that shows the full error message, usually including the table name.
From there you craft a SQL query in the input field that insert the user in the table, you could find examples online (note that you need at least basic knowledge on SQL and PHP (or ASP, Java, etc.), in order to do SQL injection, since you need to know how the database access works in order to make it fail).
Finally, SQL injection could work in any input field that is not properly processed, but it depends on how the application is programmed. I suppose that both fields would work but it will be easy do that with the password field because probably is the last one in the SQL query.
I am trying to insert some information in an MS Access database.
In my database I have the following columns and types:
log_order - Autonumber (I need this to keep the order where inserted in the db),
userID - Text,
time - Text,
date_ - text,
message - Text.
My query:
command.CommandText = "INSERT INTO logs(userID, time, date_, message) VALUES ('"+verifiedUser+"', '"+msg_time+"', '"+msg_date+"', '"+msg+"')";
OleDbDataReader reader = command.ExecuteReader();
The error that I get:
System.Data.OleDb.OleDbException: 'Syntax error in INSERT INTO statement.'
I tried several posts but no post helped me. I believe there might be a problem with the autonumber column (log_order). Because of what I remember I don't have to include it in the query.
PS: I know I have to pass the values as parameters.
Thank you in advance
Probably one of your variables (msg?) contains an apostrophe
The way you've written your SQL is a massive security risk. Please immediately look up "parameterized queries" and never, ever, ever write an sql like this again (where you use string concatenation to tack the values into the query). Your code has a proliferation of issues and using parameterized queries will solve all of them; they aren't difficult to write
It seems your data in some of the variables passed in INSERT may be causing this error. Try debugging the value in command.CommandText before executing it.
If any of the variables have a single quote they must be escaped...
Ref: How do I escape a single quote in SQL Server?
Also brush up on SQL Injection Ref: SQL Injection
I totally agree with all that has been said, but to answer your question directly, I am pretty sure you will need to put square brackets around your field names. OleDb tends not to like special characters and could well be having a problem for example with date_ ; sending [date_] instead should get round the issue.
It will not like time either. Same solution
Addendum on SQL Injection
As an aside, in fact calling Access through OleDb is relatively protected from SQL Injection. This is because any attempt to execute multiple instructions in one command fails. (You get an incorrect formatted string error). So whilst you could argue that what you are doing is safe, it is not for other db providers. The sooner you get into good habits, the less likely you will be to introduce a vulnerability in a case where it could be dangerous. If it seems like you are getting a stream of abuse, it is just because everyone here wants to keep the net safe.
We are using the new DataStream feature introduced in NetScaler 9 (we're on v10) to do content switching (described here: http://support.citrix.com/proddocs/topic/netscaler/ns-dbproxy-wrapper-con.html). We have a read-only virtual server that balances across several read-only MySql slaves. We use our Content Switching to send all "Selects" over to the read-only server.
the policy is configured as such:
mysql.req.query.command.contains("select")
our users send multi-part queries to our database server. Most often they are simple, like:
use database;
select col1 from table1;
Sometimes they will put comments at the head of the query. for example:
-- this is my query
select col1 from table1;
What we've found is that if the query simply starts with a select, everything works swimmingly. However, in the cases where there is a use statement or comments preceding the query, the content swticher fails to detect that this is a select query and it bypasses our read-only virtual server.
I am about to tell all of our developers that they must fully alias every table in every query and avoid use statements (yes, this is a good thing anyway), and also that they cannot use comments in their sql (that's just silly).
Does anyone know how I can configure my NetScaler DataStream Content Switching to ignore comments and use statements?
The decision on where to send the query is done on the first line received after successful authentication... so ignoring the comment won't work.
You could setup a responder policy which sends back an error message saying "Please don't use SQL Comments in commands sent to the Load Balanced VIP". A bit draconian, but your devs would get the message fairly quick.. but there's no way to ignore the comment, but still base a decision on the select statement. However, I was under the impression that the select statement is up to the first semi colon... so in your example above, it should (in theory) still find the select statement. I'd need to test that to be certain of the behaviour however.
Also - the USE statement is critical. This is the DB on which all subsequent commands are issued.
It would be best practice to NOT use the USE statement, but instead, change the select statement to:
select col1 from database.table1;
Once the USE statement is seen, it prevents any subsequent commands being pipelined down the same connection... So if there are a lot of Use statements, you will not get to enjoy the connection multiplexing functionality that comes with DataStream.
We learned that Block Level comments are acceptable, but single line comments are not.
This is properly ignored:
/* my comment */
These comment styles are treated as part of the query:
-- my comment
# my comment
kind of ridiculous when having SET autocommit=0 is perfectly reasonable. What about in that situation.
I've got the SQL stored procedure from hell that I've created and all input parameters are parameterised for security but it's not running as quick as I'd like so I wanted to make it dynamic and so a bit more efficient.
I know I can keep my input parameters to my stored procedure, then within it create a dynamic SQL statement into which I can then pass the input parameters of the stored procedure, but are there any security implications I need to be aware of when doing this? I'm guessing not as it just another set of parameters and they should be treated the same as the parameters passed to the current stored procedure.
Obviously, producing code like this "WHERE OrderNo = ' + #orderno is asking for trouble - I will be doing 'WHERE OrderNo = #orderno' in the dynamic SQL, but is there anything else I need to be aware of?
Thx MH
PS - before anyone suggests it, I can't create the SQL dynamically at the client side using LINQ or similar - it all (for various reasons) has to be contained and controlled at the database level
There is a form of SQL injection that many people don't think about when doing dynamic SQL in stored procedures: SQL Truncation attacks.
With a SQL truncation attack, the attacker injects a long peace of text making the used text variable overflow and lose part of the query.
This article gives more information about this.
Where your parameters are always Data Items, both when being passed to the StoredProc and when used in yor DynamicSQL, everything will stay safe.
Should any of your StoredProc's parameters end up being table or field names, and so forming part of the structure of the DynamicSQL itself, you introduce a new risk : That the parameter can be used to inject rogue SQL Code.
To prevent against such an injection attack you should always validate any such parameters.
One example of how to do this would be to use the input parameter as a token, rather than substitute it directly into the DynamicSQL...
SET #SQL = #SLQ + CASE targetTable WHEN '1' THEN 'table1'
WHEN 'tx' THEN 'tableX'
END
Some people suggest you only need to validate on the client application. But that means that if someone becomes able to execute you SP's directly, the SP has become a point of attack. I always prefer to validate both on the client AND in the server.
EDIT Performance
Note that using DynamicSQL isn't always a guarnatee of performance increases. If you use parameterised queries, the execution plans can indeed be stored. But if the queries do vary greatly, you may still find a significant overhead in compiling the SQL.
There is also the fact that dependancy tracking is lost. It's not possible to see what tables the SP is dependant on, because the code is hidden away as strings.
I have very rarely found that DynamicSQL is needed. Often a complex query can be reformed as several optimised queries. Or the data can be re-structured to meet the new demands. Or even a rethink of both the data and the algorithm using the data. One might even be able to suggest that a dependancy on DynamicSQL is an indicator of another underlying problem.
Perhaps it's not in the scope of your question, but it would be interesting to see the actual puzzle you're facing; to see if anyone has any alternative approaches for you.