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.
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 am using Visual Studio 2008 and Access 2013 as my database.
When I use special characters in a password field, my VB.Net code produces an SQL query error, especially when I am using a special char at the last chat.
For example, if I use jdjdj' as the password then an error occurs.
Normal passwords work. For example:
Admin123
123admin
123
admin
Where is the problem and how can I fix it?
You need to pass the password to the query as a parameter rather than concatenate it into the query string.
It doesn't just stop issues like this, it's also to stop malicious users deliberately taking advantage of your shortcut, to easily gain access to the database.
Check out How do I create a parameterized SQL query? Why Should I?
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.
I'm attempting to run a simple statement against an Access DB to find records.
Data validation in the records was horrible, and I cannot sanitize it. Meaning, it must be preserved as is.
I need to be able to search against a string with white space and hyphen characters removed. The following statement will work in Access 2010 direct:
select * from dummy where Replace(Replace([data1],' ',''),'-','') = 'ABCD1234';
Running it from an ODBC connection via PHP will not. It produces the following error:
SQL error: [Microsoft][ODBC Microsoft Access Driver] Undefined function 'Replace' in expression., SQL state 37000 in SQLExecDirect
Creating a query in the database that runs the function and attempting to search its values indirectly causes the same error:
select * from dummy_indirect where Expr1 = 'ABCD1234';
I've attempted to use both ODBC drivers present. ODBCJR32.dll (03/22/2010) and ACEODBC.dll (02/18/2007). To my knowledge these should be current as it was installed with the full Access 2010 and Access 2010 Database Engine.
Any ideas on how to work around this error and achieve the same effect are welcome. Please note, that I cannot alter the database in way, shape, or form. That indirect query was created in another mdb file that has the original tables linked from the original DB.
* Update *
OleDB did not really affect anything.
$dsn= "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\dummy.mdb;";
I'm not attempting to use it as a web backend either. I'm not a sadomasochist.
There is a legacy system that I must support that does use Access as a backend. Data gets populated there from other old systems that I must integrate into more modern systems. Hence, the creation of an API with Apache/PHP that is running on the server supporting the legacy system.
I need to be able to search a table that has an alphanumeric case identifier to get a numeric identifier that is unique and tied to a generator (Autonumber in access). Users have been using it a trash box for years (inconsistent data entry with sporadic notations) so the only solution I have is to strip everything except alphanumeric out of both the field value and the search value and attempt to perform a LIKE comparison against it.
If not replace() which is access supported, what ODBC compatible functions exist that I can use do the same kind of comparison?
Just to recap, the Access db engine will not recognize the Replace() function unless your query is run from within an Access application session. Any attempt from outside Access will trigger that "Undefined function" error message. You can't avoid the error by switching from ODBC to OleDb as the connection method. And you also can't trick the engine into using Replace() by hiding it in separate query (in the same or another Access db) and using that query as the data source for your main query.
This behavior is determined by Access' sandbox mode. That linked page includes a list of functions which are available in the default sandbox mode. That page also describes how you can alter the sandbox mode. If you absolutely must have Replace() available for your query, perhaps the lowest setting (0) would allow it. However, I'm not recommending you do that. I've never done it myself, so don't know anything about the consequences.
As for alternatives for Replace(), it would help to know about the variability in the values you're searching. If the space or dash characters appear in only one or a few consistent positions, you could do a pattern match with a Like expression. For example, if the search field values consist of 4 letters, an optional space or dash, followed by 4 digits, a WHERE clause like this should work for the variations of "ABCD1234":
SELECT * FROM dummy
WHERE
data1 = 'ABCD1234'
OR data1 Like 'ABCD[- ]1234';
Another possibility is to compare against a list of values:
SELECT * FROM dummy
WHERE
data1 IN ('ABCD1234','ABCD 1234','ABCD-1234');
However if your search field values can include any number of spaces or dashes at any position within the string, that approach is no good. And I would look real hard for some way to make the query task easier:
You can't clean the stored values because you're prohibited from altering the original Access db in any way. Perhaps you could create a new Access db, import the data, and clean that instead.
Set up the original Access db as a linked server in SQL Server and build your query to take advantage of SQL Server features.
Surrender. :-( Pull in a larger data set to your PHP client code, and evaluate which rows to use vs. which to ignore.
I'm not sure you can do this with ODBC and your constraints. The MS Access driver is limited (by design; MS wants you to use SQL Server for back ends).
Can you use OLEDB? that might be an option.
Using parameters instead of placing values directly in the query string is done to prevent SQL injection attacks and should always be done:
... WHERE p.name > :name ...
->setParameter('name', 'edouardo')
Does this mean that if we use parameters like this, we will always be protected against SQL injections? While using a form (registration form of FOS), I put <b>eduardo</b> instead and this was persisted to the database with the tags. I don't really understand why using parameters is preventing against SQL injections...
Why are the tags persisted to the database like this? Is there a way to remove the tags by using Symfony's validation component?
Is there a general tip or method that we should be using before persisting data in the database in Symfony?
Start with reading on what's SQL injection.
SQL injection attack takes place when value put into the SQL alters the query. As a result the query performs something else that it was intended to perform.
Example would be using edouardo' OR '1'='1 as a value which would result in:
WHERE p.name > 'edouardo' OR '1'='1'
(so the condition is always true).
"<b>eduardo</b>" is a completely valid value. In some cases you will want to save it as submited (for example content management system). Of course it could break your HTML when you take it from the database and output directly. This should be solved by your templating engine (twig will automatically escape it).
If you want process data before passing it from a form to your entity use data transformers.
If you use parameters instead of concatenation when creating a request, the program is able to tell SQL keywords and values apart. It can therefore safely escape values that may contain malicious SQL code, so that this malicious does not get executed, but stored in a field, like it should.
HTML code injection is another problem, which has nothing to do with databases. This problem is solved when displaying the value, by using automatic output escaping, which will display <b>eduardo</b> instead of eduardo. This way, any malicious js / html code won't be interpreted : it will be displayed.