In this series I will be try to explain top 10 OWASP security attacks and how these attacks are used.
https://www.owasp.org/index.php/Top_10_2013-A1-Injection.
http://en.wikipedia.org/wiki/SQL_injection says:
"SQL injection is a code injection technique, used to attack data-driven applications, in which malicious SQL statements are inserted into an entry field for execution (e.g. to dump the database contents to the attacker)"
Let’s create a simple authentication system and try this attack. I will be using Java servlet and html in this exercise. I assume that you have basic understanding of servlet and html.
I will be using Mysql database server.
Let’s create a database to save my user authentication info.
The table looks like:
Note that the password storing scheme a very week one. This is how you should not store password. How to store a password is a separate story. But for now let’s keep it simple and use the same. For our purpose we don’t care what the password is, we will try to break into the system without using any password.
The query
SELECT count (*) from logininfo
where password= ’pass’ and userName='user'
should give me result 1 if the username is ‘user’ and password is ‘pass’.
I will create a simple html page that will post username
password to a servlet which will check the database to identify valid user and
prints a message accordingly.
index.html:
<body>
<form action="login" method="post">
UserName<input type="text" name="user"/><br />
Password<input type="password" name="pass" /><br />
<input type="submit" value="Login" />
</form>
</body>
LoginCheckDAO: this checks if user is valid
public class LoginCheckDAO {
Connection con;
Statement stmt;
LoginCheckDAO() throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection(
"jdbc:mysql://localhost/afterHelloWorld", "root", "");
stmt = con.createStatement();
}
public boolean validateUser(String userName, String password) throws SQLException {
String sql = "SELECT count(*) from logininfo where password ='"+
password + "' and userName='" + userName + "'";
System.out.println(sql);
stmt.execute(sql);
ResultSet rs= stmt.getResultSet();
rs.next();
if(rs.getInt(1)==1){
return true;
}
return false;
}
}
Login.java-This is a servlet.
public class Login extends HttpServlet {
private static final long serialVersionUID = 8466351087171796777L;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
LoginCheckDAO loginCheckDAO;
boolean isLoginSucess= false;
try {
loginCheckDAO = new LoginCheckDAO();
isLoginSucess = loginCheckDAO.validateUser(
req.getParameter("user"), req.getParameter("pass"));
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
PrintWriter out = resp.getWriter();
if (isLoginSucess) {
// do Something sucessful login should be able to do.
out.println("Login SUCESS");
} else {
// display error message.
out.println("Login FAIL");
}
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>SqlInjection</display-name>
<servlet id="login">
<servlet-name>login</servlet-name>
<servlet-class>com.afterHelloWorld.Login</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
Lets now lunch the application.
you should see a page:
This should work fine and you will be correctly authenticated in most of the cases. So far so good.
NOTE: Please don't use any of the information below to attack any sites. If you try to do something bad using the information presented below, YOU AND ONLY YOU ARE RESPONSIBLE FOR ANY CONSEQUENCES.
Lets forget the implementation for now and focus our attention into breaking into the system.
Now lets try getting authenticated without using password.
The trick is to input a carefully crafted input that would beat the purpose of login page or force or application to un-expected state.
We know the authentication sql is something like:
SELECT ....... where condition.......
What if you can cause the query to be
SELECT ....... where condition or true.?
Any value we input is likely to be used as
Select ....... where fieldName='value'.
So if we insert something like value' or true or password=' in the input fields
The sql query would be something like
Select ....... where fieldName='value' or true or password='. This will always return a count greater than 0 in our query construct.
The query would be:
SELECT count(*) from logininfo where
password ='asdasd' and userName='user1' or true or password=''
which is a valid query.
Note that any attacker would only have to guess the name of field containing password and a valid username which is not a very difficult task.
Had we checked the count value > 0, the attacker would have got into the system. Luckily we have checked for count value==1;
If we could force the application to create a sql that will return 1, we would get into the system.
Such a query should be like
If we input the userName as
the resultant query would always return 1
A attacker needs to guess only the a columnName and a userName which is not difficult either. This input will break our authentication system and the attacker is able to login successfully without using a password.
This is a simple example of SQL injection.
I will try to cover other attacks in coming weeks
ReplyDelete