This page looks best with JavaScript enabled

Introduction to SQL Injections

 ·  🎃 kr0m

An SQL injection consists of executing SQL statements on a database, statements that should not be allowed by the application in the first place. This is because the programmer did not take the necessary precautions to filter user input variables. In this way, a variety of results can be achieved, from finding out the database engine used to executing commands on the operating system itself. In this article, I will explain in a very simple way how to exploit a web vulnerability in an application designed for this purpose, so we will see with real code the functioning of this type of attacks.

Our web interface will serve as an access point to the company’s database that relates the code names of the agents with their real names and addresses. Therefore, a leak of information from this database can be catastrophic. The web will be composed of several files: header, footer, functions, and login.

The files in question are:

Header:

vi /var/www/ciaweb/header.html

<!DOCTYPE html>
<html lang="es_ES">
  <head>
    <title>CIA ultra secret webpage</title>
    <meta charset="utf-8">
    <meta name="description" content="CIA ultra secret webpage">
    <meta name="author" content="Kr0m">
    <meta name="robots" content="all">
    <meta name="cache" content="cache">
    <style>
      body { padding-top: 60px; }
    </style>
    <link href="/bootstrap/css/bootstrap.css" rel="stylesheet">
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <script src="/bootstrap/js/bootstrap.min.js"></script>
  </head>
  <body>

Footer:

vi /var/www/ciaweb/footer.html

  </body>
</html>

Functions:

vi /var/www/ciaweb/dbfunctions.php

<?php
function conecta($host, $user, $pass, $db) {
    $conexion = mysqli_connect($host, $user, $pass, $db) or die(mysqli_error($conexion));
    return $conexion;
}

function consulta($id, $query){
    $resultado = mysqli_query($id, $query) or die(mysqli_error($id));
    return $resultado;
}

Login:

vi /var/www/ciaweb/login.php

<?php
require("/var/www/ciaweb/cabecera.html");
require("/var/www/ciaweb/dbfunctions.php");
if (isset($_POST['username'])) {
    $id_conexion =  conecta('localhost', 'ciadb_user', 'XXXXXXXXXXXXXXXXX', 'ciadb');
    $resultado = consulta($id_conexion, "SELECT * FROM usuarios WHERE nombre='$_POST[username]' && password='$_POST[password]'", $id_conexion);
    $N = mysqli_num_rows($resultado);
        if ($N >0){
                $fila = mysqli_fetch_assoc($resultado);
                $resultado = consulta($id_conexion, "SELECT * FROM noc", $id_conexion);
                ?>      
                <div class="well">
                  <table class="table table-striped table-hover">
                    <thead>
                      <tr>    
                        <th>ID</th>
                        <th>Nombre en clave</th>
                        <th>Nombre real</th>
                        <th>Domicilio</th>
                        <th style="width: 36px;"></th>
                      </tr>   
                   </thead>
                   <tbody>
                <?php   
                while ($fila = mysqli_fetch_assoc($resultado)) {
                ?>      
                        <tr>    
                                <td><?php echo $fila['id']?></td>
                                <td><?php echo $fila['nombre_en_clave']?></td>
                                <td><?php echo $fila['nombre_real']?></td>
                                <td><?php echo $fila['domicilio']?></td>
                    </tr>   
                <?php   
                }       
    } else {
        ?>
        <section>
            <div class="container login">
                <div class="row ">
                    <div class="center span4 well">
                        <legend>Ultra secret Cia Database</legend>
                        <form method="POST" action="/login.php" accept-charset="UTF-8">
                          <input type="text" id="username" class="span4" name="username" placeholder="Nombre de usuario" />
                          <input type="password" id="password" class="span4" name="password" placeholder="Password" />
                          <button type="submit" name="submit" class="btn btn-primary btn-block">Sign in</button>
                        </form>
                    </div>
                </div>
            </div>
            <p class="text-center muted ">Ultra secret Cia Database</p>
        </section>
        <?php
    }
} else {
    ?>
    <section>
        <div class="container login">
            <div class="row ">
                <div class="center span4 well">
                    <legend>Ultra secret Cia Database</legend>
                    <form method="POST" action="/login.php" accept-charset="UTF-8">
                      <input type="text" id="username" class="span4" name="username" placeholder="Nombre de usuario" />
                      <input type="password" id="password" class="span4" name="password" placeholder="Password" />
                      <button type="submit" name="submit" class="btn btn-primary btn-block">Sign in</button>
                    </form>
                </div>
            </div>
        </div>
        <p class="text-center muted ">Ultra secret Cia Database</p>
    </section>
    <?php
}
require("/var/www/ciaweb/pie.html");

