Monday, November 24, 2014

SQL Injection with JDBC Statement interface object

SQL Injection is an hacking technique, in which we bypass the where conditions in sql query.

Lets say there is a table called user_cred, with two columns username and password.
Currently table contains only one column, with values user1/Welcome1

Now,
select * from user_cred where username='user1' and password='Welcome1';
This will give one row.

If any of the field username/password is given wrong, then we wont get any results.
But if we know the username and without knowing password also, we can retrieve the results here:

Hack 1: Username is known and password is not known
select * from user_cred where username='user1'-- and password='NoPassword';

The key point here is that in SQL, -- starts a comment. So whatever is there after these two characters, it will not be executed. So the query results in one result.

Hack 2: Username and password, both are not known.
select * from user_cred where username='nouser' or 1=1-- and password='NoPassword';

Here we are passing and extra where condition 1=1, which is always true and the password condition is bypassed. So even though the username is wrong, we are able to get the results.

SQL Injection: We can hack Statement object:

public void sqlInjStatement(String username, String password) {
Statement st = null;
ResultSet rs = null;

try {
st = con.createStatement();
rs = st.executeQuery("select * from user_cred where username='"
+ username + "' and password='" + password + "'");

if (rs != null && rs.next())
System.out.println("SQL Injection with Statement: User("
+ username + "/" + password + ") is valid");
else
System.out.println("SQL Injection with Statement: User("
+ username + "/" + password + ") is wrong");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (st != null)
st.close();
if (rs != null) {
rs.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Testing:
test.sqlInjStatement("user1", "Welcome1");
test.sqlInjStatement("user1", "Welcome2");
test.sqlInjStatement("user1' and 1=1--", "NoPassword");
test.sqlInjStatement("nouser' or 1=1--", "NoPassword");
test.sqlInjStatement("user1'--", "Welcome2");

Output:
SQL Injection with Statement: User(user1/Welcome1) is valid
SQL Injection with Statement: User(user1/Welcome2) is wrong
SQL Injection with Statement: User(user1' and 1=1--/NoPassword) is valid
SQL Injection with Statement: User(nouser' or 1=1--/NoPassword) is valid
SQL Injection with Statement: User(user1'--/Welcome2) is valid


PreparedStatement wont allow above:

public void sqlInjPrepStatement(String username, String password) {
PreparedStatement pst = null;
ResultSet rs = null;

try {
pst = con.prepareStatement("select * from user_cred where username=? and password=?");
pst.setString(1, username);
pst.setString(2, password);
rs = pst.executeQuery();

if (rs != null && rs.next())
System.out.println("SQL Injection with PreparedStatement: User("
+ username + "/" + password + ") is valid");
else
System.out.println("SQL Injection with PreparedStatement: User("
+ username + "/" + password + ") is wrong");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (pst != null)
pst.close();
if (rs != null) {
rs.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Testing:
test.sqlInjPrepStatement("user1", "Welcome1");
test.sqlInjPrepStatement("user1", "Welcome2");
test.sqlInjPrepStatement("user1' and 1=1--", "NoPassword");
test.sqlInjPrepStatement("nouser' or 1=1--", "NoPassword");
test.sqlInjPrepStatement("user1'--", "Welcome2");

Output:
SQL Injection with PreparedStatement: User(user1/Welcome1) is valid
SQL Injection with PreparedStatement: User(user1/Welcome2) is wrong
SQL Injection with PreparedStatement: User(user1' and 1=1--/NoPassword) is wrong
SQL Injection with PreparedStatement: User(nouser' or 1=1--/NoPassword) is wrong
SQL Injection with PreparedStatement: User(user1'--/Welcome2) is wrong

No comments:

Post a Comment