OWASP WebGoat:LAB SQL Injection

From aldeid
Jump to navigation Jump to search

LAB: SQL Injection

L'objectif de cet exercice est de mettre en pratique vos acquis concernant l'injection SQL afin d'outrpasser des droits dans une application RH.

Stage 1: String SQL Injection

Il est probable que la requête de connexion soit du type suivant :

select * from employee where login_id=1 and password='pass'
                             \_ VRAI _/     \___ FAUX ____/

Sans mot de passe valide, un seul test (login_id=1) sera vrai. Comme "vrai" AND "faux" retourne "faux", l'accès n'est pas autorisé. Pour forcer la non vérification de validité du mot de passe, il suffit de modifier la requête pour qu'elle devienne :

select * from employee where login_id=1 and password='oops' or '1'='1'
                             \_ VRAI _/     \_________ VRAI _________/

Pour ce faire, il suffit d'intercepter la requête avec WebScarab et de modifier le champ de login comme suit :

Stage 2: Parameterized Query #1

Il est demandé de développer un patch afin d'empêcher l'injection réalisée à l'étape précédente :

# cd ~/WebGoat/tomcat/webapps/WebGoat/JavaSource/org/owasp/webgoat/lessons/SQLInjection/
# vim Login.java

Remplacer la requête simple :

String query = "SELECT * FROM employee WHERE userid = " + userId + " and password = '" + password + "'";
// System.out.println("Query:" + query);
try
{
  Statement answer_statement = WebSession.getConnection(s)
    .createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
  ResultSet answer_results = answer_statement.executeQuery(query);
  ...

Par une requête "préparée" :

String query = "SELECT * FROM employee WHERE userid = ? and password = ?";
try
{
  Connection connection = WebSession.getConnections(s);
  PreparedStatement statement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
  statement.setString(1, userId);
  statement.setString(2, password);
  ResultSet answer_results = statement.executeQuery();
  ...

Stage 3: Numeric SQL Injection

Il est demandé d'augmenter les privilèges du profil emloyé "Larry" en tentant une consultation du profil "Neville" non initialement prévue dans l'application, comme le montre l'écran suivant :

Pour ce faire, se connecter avec le profil de "Larry" (mot de passe "larry"), sélectionner "Larry Stooge (employee)" dans la liste des profils, cliquer sur "ViewProfile" puis intercepter la requête avec WebScarab afin de modifier le champ ... comme le montre la figure suivante :

En cliquant sur "Accept changes", on accède directement à la fiche de l'employé dont le salaire est le plus élevé (Neville).

Stage 4: Parameterized Query #2

Pour appliquer le patch de sécurité, la méthode est similaire à celle utilisée à l'étape 2 (requête "préparée").

# cd ~/WebGoat-5.2/tomcat/webapps/WebGoat/JavaSource/org/owasp/webgoat/lessons/SQLInjection/
# vim ViewProfile.java

Modifier la requête simple :

String query = "SELECT employee.* "
  + "FROM employee,ownership WHERE employee.userid = ownership.employee_id and "
  + "ownership.employer_id = " + userId + " and ownership.employee_id = " + subjectUserId;

try
{
  Statement answer_statement = WebSession.getConnection(s)
    .createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
  ResultSet answer_results = answer_statement.executeQuery(query);
  ...

Par une requête préparée :

String query = "SELECT employee.* "
  + "FROM employee,ownership WHERE employee.userid = ownership.employee_id and "
  + "ownership.employer_id = ? and ownership.employee_id = ?";

try
{
  Connection connection = WebSession.getConnections(s);
  PreparedStatement statement = connection.prepareStatement(query,
    ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
  statement.setString(1, userId);
  statement.setString(2, subjectUserId);
  ResultSet answer_results = statement.executeQuery();
  ...