NOTE: To make the interface attractive, bootstrap has been used.

Now we create the database:

CREATE DATABASE ciadb DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
USE ciadb;
CREATE TABLE noc ( id int(11) NOT NULL, nombre_en_clave varchar(80) NOT NULL, nombre_real varchar(80) NOT NULL, domicilio varchar(80) NOT NULL);
CREATE TABLE usuarios ( id int(11) NOT NULL, nombre varchar(80) NOT NULL, password varchar(80) NOT NULL);

We insert users:

INSERT INTO usuarios (id, nombre, password) VALUES ('0','maxsnake','123');
INSERT INTO usuarios (id, nombre, password) VALUES ('1','lolman','321');

INSERT INTO noc (id, nombre_en_clave, nombre_real, domicilio) VALUES ('0', 'maxsnake', 'jhon', 'calle salamandra 123');
INSERT INTO noc (id, nombre_en_clave, nombre_real, domicilio) VALUES ('1', 'lolman', 'logic', 'calle margarita 321');

We assign permissions:

USE mysql
GRANT ALL PRIVILEGES ON ciadb.* to ciadb_user@'localhost' IDENTIFIED BY 'XXXXXXXXXXXXXXXXX';
FLUSH PRIVILEGES;

We configure the vhost as follows:

<VirtualHost *:80>
        ServerAdmin kr0m@alfaexploit.com
        DocumentRoot /var/www/ciaweb
        ServerName www.ciaweb.com
        SuexecUserGroup ABC DEF
        ErrorLog /var/log/apache2/error_ciaweb.log
        CustomLog /var/log/apache2/access_ciaweb.log combined
        DirectoryIndex login.php
        ScriptAlias /local-bin /var/www/cgi-bin/ABC
        AddHandler application/x-httpd-php5 php
        Action application/x-httpd-php5 /local-bin/php-cgi

        <Directory "/var/www/cgi-bin/ABC">
            Options -Indexes ExecCGI
            Order allow,deny
            Allow from all
        </Directory>

        <Directory "/var/www/ciaweb">
            options -Indexes ExecCGI FollowSymLinks
            AllowOverride All
            order allow,deny
            Allow from all
        </Directory>
</VirtualHost>

Now we edit our hosts file so that www.ciaweb.com resolves to the IP of our server:

vi /etc/hosts

A.B.C.D     www.ciaweb.com

To be able to see clearly what happens behind the scenes, we enable the MySQL log:

set global general_log='ON';
set global general_log_file='/var/run/mysqld/mysqld.log';
exit
tail -f /var/run/mysqld/mysqld.log

We access the web from a browser and our app should appear:
http://www.ciaweb.com/

If we log in with any user, we can see the data of all agents:

Now we proceed with the injection:


What happened, but how is it possible if the code checks the user and password against the database?

As we can see, all the security of the application lies in:

$resultado = consulta($id_conexion, "SELECT * FROM usuarios WHERE nombre='$_POST[username]' && password='$_POST[password]'", $id_conexion);
    $N = mysqli_num_rows($resultado);
    if ($N >0){

The problem is that the user input is not parsed in any way, so it is possible to enter ’ or ‘1 = 1’; – as the user, which makes the select condition always true for all rows by means of 1 = 1. In this way, the select will offer as a result all the records of the table, thus fulfilling the requirement imposed by the N>0 code. Finally, the SQL query ends correctly and indicates that what comes after the ; are comments, so the query executed by the database would be as follows:

SELECT * FROM users WHERE name='' or '1 = 1'; -- ' && password=''

The code would check that the previous query actually returns results, leaving the agents exposed :)

If you liked the article, you can treat me to a RedBull here