Compare commits

..
1 Commits
Author SHA1 Message Date
Miroslav Stampar 8bf566361d Removing an obsolete utility 2018-10-02 12:57:52 +02:00
459 changed files with 6175 additions and 7370 deletions
-2
View File
@@ -3,8 +3,6 @@
*.md5 text eol=lf *.md5 text eol=lf
*.py text eol=lf *.py text eol=lf
*.xml text eol=lf *.xml text eol=lf
LICENSE text eol=lf
COMMITMENT text eol=lf
*_ binary *_ binary
*.dll binary *.dll binary
+1 -1
View File
@@ -19,7 +19,7 @@
* Client OS (e.g. `Microsoft Windows 10`) * Client OS (e.g. `Microsoft Windows 10`)
* Program version (`python sqlmap.py --version` or `sqlmap --version` depending on installation): * Program version (`python sqlmap.py --version` or `sqlmap --version` depending on installation):
* Target DBMS (e.g. `Microsoft SQL Server`): * Target DBMS (e.g. `Microsoft SQL Server`):
* Detected WAF/IPS protection (e.g. `ModSecurity` or `unknown`): * Detected WAF/IDS/IPS protection (e.g. `ModSecurity` or `unknown`):
* SQLi techniques found by sqlmap (e.g. `error-based` and `boolean-based blind`): * SQLi techniques found by sqlmap (e.g. `error-based` and `boolean-based blind`):
* Results of manual target assessment (e.g. found that the payload `query=test' AND 4113 IN ((SELECT 'foobar'))-- qKLV` works): * Results of manual target assessment (e.g. found that the payload `query=test' AND 4113 IN ((SELECT 'foobar'))-- qKLV` works):
* Relevant console output (if any): * Relevant console output (if any):
-46
View File
@@ -1,46 +0,0 @@
GPL Cooperation Commitment
Version 1.0
Before filing or continuing to prosecute any legal proceeding or claim
(other than a Defensive Action) arising from termination of a Covered
License, we commit to extend to the person or entity ('you') accused
of violating the Covered License the following provisions regarding
cure and reinstatement, taken from GPL version 3. As used here, the
term 'this License' refers to the specific Covered License being
enforced.
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly
and finally terminates your license, and (b) permanently, if the
copyright holder fails to notify you of the violation by some
reasonable means prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you
have received notice of violation of this License (for any work)
from that copyright holder, and you cure the violation prior to 30
days after your receipt of the notice.
We intend this Commitment to be irrevocable, and binding and
enforceable against us and assignees of or successors to our
copyrights.
Definitions
'Covered License' means the GNU General Public License, version 2
(GPLv2), the GNU Lesser General Public License, version 2.1
(LGPLv2.1), or the GNU Library General Public License, version 2
(LGPLv2), all as published by the Free Software Foundation.
'Defensive Action' means a legal proceeding or claim that We bring
against you in response to a prior proceeding or claim initiated by
you or your affiliate.
'We' means each contributor to this repository as of the date of
inclusion of this file, including subsidiaries of a corporate
contributor.
This work is available under a Creative Commons Attribution-ShareAlike
4.0 International license (https://creativecommons.org/licenses/by-sa/4.0/).
+1 -1
View File
@@ -1,7 +1,7 @@
COPYING -- Describes the terms under which sqlmap is distributed. A copy COPYING -- Describes the terms under which sqlmap is distributed. A copy
of the GNU General Public License (GPL) is appended to this file. of the GNU General Public License (GPL) is appended to this file.
sqlmap is (C) 2006-2019 Bernardo Damele Assumpcao Guimaraes, Miroslav Stampar. sqlmap is (C) 2006-2018 Bernardo Damele Assumpcao Guimaraes, Miroslav Stampar.
This program is free software; you may redistribute and/or modify it under This program is free software; you may redistribute and/or modify it under
the terms of the GNU General Public License as published by the Free the terms of the GNU General Public License as published by the Free
+2 -3
View File
@@ -1,10 +1,10 @@
# sqlmap # sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![PyPI version](https://badge.fury.io/py/sqlmap.svg)](https://badge.fury.io/py/sqlmap) [![GitHub closed issues](https://img.shields.io/github/issues-closed-raw/sqlmapproject/sqlmap.svg?colorB=ff69b4)](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aissue+is%3Aclosed) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap) [![PyPI version](https://badge.fury.io/py/sqlmap.svg)](https://badge.fury.io/py/sqlmap)
sqlmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers. It comes with a powerful detection engine, many niche features for the ultimate penetration tester and a broad range of switches lasting from database fingerprinting, over data fetching from the database, to accessing the underlying file system and executing commands on the operating system via out-of-band connections. sqlmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers. It comes with a powerful detection engine, many niche features for the ultimate penetration tester and a broad range of switches lasting from database fingerprinting, over data fetching from the database, to accessing the underlying file system and executing commands on the operating system via out-of-band connections.
**The sqlmap project is sponsored by [Netsparker Web Application Security Scanner](https://www.netsparker.com/scan-website-security-issues/?utm_source=sqlmap.org&utm_medium=banner&utm_campaign=github).** **The sqlmap project is sponsored by [Netsparker Web Application Security Scanner](https://www.netsparker.com/?utm_source=github.com&utm_medium=referral&utm_content=sqlmap+repo&utm_campaign=generic+advert).**
Screenshots Screenshots
---- ----
@@ -67,4 +67,3 @@ Translations
* [Russian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ru-RUS.md) * [Russian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ru-RUS.md)
* [Spanish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-es-MX.md) * [Spanish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-es-MX.md)
* [Turkish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-tr-TR.md) * [Turkish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-tr-TR.md)
* [Ukrainian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-uk-UA.md)
-6
View File
@@ -565,9 +565,6 @@ Efrain Torres, <et(at)metasploit.com>
* for helping out to improve the Metasploit Framework sqlmap auxiliary module and for committing it on the Metasploit official subversion repository * for helping out to improve the Metasploit Framework sqlmap auxiliary module and for committing it on the Metasploit official subversion repository
* for his great Metasploit WMAP Framework * for his great Metasploit WMAP Framework
Jennifer Torres, <jtorresf42(at)gmail.com>
* for contributing a tamper script luanginx.py
Sandro Tosi, <matrixhasu(at)gmail.com> Sandro Tosi, <matrixhasu(at)gmail.com>
* for helping to create sqlmap Debian package correctly * for helping to create sqlmap Debian package correctly
@@ -764,9 +761,6 @@ ultramegaman, <seclists(at)ultramegaman.com>
Vinicius, <viniciusmaxdaloop(at)gmail.com> Vinicius, <viniciusmaxdaloop(at)gmail.com>
* for reporting a minor bug * for reporting a minor bug
w8ay
* for contributing an implementation for chunked transfer-encoding (switch --chunked)
wanglei, <wanglei(at)17uxi.cn> wanglei, <wanglei(at)17uxi.cn>
* for reporting a minor bug * for reporting a minor bug
+5 -4
View File
@@ -15,6 +15,11 @@ This file lists bundled packages and their associated licensing terms.
Copyright (C) 2013, Jonathan Hartley. Copyright (C) 2013, Jonathan Hartley.
* The Fcrypt library located under thirdparty/fcrypt/. * The Fcrypt library located under thirdparty/fcrypt/.
Copyright (C) 2000, 2001, 2004 Carey Evans. Copyright (C) 2000, 2001, 2004 Carey Evans.
* The Odict library located under thirdparty/odict/.
Copyright (C) 2005, Nicola Larosa, Michael Foord.
* The Oset library located under thirdparty/oset/.
Copyright (C) 2010, BlueDynamics Alliance, Austria.
Copyright (C) 2009, Raymond Hettinger, and others.
* The PrettyPrint library located under thirdparty/prettyprint/. * The PrettyPrint library located under thirdparty/prettyprint/.
Copyright (C) 2010, Chris Hall. Copyright (C) 2010, Chris Hall.
* The SocksiPy library located under thirdparty/socks/. * The SocksiPy library located under thirdparty/socks/.
@@ -276,10 +281,6 @@ be bound by the terms and conditions of this License Agreement.
* The bottle web framework library located under thirdparty/bottle/. * The bottle web framework library located under thirdparty/bottle/.
Copyright (C) 2012, Marcel Hellkamp. Copyright (C) 2012, Marcel Hellkamp.
* The ordereddict library located under thirdparty/odict/.
Copyright (C) 2009, Raymond Hettinger.
* The six Python 2 and 3 compatibility library located under thirdparty/six/.
Copyright (C) 2010-2018, Benjamin Peterson.
* The Termcolor library located under thirdparty/termcolor/. * The Termcolor library located under thirdparty/termcolor/.
Copyright (C) 2008-2011, Volvox Development Team. Copyright (C) 2008-2011, Volvox Development Team.
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap # sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![Лиценз](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap) [![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![Лиценз](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap e инструмент за тестване и проникване, с отворен код, който автоматизира процеса на откриване и използване на недостатъците на SQL база данните чрез SQL инжекция, която ги взима от сървъра. Снабден е с мощен детектор, множество специални функции за най-добрия тестер и широк спектър от функции, които могат да се използват за множество цели - извличане на данни от базата данни, достъп до основната файлова система и изпълняване на команди на операционната система. sqlmap e инструмент за тестване и проникване, с отворен код, който автоматизира процеса на откриване и използване на недостатъците на SQL база данните чрез SQL инжекция, която ги взима от сървъра. Снабден е с мощен детектор, множество специални функции за най-добрия тестер и широк спектър от функции, които могат да се използват за множество цели - извличане на данни от базата данни, достъп до основната файлова система и изпълняване на команди на операционната система.
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap # sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap) [![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap es una herramienta para pruebas de penetración "penetration testing" de software libre que automatiza el proceso de detección y explotación de fallos mediante inyección de SQL además de tomar el control de servidores de bases de datos. Contiene un poderoso motor de detección, así como muchas de las funcionalidades escenciales para el "pentester" y una amplia gama de opciones desde la recopilación de información para identificar el objetivo conocido como "fingerprinting" mediante la extracción de información de la base de datos, hasta el acceso al sistema de archivos subyacente para ejecutar comandos en el sistema operativo a través de conexiones alternativas conocidas como "Out-of-band". sqlmap es una herramienta para pruebas de penetración "penetration testing" de software libre que automatiza el proceso de detección y explotación de fallos mediante inyección de SQL además de tomar el control de servidores de bases de datos. Contiene un poderoso motor de detección, así como muchas de las funcionalidades escenciales para el "pentester" y una amplia gama de opciones desde la recopilación de información para identificar el objetivo conocido como "fingerprinting" mediante la extracción de información de la base de datos, hasta el acceso al sistema de archivos subyacente para ejecutar comandos en el sistema operativo a través de conexiones alternativas conocidas como "Out-of-band".
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap # sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap) [![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
**sqlmap** est un outil Open Source de test d'intrusion. Cet outil permet d'automatiser le processus de détection et d'exploitation des failles d'injection SQL afin de prendre le contrôle des serveurs de base de données. __sqlmap__ dispose d'un puissant moteur de détection utilisant les techniques les plus récentes et les plus dévastatrices de tests d'intrusion comme L'Injection SQL, qui permet d'accéder à la base de données, au système de fichiers sous-jacent et permet aussi l'exécution des commandes sur le système d'exploitation. **sqlmap** est un outil Open Source de test d'intrusion. Cet outil permet d'automatiser le processus de détection et d'exploitation des failles d'injection SQL afin de prendre le contrôle des serveurs de base de données. __sqlmap__ dispose d'un puissant moteur de détection utilisant les techniques les plus récentes et les plus dévastatrices de tests d'intrusion comme L'Injection SQL, qui permet d'accéder à la base de données, au système de fichiers sous-jacent et permet aussi l'exécution des commandes sur le système d'exploitation.
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap # sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap) [![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
Το sqlmap είναι πρόγραμμα ανοιχτού κώδικα, που αυτοματοποιεί την εύρεση και εκμετάλλευση ευπαθειών τύπου SQL Injection σε βάσεις δεδομένων. Έρχεται με μια δυνατή μηχανή αναγνώρισης ευπαθειών, πολλά εξειδικευμένα χαρακτηριστικά για τον απόλυτο penetration tester όπως και με ένα μεγάλο εύρος επιλογών αρχίζοντας από την αναγνώριση της βάσης δεδομένων, κατέβασμα δεδομένων της βάσης, μέχρι και πρόσβαση στο βαθύτερο σύστημα αρχείων και εκτέλεση εντολών στο απευθείας στο λειτουργικό μέσω εκτός ζώνης συνδέσεων. Το sqlmap είναι πρόγραμμα ανοιχτού κώδικα, που αυτοματοποιεί την εύρεση και εκμετάλλευση ευπαθειών τύπου SQL Injection σε βάσεις δεδομένων. Έρχεται με μια δυνατή μηχανή αναγνώρισης ευπαθειών, πολλά εξειδικευμένα χαρακτηριστικά για τον απόλυτο penetration tester όπως και με ένα μεγάλο εύρος επιλογών αρχίζοντας από την αναγνώριση της βάσης δεδομένων, κατέβασμα δεδομένων της βάσης, μέχρι και πρόσβαση στο βαθύτερο σύστημα αρχείων και εκτέλεση εντολών στο απευθείας στο λειτουργικό μέσω εκτός ζώνης συνδέσεων.
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap # sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap) [![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap je alat namijenjen za penetracijsko testiranje koji automatizira proces detekcije i eksploatacije sigurnosnih propusta SQL injekcije te preuzimanje poslužitelja baze podataka. Dolazi s moćnim mehanizmom za detekciju, mnoštvom korisnih opcija za napredno penetracijsko testiranje te široki spektar opcija od onih za prepoznavanja baze podataka, preko dohvaćanja podataka iz baze, do pristupa zahvaćenom datotečnom sustavu i izvršavanja komandi na operacijskom sustavu korištenjem tzv. "out-of-band" veza. sqlmap je alat namijenjen za penetracijsko testiranje koji automatizira proces detekcije i eksploatacije sigurnosnih propusta SQL injekcije te preuzimanje poslužitelja baze podataka. Dolazi s moćnim mehanizmom za detekciju, mnoštvom korisnih opcija za napredno penetracijsko testiranje te široki spektar opcija od onih za prepoznavanja baze podataka, preko dohvaćanja podataka iz baze, do pristupa zahvaćenom datotečnom sustavu i izvršavanja komandi na operacijskom sustavu korištenjem tzv. "out-of-band" veza.
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap # sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap) [![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap merupakan alat _(tool)_ bantu _open source_ dalam melakukan tes penetrasi yang mengotomasi proses deteksi dan eksploitasi kelemahan _SQL injection_ dan pengambil-alihan server basisdata. sqlmap dilengkapi dengan pendeteksi canggih, fitur-fitur hanal bagi _penetration tester_, beragam cara untuk mendeteksi basisdata, hingga mengakses _file system_ dan mengeksekusi perintah dalam sistem operasi melalui koneksi _out-of-band_. sqlmap merupakan alat _(tool)_ bantu _open source_ dalam melakukan tes penetrasi yang mengotomasi proses deteksi dan eksploitasi kelemahan _SQL injection_ dan pengambil-alihan server basisdata. sqlmap dilengkapi dengan pendeteksi canggih, fitur-fitur hanal bagi _penetration tester_, beragam cara untuk mendeteksi basisdata, hingga mengakses _file system_ dan mengeksekusi perintah dalam sistem operasi melalui koneksi _out-of-band_.
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap # sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap) [![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap è uno strumento open source per il penetration testing. Il suo scopo è quello di rendere automatico il processo di scoperta ed exploit di vulnerabilità di tipo SQL injection al fine di compromettere database online. Dispone di un potente motore per la ricerca di vulnerabilità, molti strumenti di nicchia anche per il più esperto penetration tester ed un'ampia gamma di controlli che vanno dal fingerprinting di database allo scaricamento di dati, fino all'accesso al file system sottostante e l'esecuzione di comandi nel sistema operativo attraverso connessioni out-of-band. sqlmap è uno strumento open source per il penetration testing. Il suo scopo è quello di rendere automatico il processo di scoperta ed exploit di vulnerabilità di tipo SQL injection al fine di compromettere database online. Dispone di un potente motore per la ricerca di vulnerabilità, molti strumenti di nicchia anche per il più esperto penetration tester ed un'ampia gamma di controlli che vanno dal fingerprinting di database allo scaricamento di dati, fino all'accesso al file system sottostante e l'esecuzione di comandi nel sistema operativo attraverso connessioni out-of-band.
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap # sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap) [![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmapはオープンソースのペネトレーションテスティングツールです。SQLインジェクションの脆弱性の検出、活用、そしてデータベースサーバ奪取のプロセスを自動化します。 sqlmapはオープンソースのペネトレーションテスティングツールです。SQLインジェクションの脆弱性の検出、活用、そしてデータベースサーバ奪取のプロセスを自動化します。
強力な検出エンジン、ペネトレーションテスターのための多くのニッチ機能、持続的なデータベースのフィンガープリンティングから、データベースのデータ取得やアウトオブバンド接続を介したオペレーティング・システム上でのコマンド実行、ファイルシステムへのアクセスなどの広範囲に及ぶスイッチを提供します。 強力な検出エンジン、ペネトレーションテスターのための多くのニッチ機能、持続的なデータベースのフィンガープリンティングから、データベースのデータ取得やアウトオブバンド接続を介したオペレーティング・システム上でのコマンド実行、ファイルシステムへのアクセスなどの広範囲に及ぶスイッチを提供します。
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap # sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap) [![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap to open sourceowe narzędzie do testów penetracyjnych, które automatyzuje procesy detekcji, przejmowania i testowania odporności serwerów SQL na podatność na iniekcję niechcianego kodu. Zawiera potężny mechanizm detekcji, wiele niszowych funkcji dla zaawansowanych testów penetracyjnych oraz szeroki wachlarz opcji począwszy od identyfikacji bazy danych, poprzez wydobywanie z nich danych, a nawet pozwalającuch na dostęp do systemu plików o uruchamianie poleceń w systemie operacyjnym serwera poprzez niestandardowe połączenia. sqlmap to open sourceowe narzędzie do testów penetracyjnych, które automatyzuje procesy detekcji, przejmowania i testowania odporności serwerów SQL na podatność na iniekcję niechcianego kodu. Zawiera potężny mechanizm detekcji, wiele niszowych funkcji dla zaawansowanych testów penetracyjnych oraz szeroki wachlarz opcji począwszy od identyfikacji bazy danych, poprzez wydobywanie z nich danych, a nawet pozwalającuch na dostęp do systemu plików o uruchamianie poleceń w systemie operacyjnym serwera poprzez niestandardowe połączenia.
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap # sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap) [![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap é uma ferramenta de teste de penetração de código aberto que automatiza o processo de detecção e exploração de falhas de injeção SQL. Com essa ferramenta é possível assumir total controle de servidores de banco de dados em páginas web vulneráveis, inclusive de base de dados fora do sistema invadido. Ele possui um motor de detecção poderoso, empregando as últimas e mais devastadoras técnicas de teste de penetração por SQL Injection, que permite acessar a base de dados, o sistema de arquivos subjacente e executar comandos no sistema operacional. sqlmap é uma ferramenta de teste de penetração de código aberto que automatiza o processo de detecção e exploração de falhas de injeção SQL. Com essa ferramenta é possível assumir total controle de servidores de banco de dados em páginas web vulneráveis, inclusive de base de dados fora do sistema invadido. Ele possui um motor de detecção poderoso, empregando as últimas e mais devastadoras técnicas de teste de penetração por SQL Injection, que permite acessar a base de dados, o sistema de arquivos subjacente e executar comandos no sistema operacional.
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap # sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap) [![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap - это инструмент для тестирования уязвимостей с открытым исходным кодом, который автоматизирует процесс обнаружения и использования ошибок SQL-инъекций и захвата серверов баз данных. Он оснащен мощным механизмом обнаружения, множеством приятных функций для профессионального тестера уязвимостей и широким спектром скриптов, которые упрощают работу с базами данных, от сбора данных из базы данных, до доступа к базовой файловой системе и выполнения команд в операционной системе через out-of-band соединение. sqlmap - это инструмент для тестирования уязвимостей с открытым исходным кодом, который автоматизирует процесс обнаружения и использования ошибок SQL-инъекций и захвата серверов баз данных. Он оснащен мощным механизмом обнаружения, множеством приятных функций для профессионального тестера уязвимостей и широким спектром скриптов, которые упрощают работу с базами данных, от сбора данных из базы данных, до доступа к базовой файловой системе и выполнения команд в операционной системе через out-of-band соединение.
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap # sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap) [![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap sql injection açıklarını otomatik olarak tespit ve istismar etmeye yarayan açık kaynak bir penetrasyon aracıdır. sqlmap gelişmiş tespit özelliğinin yanı sıra penetrasyon testleri sırasında gerekli olabilecek bir çok aracı, -uzak veritabınınından, veri indirmek, dosya sistemine erişmek, dosya çalıştırmak gibi - işlevleri de barındırmaktadır. sqlmap sql injection açıklarını otomatik olarak tespit ve istismar etmeye yarayan açık kaynak bir penetrasyon aracıdır. sqlmap gelişmiş tespit özelliğinin yanı sıra penetrasyon testleri sırasında gerekli olabilecek bir çok aracı, -uzak veritabınınından, veri indirmek, dosya sistemine erişmek, dosya çalıştırmak gibi - işlevleri de barındırmaktadır.
-50
View File
@@ -1,50 +0,0 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![PyPI version](https://badge.fury.io/py/sqlmap.svg)](https://badge.fury.io/py/sqlmap) [![GitHub closed issues](https://img.shields.io/github/issues-closed-raw/sqlmapproject/sqlmap.svg?colorB=ff69b4)](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aissue+is%3Aclosed) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap - це інструмент для тестування вразливостей з відкритим сирцевим кодом, який автоматизує процес виявлення і використання дефектів SQL-ін'єкцій, а також захоплення серверів баз даних. Він оснащений потужним механізмом виявлення, безліччю приємних функцій для професійного тестувальника вразливостей і широким спектром скриптів, які спрощують роботу з базами даних - від відбитка бази даних до доступу до базової файлової системи та виконання команд в операційній системі через out-of-band з'єднання.
Скриншоти
----
![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Ви можете ознайомитися з [колекцією скриншотів](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots), які демонструють деякі функції в wiki.
Встановлення
----
Ви можете завантажити останню версію tarball натиснувши [сюди](https://github.com/sqlmapproject/sqlmap/tarball/master) або останню версію zipball натиснувши [сюди](https://github.com/sqlmapproject/sqlmap/zipball/master).
Найкраще завантажити sqlmap шляхом клонування [Git](https://github.com/sqlmapproject/sqlmap) репозиторію:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap «працює з коробки» з [Python](http://www.python.org/download/) версії **2.6.x** та **2.7.x** на будь-якій платформі.
Використання
----
Щоб отримати список основних опцій і перемикачів, використовуйте:
python sqlmap.py -h
Щоб отримати список всіх опцій і перемикачів, використовуйте:
python sqlmap.py -hh
Ви можете знайти приклад виконання [тут](https://asciinema.org/a/46601).
Для того, щоб ознайомитися з можливостями sqlmap, списком підтримуваних функцій та описом всіх параметрів і перемикачів, а також прикладами, вам рекомендується скористатися [інструкцією користувача](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Посилання
----
* Основний сайт: http://sqlmap.org
* Завантаження: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) або [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* Канал новин RSS: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Відстеження проблем: https://github.com/sqlmapproject/sqlmap/issues
* Інструкція користувача: https://github.com/sqlmapproject/sqlmap/wiki
* Поширенні питання (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
* Twitter: [@sqlmap](https://twitter.com/sqlmap)
* Демо: [http://www.youtube.com/user/inquisb/videos](http://www.youtube.com/user/inquisb/videos)
* Скриншоти: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap # sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap) [![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap 是一个开源的渗透测试工具,可以用来自动化的检测,利用SQL注入漏洞,获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的渗透测试的功能选项,包括获取数据库中存储的数据,访问操作系统文件甚至可以通过外带数据连接的方式执行操作系统命令。 sqlmap 是一个开源的渗透测试工具,可以用来自动化的检测,利用SQL注入漏洞,获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的渗透测试的功能选项,包括获取数据库中存储的数据,访问操作系统文件甚至可以通过外带数据连接的方式执行操作系统命令。
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+4 -3
View File
@@ -3,11 +3,12 @@
""" """
beep.py - Make a beep sound beep.py - Make a beep sound
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import os import os
import subprocess
import sys import sys
import wave import wave
@@ -15,11 +16,11 @@ BEEP_WAV_FILENAME = os.path.join(os.path.dirname(__file__), "beep.wav")
def beep(): def beep():
try: try:
if sys.platform == "nt": if subprocess.mswindows:
_win_wav_play(BEEP_WAV_FILENAME) _win_wav_play(BEEP_WAV_FILENAME)
elif sys.platform == "darwin": elif sys.platform == "darwin":
_mac_beep() _mac_beep()
elif sys.platform.startswith("linux"): elif sys.platform == "linux2":
_linux_wav_play(BEEP_WAV_FILENAME) _linux_wav_play(BEEP_WAV_FILENAME)
else: else:
_speaker_beep() _speaker_beep()
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+11 -16
View File
@@ -3,28 +3,24 @@
""" """
cloak.py - Simple file encryption/compression utility cloak.py - Simple file encryption/compression utility
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
from __future__ import print_function
import os import os
import struct
import sys import sys
import zlib import zlib
from optparse import OptionError from optparse import OptionError
from optparse import OptionParser from optparse import OptionParser
if sys.version_info >= (3, 0):
xrange = range
def hideAscii(data): def hideAscii(data):
retVal = b"" retVal = ""
for i in xrange(len(data)): for i in xrange(len(data)):
value = data[i] if isinstance(data[i], int) else ord(data[i]) if ord(data[i]) < 128:
retVal += struct.pack('B', value ^ (127 if value < 128 else 0)) retVal += chr(ord(data[i]) ^ 127)
else:
retVal += data[i]
return retVal return retVal
@@ -41,9 +37,8 @@ def decloak(inputFile=None, data=None):
data = f.read() data = f.read()
try: try:
data = zlib.decompress(hideAscii(data)) data = zlib.decompress(hideAscii(data))
except Exception as ex: except:
print(ex) print 'ERROR: the provided input file \'%s\' does not contain valid cloaked content' % inputFile
print('ERROR: the provided input file \'%s\' does not contain valid cloaked content' % inputFile)
sys.exit(1) sys.exit(1)
finally: finally:
f.close() f.close()
@@ -64,11 +59,11 @@ def main():
if not args.inputFile: if not args.inputFile:
parser.error('Missing the input file, -h for help') parser.error('Missing the input file, -h for help')
except (OptionError, TypeError) as ex: except (OptionError, TypeError), e:
parser.error(ex) parser.error(e)
if not os.path.isfile(args.inputFile): if not os.path.isfile(args.inputFile):
print('ERROR: the provided input file \'%s\' is non existent' % args.inputFile) print 'ERROR: the provided input file \'%s\' is non existent' % args.inputFile
sys.exit(1) sys.exit(1)
if not args.decrypt: if not args.decrypt:
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+8 -9
View File
@@ -3,14 +3,13 @@
""" """
dbgtool.py - Portable executable to ASCII debug script converter dbgtool.py - Portable executable to ASCII debug script converter
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
from __future__ import print_function
import os import os
import sys import sys
import struct
from optparse import OptionError from optparse import OptionError
from optparse import OptionParser from optparse import OptionParser
@@ -20,7 +19,7 @@ def convert(inputFile):
fileSize = fileStat.st_size fileSize = fileStat.st_size
if fileSize > 65280: if fileSize > 65280:
print("ERROR: the provided input file '%s' is too big for debug.exe" % inputFile) print "ERROR: the provided input file '%s' is too big for debug.exe" % inputFile
sys.exit(1) sys.exit(1)
script = "n %s\nr cx\n" % os.path.basename(inputFile.replace(".", "_")) script = "n %s\nr cx\n" % os.path.basename(inputFile.replace(".", "_"))
@@ -33,7 +32,7 @@ def convert(inputFile):
fileContent = fp.read() fileContent = fp.read()
for fileChar in fileContent: for fileChar in fileContent:
unsignedFileChar = fileChar if sys.version_info >= (3, 0) else ord(fileChar) unsignedFileChar = struct.unpack("B", fileChar)[0]
if unsignedFileChar != 0: if unsignedFileChar != 0:
counter2 += 1 counter2 += 1
@@ -60,7 +59,7 @@ def convert(inputFile):
def main(inputFile, outputFile): def main(inputFile, outputFile):
if not os.path.isfile(inputFile): if not os.path.isfile(inputFile):
print("ERROR: the provided input file '%s' is not a regular file" % inputFile) print "ERROR: the provided input file '%s' is not a regular file" % inputFile
sys.exit(1) sys.exit(1)
script = convert(inputFile) script = convert(inputFile)
@@ -71,7 +70,7 @@ def main(inputFile, outputFile):
sys.stdout.write(script) sys.stdout.write(script)
sys.stdout.close() sys.stdout.close()
else: else:
print(script) print script
if __name__ == "__main__": if __name__ == "__main__":
usage = "%s -i <input file> [-o <output file>]" % sys.argv[0] usage = "%s -i <input file> [-o <output file>]" % sys.argv[0]
@@ -87,8 +86,8 @@ if __name__ == "__main__":
if not args.inputFile: if not args.inputFile:
parser.error("Missing the input file, -h for help") parser.error("Missing the input file, -h for help")
except (OptionError, TypeError) as ex: except (OptionError, TypeError), e:
parser.error(ex) parser.error(e)
inputFile = args.inputFile inputFile = args.inputFile
outputFile = args.outputFile outputFile = args.outputFile
+3 -2
View File
@@ -22,6 +22,7 @@
import os import os
import select import select
import socket import socket
import subprocess
import sys import sys
def setNonBlocking(fd): def setNonBlocking(fd):
@@ -36,7 +37,7 @@ def setNonBlocking(fd):
fcntl.fcntl(fd, fcntl.F_SETFL, flags) fcntl.fcntl(fd, fcntl.F_SETFL, flags)
def main(src, dst): def main(src, dst):
if sys.platform == "nt": if subprocess.mswindows:
sys.stderr.write('icmpsh master can only run on Posix systems\n') sys.stderr.write('icmpsh master can only run on Posix systems\n')
sys.exit(255) sys.exit(255)
@@ -127,7 +128,7 @@ def main(src, dst):
try: try:
# Send it to the target host # Send it to the target host
sock.sendto(ip.get_packet(), (dst, 0)) sock.sendto(ip.get_packet(), (dst, 0))
except socket.error as ex: except socket.error, ex:
sys.stderr.write("'%s'\n" % ex) sys.stderr.write("'%s'\n" % ex)
sys.stderr.flush() sys.stderr.flush()
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+5 -10
View File
@@ -1,14 +1,12 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
safe2bin.py - Simple safe(hex) to binary format converter safe2bin.py - Simple safe(hex) to binary format converter
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
from __future__ import print_function
import binascii import binascii
import re import re
import string import string
@@ -18,9 +16,6 @@ import sys
from optparse import OptionError from optparse import OptionError
from optparse import OptionParser from optparse import OptionParser
if sys.version_info >= (3, 0):
xrange = range
# Regex used for recognition of hex encoded characters # Regex used for recognition of hex encoded characters
HEX_ENCODED_CHAR_REGEX = r"(?P<result>\\x[0-9A-Fa-f]{2})" HEX_ENCODED_CHAR_REGEX = r"(?P<result>\\x[0-9A-Fa-f]{2})"
@@ -113,11 +108,11 @@ def main():
if not args.inputFile: if not args.inputFile:
parser.error('Missing the input file, -h for help') parser.error('Missing the input file, -h for help')
except (OptionError, TypeError) as ex: except (OptionError, TypeError), e:
parser.error(ex) parser.error(e)
if not os.path.isfile(args.inputFile): if not os.path.isfile(args.inputFile):
print('ERROR: the provided input file \'%s\' is not a regular file' % args.inputFile) print 'ERROR: the provided input file \'%s\' is not a regular file' % args.inputFile
sys.exit(1) sys.exit(1)
f = open(args.inputFile, 'r') f = open(args.inputFile, 'r')
-7
View File
@@ -1,7 +0,0 @@
#!/bin/bash
# Copyright (c) 2006-2013 sqlmap developers (http://sqlmap.org/)
# See the file 'LICENSE' for copying permission
# Stress test against Python3
for i in $(find . -iname "*.py" | grep -v __init__); do python3 -c 'import '`echo $i | cut -d '.' -f 2 | cut -d '/' -f 2- | sed 's/\//./g'`''; done
+17 -20
View File
@@ -1,30 +1,27 @@
#!/usr/bin/env python #!/usr/bin/env python
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) # Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
# See the file 'LICENSE' for copying permission # See the file 'LICENSE' for copying permission
# Removes duplicate entries in wordlist like files # Removes duplicate entries in wordlist like files
from __future__ import print_function
import sys import sys
if __name__ == "__main__": if len(sys.argv) > 0:
if len(sys.argv) > 1: items = list()
items = list()
with open(sys.argv[1], 'r') as f: with open(sys.argv[1], 'r') as f:
for item in f.readlines(): for item in f.readlines():
item = item.strip() item = item.strip()
try: try:
str.encode(item) str.encode(item)
if item in items: if item in items:
if item: if item:
print(item) print item
else: else:
items.append(item) items.append(item)
except: except:
pass pass
with open(sys.argv[1], 'w+') as f: with open(sys.argv[1], 'w+') as f:
f.writelines("\n".join(items)) f.writelines("\n".join(items))
+7 -7
View File
@@ -1,6 +1,7 @@
#! /usr/bin/env python #! /usr/bin/env python
from __future__ import print_function # Runs pylint on all python scripts found in a directory tree
# Reference: http://rowinggolfer.blogspot.com/2009/08/pylint-recursively.html
import os import os
import sys import sys
@@ -8,20 +9,19 @@ import sys
def check(filepath): def check(filepath):
if filepath.endswith(".py"): if filepath.endswith(".py"):
content = open(filepath, "rb").read() content = open(filepath, "rb").read()
pattern = "\n\n\n".encode("ascii")
if pattern in content: if "\n\n\n" in content:
index = content.find(pattern) index = content.find("\n\n\n")
print(filepath, repr(content[index - 30:index + 30])) print filepath, repr(content[index - 30:index + 30])
if __name__ == "__main__": if __name__ == "__main__":
try: try:
BASE_DIRECTORY = sys.argv[1] BASE_DIRECTORY = sys.argv[1]
except IndexError: except IndexError:
print("no directory specified, defaulting to current working directory") print "no directory specified, defaulting to current working directory"
BASE_DIRECTORY = os.getcwd() BASE_DIRECTORY = os.getcwd()
print("looking for *.py scripts in subdirectories of '%s'" % BASE_DIRECTORY) print "looking for *.py scripts in subdirectories of ", BASE_DIRECTORY
for root, dirs, files in os.walk(BASE_DIRECTORY): for root, dirs, files in os.walk(BASE_DIRECTORY):
if any(_ in root for _ in ("extra", "thirdparty")): if any(_ in root for _ in ("extra", "thirdparty")):
continue continue
+1 -12
View File
@@ -1,17 +1,6 @@
#!/bin/bash #!/bin/bash
: '
cat > .git/hooks/post-commit << EOF
#!/bin/bash
source ./extra/shutils/postcommit-hook.sh
EOF
chmod +x .git/hooks/post-commit
'
SETTINGS="../../lib/core/settings.py" SETTINGS="../../lib/core/settings.py"
PYPI="../../extra/shutils/pypi.sh"
declare -x SCRIPTPATH="${0}" declare -x SCRIPTPATH="${0}"
@@ -29,6 +18,6 @@ then
git tag $NEW_TAG git tag $NEW_TAG
git push origin $NEW_TAG git push origin $NEW_TAG
echo "Going to push PyPI package" echo "Going to push PyPI package"
/bin/bash ${SCRIPTPATH%/*}/$PYPI /bin/bash ${SCRIPTPATH%/*}/pypi.sh
fi fi
fi fi
+6 -11
View File
@@ -1,22 +1,14 @@
#!/bin/bash #!/bin/bash
: '
cat > .git/hooks/pre-commit << EOF
#!/bin/bash
source ./extra/shutils/precommit-hook.sh
EOF
chmod +x .git/hooks/pre-commit
'
PROJECT="../../" PROJECT="../../"
SETTINGS="../../lib/core/settings.py" SETTINGS="../../lib/core/settings.py"
CHECKSUM="../../txt/checksum.md5"
declare -x SCRIPTPATH="${0}" declare -x SCRIPTPATH="${0}"
PROJECT_FULLPATH=${SCRIPTPATH%/*}/$PROJECT PROJECT_FULLPATH=${SCRIPTPATH%/*}/$PROJECT
SETTINGS_FULLPATH=${SCRIPTPATH%/*}/$SETTINGS SETTINGS_FULLPATH=${SCRIPTPATH%/*}/$SETTINGS
CHECKSUM_FULLPATH=${SCRIPTPATH%/*}/$CHECKSUM
git diff $SETTINGS_FULLPATH | grep "VERSION =" > /dev/null && exit 0 git diff $SETTINGS_FULLPATH | grep "VERSION =" > /dev/null && exit 0
@@ -24,7 +16,7 @@ if [ -f $SETTINGS_FULLPATH ]
then then
LINE=$(grep -o ${SETTINGS_FULLPATH} -e 'VERSION = "[0-9.]*"') LINE=$(grep -o ${SETTINGS_FULLPATH} -e 'VERSION = "[0-9.]*"')
declare -a LINE declare -a LINE
INCREMENTED=$(python -c "import re, sys, time; version = re.search('\"([0-9.]*)\"', sys.argv[1]).group(1); _ = version.split('.'); _.extend([0] * (4 - len(_))); _[-1] = str(int(_[-1]) + 1); month = str(time.gmtime().tm_mon); _[-1] = '0' if _[-2] != month else _[-1]; _[-2] = month; print sys.argv[1].replace(version, '.'.join(_))" "$LINE") INCREMENTED=$(python -c "import re, sys, time; version = re.search('\"([0-9.]*)\"', sys.argv[1]).group(1); _ = version.split('.'); _.append(0) if len(_) < 3 else _; _[-1] = str(int(_[-1]) + 1); month = str(time.gmtime().tm_mon); _[-1] = '0' if _[-2] != month else _[-1]; _[-2] = month; print sys.argv[1].replace(version, '.'.join(_))" "$LINE")
if [ -n "$INCREMENTED" ] if [ -n "$INCREMENTED" ]
then then
sed -i "s/${LINE}/${INCREMENTED}/" $SETTINGS_FULLPATH sed -i "s/${LINE}/${INCREMENTED}/" $SETTINGS_FULLPATH
@@ -35,3 +27,6 @@ then
fi fi
git add "$SETTINGS_FULLPATH" git add "$SETTINGS_FULLPATH"
fi fi
truncate -s 0 "$CHECKSUM_FULLPATH"
cd $PROJECT_FULLPATH && for i in $(find . -name "*.py" -o -name "*.xml" -o -iname "*_" | sort); do git ls-files $i --error-unmatch &>/dev/null && md5sum $i | stdbuf -i0 -o0 -e0 sed 's/\.\///' >> "$CHECKSUM_FULLPATH"; git add "$CHECKSUM_FULLPATH"; done
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) # Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
# See the file 'LICENSE' for copying permission # See the file 'LICENSE' for copying permission
# Runs pycodestyle on all python files (prerequisite: pip install pycodestyle) # Runs pycodestyle on all python files (prerequisite: pip install pycodestyle)
+9 -11
View File
@@ -3,8 +3,6 @@
# Runs pylint on all python scripts found in a directory tree # Runs pylint on all python scripts found in a directory tree
# Reference: http://rowinggolfer.blogspot.com/2009/08/pylint-recursively.html # Reference: http://rowinggolfer.blogspot.com/2009/08/pylint-recursively.html
from __future__ import print_function
import os import os
import re import re
import sys import sys
@@ -19,26 +17,26 @@ def check(module):
if module[-3:] == ".py": if module[-3:] == ".py":
print("CHECKING ", module) print "CHECKING ", module
pout = os.popen("pylint --rcfile=/dev/null %s" % module, 'r') pout = os.popen("pylint --rcfile=/dev/null %s" % module, 'r')
for line in pout: for line in pout:
if re.match(r"\AE:", line): if re.match(r"\AE:", line):
print(line.strip()) print line.strip()
if __RATING__ and "Your code has been rated at" in line: if __RATING__ and "Your code has been rated at" in line:
print(line) print line
score = re.findall(r"\d.\d\d", line)[0] score = re.findall(r"\d.\d\d", line)[0]
total += float(score) total += float(score)
count += 1 count += 1
if __name__ == "__main__": if __name__ == "__main__":
try: try:
print(sys.argv) print sys.argv
BASE_DIRECTORY = sys.argv[1] BASE_DIRECTORY = sys.argv[1]
except IndexError: except IndexError:
print("no directory specified, defaulting to current working directory") print "no directory specified, defaulting to current working directory"
BASE_DIRECTORY = os.getcwd() BASE_DIRECTORY = os.getcwd()
print("looking for *.py scripts in subdirectories of ", BASE_DIRECTORY) print "looking for *.py scripts in subdirectories of ", BASE_DIRECTORY
for root, dirs, files in os.walk(BASE_DIRECTORY): for root, dirs, files in os.walk(BASE_DIRECTORY):
if any(_ in root for _ in ("extra", "thirdparty")): if any(_ in root for _ in ("extra", "thirdparty")):
continue continue
@@ -47,6 +45,6 @@ if __name__ == "__main__":
check(filepath) check(filepath)
if __RATING__: if __RATING__:
print("==" * 50) print "==" * 50
print("%d modules found" % count) print "%d modules found" % count
print("AVERAGE SCORE = %.02f" % (total / count)) print "AVERAGE SCORE = %.02f" % (total / count)
+6 -11
View File
@@ -16,7 +16,7 @@ cat > $TMP_DIR/setup.py << EOF
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -26,16 +26,10 @@ setup(
name='sqlmap', name='sqlmap',
version='$VERSION', version='$VERSION',
description='Automatic SQL injection and database takeover tool', description='Automatic SQL injection and database takeover tool',
long_description=open('README.rst').read(), long_description='sqlmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers. It comes with a powerful detection engine, many niche features for the ultimate penetration tester and a broad range of switches lasting from database fingerprinting, over data fetching from the database, to accessing the underlying file system and executing commands on the operating system via out-of-band connections.',
long_description_content_type='text/x-rst',
author='Bernardo Damele Assumpcao Guimaraes, Miroslav Stampar', author='Bernardo Damele Assumpcao Guimaraes, Miroslav Stampar',
author_email='[email protected], [email protected]', author_email='[email protected], [email protected]',
url='http://sqlmap.org', url='http://sqlmap.org',
project_urls={
'Documentation': 'https://github.com/sqlmapproject/sqlmap/wiki',
'Source': 'https://github.com/sqlmapproject/sqlmap/',
'Tracker': 'https://github.com/sqlmapproject/sqlmap/issues',
},
download_url='https://github.com/sqlmapproject/sqlmap/archive/$VERSION.zip', download_url='https://github.com/sqlmapproject/sqlmap/archive/$VERSION.zip',
license='GNU General Public License v2 (GPLv2)', license='GNU General Public License v2 (GPLv2)',
packages=find_packages(), packages=find_packages(),
@@ -67,7 +61,7 @@ cat > sqlmap/__init__.py << EOF
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -159,7 +153,7 @@ Links
- User's manual: https://github.com/sqlmapproject/sqlmap/wiki - User's manual: https://github.com/sqlmapproject/sqlmap/wiki
- Frequently Asked Questions (FAQ): - Frequently Asked Questions (FAQ):
https://github.com/sqlmapproject/sqlmap/wiki/FAQ https://github.com/sqlmapproject/sqlmap/wiki/FAQ
- Twitter: https://twitter.com/sqlmap - Twitter: [@sqlmap](https://twitter.com/sqlmap)
- Demos: http://www.youtube.com/user/inquisb/videos - Demos: http://www.youtube.com/user/inquisb/videos
- Screenshots: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots - Screenshots: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
@@ -177,6 +171,7 @@ Links
EOF EOF
sed -i "s/^VERSION =.*/VERSION = \"$VERSION\"/g" sqlmap/lib/core/settings.py sed -i "s/^VERSION =.*/VERSION = \"$VERSION\"/g" sqlmap/lib/core/settings.py
sed -i "s/^TYPE =.*/TYPE = \"$TYPE\"/g" sqlmap/lib/core/settings.py sed -i "s/^TYPE =.*/TYPE = \"$TYPE\"/g" sqlmap/lib/core/settings.py
sed -i "s/.*lib\/core\/settings\.py/`md5sum sqlmap/lib/core/settings.py | cut -d ' ' -f 1` lib\/core\/settings\.py/g" sqlmap/txt/checksum.md5
for file in $(find sqlmap -type f | grep -v -E "\.(git|yml)"); do echo include $file >> MANIFEST.in; done for file in $(find sqlmap -type f | grep -v -E "\.(git|yml)"); do echo include $file >> MANIFEST.in; done
python setup.py sdist upload python setup.py sdist upload
rm -rf $TMP_DIR rm -rf $TMP_DIR
+164
View File
@@ -0,0 +1,164 @@
#!/usr/bin/env python
# Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
# See the file 'LICENSE' for copying permission
import codecs
import inspect
import os
import re
import smtplib
import subprocess
import sys
import time
import traceback
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
sys.path.append(os.path.normpath("%s/../../" % os.path.dirname(inspect.getfile(inspect.currentframe()))))
from lib.core.revision import getRevisionNumber
START_TIME = time.strftime("%H:%M:%S %d-%m-%Y", time.gmtime())
SQLMAP_HOME = "/opt/sqlmap"
SMTP_SERVER = "127.0.0.1"
SMTP_PORT = 25
SMTP_TIMEOUT = 30
FROM = "[email protected]"
# TO = "[email protected]"
TO = ["[email protected]", "[email protected]"]
SUBJECT = "regression test started on %s using revision %s" % (START_TIME, getRevisionNumber())
TARGET = "debian"
def prepare_email(content):
global FROM
global TO
global SUBJECT
msg = MIMEMultipart()
msg["Subject"] = SUBJECT
msg["From"] = FROM
msg["To"] = TO if isinstance(TO, basestring) else ','.join(TO)
msg.attach(MIMEText(content))
return msg
def send_email(msg):
global SMTP_SERVER
global SMTP_PORT
global SMTP_TIMEOUT
try:
s = smtplib.SMTP(host=SMTP_SERVER, port=SMTP_PORT, timeout=SMTP_TIMEOUT)
s.sendmail(FROM, TO, msg.as_string())
s.quit()
# Catch all for SMTP exceptions
except smtplib.SMTPException, e:
print "Failure to send email: %s" % str(e)
def failure_email(msg):
msg = prepare_email(msg)
send_email(msg)
sys.exit(1)
def main():
global SUBJECT
content = ""
test_counts = []
attachments = {}
updateproc = subprocess.Popen("cd /opt/sqlmap/ ; python /opt/sqlmap/sqlmap.py --update", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = updateproc.communicate()
if stderr:
failure_email("Update of sqlmap failed with error:\n\n%s" % stderr)
regressionproc = subprocess.Popen("python /opt/sqlmap/sqlmap.py --live-test", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False)
stdout, stderr = regressionproc.communicate()
if stderr:
failure_email("Execution of regression test failed with error:\n\n%s" % stderr)
failed_tests = re.findall(r"running live test case: (.+?) \((\d+)\/\d+\)[\r]*\n.+test failed (at parsing items: (.+))?\s*\- scan folder: (\/.+) \- traceback: (.*?)( - SQL injection not detected)?[\r]*\n", stdout)
for failed_test in failed_tests:
title = failed_test[0]
test_count = int(failed_test[1])
parse = failed_test[3] if failed_test[3] else None
output_folder = failed_test[4]
traceback = False if failed_test[5] == "False" else bool(failed_test[5])
detected = False if failed_test[6] else True
test_counts.append(test_count)
console_output_file = os.path.join(output_folder, "console_output")
log_file = os.path.join(output_folder, TARGET, "log")
traceback_file = os.path.join(output_folder, "traceback")
if os.path.exists(console_output_file):
console_output_fd = codecs.open(console_output_file, "rb", "utf8")
console_output = console_output_fd.read()
console_output_fd.close()
attachments[test_count] = str(console_output)
if os.path.exists(log_file):
log_fd = codecs.open(log_file, "rb", "utf8")
log = log_fd.read()
log_fd.close()
if os.path.exists(traceback_file):
traceback_fd = codecs.open(traceback_file, "rb", "utf8")
traceback = traceback_fd.read()
traceback_fd.close()
content += "Failed test case '%s' (#%d)" % (title, test_count)
if parse:
content += " at parsing: %s:\n\n" % parse
content += "### Log file:\n\n"
content += "%s\n\n" % log
elif not detected:
content += " - SQL injection not detected\n\n"
else:
content += "\n\n"
if traceback:
content += "### Traceback:\n\n"
content += "%s\n\n" % str(traceback)
content += "#######################################################################\n\n"
end_string = "Regression test finished at %s" % time.strftime("%H:%M:%S %d-%m-%Y", time.gmtime())
if content:
content += end_string
SUBJECT = "Failed %s (%s)" % (SUBJECT, ", ".join("#%d" % count for count in test_counts))
msg = prepare_email(content)
for test_count, attachment in attachments.items():
attachment = MIMEText(attachment)
attachment.add_header("Content-Disposition", "attachment", filename="test_case_%d_console_output.txt" % test_count)
msg.attach(attachment)
send_email(msg)
else:
SUBJECT = "Successful %s" % SUBJECT
msg = prepare_email("All test cases were successful\n\n%s" % end_string)
send_email(msg)
if __name__ == "__main__":
log_fd = open("/tmp/sqlmapregressiontest.log", "wb")
log_fd.write("Regression test started at %s\n" % START_TIME)
try:
main()
except Exception, e:
log_fd.write("An exception has occurred:\n%s" % str(traceback.format_exc()))
log_fd.write("Regression test finished at %s\n\n" % time.strftime("%H:%M:%S %d-%m-%Y", time.gmtime()))
log_fd.close()
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+141
View File
@@ -0,0 +1,141 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import cookielib
import re
import socket
import sys
import urllib
import urllib2
import ConfigParser
from operator import itemgetter
TIMEOUT = 10
CONFIG_FILE = 'sqlharvest.cfg'
TABLES_FILE = 'tables.txt'
USER_AGENT = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; AskTB5.3)'
SEARCH_URL = 'http://www.google.com/m?source=mobileproducts&dc=gorganic'
MAX_FILE_SIZE = 2 * 1024 * 1024 # if a result (.sql) file for downloading is more than 2MB in size just skip it
QUERY = 'CREATE TABLE ext:sql'
REGEX_URLS = r';u=([^"]+?)&amp;q='
REGEX_RESULT = r'(?i)CREATE TABLE\s*(/\*.*\*/)?\s*(IF NOT EXISTS)?\s*(?P<result>[^\(;]+)'
def main():
tables = dict()
cookies = cookielib.CookieJar()
cookie_processor = urllib2.HTTPCookieProcessor(cookies)
opener = urllib2.build_opener(cookie_processor)
opener.addheaders = [("User-Agent", USER_AGENT)]
conn = opener.open(SEARCH_URL)
page = conn.read() # set initial cookie values
config = ConfigParser.ConfigParser()
config.read(CONFIG_FILE)
if not config.has_section("options"):
config.add_section("options")
if not config.has_option("options", "index"):
config.set("options", "index", "0")
i = int(config.get("options", "index"))
try:
with open(TABLES_FILE, 'r') as f:
for line in f.xreadlines():
if len(line) > 0 and ',' in line:
temp = line.split(',')
tables[temp[0]] = int(temp[1])
except:
pass
socket.setdefaulttimeout(TIMEOUT)
files, old_files = None, None
try:
while True:
abort = False
old_files = files
files = []
try:
conn = opener.open("%s&q=%s&start=%d&sa=N" % (SEARCH_URL, QUERY.replace(' ', '+'), i * 10))
page = conn.read()
for match in re.finditer(REGEX_URLS, page):
files.append(urllib.unquote(match.group(1)))
if len(files) >= 10:
break
abort = (files == old_files)
except KeyboardInterrupt:
raise
except Exception, msg:
print msg
if abort:
break
sys.stdout.write("\n---------------\n")
sys.stdout.write("Result page #%d\n" % (i + 1))
sys.stdout.write("---------------\n")
for sqlfile in files:
print sqlfile
try:
req = urllib2.Request(sqlfile)
response = urllib2.urlopen(req)
if "Content-Length" in response.headers:
if int(response.headers.get("Content-Length")) > MAX_FILE_SIZE:
continue
page = response.read()
found = False
counter = 0
for match in re.finditer(REGEX_RESULT, page):
counter += 1
table = match.group("result").strip().strip("`\"'").replace('"."', ".").replace("].[", ".").strip('[]')
if table and not any(_ in table for _ in ('>', '<', '--', ' ')):
found = True
sys.stdout.write('*')
if table in tables:
tables[table] += 1
else:
tables[table] = 1
if found:
sys.stdout.write("\n")
except KeyboardInterrupt:
raise
except Exception, msg:
print msg
else:
i += 1
except KeyboardInterrupt:
pass
finally:
with open(TABLES_FILE, 'w+') as f:
tables = sorted(tables.items(), key=itemgetter(1), reverse=True)
for table, count in tables:
f.write("%s,%d\n" % (table, count))
config.set("options", "index", str(i + 1))
with open(CONFIG_FILE, 'w+') as f:
config.write(f)
if __name__ == "__main__":
main()
-148
View File
@@ -1,148 +0,0 @@
#!/usr/bin/env python
"""
vulnserver.py - Trivial SQLi vulnerable HTTP server (Note: for testing purposes)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from __future__ import print_function
import re
import sqlite3
import sys
import traceback
if sys.version_info >= (3, 0):
from http.client import FOUND
from http.client import NOT_FOUND
from http.client import OK
from http.server import BaseHTTPRequestHandler
from http.server import HTTPServer
from socketserver import ThreadingMixIn
from urllib.parse import parse_qs
from urllib.parse import unquote_plus
else:
from BaseHTTPServer import BaseHTTPRequestHandler
from BaseHTTPServer import HTTPServer
from httplib import FOUND
from httplib import NOT_FOUND
from httplib import OK
from SocketServer import ThreadingMixIn
from urlparse import parse_qs
from urllib import unquote_plus
SCHEMA = """
CREATE TABLE users (
id INTEGER,
name TEXT,
surname TEXT
);
INSERT INTO users (id, name, surname) VALUES (1, 'luther', 'blisset');
INSERT INTO users (id, name, surname) VALUES (2, 'fluffy', 'bunny');
INSERT INTO users (id, name, surname) VALUES (3, 'wu', 'ming');
INSERT INTO users (id, name, surname) VALUES (4, 'sqlmap/1.0-dev (http://sqlmap.org)', 'user agent header');
INSERT INTO users (id, name, surname) VALUES (5, NULL, 'nameisnull');
"""
LISTEN_ADDRESS = "localhost"
LISTEN_PORT = 8440
_conn = None
_cursor = None
_server = None
def init():
global _conn
global _cursor
_conn = sqlite3.connect(":memory:", isolation_level=None, check_same_thread=False)
_cursor = _conn.cursor()
_cursor.executescript(SCHEMA)
class ThreadingServer(ThreadingMixIn, HTTPServer):
def finish_request(self, *args, **kwargs):
try:
HTTPServer.finish_request(self, *args, **kwargs)
except Exception:
traceback.print_exc()
class ReqHandler(BaseHTTPRequestHandler):
def do_REQUEST(self):
path, query = self.path.split('?', 1) if '?' in self.path else (self.path, "")
params = {}
if query:
params.update(parse_qs(query))
if hasattr(self, "data"):
params.update(parse_qs(self.data))
for key in params:
if params[key]:
params[key] = params[key][-1]
self.url, self.params = path, params
if self.url == '/':
if "id" not in params:
self.send_response(FOUND)
self.send_header("Connection", "close")
self.send_header("Location", "/?id=1")
self.end_headers()
else:
self.send_response(OK)
self.send_header("Content-type", "text/html")
self.send_header("Connection", "close")
self.end_headers()
try:
_cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % self.params.get("id", ""))
output = "<b>SQL results:</b>\n"
output += "<table border=\"1\">\n"
for row in _cursor.fetchall():
output += "<tr>"
for value in row:
output += "<td>%s</td>" % value
output += "</tr>\n"
output += "</table>\n"
output += "</body></html>";
except Exception as ex:
output = "%s: %s" % (re.search(r"'([^']+)'", str(type(ex))).group(1), ex)
self.wfile.write(output.encode("utf8"))
else:
self.send_response(NOT_FOUND)
self.send_header("Connection", "close")
self.end_headers()
def do_GET(self):
self.do_REQUEST()
def do_POST(self):
length = int(self.headers.get("Content-length", 0))
if length:
data = self.rfile.read(length)
data = unquote_plus(data.decode("utf8"))
self.data = data
self.do_REQUEST()
def run(address=LISTEN_ADDRESS, port=LISTEN_PORT):
global _server
try:
_server = ThreadingServer((address, port), ReqHandler)
print("[i] running HTTP server at '%s:%d'" % (address, port))
_server.serve_forever()
except KeyboardInterrupt:
_server.socket.close()
raise
if __name__ == "__main__":
try:
init()
run(sys.argv[1] if len(sys.argv) > 1 else LISTEN_ADDRESS, int(sys.argv[2] if len(sys.argv) > 2 else LISTEN_PORT))
except KeyboardInterrupt:
print("\r[x] Ctrl-C received")
+8
View File
@@ -0,0 +1,8 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
pass
+119
View File
@@ -0,0 +1,119 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import cookielib
import glob
import httplib
import inspect
import os
import re
import subprocess
import sys
import urllib2
sys.dont_write_bytecode = True
NAME, VERSION, AUTHOR = "WAF Detectify", "0.1", "sqlmap developers (@sqlmap)"
TIMEOUT = 10
HEADERS = {"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate", "Cache-Control": "max-age=0"}
SQLMAP_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
SCRIPTS_DIR = os.path.join(SQLMAP_DIR, "waf")
LEVEL_COLORS = {"o": "\033[00;94m", "x": "\033[00;91m", "!": "\033[00;93m", "i": "\033[00;92m"}
CACHE = {}
WAF_FUNCTIONS = []
def get_page(get=None, url=None, host=None, data=None):
key = (get, url, host, data)
if key in CACHE:
return CACHE[key]
page, headers, code = None, {}, httplib.OK
url = url or ("%s%s%s" % (sys.argv[1], '?' if '?' not in sys.argv[1] else '&', get) if get else sys.argv[1])
if not url.startswith("http"):
url = "http://%s" % url
try:
req = urllib2.Request("".join(url[_].replace(' ', "%20") if _ > url.find('?') else url[_] for _ in xrange(len(url))), data, HEADERS)
conn = urllib2.urlopen(req, timeout=TIMEOUT)
page = conn.read()
headers = conn.info()
except Exception, ex:
code = getattr(ex, "code", None)
page = ex.read() if hasattr(ex, "read") else getattr(ex, "msg", "")
headers = ex.info() if hasattr(ex, "info") else {}
result = CACHE[key] = page, headers, code
return result
def colorize(message):
if not subprocess.mswindows and sys.stdout.isatty():
message = re.sub(r"\[(.)\]", lambda match: "[%s%s\033[00;49m]" % (LEVEL_COLORS[match.group(1)], match.group(1)), message)
message = message.replace("@sqlmap", "\033[00;96m@sqlmap\033[00;49m")
message = message.replace(NAME, "\033[00;93m%s\033[00;49m" % NAME)
return message
def main():
global WAF_FUNCTIONS
print colorize("%s #v%s\n by: %s\n" % (NAME, VERSION, AUTHOR))
if len(sys.argv) < 2:
exit(colorize("[x] usage: python %s <hostname>" % os.path.split(__file__)[-1]))
cookie_jar = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie_jar))
urllib2.install_opener(opener)
sys.path.insert(0, SQLMAP_DIR)
for found in glob.glob(os.path.join(SCRIPTS_DIR, "*.py")):
dirname, filename = os.path.split(found)
dirname = os.path.abspath(dirname)
if filename == "__init__.py":
continue
if dirname not in sys.path:
sys.path.insert(0, dirname)
try:
if filename[:-3] in sys.modules:
del sys.modules[filename[:-3]]
module = __import__(filename[:-3].encode(sys.getfilesystemencoding() or "utf8"))
except ImportError, msg:
exit(colorize("[x] cannot import WAF script '%s' (%s)" % (filename[:-3], msg)))
_ = dict(inspect.getmembers(module))
if "detect" not in _:
exit(colorize("[x] missing function 'detect(get_page)' in WAF script '%s'" % found))
else:
WAF_FUNCTIONS.append((_["detect"], _.get("__product__", filename[:-3])))
WAF_FUNCTIONS = sorted(WAF_FUNCTIONS, key=lambda _: "generic" in _[1].lower())
print colorize("[i] %d WAF scripts loaded" % len(WAF_FUNCTIONS))
found = False
for function, product in WAF_FUNCTIONS:
if found and "unknown" in product.lower():
continue
if function(get_page):
print colorize("[!] WAF/IPS identified as '%s'" % product)
found = True
if not found:
print colorize("[o] nothing found")
print
if __name__ == "__main__":
main()
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+15 -65
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -75,7 +75,7 @@ def action():
if conf.getPasswordHashes: if conf.getPasswordHashes:
try: try:
conf.dumper.userSettings("database management system users password hashes", conf.dbmsHandler.getPasswordHashes(), "password hash", CONTENT_TYPE.PASSWORDS) conf.dumper.userSettings("database management system users password hashes", conf.dbmsHandler.getPasswordHashes(), "password hash", CONTENT_TYPE.PASSWORDS)
except SqlmapNoneDataException as ex: except SqlmapNoneDataException, ex:
logger.critical(ex) logger.critical(ex)
except: except:
raise raise
@@ -83,7 +83,7 @@ def action():
if conf.getPrivileges: if conf.getPrivileges:
try: try:
conf.dumper.userSettings("database management system users privileges", conf.dbmsHandler.getPrivileges(), "privilege", CONTENT_TYPE.PRIVILEGES) conf.dumper.userSettings("database management system users privileges", conf.dbmsHandler.getPrivileges(), "privilege", CONTENT_TYPE.PRIVILEGES)
except SqlmapNoneDataException as ex: except SqlmapNoneDataException, ex:
logger.critical(ex) logger.critical(ex)
except: except:
raise raise
@@ -91,90 +91,40 @@ def action():
if conf.getRoles: if conf.getRoles:
try: try:
conf.dumper.userSettings("database management system users roles", conf.dbmsHandler.getRoles(), "role", CONTENT_TYPE.ROLES) conf.dumper.userSettings("database management system users roles", conf.dbmsHandler.getRoles(), "role", CONTENT_TYPE.ROLES)
except SqlmapNoneDataException as ex: except SqlmapNoneDataException, ex:
logger.critical(ex) logger.critical(ex)
except: except:
raise raise
if conf.getDbs: if conf.getDbs:
try: conf.dumper.dbs(conf.dbmsHandler.getDbs())
conf.dumper.dbs(conf.dbmsHandler.getDbs())
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.getTables: if conf.getTables:
try: conf.dumper.dbTables(conf.dbmsHandler.getTables())
conf.dumper.dbTables(conf.dbmsHandler.getTables())
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.commonTables: if conf.commonTables:
try: conf.dumper.dbTables(tableExists(paths.COMMON_TABLES))
conf.dumper.dbTables(tableExists(paths.COMMON_TABLES))
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.getSchema: if conf.getSchema:
try: conf.dumper.dbTableColumns(conf.dbmsHandler.getSchema(), CONTENT_TYPE.SCHEMA)
conf.dumper.dbTableColumns(conf.dbmsHandler.getSchema(), CONTENT_TYPE.SCHEMA)
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.getColumns: if conf.getColumns:
try: conf.dumper.dbTableColumns(conf.dbmsHandler.getColumns(), CONTENT_TYPE.COLUMNS)
conf.dumper.dbTableColumns(conf.dbmsHandler.getColumns(), CONTENT_TYPE.COLUMNS)
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.getCount: if conf.getCount:
try: conf.dumper.dbTablesCount(conf.dbmsHandler.getCount())
conf.dumper.dbTablesCount(conf.dbmsHandler.getCount())
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.commonColumns: if conf.commonColumns:
try: conf.dumper.dbTableColumns(columnExists(paths.COMMON_COLUMNS))
conf.dumper.dbTableColumns(columnExists(paths.COMMON_COLUMNS))
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.dumpTable: if conf.dumpTable:
try: conf.dbmsHandler.dumpTable()
conf.dbmsHandler.dumpTable()
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.dumpAll: if conf.dumpAll:
try: conf.dbmsHandler.dumpAll()
conf.dbmsHandler.dumpAll()
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.search: if conf.search:
try: conf.dbmsHandler.search()
conf.dbmsHandler.search()
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.query: if conf.query:
conf.dumper.query(conf.query, conf.dbmsHandler.sqlQuery(conf.query)) conf.dumper.query(conf.query, conf.dbmsHandler.sqlQuery(conf.query))
+64 -107
View File
@@ -1,11 +1,12 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import copy import copy
import httplib
import logging import logging
import os import os
import random import random
@@ -21,7 +22,6 @@ from lib.core.agent import agent
from lib.core.common import Backend from lib.core.common import Backend
from lib.core.common import extractRegexResult from lib.core.common import extractRegexResult
from lib.core.common import extractTextTagContent from lib.core.common import extractTextTagContent
from lib.core.common import filterNone
from lib.core.common import findDynamicContent from lib.core.common import findDynamicContent
from lib.core.common import Format from lib.core.common import Format
from lib.core.common import getFilteredPageContent from lib.core.common import getFilteredPageContent
@@ -48,7 +48,6 @@ from lib.core.common import unArrayizeValue
from lib.core.common import urlencode from lib.core.common import urlencode
from lib.core.common import wasLastResponseDBMSError from lib.core.common import wasLastResponseDBMSError
from lib.core.common import wasLastResponseHTTPError from lib.core.common import wasLastResponseHTTPError
from lib.core.compat import xrange
from lib.core.convert import unicodeencode from lib.core.convert import unicodeencode
from lib.core.defaults import defaults from lib.core.defaults import defaults
from lib.core.data import conf from lib.core.data import conf
@@ -70,14 +69,11 @@ from lib.core.enums import NULLCONNECTION
from lib.core.enums import PAYLOAD from lib.core.enums import PAYLOAD
from lib.core.enums import PLACE from lib.core.enums import PLACE
from lib.core.enums import REDIRECTION from lib.core.enums import REDIRECTION
from lib.core.enums import WEB_PLATFORM
from lib.core.exception import SqlmapConnectionException from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapDataException
from lib.core.exception import SqlmapNoneDataException from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapSilentQuitException from lib.core.exception import SqlmapSilentQuitException
from lib.core.exception import SqlmapSkipTargetException from lib.core.exception import SqlmapSkipTargetException
from lib.core.exception import SqlmapUserQuitException from lib.core.exception import SqlmapUserQuitException
from lib.core.settings import BOUNDED_INJECTION_MARKER
from lib.core.settings import CANDIDATE_SENTENCE_MIN_LENGTH from lib.core.settings import CANDIDATE_SENTENCE_MIN_LENGTH
from lib.core.settings import CHECK_INTERNET_ADDRESS from lib.core.settings import CHECK_INTERNET_ADDRESS
from lib.core.settings import CHECK_INTERNET_VALUE from lib.core.settings import CHECK_INTERNET_VALUE
@@ -87,13 +83,12 @@ from lib.core.settings import DUMMY_NON_SQLI_CHECK_APPENDIX
from lib.core.settings import FI_ERROR_REGEX from lib.core.settings import FI_ERROR_REGEX
from lib.core.settings import FORMAT_EXCEPTION_STRINGS from lib.core.settings import FORMAT_EXCEPTION_STRINGS
from lib.core.settings import HEURISTIC_CHECK_ALPHABET from lib.core.settings import HEURISTIC_CHECK_ALPHABET
from lib.core.settings import IPS_WAF_CHECK_PAYLOAD from lib.core.settings import IDS_WAF_CHECK_PAYLOAD
from lib.core.settings import IDS_WAF_CHECK_RATIO from lib.core.settings import IDS_WAF_CHECK_RATIO
from lib.core.settings import IDS_WAF_CHECK_TIMEOUT from lib.core.settings import IDS_WAF_CHECK_TIMEOUT
from lib.core.settings import MAX_DIFFLIB_SEQUENCE_LENGTH from lib.core.settings import MAX_DIFFLIB_SEQUENCE_LENGTH
from lib.core.settings import NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH from lib.core.settings import NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH
from lib.core.settings import PRECONNECT_INCOMPATIBLE_SERVERS from lib.core.settings import PRECONNECT_INCOMPATIBLE_SERVERS
from lib.core.settings import SINGLE_QUOTE_MARKER
from lib.core.settings import SLEEP_TIME_MARKER from lib.core.settings import SLEEP_TIME_MARKER
from lib.core.settings import SUHOSIN_MAX_VALUE_LENGTH from lib.core.settings import SUHOSIN_MAX_VALUE_LENGTH
from lib.core.settings import SUPPORTED_DBMS from lib.core.settings import SUPPORTED_DBMS
@@ -107,8 +102,6 @@ from lib.request.inject import checkBooleanExpression
from lib.request.templates import getPageTemplate from lib.request.templates import getPageTemplate
from lib.techniques.union.test import unionTest from lib.techniques.union.test import unionTest
from lib.techniques.union.use import configUnion from lib.techniques.union.use import configUnion
from thirdparty import six
from thirdparty.six.moves import http_client as _http_client
def checkSqlInjection(place, parameter, value): def checkSqlInjection(place, parameter, value):
# Store here the details about boundaries and payload used to # Store here the details about boundaries and payload used to
@@ -367,7 +360,7 @@ def checkSqlInjection(place, parameter, value):
# Parse test's <request> # Parse test's <request>
comment = agent.getComment(test.request) if len(conf.boundaries) > 1 else None comment = agent.getComment(test.request) if len(conf.boundaries) > 1 else None
fstPayload = agent.cleanupPayload(test.request.payload, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) and BOUNDED_INJECTION_MARKER not in (value or "") else None) fstPayload = agent.cleanupPayload(test.request.payload, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) else None)
for boundary in boundaries: for boundary in boundaries:
injectable = False injectable = False
@@ -429,14 +422,11 @@ def checkSqlInjection(place, parameter, value):
templatePayload = None templatePayload = None
vector = None vector = None
origValue = value
if kb.customInjectionMark in origValue:
origValue = origValue.split(kb.customInjectionMark)[0]
origValue = re.search(r"(\w*)\Z", origValue).group(1)
# Threat the parameter original value according to the # Threat the parameter original value according to the
# test's <where> tag # test's <where> tag
if where == PAYLOAD.WHERE.ORIGINAL or conf.prefix: if where == PAYLOAD.WHERE.ORIGINAL or conf.prefix:
origValue = value
if kb.tamperFunctions: if kb.tamperFunctions:
templatePayload = agent.payload(place, parameter, value="", newValue=origValue, where=where) templatePayload = agent.payload(place, parameter, value="", newValue=origValue, where=where)
elif where == PAYLOAD.WHERE.NEGATIVE: elif where == PAYLOAD.WHERE.NEGATIVE:
@@ -446,7 +436,7 @@ def checkSqlInjection(place, parameter, value):
if conf.invalidLogical: if conf.invalidLogical:
_ = int(kb.data.randomInt[:2]) _ = int(kb.data.randomInt[:2])
origValue = "%s AND %s LIKE %s" % (origValue, _, _ + 1) origValue = "%s AND %s LIKE %s" % (value, _, _ + 1)
elif conf.invalidBignum: elif conf.invalidBignum:
origValue = kb.data.randomInt[:6] origValue = kb.data.randomInt[:6]
elif conf.invalidString: elif conf.invalidString:
@@ -481,13 +471,13 @@ def checkSqlInjection(place, parameter, value):
# payload was successful # payload was successful
# Parse test's <response> # Parse test's <response>
for method, check in test.response.items(): for method, check in test.response.items():
check = agent.cleanupPayload(check, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) and BOUNDED_INJECTION_MARKER not in (value or "") else None) check = agent.cleanupPayload(check, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) else None)
# In case of boolean-based blind SQL injection # In case of boolean-based blind SQL injection
if method == PAYLOAD.METHOD.COMPARISON: if method == PAYLOAD.METHOD.COMPARISON:
# Generate payload used for comparison # Generate payload used for comparison
def genCmpPayload(): def genCmpPayload():
sndPayload = agent.cleanupPayload(test.response.comparison, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) and BOUNDED_INJECTION_MARKER not in (value or "") else None) sndPayload = agent.cleanupPayload(test.response.comparison, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) else None)
# Forge response payload by prepending with # Forge response payload by prepending with
# boundary's prefix and appending the boundary's # boundary's prefix and appending the boundary's
@@ -582,7 +572,7 @@ def checkSqlInjection(place, parameter, value):
else: else:
errorSet = set() errorSet = set()
candidates = filterNone(_.strip() if _.strip() in trueRawResponse and _.strip() not in falseRawResponse else None for _ in (trueSet - falseSet - errorSet)) candidates = filter(None, (_.strip() if _.strip() in trueRawResponse and _.strip() not in falseRawResponse else None for _ in (trueSet - falseSet - errorSet)))
if candidates: if candidates:
candidates = sorted(candidates, key=lambda _: len(_)) candidates = sorted(candidates, key=lambda _: len(_))
@@ -596,7 +586,7 @@ def checkSqlInjection(place, parameter, value):
logger.info(infoMsg) logger.info(infoMsg)
if not any((conf.string, conf.notString)): if not any((conf.string, conf.notString)):
candidates = filterNone(_.strip() if _.strip() in falseRawResponse and _.strip() not in trueRawResponse else None for _ in (falseSet - trueSet)) candidates = filter(None, (_.strip() if _.strip() in falseRawResponse and _.strip() not in trueRawResponse else None for _ in (falseSet - trueSet)))
if candidates: if candidates:
candidates = sorted(candidates, key=lambda _: len(_)) candidates = sorted(candidates, key=lambda _: len(_))
@@ -621,7 +611,7 @@ def checkSqlInjection(place, parameter, value):
page, headers, _ = Request.queryPage(reqPayload, place, content=True, raise404=False) page, headers, _ = Request.queryPage(reqPayload, place, content=True, raise404=False)
output = extractRegexResult(check, page, re.DOTALL | re.IGNORECASE) output = extractRegexResult(check, page, re.DOTALL | re.IGNORECASE)
output = output or extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None, re.DOTALL | re.IGNORECASE) output = output or extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None, re.DOTALL | re.IGNORECASE)
output = output or extractRegexResult(check, listToStrValue((headers[key] for key in headers if key.lower() != URI_HTTP_HEADER.lower()) if headers else None), re.DOTALL | re.IGNORECASE) output = output or extractRegexResult(check, listToStrValue((headers[key] for key in headers.keys() if key.lower() != URI_HTTP_HEADER.lower()) if headers else None), re.DOTALL | re.IGNORECASE)
output = output or extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None, re.DOTALL | re.IGNORECASE) output = output or extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None, re.DOTALL | re.IGNORECASE)
if output: if output:
@@ -633,10 +623,10 @@ def checkSqlInjection(place, parameter, value):
injectable = True injectable = True
except SqlmapConnectionException as ex: except SqlmapConnectionException, msg:
debugMsg = "problem occurred most likely because the " debugMsg = "problem occurred most likely because the "
debugMsg += "server hasn't recovered as expected from the " debugMsg += "server hasn't recovered as expected from the "
debugMsg += "error-based payload used ('%s')" % getSafeExString(ex) debugMsg += "error-based payload used ('%s')" % msg
logger.debug(debugMsg) logger.debug(debugMsg)
# In case of time-based blind or stacked queries # In case of time-based blind or stacked queries
@@ -695,7 +685,7 @@ def checkSqlInjection(place, parameter, value):
# Test for UNION query SQL injection # Test for UNION query SQL injection
reqPayload, vector = unionTest(comment, place, parameter, value, prefix, suffix) reqPayload, vector = unionTest(comment, place, parameter, value, prefix, suffix)
if isinstance(reqPayload, six.string_types): if isinstance(reqPayload, basestring):
infoMsg = "%s parameter '%s' is '%s' injectable" % (paramType, parameter, title) infoMsg = "%s parameter '%s' is '%s' injectable" % (paramType, parameter, title)
logger.info(infoMsg) logger.info(infoMsg)
@@ -869,8 +859,8 @@ def heuristicCheckDbms(injection):
if conf.noEscape and dbms not in FROM_DUMMY_TABLE: if conf.noEscape and dbms not in FROM_DUMMY_TABLE:
continue continue
if checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr1, SINGLE_QUOTE_MARKER)): if checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr1)):
if not checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr2, SINGLE_QUOTE_MARKER)): if not checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr2)):
retVal = dbms retVal = dbms
break break
@@ -1059,19 +1049,9 @@ def heuristicCheckSqlInjection(place, parameter):
kb.heuristicTest = HEURISTIC_TEST.CASTED if casting else HEURISTIC_TEST.NEGATIVE if not result else HEURISTIC_TEST.POSITIVE kb.heuristicTest = HEURISTIC_TEST.CASTED if casting else HEURISTIC_TEST.NEGATIVE if not result else HEURISTIC_TEST.POSITIVE
if casting: if casting:
errMsg = "possible %s casting detected (e.g. '" % ("integer" if origValue.isdigit() else "type") errMsg = "possible %s casting " % ("integer" if origValue.isdigit() else "type")
errMsg += "detected (e.g. \"$%s=intval($_REQUEST['%s'])\") " % (parameter, parameter)
platform = conf.url.split('.')[-1].lower() errMsg += "at the back-end web application"
if platform == WEB_PLATFORM.ASP:
errMsg += "%s=CInt(request.querystring(\"%s\"))" % (parameter, parameter)
elif platform == WEB_PLATFORM.ASPX:
errMsg += "int.TryParse(Request.QueryString[\"%s\"], out %s)" % (parameter, parameter)
elif platform == WEB_PLATFORM.JSP:
errMsg += "%s=Integer.parseInt(request.getParameter(\"%s\"))" % (parameter, parameter)
else:
errMsg += "$%s=intval($_REQUEST[\"%s\"])" % (parameter, parameter)
errMsg += "') at the back-end web application"
logger.error(errMsg) logger.error(errMsg)
if kb.ignoreCasted is None: if kb.ignoreCasted is None:
@@ -1136,6 +1116,14 @@ def checkDynParam(place, parameter, value):
try: try:
payload = agent.payload(place, parameter, value, getUnicode(randInt)) payload = agent.payload(place, parameter, value, getUnicode(randInt))
dynResult = Request.queryPage(payload, place, raise404=False) dynResult = Request.queryPage(payload, place, raise404=False)
if not dynResult:
infoMsg = "confirming that %s parameter '%s' is dynamic" % (paramType, parameter)
logger.info(infoMsg)
randInt = randomInt()
payload = agent.payload(place, parameter, value, getUnicode(randInt))
dynResult = Request.queryPage(payload, place, raise404=False)
except SqlmapConnectionException: except SqlmapConnectionException:
pass pass
@@ -1340,9 +1328,6 @@ def checkWaf():
if any((conf.string, conf.notString, conf.regexp, conf.dummy, conf.offline, conf.skipWaf)): if any((conf.string, conf.notString, conf.regexp, conf.dummy, conf.offline, conf.skipWaf)):
return None return None
if kb.originalCode == _http_client.NOT_FOUND:
return None
_ = hashDBRetrieve(HASHDB_KEYS.CHECK_WAF_RESULT, True) _ = hashDBRetrieve(HASHDB_KEYS.CHECK_WAF_RESULT, True)
if _ is not None: if _ is not None:
if _: if _:
@@ -1359,7 +1344,7 @@ def checkWaf():
logger.info(infoMsg) logger.info(infoMsg)
retVal = False retVal = False
payload = "%d %s" % (randomInt(), IPS_WAF_CHECK_PAYLOAD) payload = "%d %s" % (randomInt(), IDS_WAF_CHECK_PAYLOAD)
if PLACE.URI in conf.parameters: if PLACE.URI in conf.parameters:
place = PLACE.POST place = PLACE.POST
@@ -1370,11 +1355,9 @@ def checkWaf():
value += "%s=%s" % (randomStr(), agent.addPayloadDelimiters(payload)) value += "%s=%s" % (randomStr(), agent.addPayloadDelimiters(payload))
pushValue(kb.redirectChoice) pushValue(kb.redirectChoice)
pushValue(kb.resendPostOnRedirect)
pushValue(conf.timeout) pushValue(conf.timeout)
kb.redirectChoice = REDIRECTION.YES kb.redirectChoice = REDIRECTION.YES
kb.resendPostOnRedirect = False
conf.timeout = IDS_WAF_CHECK_TIMEOUT conf.timeout = IDS_WAF_CHECK_TIMEOUT
try: try:
@@ -1385,7 +1368,6 @@ def checkWaf():
kb.matchRatio = None kb.matchRatio = None
conf.timeout = popValue() conf.timeout = popValue()
kb.resendPostOnRedirect = popValue()
kb.redirectChoice = popValue() kb.redirectChoice = popValue()
if retVal: if retVal:
@@ -1427,24 +1409,16 @@ def identifyWaf():
page, headers, code = None, None, None page, headers, code = None, None, None
try: try:
pushValue(kb.redirectChoice) pushValue(kb.redirectChoice)
pushValue(kb.resendPostOnRedirect) kb.redirectChoice = REDIRECTION.NO
kb.redirectChoice = REDIRECTION.YES
kb.resendPostOnRedirect = True
if kwargs.get("get"): if kwargs.get("get"):
kwargs["get"] = urlencode(kwargs["get"]) kwargs["get"] = urlencode(kwargs["get"])
kwargs["raise404"] = False kwargs["raise404"] = False
kwargs["silent"] = True kwargs["silent"] = True
kwargs["finalCode"] = True
page, headers, code = Request.getPage(*args, **kwargs) page, headers, code = Request.getPage(*args, **kwargs)
except Exception: except Exception:
pass pass
finally: finally:
kb.resendPostOnRedirect = popValue()
kb.redirectChoice = popValue() kb.redirectChoice = popValue()
return page or "", headers or {}, code return page or "", headers or {}, code
retVal = [] retVal = []
@@ -1456,7 +1430,7 @@ def identifyWaf():
try: try:
logger.debug("checking for WAF/IPS product '%s'" % product) logger.debug("checking for WAF/IPS product '%s'" % product)
found = function(_) found = function(_)
except Exception as ex: except Exception, ex:
errMsg = "exception occurred while running " errMsg = "exception occurred while running "
errMsg += "WAF script for '%s' ('%s')" % (product, getSafeExString(ex)) errMsg += "WAF script for '%s' ('%s')" % (product, getSafeExString(ex))
logger.critical(errMsg) logger.critical(errMsg)
@@ -1510,59 +1484,46 @@ def checkNullConnection():
if conf.data: if conf.data:
return False return False
_ = hashDBRetrieve(HASHDB_KEYS.CHECK_NULL_CONNECTION_RESULT, True) infoMsg = "testing NULL connection to the target URL"
if _ is not None: logger.info(infoMsg)
kb.nullConnection = _
if _: pushValue(kb.pageCompress)
dbgMsg = "resuming NULL connection method '%s'" % _ kb.pageCompress = False
logger.debug(dbgMsg)
else: try:
infoMsg = "testing NULL connection to the target URL" page, headers, _ = Request.getPage(method=HTTPMETHOD.HEAD, raise404=False)
logger.info(infoMsg)
pushValue(kb.pageCompress) if not page and HTTP_HEADER.CONTENT_LENGTH in (headers or {}):
kb.pageCompress = False kb.nullConnection = NULLCONNECTION.HEAD
try: infoMsg = "NULL connection is supported with HEAD method ('Content-Length')"
page, headers, _ = Request.getPage(method=HTTPMETHOD.HEAD, raise404=False) logger.info(infoMsg)
else:
page, headers, _ = Request.getPage(auxHeaders={HTTP_HEADER.RANGE: "bytes=-1"})
if not page and HTTP_HEADER.CONTENT_LENGTH in (headers or {}): if page and len(page) == 1 and HTTP_HEADER.CONTENT_RANGE in (headers or {}):
kb.nullConnection = NULLCONNECTION.HEAD kb.nullConnection = NULLCONNECTION.RANGE
infoMsg = "NULL connection is supported with HEAD method ('Content-Length')" infoMsg = "NULL connection is supported with GET method ('Range')"
logger.info(infoMsg) logger.info(infoMsg)
else: else:
page, headers, _ = Request.getPage(auxHeaders={HTTP_HEADER.RANGE: "bytes=-1"}) _, headers, _ = Request.getPage(skipRead=True)
if page and len(page) == 1 and HTTP_HEADER.CONTENT_RANGE in (headers or {}): if HTTP_HEADER.CONTENT_LENGTH in (headers or {}):
kb.nullConnection = NULLCONNECTION.RANGE kb.nullConnection = NULLCONNECTION.SKIP_READ
infoMsg = "NULL connection is supported with GET method ('Range')" infoMsg = "NULL connection is supported with 'skip-read' method"
logger.info(infoMsg) logger.info(infoMsg)
else:
_, headers, _ = Request.getPage(skipRead=True)
if HTTP_HEADER.CONTENT_LENGTH in (headers or {}): except SqlmapConnectionException:
kb.nullConnection = NULLCONNECTION.SKIP_READ pass
infoMsg = "NULL connection is supported with 'skip-read' method" finally:
logger.info(infoMsg) kb.pageCompress = popValue()
except SqlmapConnectionException: return kb.nullConnection is not None
pass
finally:
kb.pageCompress = popValue()
kb.nullConnection = False if kb.nullConnection is None else kb.nullConnection
hashDBWrite(HASHDB_KEYS.CHECK_NULL_CONNECTION_RESULT, kb.nullConnection, True)
return kb.nullConnection in getPublicTypeMembers(NULLCONNECTION, True)
def checkConnection(suppressOutput=False): def checkConnection(suppressOutput=False):
threadData = getCurrentThreadData()
if not re.search(r"\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\Z", conf.hostname): if not re.search(r"\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\Z", conf.hostname):
if not any((conf.proxy, conf.tor, conf.dummy, conf.offline)): if not any((conf.proxy, conf.tor, conf.dummy, conf.offline)):
try: try:
@@ -1572,14 +1533,10 @@ def checkConnection(suppressOutput=False):
except socket.gaierror: except socket.gaierror:
errMsg = "host '%s' does not exist" % conf.hostname errMsg = "host '%s' does not exist" % conf.hostname
raise SqlmapConnectionException(errMsg) raise SqlmapConnectionException(errMsg)
except socket.error as ex: except socket.error, ex:
errMsg = "problem occurred while " errMsg = "problem occurred while "
errMsg += "resolving a host name '%s' ('%s')" % (conf.hostname, getSafeExString(ex)) errMsg += "resolving a host name '%s' ('%s')" % (conf.hostname, getSafeExString(ex))
raise SqlmapConnectionException(errMsg) raise SqlmapConnectionException(errMsg)
except UnicodeError as ex:
errMsg = "problem occurred while "
errMsg += "handling a host name '%s' ('%s')" % (conf.hostname, getSafeExString(ex))
raise SqlmapDataException(errMsg)
if not suppressOutput and not conf.dummy and not conf.offline: if not suppressOutput and not conf.dummy and not conf.offline:
infoMsg = "testing connection to the target URL" infoMsg = "testing connection to the target URL"
@@ -1587,7 +1544,8 @@ def checkConnection(suppressOutput=False):
try: try:
kb.originalPageTime = time.time() kb.originalPageTime = time.time()
Request.queryPage(content=True, noteResponseTime=False) page, headers, _ = Request.queryPage(content=True, noteResponseTime=False)
kb.originalPage = kb.pageTemplate = page
kb.errorIsNone = False kb.errorIsNone = False
@@ -1610,14 +1568,16 @@ def checkConnection(suppressOutput=False):
else: else:
kb.errorIsNone = True kb.errorIsNone = True
threadData = getCurrentThreadData()
if kb.redirectChoice == REDIRECTION.YES and threadData.lastRedirectURL and threadData.lastRedirectURL[0] == threadData.lastRequestUID: if kb.redirectChoice == REDIRECTION.YES and threadData.lastRedirectURL and threadData.lastRedirectURL[0] == threadData.lastRequestUID:
if (threadData.lastRedirectURL[1] or "").startswith("https://") and unicodeencode(conf.hostname) in threadData.lastRedirectURL[1]: if (threadData.lastRedirectURL[1] or "").startswith("https://") and unicodeencode(conf.hostname) in threadData.lastRedirectURL[1]:
conf.url = re.sub(r"https?://", "https://", conf.url) conf.url = re.sub(r"https?://", "https://", conf.url)
match = re.search(r":(\d+)", threadData.lastRedirectURL[1]) match = re.search(r":(\d+)", threadData.lastRedirectURL[1])
port = match.group(1) if match else 443 port = match.group(1) if match else 443
conf.url = re.sub(r":\d+(/|\Z)", ":%s\g<1>" % port, conf.url) conf.url = re.sub(r":\d+/", ":%s/" % port, conf.url)
except SqlmapConnectionException as ex: except SqlmapConnectionException, ex:
if conf.ipv6: if conf.ipv6:
warnMsg = "check connection to a provided " warnMsg = "check connection to a provided "
warnMsg += "IPv6 address with a tool like ping6 " warnMsg += "IPv6 address with a tool like ping6 "
@@ -1626,7 +1586,7 @@ def checkConnection(suppressOutput=False):
warnMsg += "any addressing issues" warnMsg += "any addressing issues"
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
if any(code in kb.httpErrorCodes for code in (_http_client.NOT_FOUND, )): if any(code in kb.httpErrorCodes for code in (httplib.NOT_FOUND, )):
errMsg = getSafeExString(ex) errMsg = getSafeExString(ex)
logger.critical(errMsg) logger.critical(errMsg)
@@ -1640,9 +1600,6 @@ def checkConnection(suppressOutput=False):
kb.ignoreNotFound = True kb.ignoreNotFound = True
else: else:
raise raise
finally:
kb.originalPage = kb.pageTemplate = threadData.lastPage
kb.originalCode = threadData.lastCode
return True return True
+18 -33
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -40,7 +40,6 @@ from lib.core.common import safeCSValue
from lib.core.common import showHttpErrorCodes from lib.core.common import showHttpErrorCodes
from lib.core.common import urlencode from lib.core.common import urlencode
from lib.core.common import urldecode from lib.core.common import urldecode
from lib.core.compat import xrange
from lib.core.data import conf from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
@@ -57,11 +56,9 @@ from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapNotVulnerableException from lib.core.exception import SqlmapNotVulnerableException
from lib.core.exception import SqlmapSilentQuitException from lib.core.exception import SqlmapSilentQuitException
from lib.core.exception import SqlmapSkipTargetException from lib.core.exception import SqlmapSkipTargetException
from lib.core.exception import SqlmapSystemException
from lib.core.exception import SqlmapValueException from lib.core.exception import SqlmapValueException
from lib.core.exception import SqlmapUserQuitException from lib.core.exception import SqlmapUserQuitException
from lib.core.settings import ASP_NET_CONTROL_REGEX from lib.core.settings import ASP_NET_CONTROL_REGEX
from lib.core.settings import CSRF_TOKEN_PARAMETER_INFIXES
from lib.core.settings import DEFAULT_GET_POST_DELIMITER from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import EMPTY_FORM_FIELDS_REGEX from lib.core.settings import EMPTY_FORM_FIELDS_REGEX
from lib.core.settings import IGNORE_PARAMETERS from lib.core.settings import IGNORE_PARAMETERS
@@ -72,7 +69,6 @@ from lib.core.settings import REFERER_ALIASES
from lib.core.settings import USER_AGENT_ALIASES from lib.core.settings import USER_AGENT_ALIASES
from lib.core.target import initTargetEnv from lib.core.target import initTargetEnv
from lib.core.target import setupTargetEnv from lib.core.target import setupTargetEnv
from lib.utils.hash import crackHashFile
def _selectInjection(): def _selectInjection():
""" """
@@ -91,7 +87,7 @@ def _selectInjection():
if point not in points: if point not in points:
points[point] = injection points[point] = injection
else: else:
for key in points[point]: for key in points[point].keys():
if key != 'data': if key != 'data':
points[point][key] = points[point][key] or injection[key] points[point][key] = points[point][key] or injection[key]
points[point]['data'].update(injection['data']) points[point]['data'].update(injection['data'])
@@ -245,22 +241,18 @@ def _saveToResultsFile():
if key not in results: if key not in results:
results[key] = [] results[key] = []
results[key].extend(list(injection.data.keys())) results[key].extend(injection.data.keys())
try: for key, value in results.items():
for key, value in results.items(): place, parameter, notes = key
place, parameter, notes = key line = "%s,%s,%s,%s,%s%s" % (safeCSValue(kb.originalUrls.get(conf.url) or conf.url), place, parameter, "".join(techniques[_][0].upper() for _ in sorted(value)), notes, os.linesep)
line = "%s,%s,%s,%s,%s%s" % (safeCSValue(kb.originalUrls.get(conf.url) or conf.url), place, parameter, "".join(techniques[_][0].upper() for _ in sorted(value)), notes, os.linesep) conf.resultsFP.write(line)
conf.resultsFP.write(line)
if not results: if not results:
line = "%s,,,,%s" % (conf.url, os.linesep) line = "%s,,,,%s" % (conf.url, os.linesep)
conf.resultsFP.write(line) conf.resultsFP.write(line)
conf.resultsFP.flush() conf.resultsFP.flush()
except IOError as ex:
errMsg = "unable to write to the results file '%s' ('%s'). " % (conf.resultsFilename, getSafeExString(ex))
raise SqlmapSystemException(errMsg)
@stackedmethod @stackedmethod
def start(): def start():
@@ -270,9 +262,6 @@ def start():
check if they are dynamic and SQL injection affected check if they are dynamic and SQL injection affected
""" """
if conf.hashFile:
crackHashFile(conf.hashFile)
if conf.direct: if conf.direct:
initTargetEnv() initTargetEnv()
setupTargetEnv() setupTargetEnv()
@@ -318,7 +307,6 @@ def start():
conf.cookie = targetCookie conf.cookie = targetCookie
conf.httpHeaders = list(initialHeaders) conf.httpHeaders = list(initialHeaders)
conf.httpHeaders.extend(targetHeaders or []) conf.httpHeaders.extend(targetHeaders or [])
conf.httpHeaders = [conf.httpHeaders[i] for i in xrange(len(conf.httpHeaders)) if conf.httpHeaders[i][0].upper() not in (__[0].upper() for __ in conf.httpHeaders[i + 1:])]
initTargetEnv() initTargetEnv()
parseTargetUrl() parseTargetUrl()
@@ -428,7 +416,7 @@ def start():
checkStability() checkStability()
# Do a little prioritization reorder of a testable parameter list # Do a little prioritization reorder of a testable parameter list
parameters = list(conf.parameters.keys()) parameters = conf.parameters.keys()
# Order of testing list (first to last) # Order of testing list (first to last)
orderList = (PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER, PLACE.URI, PLACE.POST, PLACE.GET) orderList = (PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER, PLACE.URI, PLACE.POST, PLACE.GET)
@@ -492,7 +480,7 @@ def start():
elif parameter in conf.testParameter: elif parameter in conf.testParameter:
pass pass
elif parameter in conf.rParam: elif parameter == conf.rParam:
testSqlInj = False testSqlInj = False
infoMsg = "skipping randomizing %s parameter '%s'" % (paramType, parameter) infoMsg = "skipping randomizing %s parameter '%s'" % (paramType, parameter)
@@ -510,14 +498,14 @@ def start():
infoMsg = "skipping %s parameter '%s'" % (paramType, parameter) infoMsg = "skipping %s parameter '%s'" % (paramType, parameter)
logger.info(infoMsg) logger.info(infoMsg)
elif conf.csrfToken and re.search(conf.csrfToken, parameter, re.I): elif parameter == conf.csrfToken:
testSqlInj = False testSqlInj = False
infoMsg = "skipping anti-CSRF token parameter '%s'" % parameter infoMsg = "skipping anti-CSRF token parameter '%s'" % parameter
logger.info(infoMsg) logger.info(infoMsg)
# Ignore session-like parameters for --level < 4 # Ignore session-like parameters for --level < 4
elif conf.level < 4 and (parameter.upper() in IGNORE_PARAMETERS or any(_ in parameter.lower() for _ in CSRF_TOKEN_PARAMETER_INFIXES) or parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX)): elif conf.level < 4 and (parameter.upper() in IGNORE_PARAMETERS or parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX)):
testSqlInj = False testSqlInj = False
infoMsg = "ignoring %s parameter '%s'" % (paramType, parameter) infoMsg = "ignoring %s parameter '%s'" % (paramType, parameter)
@@ -536,7 +524,7 @@ def start():
testSqlInj = False testSqlInj = False
else: else:
infoMsg = "%s parameter '%s' appears to be dynamic" % (paramType, parameter) infoMsg = "%s parameter '%s' is dynamic" % (paramType, parameter)
logger.info(infoMsg) logger.info(infoMsg)
kb.testedParams.add(paramKey) kb.testedParams.add(paramKey)
@@ -643,9 +631,6 @@ def start():
errMsg += "involved (e.g. WAF) maybe you could try to use " errMsg += "involved (e.g. WAF) maybe you could try to use "
errMsg += "option '--tamper' (e.g. '--tamper=space2comment')" errMsg += "option '--tamper' (e.g. '--tamper=space2comment')"
if not conf.randomAgent:
errMsg += " and/or switch '--random-agent'"
raise SqlmapNotVulnerableException(errMsg.rstrip('.')) raise SqlmapNotVulnerableException(errMsg.rstrip('.'))
else: else:
# Flush the flag # Flush the flag
@@ -690,7 +675,7 @@ def start():
except SqlmapSilentQuitException: except SqlmapSilentQuitException:
raise raise
except SqlmapBaseException as ex: except SqlmapBaseException, ex:
errMsg = getSafeExString(ex) errMsg = getSafeExString(ex)
if conf.multipleTargets: if conf.multipleTargets:
+14 -31
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -10,7 +10,6 @@ from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.dicts import DBMS_DICT from lib.core.dicts import DBMS_DICT
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.exception import SqlmapConnectionException
from lib.core.settings import MSSQL_ALIASES from lib.core.settings import MSSQL_ALIASES
from lib.core.settings import MYSQL_ALIASES from lib.core.settings import MYSQL_ALIASES
from lib.core.settings import ORACLE_ALIASES from lib.core.settings import ORACLE_ALIASES
@@ -22,7 +21,6 @@ from lib.core.settings import MAXDB_ALIASES
from lib.core.settings import SYBASE_ALIASES from lib.core.settings import SYBASE_ALIASES
from lib.core.settings import DB2_ALIASES from lib.core.settings import DB2_ALIASES
from lib.core.settings import HSQLDB_ALIASES from lib.core.settings import HSQLDB_ALIASES
from lib.core.settings import H2_ALIASES
from lib.core.settings import INFORMIX_ALIASES from lib.core.settings import INFORMIX_ALIASES
from lib.utils.sqlalchemy import SQLAlchemy from lib.utils.sqlalchemy import SQLAlchemy
@@ -48,8 +46,6 @@ from plugins.dbms.db2 import DB2Map
from plugins.dbms.db2.connector import Connector as DB2Conn from plugins.dbms.db2.connector import Connector as DB2Conn
from plugins.dbms.hsqldb import HSQLDBMap from plugins.dbms.hsqldb import HSQLDBMap
from plugins.dbms.hsqldb.connector import Connector as HSQLDBConn from plugins.dbms.hsqldb.connector import Connector as HSQLDBConn
from plugins.dbms.h2 import H2Map
from plugins.dbms.h2.connector import Connector as H2Conn
from plugins.dbms.informix import InformixMap from plugins.dbms.informix import InformixMap
from plugins.dbms.informix.connector import Connector as InformixConn from plugins.dbms.informix.connector import Connector as InformixConn
@@ -71,7 +67,6 @@ def setHandler():
(DBMS.SYBASE, SYBASE_ALIASES, SybaseMap, SybaseConn), (DBMS.SYBASE, SYBASE_ALIASES, SybaseMap, SybaseConn),
(DBMS.DB2, DB2_ALIASES, DB2Map, DB2Conn), (DBMS.DB2, DB2_ALIASES, DB2Map, DB2Conn),
(DBMS.HSQLDB, HSQLDB_ALIASES, HSQLDBMap, HSQLDBConn), (DBMS.HSQLDB, HSQLDB_ALIASES, HSQLDBMap, HSQLDBConn),
(DBMS.H2, H2_ALIASES, H2Map, H2Conn),
(DBMS.INFORMIX, INFORMIX_ALIASES, InformixMap, InformixConn), (DBMS.INFORMIX, INFORMIX_ALIASES, InformixMap, InformixConn),
] ]
@@ -95,41 +90,29 @@ def setHandler():
conf.dbmsConnector = Connector() conf.dbmsConnector = Connector()
if conf.direct: if conf.direct:
exception = None
dialect = DBMS_DICT[dbms][3] dialect = DBMS_DICT[dbms][3]
if dialect: if dialect:
try: sqlalchemy = SQLAlchemy(dialect=dialect)
sqlalchemy = SQLAlchemy(dialect=dialect) sqlalchemy.connect()
sqlalchemy.connect()
if sqlalchemy.connector: if sqlalchemy.connector:
conf.dbmsConnector = sqlalchemy conf.dbmsConnector = sqlalchemy
except Exception as ex: else:
exception = ex try:
conf.dbmsConnector.connect()
if not dialect or exception: except NameError:
try: pass
conf.dbmsConnector.connect() else:
except Exception as ex: conf.dbmsConnector.connect()
if exception:
raise exception
else:
if not isinstance(ex, NameError):
raise
else:
msg = "support for direct connection to '%s' is not available. " % dbms
msg += "Please rerun with '--dependencies'"
raise SqlmapConnectionException(msg)
if conf.forceDbms == dbms or handler.checkDbms(): if conf.forceDbms == dbms or handler.checkDbms():
if kb.resolutionDbms: if kb.resolutionDbms:
conf.dbmsHandler = max(_ for _ in items if _[0] == kb.resolutionDbms)[2]() conf.dbmsHandler = max(_ for _ in items if _[0] == kb.resolutionDbms)[2]()
conf.dbmsHandler._dbms = kb.resolutionDbms
else: else:
conf.dbmsHandler = handler conf.dbmsHandler = handler
conf.dbmsHandler._dbms = dbms
conf.dbmsHandler._dbms = dbms
break break
else: else:
conf.dbmsConnector = None conf.dbmsConnector = None
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+9 -16
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -9,7 +9,6 @@ import re
from lib.core.common import Backend from lib.core.common import Backend
from lib.core.common import extractRegexResult from lib.core.common import extractRegexResult
from lib.core.common import filterNone
from lib.core.common import getSQLSnippet from lib.core.common import getSQLSnippet
from lib.core.common import getUnicode from lib.core.common import getUnicode
from lib.core.common import isDBMSVersionAtLeast from lib.core.common import isDBMSVersionAtLeast
@@ -24,7 +23,6 @@ from lib.core.common import splitFields
from lib.core.common import unArrayizeValue from lib.core.common import unArrayizeValue
from lib.core.common import urlencode from lib.core.common import urlencode
from lib.core.common import zeroDepthSearch from lib.core.common import zeroDepthSearch
from lib.core.compat import xrange
from lib.core.data import conf from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import queries from lib.core.data import queries
@@ -45,7 +43,6 @@ from lib.core.settings import INFERENCE_MARKER
from lib.core.settings import NULL from lib.core.settings import NULL
from lib.core.settings import PAYLOAD_DELIMITER from lib.core.settings import PAYLOAD_DELIMITER
from lib.core.settings import REPLACEMENT_MARKER from lib.core.settings import REPLACEMENT_MARKER
from lib.core.settings import SINGLE_QUOTE_MARKER
from lib.core.settings import SLEEP_TIME_MARKER from lib.core.settings import SLEEP_TIME_MARKER
from lib.core.unescaper import unescaper from lib.core.unescaper import unescaper
@@ -107,9 +104,9 @@ class Agent(object):
if place == PLACE.URI: if place == PLACE.URI:
origValue = origValue.split(kb.customInjectionMark)[0] origValue = origValue.split(kb.customInjectionMark)[0]
else: else:
origValue = filterNone(re.search(_, origValue.split(BOUNDED_INJECTION_MARKER)[0]) for _ in (r"\w+\Z", r"[^\"'><]+\Z", r"[^ ]+\Z"))[0].group(0) origValue = filter(None, (re.search(_, origValue.split(BOUNDED_INJECTION_MARKER)[0]) for _ in (r"\w+\Z", r"[^\"'><]+\Z", r"[^ ]+\Z")))[0].group(0)
origValue = origValue[origValue.rfind('/') + 1:] origValue = origValue[origValue.rfind('/') + 1:]
for char in ('?', '=', ':', ',', '&'): for char in ('?', '=', ':', ','):
if char in origValue: if char in origValue:
origValue = origValue[origValue.rfind(char) + 1:] origValue = origValue[origValue.rfind(char) + 1:]
elif place == PLACE.CUSTOM_POST: elif place == PLACE.CUSTOM_POST:
@@ -249,9 +246,6 @@ class Agent(object):
else: else:
query = kb.injection.prefix or prefix or "" query = kb.injection.prefix or prefix or ""
if "SELECT '[RANDSTR]'" in query: # escaping of pre-WHERE prefixes
query = query.replace("'[RANDSTR]'", unescaper.escape(randomStr(), quote=False))
if not (expression and expression[0] == ';') and not (query and query[-1] in ('(', ')') and expression and expression[0] in ('(', ')')) and not (query and query[-1] == '('): if not (expression and expression[0] == ';') and not (query and query[-1] in ('(', ')') and expression and expression[0] in ('(', ')')) and not (query and query[-1] == '('):
query += " " query += " "
@@ -351,7 +345,6 @@ class Agent(object):
if payload: if payload:
payload = payload.replace(SLEEP_TIME_MARKER, str(conf.timeSec)) payload = payload.replace(SLEEP_TIME_MARKER, str(conf.timeSec))
payload = payload.replace(SINGLE_QUOTE_MARKER, "'")
for _ in set(re.findall(r"\[RANDNUM(?:\d+)?\]", payload, re.I)): for _ in set(re.findall(r"\[RANDNUM(?:\d+)?\]", payload, re.I)):
payload = payload.replace(_, str(randomInt())) payload = payload.replace(_, str(randomInt()))
@@ -626,7 +619,7 @@ class Agent(object):
elif fieldsNoSelect: elif fieldsNoSelect:
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop) concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2): elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB):
if fieldsExists: if fieldsExists:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
concatenatedQuery += "||'%s'" % kb.chars.stop concatenatedQuery += "||'%s'" % kb.chars.stop
@@ -825,7 +818,7 @@ class Agent(object):
limitRegExp2 = None limitRegExp2 = None
if (limitRegExp or limitRegExp2) or (Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and topLimit): if (limitRegExp or limitRegExp2) or (Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and topLimit):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
@@ -915,14 +908,14 @@ class Agent(object):
fromFrom = limitedQuery[fromIndex + 1:] fromFrom = limitedQuery[fromIndex + 1:]
orderBy = None orderBy = None
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1) limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
limitedQuery += " %s" % limitStr limitedQuery += " %s" % limitStr
elif Backend.isDbms(DBMS.HSQLDB): elif Backend.isDbms(DBMS.HSQLDB):
match = re.search(r"ORDER BY [^ ]+", limitedQuery) match = re.search(r"ORDER BY [^ ]+", limitedQuery)
if match: if match:
limitedQuery = re.sub(r"\s*%s\s*" % re.escape(match.group(0)), " ", limitedQuery).strip() limitedQuery = re.sub(r"\s*%s\s*" % match.group(0), " ", limitedQuery).strip()
limitedQuery += " %s" % match.group(0) limitedQuery += " %s" % match.group(0)
if query.startswith("SELECT "): if query.startswith("SELECT "):
@@ -1096,7 +1089,7 @@ class Agent(object):
if conf.dumpWhere and query: if conf.dumpWhere and query:
prefix, suffix = query.split(" ORDER BY ") if " ORDER BY " in query else (query, "") prefix, suffix = query.split(" ORDER BY ") if " ORDER BY " in query else (query, "")
if conf.tbl and "%s)" % conf.tbl.upper() in prefix.upper(): if "%s)" % conf.tbl.upper() in prefix.upper():
prefix = re.sub(r"(?i)%s\)" % re.escape(conf.tbl), "%s WHERE %s)" % (conf.tbl, conf.dumpWhere), prefix) prefix = re.sub(r"(?i)%s\)" % re.escape(conf.tbl), "%s WHERE %s)" % (conf.tbl, conf.dumpWhere), prefix)
elif re.search(r"(?i)\bWHERE\b", prefix): elif re.search(r"(?i)\bWHERE\b", prefix):
prefix += " AND %s" % conf.dumpWhere prefix += " AND %s" % conf.dumpWhere
+7 -8
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -16,7 +16,6 @@ import os
import sys import sys
import tempfile import tempfile
from lib.core.compat import xrange
from lib.core.enums import MKSTEMP_PREFIX from lib.core.enums import MKSTEMP_PREFIX
from lib.core.exception import SqlmapSystemException from lib.core.exception import SqlmapSystemException
from lib.core.settings import BIGARRAY_CHUNK_SIZE from lib.core.settings import BIGARRAY_CHUNK_SIZE
@@ -88,7 +87,7 @@ class BigArray(list):
try: try:
with open(self.chunks[-1], "rb") as f: with open(self.chunks[-1], "rb") as f:
self.chunks[-1] = pickle.loads(bz2.decompress(f.read())) self.chunks[-1] = pickle.loads(bz2.decompress(f.read()))
except IOError as ex: except IOError, ex:
errMsg = "exception occurred while retrieving data " errMsg = "exception occurred while retrieving data "
errMsg += "from a temporary file ('%s')" % ex.message errMsg += "from a temporary file ('%s')" % ex.message
raise SqlmapSystemException(errMsg) raise SqlmapSystemException(errMsg)
@@ -110,7 +109,7 @@ class BigArray(list):
with open(filename, "w+b") as f: with open(filename, "w+b") as f:
f.write(bz2.compress(pickle.dumps(chunk, pickle.HIGHEST_PROTOCOL), BIGARRAY_COMPRESS_LEVEL)) f.write(bz2.compress(pickle.dumps(chunk, pickle.HIGHEST_PROTOCOL), BIGARRAY_COMPRESS_LEVEL))
return filename return filename
except (OSError, IOError) as ex: except (OSError, IOError), ex:
errMsg = "exception occurred while storing data " errMsg = "exception occurred while storing data "
errMsg += "to a temporary file ('%s'). Please " % ex.message errMsg += "to a temporary file ('%s'). Please " % ex.message
errMsg += "make sure that there is enough disk space left. If problem persists, " errMsg += "make sure that there is enough disk space left. If problem persists, "
@@ -127,7 +126,7 @@ class BigArray(list):
try: try:
with open(self.chunks[index], "rb") as f: with open(self.chunks[index], "rb") as f:
self.cache = Cache(index, pickle.loads(bz2.decompress(f.read())), False) self.cache = Cache(index, pickle.loads(bz2.decompress(f.read())), False)
except Exception as ex: except Exception, ex:
errMsg = "exception occurred while retrieving data " errMsg = "exception occurred while retrieving data "
errMsg += "from a temporary file ('%s')" % ex.message errMsg += "from a temporary file ('%s')" % ex.message
raise SqlmapSystemException(errMsg) raise SqlmapSystemException(errMsg)
@@ -149,7 +148,7 @@ class BigArray(list):
if y < 0: if y < 0:
y += len(self) y += len(self)
index = y // self.chunk_length index = y / self.chunk_length
offset = y % self.chunk_length offset = y % self.chunk_length
chunk = self.chunks[index] chunk = self.chunks[index]
@@ -160,7 +159,7 @@ class BigArray(list):
return self.cache.data[offset] return self.cache.data[offset]
def __setitem__(self, y, value): def __setitem__(self, y, value):
index = y // self.chunk_length index = y / self.chunk_length
offset = y % self.chunk_length offset = y % self.chunk_length
chunk = self.chunks[index] chunk = self.chunks[index]
+208 -386
View File
File diff suppressed because it is too large Load Diff
-172
View File
@@ -1,172 +0,0 @@
#!/usr/bin/env python2
"""
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import binascii
import os
import random
import uuid
import sys
class WichmannHill(random.Random):
"""
Reference: https://svn.python.org/projects/python/trunk/Lib/random.py
"""
VERSION = 1 # used by getstate/setstate
def seed(self, a=None):
"""Initialize internal state from hashable object.
None or no argument seeds from current time or from an operating
system specific randomness source if available.
If a is not None or an int or long, hash(a) is used instead.
If a is an int or long, a is used directly. Distinct values between
0 and 27814431486575L inclusive are guaranteed to yield distinct
internal states (this guarantee is specific to the default
Wichmann-Hill generator).
"""
if a is None:
try:
a = int(binascii.hexlify(os.urandom(16)), 16)
except NotImplementedError:
import time
a = int(time.time() * 256) # use fractional seconds
if not isinstance(a, int):
a = hash(a)
a, x = divmod(a, 30268)
a, y = divmod(a, 30306)
a, z = divmod(a, 30322)
self._seed = int(x)+1, int(y)+1, int(z)+1
self.gauss_next = None
def random(self):
"""Get the next random number in the range [0.0, 1.0)."""
# Wichman-Hill random number generator.
#
# Wichmann, B. A. & Hill, I. D. (1982)
# Algorithm AS 183:
# An efficient and portable pseudo-random number generator
# Applied Statistics 31 (1982) 188-190
#
# see also:
# Correction to Algorithm AS 183
# Applied Statistics 33 (1984) 123
#
# McLeod, A. I. (1985)
# A remark on Algorithm AS 183
# Applied Statistics 34 (1985),198-200
# This part is thread-unsafe:
# BEGIN CRITICAL SECTION
x, y, z = self._seed
x = (171 * x) % 30269
y = (172 * y) % 30307
z = (170 * z) % 30323
self._seed = x, y, z
# END CRITICAL SECTION
# Note: on a platform using IEEE-754 double arithmetic, this can
# never return 0.0 (asserted by Tim; proof too long for a comment).
return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0
def getstate(self):
"""Return internal state; can be passed to setstate() later."""
return self.VERSION, self._seed, self.gauss_next
def setstate(self, state):
"""Restore internal state from object returned by getstate()."""
version = state[0]
if version == 1:
version, self._seed, self.gauss_next = state
else:
raise ValueError("state with version %s passed to "
"Random.setstate() of version %s" %
(version, self.VERSION))
def jumpahead(self, n):
"""Act as if n calls to random() were made, but quickly.
n is an int, greater than or equal to 0.
Example use: If you have 2 threads and know that each will
consume no more than a million random numbers, create two Random
objects r1 and r2, then do
r2.setstate(r1.getstate())
r2.jumpahead(1000000)
Then r1 and r2 will use guaranteed-disjoint segments of the full
period.
"""
if not n >= 0:
raise ValueError("n must be >= 0")
x, y, z = self._seed
x = int(x * pow(171, n, 30269)) % 30269
y = int(y * pow(172, n, 30307)) % 30307
z = int(z * pow(170, n, 30323)) % 30323
self._seed = x, y, z
def __whseed(self, x=0, y=0, z=0):
"""Set the Wichmann-Hill seed from (x, y, z).
These must be integers in the range [0, 256).
"""
if not type(x) == type(y) == type(z) == int:
raise TypeError('seeds must be integers')
if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256):
raise ValueError('seeds must be in range(0, 256)')
if 0 == x == y == z:
# Initialize from current time
import time
t = int(time.time() * 256)
t = int((t&0xffffff) ^ (t>>24))
t, x = divmod(t, 256)
t, y = divmod(t, 256)
t, z = divmod(t, 256)
# Zero is a poor seed, so substitute 1
self._seed = (x or 1, y or 1, z or 1)
self.gauss_next = None
def whseed(self, a=None):
"""Seed from hashable object's hash code.
None or no argument seeds from current time. It is not guaranteed
that objects with distinct hash codes lead to distinct internal
states.
This is obsolete, provided for compatibility with the seed routine
used prior to Python 2.1. Use the .seed() method instead.
"""
if a is None:
self.__whseed()
return
a = hash(a)
a, x = divmod(a, 256)
a, y = divmod(a, 256)
a, z = divmod(a, 256)
x = (x + a) % 256 or 1
y = (y + a) % 256 or 1
z = (z + a) % 256 or 1
self.__whseed(x, y, z)
# Reference: https://github.com/urllib3/urllib3/blob/master/src/urllib3/filepost.py
def choose_boundary():
return uuid.uuid4().hex
if sys.version_info >= (3, 0):
xrange = range
else:
xrange = xrange
+40 -32
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -9,15 +9,18 @@ try:
import cPickle as pickle import cPickle as pickle
except: except:
import pickle import pickle
finally:
import pickle as picklePy
import base64 import base64
import json import json
import re import re
import StringIO
import sys import sys
from lib.core.settings import IS_WIN from lib.core.settings import IS_WIN
from lib.core.settings import UNICODE_ENCODING from lib.core.settings import UNICODE_ENCODING
from thirdparty import six from lib.core.settings import PICKLE_REDUCE_WHITELIST
def base64decode(value): def base64decode(value):
""" """
@@ -27,7 +30,7 @@ def base64decode(value):
'foobar' 'foobar'
""" """
return base64.b64decode(unicodeencode(value)) return base64.b64decode(value)
def base64encode(value): def base64encode(value):
""" """
@@ -37,7 +40,7 @@ def base64encode(value):
'Zm9vYmFy' 'Zm9vYmFy'
""" """
return base64.b64encode(unicodeencode(value)) return base64.b64encode(value)
def base64pickle(value): def base64pickle(value):
""" """
@@ -63,7 +66,7 @@ def base64pickle(value):
return retVal return retVal
def base64unpickle(value): def base64unpickle(value, unsafe=False):
""" """
Decodes value from Base64 to plain format and deserializes (with pickle) its content Decodes value from Base64 to plain format and deserializes (with pickle) its content
@@ -73,10 +76,26 @@ def base64unpickle(value):
retVal = None retVal = None
def _(self):
if len(self.stack) > 1:
func = self.stack[-2]
if func not in PICKLE_REDUCE_WHITELIST:
raise Exception("abusing reduce() is bad, Mkay!")
self.load_reduce()
def loads(str):
f = StringIO.StringIO(str)
if unsafe:
unpickler = picklePy.Unpickler(f)
unpickler.dispatch[picklePy.REDUCE] = _
else:
unpickler = pickle.Unpickler(f)
return unpickler.load()
try: try:
retVal = pickle.loads(base64decode(value)) retVal = loads(base64decode(value))
except TypeError: except TypeError:
retVal = pickle.loads(base64decode(bytes(value))) retVal = loads(base64decode(bytes(value)))
return retVal return retVal
@@ -89,14 +108,7 @@ def hexdecode(value):
""" """
value = value.lower() value = value.lower()
value = value[2:] if value.startswith("0x") else value return (value[2:] if value.startswith("0x") else value).decode("hex")
if six.PY2:
retVal = value.decode("hex")
else:
retVal = bytes.fromhex(value)
return retVal
def hexencode(value, encoding=None): def hexencode(value, encoding=None):
""" """
@@ -106,14 +118,7 @@ def hexencode(value, encoding=None):
'666f6f626172' '666f6f626172'
""" """
retVal = unicodeencode(value, encoding) return unicodeencode(value, encoding).encode("hex")
if six.PY2:
retVal = retVal.encode("hex")
else:
retVal = retVal.hex()
return retVal
def unicodeencode(value, encoding=None): def unicodeencode(value, encoding=None):
""" """
@@ -124,13 +129,11 @@ def unicodeencode(value, encoding=None):
""" """
retVal = value retVal = value
if isinstance(value, unicode):
if isinstance(value, six.text_type):
try: try:
retVal = value.encode(encoding or UNICODE_ENCODING) retVal = value.encode(encoding or UNICODE_ENCODING)
except UnicodeEncodeError: except UnicodeEncodeError:
retVal = value.encode(encoding or UNICODE_ENCODING, "replace") retVal = value.encode(UNICODE_ENCODING, "replace")
return retVal return retVal
def utf8encode(value): def utf8encode(value):
@@ -162,7 +165,7 @@ def htmlunescape(value):
""" """
retVal = value retVal = value
if value and isinstance(value, six.string_types): if value and isinstance(value, basestring):
codes = (("&lt;", '<'), ("&gt;", '>'), ("&quot;", '"'), ("&nbsp;", ' '), ("&amp;", '&'), ("&apos;", "'")) codes = (("&lt;", '<'), ("&gt;", '>'), ("&quot;", '"'), ("&nbsp;", ' '), ("&amp;", '&'), ("&apos;", "'"))
retVal = reduce(lambda x, y: x.replace(y[0], y[1]), codes, retVal) retVal = reduce(lambda x, y: x.replace(y[0], y[1]), codes, retVal)
try: try:
@@ -180,11 +183,13 @@ def stdoutencode(data):
retVal = None retVal = None
try: try:
retVal = unicodeencode(data or "", sys.stdout.encoding) data = data or ""
# Reference: http://bugs.python.org/issue1602 # Reference: http://bugs.python.org/issue1602
if IS_WIN: if IS_WIN:
if '?' in retVal and '?' not in retVal: output = data.encode(sys.stdout.encoding, "replace")
if '?' in output and '?' not in data:
warnMsg = "cannot properly display Unicode characters " warnMsg = "cannot properly display Unicode characters "
warnMsg += "inside Windows OS command prompt " warnMsg += "inside Windows OS command prompt "
warnMsg += "(http://bugs.python.org/issue1602). All " warnMsg += "(http://bugs.python.org/issue1602). All "
@@ -194,8 +199,11 @@ def stdoutencode(data):
warnMsg += "corresponding output files. " warnMsg += "corresponding output files. "
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
retVal = output
else:
retVal = data.encode(sys.stdout.encoding)
except: except:
retVal = unicodeencode(data or "") retVal = data.encode(UNICODE_ENCODING) if isinstance(data, unicode) else data
return retVal return retVal
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+2 -97
View File
@@ -1,16 +1,13 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import collections
import copy import copy
import types import types
from thirdparty.odict import OrderedDict
class AttribDict(dict): class AttribDict(dict):
""" """
This class defines the sqlmap object, inheriting from Python data This class defines the sqlmap object, inheriting from Python data
@@ -107,95 +104,3 @@ class InjectionDict(AttribDict):
self.dbms = None self.dbms = None
self.dbms_version = None self.dbms_version = None
self.os = None self.os = None
# Reference: https://www.kunxi.org/2014/05/lru-cache-in-python
class LRUDict(object):
def __init__(self, capacity):
self.capacity = capacity
self.cache = OrderedDict()
def __len__(self):
return len(self.cache)
def __contains__(self, key):
return key in self.cache
def __getitem__(self, key):
value = self.cache.pop(key)
self.cache[key] = value
return value
def get(self, key):
return self.__getitem__(key)
def __setitem__(self, key, value):
try:
self.cache.pop(key)
except KeyError:
if len(self.cache) >= self.capacity:
self.cache.popitem(last=False)
self.cache[key] = value
def set(self, key, value):
self.__setitem__(key, value)
def keys(self):
return self.cache.keys()
# Reference: https://code.activestate.com/recipes/576694/
class OrderedSet(collections.MutableSet):
def __init__(self, iterable=None):
self.end = end = []
end += [None, end, end] # sentinel node for doubly linked list
self.map = {} # key --> [key, prev, next]
if iterable is not None:
self |= iterable
def __len__(self):
return len(self.map)
def __contains__(self, key):
return key in self.map
def add(self, key):
if key not in self.map:
end = self.end
curr = end[1]
curr[2] = end[1] = self.map[key] = [key, curr, end]
def discard(self, key):
if key in self.map:
key, prev, next = self.map.pop(key)
prev[2] = next
next[1] = prev
def __iter__(self):
end = self.end
curr = end[2]
while curr is not end:
yield curr[0]
curr = curr[2]
def __reversed__(self):
end = self.end
curr = end[1]
while curr is not end:
yield curr[0]
curr = curr[1]
def pop(self, last=True):
if not self:
raise KeyError('set is empty')
key = self.end[1][0] if last else self.end[2][0]
self.discard(key)
return key
def __repr__(self):
if not self:
return '%s()' % (self.__class__.__name__,)
return '%s(%r)' % (self.__class__.__name__, list(self))
def __eq__(self, other):
if isinstance(other, OrderedSet):
return len(self) == len(other) and list(self) == list(other)
return set(self) == set(other)
+6 -25
View File
@@ -1,50 +1,31 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import functools
import hashlib import hashlib
import threading
from lib.core.settings import MAX_CACHE_ITEMS
from lib.core.datatype import LRUDict
from lib.core.threads import getCurrentThreadData from lib.core.threads import getCurrentThreadData
_lock = threading.Lock() def cachedmethod(f, cache={}):
def cachedmethod(f, cache=LRUDict(capacity=MAX_CACHE_ITEMS)):
""" """
Method with a cached content Method with a cached content
Reference: http://code.activestate.com/recipes/325205-cache-decorator-in-python-24/ Reference: http://code.activestate.com/recipes/325205-cache-decorator-in-python-24/
""" """
@functools.wraps(f)
def _(*args, **kwargs): def _(*args, **kwargs):
key = int(hashlib.md5("|".join(str(_) for _ in (f, args, kwargs))).hexdigest(), 16) & 0x7fffffffffffffff key = int(hashlib.md5("|".join(str(_) for _ in (f, args, kwargs))).hexdigest(), 16) & 0x7fffffffffffffff
if key not in cache:
cache[key] = f(*args, **kwargs)
try: return cache[key]
with _lock:
result = cache[key]
except KeyError:
result = f(*args, **kwargs)
with _lock:
cache[key] = result
return result
return _ return _
def stackedmethod(f): def stackedmethod(f):
"""
Method using pushValue/popValue functions (fallback function for stack realignment)
"""
@functools.wraps(f)
def _(*args, **kwargs): def _(*args, **kwargs):
threadData = getCurrentThreadData() threadData = getCurrentThreadData()
originalLevel = len(threadData.valueStack) originalLevel = len(threadData.valueStack)
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+2 -4
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -22,7 +22,6 @@ from lib.core.settings import MAXDB_ALIASES
from lib.core.settings import SYBASE_ALIASES from lib.core.settings import SYBASE_ALIASES
from lib.core.settings import DB2_ALIASES from lib.core.settings import DB2_ALIASES
from lib.core.settings import HSQLDB_ALIASES from lib.core.settings import HSQLDB_ALIASES
from lib.core.settings import H2_ALIASES
from lib.core.settings import INFORMIX_ALIASES from lib.core.settings import INFORMIX_ALIASES
FIREBIRD_TYPES = { FIREBIRD_TYPES = {
@@ -196,7 +195,6 @@ DBMS_DICT = {
DBMS.SYBASE: (SYBASE_ALIASES, "python-pymssql", "https://github.com/pymssql/pymssql", "sybase"), DBMS.SYBASE: (SYBASE_ALIASES, "python-pymssql", "https://github.com/pymssql/pymssql", "sybase"),
DBMS.DB2: (DB2_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"), DBMS.DB2: (DB2_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"),
DBMS.HSQLDB: (HSQLDB_ALIASES, "python jaydebeapi & python-jpype", "https://pypi.python.org/pypi/JayDeBeApi/ & http://jpype.sourceforge.net/", None), DBMS.HSQLDB: (HSQLDB_ALIASES, "python jaydebeapi & python-jpype", "https://pypi.python.org/pypi/JayDeBeApi/ & http://jpype.sourceforge.net/", None),
DBMS.H2: (H2_ALIASES, None, None, None),
DBMS.INFORMIX: (INFORMIX_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"), DBMS.INFORMIX: (INFORMIX_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"),
} }
+19 -21
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -20,7 +20,6 @@ from lib.core.common import dataToStdout
from lib.core.common import getSafeExString from lib.core.common import getSafeExString
from lib.core.common import getUnicode from lib.core.common import getUnicode
from lib.core.common import isListLike from lib.core.common import isListLike
from lib.core.common import isMultiThreadMode
from lib.core.common import normalizeUnicode from lib.core.common import normalizeUnicode
from lib.core.common import openFile from lib.core.common import openFile
from lib.core.common import prioritySortColumns from lib.core.common import prioritySortColumns
@@ -28,7 +27,6 @@ from lib.core.common import randomInt
from lib.core.common import safeCSValue from lib.core.common import safeCSValue
from lib.core.common import unicodeencode from lib.core.common import unicodeencode
from lib.core.common import unsafeSQLIdentificatorNaming from lib.core.common import unsafeSQLIdentificatorNaming
from lib.core.compat import xrange
from lib.core.data import conf from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
@@ -51,7 +49,6 @@ from lib.core.settings import UNICODE_ENCODING
from lib.core.settings import UNSAFE_DUMP_FILEPATH_REPLACEMENT from lib.core.settings import UNSAFE_DUMP_FILEPATH_REPLACEMENT
from lib.core.settings import VERSION_STRING from lib.core.settings import VERSION_STRING
from lib.core.settings import WINDOWS_RESERVED_NAMES from lib.core.settings import WINDOWS_RESERVED_NAMES
from thirdparty import six
from thirdparty.magic import magic from thirdparty.magic import magic
from extra.safe2bin.safe2bin import safechardecode from extra.safe2bin.safe2bin import safechardecode
@@ -77,17 +74,16 @@ class Dump(object):
if console: if console:
dataToStdout(text) dataToStdout(text)
multiThreadMode = isMultiThreadMode() if kb.get("multiThreadMode"):
if multiThreadMode:
self._lock.acquire() self._lock.acquire()
try: try:
self._outputFP.write(text) self._outputFP.write(text)
except IOError as ex: except IOError, ex:
errMsg = "error occurred while writing to log file ('%s')" % getSafeExString(ex) errMsg = "error occurred while writing to log file ('%s')" % getSafeExString(ex)
raise SqlmapGenericException(errMsg) raise SqlmapGenericException(errMsg)
if multiThreadMode: if kb.get("multiThreadMode"):
self._lock.release() self._lock.release()
kb.dataOutputFlag = True kb.dataOutputFlag = True
@@ -103,7 +99,7 @@ class Dump(object):
self._outputFile = os.path.join(conf.outputPath, "log") self._outputFile = os.path.join(conf.outputPath, "log")
try: try:
self._outputFP = openFile(self._outputFile, "ab" if not conf.flushSession else "wb") self._outputFP = openFile(self._outputFile, "ab" if not conf.flushSession else "wb")
except IOError as ex: except IOError, ex:
errMsg = "error occurred while opening log file ('%s')" % getSafeExString(ex) errMsg = "error occurred while opening log file ('%s')" % getSafeExString(ex)
raise SqlmapGenericException(errMsg) raise SqlmapGenericException(errMsg)
@@ -114,6 +110,8 @@ class Dump(object):
self._write(data, content_type=content_type) self._write(data, content_type=content_type)
def string(self, header, data, content_type=None, sort=True): def string(self, header, data, content_type=None, sort=True):
kb.stickyLevel = None
if conf.api: if conf.api:
self._write(data, content_type=content_type) self._write(data, content_type=content_type)
return return
@@ -135,7 +133,7 @@ class Dump(object):
if "\n" in _: if "\n" in _:
self._write("%s:\n---\n%s\n---" % (header, _)) self._write("%s:\n---\n%s\n---" % (header, _))
else: else:
self._write("%s: %s" % (header, ("'%s'" % _) if isinstance(data, six.string_types) else _)) self._write("%s: %s" % (header, ("'%s'" % _) if isinstance(data, basestring) else _))
else: else:
self._write("%s:\tNone" % header) self._write("%s:\tNone" % header)
@@ -144,7 +142,7 @@ class Dump(object):
try: try:
elements = set(elements) elements = set(elements)
elements = list(elements) elements = list(elements)
elements.sort(key=lambda _: _.lower() if hasattr(_, "lower") else _) elements.sort(key=lambda _: _.lower() if isinstance(_, basestring) else _)
except: except:
pass pass
@@ -156,7 +154,7 @@ class Dump(object):
self._write("%s [%d]:" % (header, len(elements))) self._write("%s [%d]:" % (header, len(elements)))
for element in elements: for element in elements:
if isinstance(element, six.string_types): if isinstance(element, basestring):
self._write("[*] %s" % element) self._write("[*] %s" % element)
elif isListLike(element): elif isListLike(element):
self._write("[*] " + ", ".join(getUnicode(e) for e in element)) self._write("[*] " + ", ".join(getUnicode(e) for e in element))
@@ -173,7 +171,7 @@ class Dump(object):
def currentDb(self, data): def currentDb(self, data):
if Backend.isDbms(DBMS.MAXDB): if Backend.isDbms(DBMS.MAXDB):
self.string("current database (no practical usage on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB) self.string("current database (no practical usage on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2): elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB):
self.string("current schema (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB) self.string("current schema (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
else: else:
self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB) self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB)
@@ -195,7 +193,7 @@ class Dump(object):
userSettings = userSettings[0] userSettings = userSettings[0]
users = userSettings.keys() users = userSettings.keys()
users.sort(key=lambda _: _.lower() if hasattr(_, "lower") else _) users.sort(key=lambda _: _.lower() if isinstance(_, basestring) else _)
if conf.api: if conf.api:
self._write(userSettings, content_type=content_type) self._write(userSettings, content_type=content_type)
@@ -289,7 +287,7 @@ class Dump(object):
colType = None colType = None
colList = columns.keys() colList = columns.keys()
colList.sort(key=lambda _: _.lower() if hasattr(_, "lower") else _) colList.sort(key=lambda _: _.lower() if isinstance(_, basestring) else _)
for column in colList: for column in colList:
colType = columns[column] colType = columns[column]
@@ -381,7 +379,7 @@ class Dump(object):
if count is None: if count is None:
count = "Unknown" count = "Unknown"
tables.sort(key=lambda _: _.lower() if hasattr(_, "lower") else _) tables.sort(key=lambda _: _.lower() if isinstance(_, basestring) else _)
for table in tables: for table in tables:
blank1 = " " * (maxlength1 - len(normalizeUnicode(table) or unicode(table))) blank1 = " " * (maxlength1 - len(normalizeUnicode(table) or unicode(table)))
@@ -428,10 +426,10 @@ class Dump(object):
if not os.path.isdir(dumpDbPath): if not os.path.isdir(dumpDbPath):
try: try:
os.makedirs(dumpDbPath) os.makedirs(dumpDbPath)
except Exception as ex: except Exception, ex:
try: try:
tempDir = tempfile.mkdtemp(prefix="sqlmapdb") tempDir = tempfile.mkdtemp(prefix="sqlmapdb")
except IOError as _: except IOError, _:
errMsg = "unable to write to the temporary directory ('%s'). " % _ errMsg = "unable to write to the temporary directory ('%s'). " % _
errMsg += "Please make sure that your disk is not full and " errMsg += "Please make sure that your disk is not full and "
errMsg += "that you have sufficient write permissions to " errMsg += "that you have sufficient write permissions to "
@@ -626,8 +624,8 @@ class Dump(object):
with open(filepath, "wb") as f: with open(filepath, "wb") as f:
_ = safechardecode(value, True) _ = safechardecode(value, True)
f.write(_) f.write(_)
except magic.MagicException as ex: except magic.MagicException, err:
logger.debug(getSafeExString(ex)) logger.debug(str(err))
if conf.dumpFormat == DUMP_FORMAT.CSV: if conf.dumpFormat == DUMP_FORMAT.CSV:
if field == fields: if field == fields:
+8 -20
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -43,7 +43,6 @@ class DBMS:
SQLITE = "SQLite" SQLITE = "SQLite"
SYBASE = "Sybase" SYBASE = "Sybase"
HSQLDB = "HSQLDB" HSQLDB = "HSQLDB"
H2 = "H2"
INFORMIX = "Informix" INFORMIX = "Informix"
class DBMS_DIRECTORY_NAME: class DBMS_DIRECTORY_NAME:
@@ -58,7 +57,6 @@ class DBMS_DIRECTORY_NAME:
SQLITE = "sqlite" SQLITE = "sqlite"
SYBASE = "sybase" SYBASE = "sybase"
HSQLDB = "hsqldb" HSQLDB = "hsqldb"
H2 = "h2"
INFORMIX = "informix" INFORMIX = "informix"
class CUSTOM_LOGGING: class CUSTOM_LOGGING:
@@ -156,17 +154,13 @@ class HASH:
# Reference: http://www.zytrax.com/tech/web/mobile_ids.html # Reference: http://www.zytrax.com/tech/web/mobile_ids.html
class MOBILES: class MOBILES:
BLACKBERRY = ("BlackBerry Z10", "Mozilla/5.0 (BB10; Kbd) AppleWebKit/537.35+ (KHTML, like Gecko) Version/10.3.3.2205 Mobile Safari/537.35+") BLACKBERRY = ("BlackBerry 9900", "Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.1.0.346 Mobile Safari/534.11+")
GALAXY = ("Samsung Galaxy S7", "Mozilla/5.0 (Linux; Android 7.0; SM-G930V Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.125 Mobile Safari/537.36") GALAXY = ("Samsung Galaxy S", "Mozilla/5.0 (Linux; U; Android 2.2; en-US; SGH-T959D Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1")
HP = ("HP iPAQ 6365", "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320; HP iPAQ h6300)") HP = ("HP iPAQ 6365", "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320; HP iPAQ h6300)")
HTC = ("HTC 10", "Mozilla/5.0 (Linux; Android 8.0.0; HTC 10 Build/OPR1.170623.027) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36") HTC = ("HTC Sensation", "Mozilla/5.0 (Linux; U; Android 4.0.3; de-ch; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30")
HUAWEI = ("Huawei P8", "Mozilla/5.0 (Linux; Android 4.4.4; HUAWEI H891L Build/HuaweiH891L) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Mobile Safari/537.36") IPHONE = ("Apple iPhone 4s", "Mozilla/5.0 (iPhone; CPU iPhone OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B179 Safari/7534.48.3")
IPHONE = ("Apple iPhone 8", "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1")
LUMIA = ("Microsoft Lumia 950", "Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Mobile Safari/537.36 Edge/15.14977")
NEXUS = ("Google Nexus 7", "Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19") NEXUS = ("Google Nexus 7", "Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19")
NOKIA = ("Nokia N97", "Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/10.0.012; Profile/MIDP-2.1 Configuration/CLDC-1.1; en-us) AppleWebKit/525 (KHTML, like Gecko) WicKed/7.1.12344") NOKIA = ("Nokia N97", "Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/10.0.012; Profile/MIDP-2.1 Configuration/CLDC-1.1; en-us) AppleWebKit/525 (KHTML, like Gecko) WicKed/7.1.12344")
PIXEL = ("Google Pixel", "Mozilla/5.0 (Linux; Android 8.0.0; Pixel Build/OPR3.170623.013) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36")
XIAOMI = ("Xiaomi Mi 3", "Mozilla/5.0 (Linux; U; Android 4.4.4; en-gb; MI 3W Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36 XiaoMi/MiuiBrowser/2.1.1")
class PROXY_TYPE: class PROXY_TYPE:
HTTP = "HTTP" HTTP = "HTTP"
@@ -231,7 +225,6 @@ class HASHDB_KEYS:
DBMS = "DBMS" DBMS = "DBMS"
DBMS_FORK = "DBMS_FORK" DBMS_FORK = "DBMS_FORK"
CHECK_WAF_RESULT = "CHECK_WAF_RESULT" CHECK_WAF_RESULT = "CHECK_WAF_RESULT"
CHECK_NULL_CONNECTION_RESULT = "CHECK_NULL_CONNECTION_RESULT"
CONF_TMP_PATH = "CONF_TMP_PATH" CONF_TMP_PATH = "CONF_TMP_PATH"
KB_ABS_FILE_PATHS = "KB_ABS_FILE_PATHS" KB_ABS_FILE_PATHS = "KB_ABS_FILE_PATHS"
KB_BRUTE_COLUMNS = "KB_BRUTE_COLUMNS" KB_BRUTE_COLUMNS = "KB_BRUTE_COLUMNS"
@@ -253,7 +246,7 @@ class PAYLOAD:
2: "error-based", 2: "error-based",
3: "inline query", 3: "inline query",
4: "stacked queries", 4: "stacked queries",
5: "time-based blind", 5: "AND/OR time-based blind",
6: "UNION query", 6: "UNION query",
} }
@@ -315,7 +308,7 @@ class ADJUST_TIME_DELAY:
NO = 0 NO = 0
YES = 1 YES = 1
class WEB_PLATFORM: class WEB_API:
PHP = "php" PHP = "php"
ASP = "asp" ASP = "asp"
ASPX = "aspx" ASPX = "aspx"
@@ -378,13 +371,8 @@ class MKSTEMP_PREFIX:
COOKIE_JAR = "sqlmapcookiejar-" COOKIE_JAR = "sqlmapcookiejar-"
BIG_ARRAY = "sqlmapbigarray-" BIG_ARRAY = "sqlmapbigarray-"
SPECIFIC_RESPONSE = "sqlmapresponse-" SPECIFIC_RESPONSE = "sqlmapresponse-"
PREPROCESS = "sqlmappreprocess-"
class TIMEOUT_STATE: class TIMEOUT_STATE:
NORMAL = 0 NORMAL = 0
EXCEPTION = 1 EXCEPTION = 1
TIMEOUT = 2 TIMEOUT = 2
class HINT:
PREPEND = 0
APPEND = 1
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+130 -295
View File
@@ -1,10 +1,11 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import cookielib
import glob import glob
import inspect import inspect
import logging import logging
@@ -12,10 +13,13 @@ import os
import random import random
import re import re
import socket import socket
import string
import sys import sys
import tempfile import tempfile
import threading import threading
import time import time
import urllib2
import urlparse
import lib.controller.checks import lib.controller.checks
import lib.core.common import lib.core.common
@@ -29,22 +33,19 @@ from lib.core.common import Backend
from lib.core.common import boldifyMessage from lib.core.common import boldifyMessage
from lib.core.common import checkFile from lib.core.common import checkFile
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import decodeStringEscape
from lib.core.common import getPublicTypeMembers from lib.core.common import getPublicTypeMembers
from lib.core.common import getSafeExString from lib.core.common import getSafeExString
from lib.core.common import getUnicode
from lib.core.common import filterNone
from lib.core.common import findLocalPort from lib.core.common import findLocalPort
from lib.core.common import findPageForms from lib.core.common import findPageForms
from lib.core.common import getConsoleWidth from lib.core.common import getConsoleWidth
from lib.core.common import getFileItems from lib.core.common import getFileItems
from lib.core.common import getFileType from lib.core.common import getFileType
from lib.core.common import intersect
from lib.core.common import normalizePath from lib.core.common import normalizePath
from lib.core.common import ntToPosixSlashes from lib.core.common import ntToPosixSlashes
from lib.core.common import openFile from lib.core.common import openFile
from lib.core.common import parseRequestFile from lib.core.common import parseRequestFile
from lib.core.common import parseTargetDirect from lib.core.common import parseTargetDirect
from lib.core.common import parseTargetUrl
from lib.core.common import paths from lib.core.common import paths
from lib.core.common import randomStr from lib.core.common import randomStr
from lib.core.common import readCachedFileContent from lib.core.common import readCachedFileContent
@@ -52,14 +53,12 @@ from lib.core.common import readInput
from lib.core.common import resetCookieJar from lib.core.common import resetCookieJar
from lib.core.common import runningAsAdmin from lib.core.common import runningAsAdmin
from lib.core.common import safeExpandUser from lib.core.common import safeExpandUser
from lib.core.common import safeFilepathEncode
from lib.core.common import saveConfig from lib.core.common import saveConfig
from lib.core.common import setColor from lib.core.common import setColor
from lib.core.common import setOptimize from lib.core.common import setOptimize
from lib.core.common import setPaths from lib.core.common import setPaths
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage
from lib.core.common import urldecode from lib.core.common import urldecode
from lib.core.compat import xrange
from lib.core.data import conf from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
@@ -67,7 +66,6 @@ from lib.core.data import mergedOptions
from lib.core.data import queries from lib.core.data import queries
from lib.core.datatype import AttribDict from lib.core.datatype import AttribDict
from lib.core.datatype import InjectionDict from lib.core.datatype import InjectionDict
from lib.core.datatype import OrderedSet
from lib.core.defaults import defaults from lib.core.defaults import defaults
from lib.core.dicts import DBMS_DICT from lib.core.dicts import DBMS_DICT
from lib.core.dicts import DUMP_REPLACEMENTS from lib.core.dicts import DUMP_REPLACEMENTS
@@ -77,7 +75,6 @@ from lib.core.enums import CUSTOM_LOGGING
from lib.core.enums import DUMP_FORMAT from lib.core.enums import DUMP_FORMAT
from lib.core.enums import HTTP_HEADER from lib.core.enums import HTTP_HEADER
from lib.core.enums import HTTPMETHOD from lib.core.enums import HTTPMETHOD
from lib.core.enums import MKSTEMP_PREFIX
from lib.core.enums import MOBILES from lib.core.enums import MOBILES
from lib.core.enums import OPTION_TYPE from lib.core.enums import OPTION_TYPE
from lib.core.enums import PAYLOAD from lib.core.enums import PAYLOAD
@@ -86,7 +83,6 @@ from lib.core.enums import PROXY_TYPE
from lib.core.enums import REFLECTIVE_COUNTER from lib.core.enums import REFLECTIVE_COUNTER
from lib.core.enums import WIZARD from lib.core.enums import WIZARD
from lib.core.exception import SqlmapConnectionException from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapDataException
from lib.core.exception import SqlmapFilePathException from lib.core.exception import SqlmapFilePathException
from lib.core.exception import SqlmapGenericException from lib.core.exception import SqlmapGenericException
from lib.core.exception import SqlmapInstallationException from lib.core.exception import SqlmapInstallationException
@@ -104,12 +100,11 @@ from lib.core.optiondict import optDict
from lib.core.settings import CODECS_LIST_PAGE from lib.core.settings import CODECS_LIST_PAGE
from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR
from lib.core.settings import DBMS_ALIASES from lib.core.settings import DBMS_ALIASES
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import DEFAULT_PAGE_ENCODING from lib.core.settings import DEFAULT_PAGE_ENCODING
from lib.core.settings import DEFAULT_TOR_HTTP_PORTS from lib.core.settings import DEFAULT_TOR_HTTP_PORTS
from lib.core.settings import DEFAULT_TOR_SOCKS_PORTS from lib.core.settings import DEFAULT_TOR_SOCKS_PORTS
from lib.core.settings import DEFAULT_USER_AGENT
from lib.core.settings import DUMMY_URL from lib.core.settings import DUMMY_URL
from lib.core.settings import INJECT_HERE_REGEX
from lib.core.settings import IS_WIN from lib.core.settings import IS_WIN
from lib.core.settings import KB_CHARS_BOUNDARY_CHAR from lib.core.settings import KB_CHARS_BOUNDARY_CHAR
from lib.core.settings import KB_CHARS_LOW_FREQUENCY_ALPHABET from lib.core.settings import KB_CHARS_LOW_FREQUENCY_ALPHABET
@@ -119,14 +114,17 @@ from lib.core.settings import MAX_NUMBER_OF_THREADS
from lib.core.settings import NULL from lib.core.settings import NULL
from lib.core.settings import PARAMETER_SPLITTING_REGEX from lib.core.settings import PARAMETER_SPLITTING_REGEX
from lib.core.settings import PRECONNECT_CANDIDATE_TIMEOUT from lib.core.settings import PRECONNECT_CANDIDATE_TIMEOUT
from lib.core.settings import SITE
from lib.core.settings import SOCKET_PRE_CONNECT_QUEUE_SIZE from lib.core.settings import SOCKET_PRE_CONNECT_QUEUE_SIZE
from lib.core.settings import SQLMAP_ENVIRONMENT_PREFIX from lib.core.settings import SQLMAP_ENVIRONMENT_PREFIX
from lib.core.settings import SUPPORTED_DBMS from lib.core.settings import SUPPORTED_DBMS
from lib.core.settings import SUPPORTED_OS from lib.core.settings import SUPPORTED_OS
from lib.core.settings import TIME_DELAY_CANDIDATES from lib.core.settings import TIME_DELAY_CANDIDATES
from lib.core.settings import UNICODE_ENCODING
from lib.core.settings import UNION_CHAR_REGEX from lib.core.settings import UNION_CHAR_REGEX
from lib.core.settings import UNKNOWN_DBMS_VERSION from lib.core.settings import UNKNOWN_DBMS_VERSION
from lib.core.settings import URI_INJECTABLE_REGEX from lib.core.settings import URI_INJECTABLE_REGEX
from lib.core.settings import VERSION_STRING
from lib.core.threads import getCurrentThreadData from lib.core.threads import getCurrentThreadData
from lib.core.threads import setDaemon from lib.core.threads import setDaemon
from lib.core.update import update from lib.core.update import update
@@ -138,7 +136,6 @@ from lib.request.basic import checkCharEncoding
from lib.request.connect import Connect as Request from lib.request.connect import Connect as Request
from lib.request.dns import DNSServer from lib.request.dns import DNSServer
from lib.request.basicauthhandler import SmartHTTPBasicAuthHandler from lib.request.basicauthhandler import SmartHTTPBasicAuthHandler
from lib.request.chunkedhandler import ChunkedHandler
from lib.request.httpshandler import HTTPSHandler from lib.request.httpshandler import HTTPSHandler
from lib.request.pkihandler import HTTPSPKIAuthHandler from lib.request.pkihandler import HTTPSPKIAuthHandler
from lib.request.rangehandler import HTTPRangeHandler from lib.request.rangehandler import HTTPRangeHandler
@@ -149,20 +146,16 @@ from lib.utils.crawler import crawl
from lib.utils.deps import checkDependencies from lib.utils.deps import checkDependencies
from lib.utils.search import search from lib.utils.search import search
from lib.utils.purge import purge from lib.utils.purge import purge
from thirdparty import six
from thirdparty.keepalive import keepalive from thirdparty.keepalive import keepalive
from thirdparty.multipart import multipartpost from thirdparty.multipart import multipartpost
from thirdparty.six.moves import http_client as _http_client from thirdparty.oset.pyoset import oset
from thirdparty.six.moves import http_cookiejar as _http_cookiejar
from thirdparty.six.moves import urllib as _urllib
from thirdparty.socks import socks from thirdparty.socks import socks
from xml.etree.ElementTree import ElementTree from xml.etree.ElementTree import ElementTree
authHandler = _urllib.request.BaseHandler() authHandler = urllib2.BaseHandler()
chunkedHandler = ChunkedHandler()
httpsHandler = HTTPSHandler() httpsHandler = HTTPSHandler()
keepAliveHandler = keepalive.HTTPHandler() keepAliveHandler = keepalive.HTTPHandler()
proxyHandler = _urllib.request.ProxyHandler() proxyHandler = urllib2.ProxyHandler()
redirectHandler = SmartRedirectHandler() redirectHandler = SmartRedirectHandler()
rangeHandler = HTTPRangeHandler() rangeHandler = HTTPRangeHandler()
multipartPostHandler = multipartpost.MultipartPostHandler() multipartPostHandler = multipartpost.MultipartPostHandler()
@@ -202,7 +195,7 @@ def _loadQueries():
tree = ElementTree() tree = ElementTree()
try: try:
tree.parse(paths.QUERIES_XML) tree.parse(paths.QUERIES_XML)
except Exception as ex: except Exception, ex:
errMsg = "something appears to be wrong with " errMsg = "something appears to be wrong with "
errMsg += "the file '%s' ('%s'). Please make " % (paths.QUERIES_XML, getSafeExString(ex)) errMsg += "the file '%s' ('%s'). Please make " % (paths.QUERIES_XML, getSafeExString(ex))
errMsg += "sure that you haven't made any changes to it" errMsg += "sure that you haven't made any changes to it"
@@ -230,13 +223,12 @@ def _setMultipleTargets():
errMsg = "the specified list of targets does not exist" errMsg = "the specified list of targets does not exist"
raise SqlmapFilePathException(errMsg) raise SqlmapFilePathException(errMsg)
if checkFile(conf.logFile, False): if os.path.isfile(conf.logFile):
for target in parseRequestFile(conf.logFile): for target in parseRequestFile(conf.logFile):
url, _, data, _, _ = target url = target[0]
key = re.sub(r"(\w+=)[^%s ]*" % (conf.paramDel or DEFAULT_GET_POST_DELIMITER), r"\g<1>", "%s %s" % (url, data)) if url not in seen:
if key not in seen:
kb.targets.add(target) kb.targets.add(target)
seen.add(key) seen.add(url)
elif os.path.isdir(conf.logFile): elif os.path.isdir(conf.logFile):
files = os.listdir(conf.logFile) files = os.listdir(conf.logFile)
@@ -247,11 +239,10 @@ def _setMultipleTargets():
continue continue
for target in parseRequestFile(os.path.join(conf.logFile, reqFile)): for target in parseRequestFile(os.path.join(conf.logFile, reqFile)):
url, _, data, _, _ = target url = target[0]
key = re.sub(r"(\w+=)[^%s ]*" % (conf.paramDel or DEFAULT_GET_POST_DELIMITER), r"\g<1>", "%s %s" % (url, data)) if url not in seen:
if key not in seen:
kb.targets.add(target) kb.targets.add(target)
seen.add(key) seen.add(url)
else: else:
errMsg = "the specified list of targets is not a file " errMsg = "the specified list of targets is not a file "
@@ -296,7 +287,7 @@ def _setRequestFromFile():
conf.requestFile = safeExpandUser(conf.requestFile) conf.requestFile = safeExpandUser(conf.requestFile)
seen = set() seen = set()
if not checkFile(conf.requestFile, False): if not os.path.isfile(conf.requestFile):
errMsg = "specified HTTP request file '%s' " % conf.requestFile errMsg = "specified HTTP request file '%s' " % conf.requestFile
errMsg += "does not exist" errMsg += "does not exist"
raise SqlmapFilePathException(errMsg) raise SqlmapFilePathException(errMsg)
@@ -313,7 +304,7 @@ def _setRequestFromFile():
if conf.secondReq: if conf.secondReq:
conf.secondReq = safeExpandUser(conf.secondReq) conf.secondReq = safeExpandUser(conf.secondReq)
if not checkFile(conf.secondReq, False): if not os.path.isfile(conf.secondReq):
errMsg = "specified second-order HTTP request file '%s' " % conf.secondReq errMsg = "specified second-order HTTP request file '%s' " % conf.secondReq
errMsg += "does not exist" errMsg += "does not exist"
raise SqlmapFilePathException(errMsg) raise SqlmapFilePathException(errMsg)
@@ -321,7 +312,7 @@ def _setRequestFromFile():
infoMsg = "parsing second-order HTTP request from '%s'" % conf.secondReq infoMsg = "parsing second-order HTTP request from '%s'" % conf.secondReq
logger.info(infoMsg) logger.info(infoMsg)
target = next(parseRequestFile(conf.secondReq, False)) target = parseRequestFile(conf.secondReq, False).next()
kb.secondReq = target kb.secondReq = target
def _setCrawler(): def _setCrawler():
@@ -343,7 +334,7 @@ def _setCrawler():
if conf.verbose in (1, 2): if conf.verbose in (1, 2):
status = "%d/%d links visited (%d%%)" % (i + 1, len(targets), round(100.0 * (i + 1) / len(targets))) status = "%d/%d links visited (%d%%)" % (i + 1, len(targets), round(100.0 * (i + 1) / len(targets)))
dataToStdout("\r[%s] [INFO] %s" % (time.strftime("%X"), status), True) dataToStdout("\r[%s] [INFO] %s" % (time.strftime("%X"), status), True)
except Exception as ex: except Exception, ex:
errMsg = "problem occurred while crawling at '%s' ('%s')" % (target, getSafeExString(ex)) errMsg = "problem occurred while crawling at '%s' ('%s')" % (target, getSafeExString(ex))
logger.error(errMsg) logger.error(errMsg)
@@ -415,7 +406,7 @@ def _setBulkMultipleTargets():
infoMsg = "parsing multiple targets list from '%s'" % conf.bulkFile infoMsg = "parsing multiple targets list from '%s'" % conf.bulkFile
logger.info(infoMsg) logger.info(infoMsg)
if not checkFile(conf.bulkFile, False): if not os.path.isfile(conf.bulkFile):
errMsg = "the specified bulk file " errMsg = "the specified bulk file "
errMsg += "does not exist" errMsg += "does not exist"
raise SqlmapFilePathException(errMsg) raise SqlmapFilePathException(errMsg)
@@ -479,7 +470,7 @@ def _findPageForms():
dataToStdout("\r[%s] [INFO] %s" % (time.strftime("%X"), status), True) dataToStdout("\r[%s] [INFO] %s" % (time.strftime("%X"), status), True)
except KeyboardInterrupt: except KeyboardInterrupt:
break break
except Exception as ex: except Exception, ex:
errMsg = "problem occurred while searching for forms at '%s' ('%s')" % (target, getSafeExString(ex)) errMsg = "problem occurred while searching for forms at '%s' ('%s')" % (target, getSafeExString(ex))
logger.error(errMsg) logger.error(errMsg)
@@ -554,11 +545,11 @@ def _setMetasploit():
if conf.msfPath: if conf.msfPath:
for path in (conf.msfPath, os.path.join(conf.msfPath, "bin")): for path in (conf.msfPath, os.path.join(conf.msfPath, "bin")):
if any(os.path.exists(normalizePath(os.path.join(path, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in ("msfcli", "msfconsole")): if any(os.path.exists(normalizePath(os.path.join(path, _))) for _ in ("msfcli", "msfconsole")):
msfEnvPathExists = True msfEnvPathExists = True
if all(os.path.exists(normalizePath(os.path.join(path, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in ("msfvenom",)): if all(os.path.exists(normalizePath(os.path.join(path, _))) for _ in ("msfvenom",)):
kb.oldMsf = False kb.oldMsf = False
elif all(os.path.exists(normalizePath(os.path.join(path, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in ("msfencode", "msfpayload")): elif all(os.path.exists(normalizePath(os.path.join(path, _))) for _ in ("msfencode", "msfpayload")):
kb.oldMsf = True kb.oldMsf = True
else: else:
msfEnvPathExists = False msfEnvPathExists = False
@@ -593,11 +584,11 @@ def _setMetasploit():
for envPath in envPaths: for envPath in envPaths:
envPath = envPath.replace(";", "") envPath = envPath.replace(";", "")
if any(os.path.exists(normalizePath(os.path.join(envPath, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in ("msfcli", "msfconsole")): if any(os.path.exists(normalizePath(os.path.join(envPath, _))) for _ in ("msfcli", "msfconsole")):
msfEnvPathExists = True msfEnvPathExists = True
if all(os.path.exists(normalizePath(os.path.join(envPath, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in ("msfvenom",)): if all(os.path.exists(normalizePath(os.path.join(envPath, _))) for _ in ("msfvenom",)):
kb.oldMsf = False kb.oldMsf = False
elif all(os.path.exists(normalizePath(os.path.join(envPath, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in ("msfencode", "msfpayload")): elif all(os.path.exists(normalizePath(os.path.join(envPath, _))) for _ in ("msfencode", "msfpayload")):
kb.oldMsf = True kb.oldMsf = True
else: else:
msfEnvPathExists = False msfEnvPathExists = False
@@ -661,7 +652,7 @@ def _setTechnique():
validTechniques = sorted(getPublicTypeMembers(PAYLOAD.TECHNIQUE), key=lambda x: x[1]) validTechniques = sorted(getPublicTypeMembers(PAYLOAD.TECHNIQUE), key=lambda x: x[1])
validLetters = [_[0][0].upper() for _ in validTechniques] validLetters = [_[0][0].upper() for _ in validTechniques]
if conf.tech and isinstance(conf.tech, six.string_types): if conf.tech and isinstance(conf.tech, basestring):
_ = [] _ = []
for letter in conf.tech.upper(): for letter in conf.tech.upper():
@@ -739,8 +730,8 @@ def _setTamperingFunctions():
for script in re.split(PARAMETER_SPLITTING_REGEX, conf.tamper): for script in re.split(PARAMETER_SPLITTING_REGEX, conf.tamper):
found = False found = False
path = safeFilepathEncode(paths.SQLMAP_TAMPER_PATH) path = paths.SQLMAP_TAMPER_PATH.encode(sys.getfilesystemencoding() or UNICODE_ENCODING)
script = safeFilepathEncode(script.strip()) script = script.strip().encode(sys.getfilesystemencoding() or UNICODE_ENCODING)
try: try:
if not script: if not script:
@@ -775,9 +766,9 @@ def _setTamperingFunctions():
sys.path.insert(0, dirname) sys.path.insert(0, dirname)
try: try:
module = __import__(safeFilepathEncode(filename[:-3])) module = __import__(filename[:-3].encode(sys.getfilesystemencoding() or UNICODE_ENCODING))
except Exception as ex: except Exception, ex:
raise SqlmapSyntaxException("cannot import tamper module '%s' (%s)" % (getUnicode(filename[:-3]), getSafeExString(ex))) raise SqlmapSyntaxException("cannot import tamper module '%s' (%s)" % (filename[:-3], getSafeExString(ex)))
priority = PRIORITY.NORMAL if not hasattr(module, "__priority__") else module.__priority__ priority = PRIORITY.NORMAL if not hasattr(module, "__priority__") else module.__priority__
@@ -785,7 +776,7 @@ def _setTamperingFunctions():
if name == "tamper" and inspect.getargspec(function).args and inspect.getargspec(function).keywords == "kwargs": if name == "tamper" and inspect.getargspec(function).args and inspect.getargspec(function).keywords == "kwargs":
found = True found = True
kb.tamperFunctions.append(function) kb.tamperFunctions.append(function)
function.__name__ = module.__name__ function.func_name = module.__name__
if check_priority and priority > last_priority: if check_priority and priority > last_priority:
message = "it appears that you might have mixed " message = "it appears that you might have mixed "
@@ -809,9 +800,9 @@ def _setTamperingFunctions():
elif name == "dependencies": elif name == "dependencies":
try: try:
function() function()
except Exception as ex: except Exception, ex:
errMsg = "error occurred while checking dependencies " errMsg = "error occurred while checking dependencies "
errMsg += "for tamper module '%s' ('%s')" % (getUnicode(filename[:-3]), getSafeExString(ex)) errMsg += "for tamper module '%s' ('%s')" % (filename[:-3], getSafeExString(ex))
raise SqlmapGenericException(errMsg) raise SqlmapGenericException(errMsg)
if not found: if not found:
@@ -831,80 +822,6 @@ def _setTamperingFunctions():
for _, function in priorities: for _, function in priorities:
kb.tamperFunctions.append(function) kb.tamperFunctions.append(function)
def _setPreprocessFunctions():
"""
Loads preprocess functions from given script(s)
"""
if conf.preprocess:
for script in re.split(PARAMETER_SPLITTING_REGEX, conf.preprocess):
found = False
script = safeFilepathEncode(script.strip())
try:
if not script:
continue
if not os.path.exists(script):
errMsg = "preprocess script '%s' does not exist" % script
raise SqlmapFilePathException(errMsg)
elif not script.endswith(".py"):
errMsg = "preprocess script '%s' should have an extension '.py'" % script
raise SqlmapSyntaxException(errMsg)
except UnicodeDecodeError:
errMsg = "invalid character provided in option '--preprocess'"
raise SqlmapSyntaxException(errMsg)
dirname, filename = os.path.split(script)
dirname = os.path.abspath(dirname)
infoMsg = "loading preprocess module '%s'" % filename[:-3]
logger.info(infoMsg)
if not os.path.exists(os.path.join(dirname, "__init__.py")):
errMsg = "make sure that there is an empty file '__init__.py' "
errMsg += "inside of preprocess scripts directory '%s'" % dirname
raise SqlmapGenericException(errMsg)
if dirname not in sys.path:
sys.path.insert(0, dirname)
try:
module = __import__(safeFilepathEncode(filename[:-3]))
except Exception as ex:
raise SqlmapSyntaxException("cannot import preprocess module '%s' (%s)" % (getUnicode(filename[:-3]), getSafeExString(ex)))
for name, function in inspect.getmembers(module, inspect.isfunction):
if name == "preprocess" and inspect.getargspec(function).args and all(_ in inspect.getargspec(function).args for _ in ("page", "headers", "code")):
found = True
kb.preprocessFunctions.append(function)
function.__name__ = module.__name__
break
if not found:
errMsg = "missing function 'preprocess(page, headers=None, code=None)' "
errMsg += "in preprocess script '%s'" % script
raise SqlmapGenericException(errMsg)
else:
try:
_, _, _ = function("", {}, None)
except:
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.PREPROCESS, suffix=".py")
os.close(handle)
open(filename, "w+b").write("#!/usr/bin/env\n\ndef preprocess(page, headers=None, code=None):\n return page, headers, code\n")
open(os.path.join(os.path.dirname(filename), "__init__.py"), "w+b").write("pass")
errMsg = "function 'preprocess(page, headers=None, code=None)' "
errMsg += "in preprocess script '%s' " % script
errMsg += "should return a tuple '(page, headers, code)' "
errMsg += "(Note: find template script at '%s')" % filename
raise SqlmapGenericException(errMsg)
def _setWafFunctions(): def _setWafFunctions():
""" """
Loads WAF/IPS detecting functions from script(s) Loads WAF/IPS detecting functions from script(s)
@@ -927,9 +844,9 @@ def _setWafFunctions():
try: try:
if filename[:-3] in sys.modules: if filename[:-3] in sys.modules:
del sys.modules[filename[:-3]] del sys.modules[filename[:-3]]
module = __import__(safeFilepathEncode(filename[:-3])) module = __import__(filename[:-3].encode(sys.getfilesystemencoding() or UNICODE_ENCODING))
except ImportError as ex: except ImportError, msg:
raise SqlmapSyntaxException("cannot import WAF script '%s' (%s)" % (getUnicode(filename[:-3]), getSafeExString(ex))) raise SqlmapSyntaxException("cannot import WAF script '%s' (%s)" % (filename[:-3], msg))
_ = dict(inspect.getmembers(module)) _ = dict(inspect.getmembers(module))
if "detect" not in _: if "detect" not in _:
@@ -978,12 +895,6 @@ def _setSocketPreConnect():
family, type, proto, address = key family, type, proto, address = key
s = socket.socket(family, type, proto) s = socket.socket(family, type, proto)
s._connect(address) s._connect(address)
try:
if type == socket.SOCK_STREAM:
# Reference: https://www.techrepublic.com/article/tcp-ip-options-for-high-performance-data-transmission/
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
except:
pass
with kb.locks.socket: with kb.locks.socket:
socket._ready[key].append((s._sock, time.time())) socket._ready[key].append((s._sock, time.time()))
except KeyboardInterrupt: except KeyboardInterrupt:
@@ -1055,8 +966,8 @@ def _setHTTPHandlers():
logger.debug(debugMsg) logger.debug(debugMsg)
try: try:
_ = _urllib.parse.urlsplit(conf.proxy) _ = urlparse.urlsplit(conf.proxy)
except Exception as ex: except Exception, ex:
errMsg = "invalid proxy address '%s' ('%s')" % (conf.proxy, getSafeExString(ex)) errMsg = "invalid proxy address '%s' ('%s')" % (conf.proxy, getSafeExString(ex))
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
@@ -1091,14 +1002,10 @@ def _setHTTPHandlers():
if scheme in (PROXY_TYPE.SOCKS4, PROXY_TYPE.SOCKS5): if scheme in (PROXY_TYPE.SOCKS4, PROXY_TYPE.SOCKS5):
proxyHandler.proxies = {} proxyHandler.proxies = {}
if scheme == PROXY_TYPE.SOCKS4:
warnMsg = "SOCKS4 does not support resolving (DNS) names (i.e. causing DNS leakage)"
singleTimeWarnMessage(warnMsg)
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5 if scheme == PROXY_TYPE.SOCKS5 else socks.PROXY_TYPE_SOCKS4, hostname, port, username=username, password=password) socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5 if scheme == PROXY_TYPE.SOCKS5 else socks.PROXY_TYPE_SOCKS4, hostname, port, username=username, password=password)
socks.wrapmodule(_http_client) socks.wrapmodule(urllib2)
else: else:
socks.unwrapmodule(_http_client) socks.unwrapmodule(urllib2)
if conf.proxyCred: if conf.proxyCred:
# Reference: http://stackoverflow.com/questions/34079/how-to-specify-an-authenticated-proxy-for-a-python-http-connection # Reference: http://stackoverflow.com/questions/34079/how-to-specify-an-authenticated-proxy-for-a-python-http-connection
@@ -1114,16 +1021,16 @@ def _setHTTPHandlers():
debugMsg = "creating HTTP requests opener object" debugMsg = "creating HTTP requests opener object"
logger.debug(debugMsg) logger.debug(debugMsg)
handlers = filterNone([multipartPostHandler, proxyHandler if proxyHandler.proxies else None, authHandler, redirectHandler, rangeHandler, chunkedHandler if conf.chunked else None, httpsHandler]) handlers = filter(None, [multipartPostHandler, proxyHandler if proxyHandler.proxies else None, authHandler, redirectHandler, rangeHandler, httpsHandler])
if not conf.dropSetCookie: if not conf.dropSetCookie:
if not conf.loadCookies: if not conf.loadCookies:
conf.cj = _http_cookiejar.CookieJar() conf.cj = cookielib.CookieJar()
else: else:
conf.cj = _http_cookiejar.MozillaCookieJar() conf.cj = cookielib.MozillaCookieJar()
resetCookieJar(conf.cj) resetCookieJar(conf.cj)
handlers.append(_urllib.request.HTTPCookieProcessor(conf.cj)) handlers.append(urllib2.HTTPCookieProcessor(conf.cj))
# Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html # Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
if conf.keepAlive: if conf.keepAlive:
@@ -1139,8 +1046,8 @@ def _setHTTPHandlers():
else: else:
handlers.append(keepAliveHandler) handlers.append(keepAliveHandler)
opener = _urllib.request.build_opener(*handlers) opener = urllib2.build_opener(*handlers)
_urllib.request.install_opener(opener) urllib2.install_opener(opener)
def _setSafeVisit(): def _setSafeVisit():
""" """
@@ -1153,26 +1060,26 @@ def _setSafeVisit():
checkFile(conf.safeReqFile) checkFile(conf.safeReqFile)
raw = readCachedFileContent(conf.safeReqFile) raw = readCachedFileContent(conf.safeReqFile)
match = re.search(r"\A([A-Z]+) ([^ ]+) HTTP/[0-9.]+\Z", raw.split('\n')[0].strip()) match = re.search(r"\A([A-Z]+) ([^ ]+) HTTP/[0-9.]+\Z", raw[:raw.find('\n')])
if match: if match:
kb.safeReq.method = match.group(1) kb.safeReq.method = match.group(1)
kb.safeReq.url = match.group(2) kb.safeReq.url = match.group(2)
kb.safeReq.headers = {} kb.safeReq.headers = {}
for line in raw.split('\n')[1:]: for line in raw[raw.find('\n') + 1:].split('\n'):
line = line.strip() line = line.strip()
if line and ':' in line: if line and ':' in line:
key, value = line.split(':', 1) key, value = line.split(':', 1)
value = value.strip() value = value.strip()
kb.safeReq.headers[key] = value kb.safeReq.headers[key] = value
if key.upper() == HTTP_HEADER.HOST.upper(): if key == HTTP_HEADER.HOST:
if not value.startswith("http"): if not value.startswith("http"):
scheme = "http" scheme = "http"
if value.endswith(":443"): if value.endswith(":443"):
scheme = "https" scheme = "https"
value = "%s://%s" % (scheme, value) value = "%s://%s" % (scheme, value)
kb.safeReq.url = _urllib.parse.urljoin(value, kb.safeReq.url) kb.safeReq.url = urlparse.urljoin(value, kb.safeReq.url)
else: else:
break break
@@ -1281,7 +1188,7 @@ def _setHTTPAuthentication():
elif authType == AUTH_TYPE.NTLM: elif authType == AUTH_TYPE.NTLM:
regExp = "^(.*\\\\.*):(.*?)$" regExp = "^(.*\\\\.*):(.*?)$"
errMsg = "HTTP NTLM authentication credentials value must " errMsg = "HTTP NTLM authentication credentials value must "
errMsg += "be in format 'DOMAIN\\username:password'" errMsg += "be in format 'DOMAIN\username:password'"
elif authType == AUTH_TYPE.PKI: elif authType == AUTH_TYPE.PKI:
errMsg = "HTTP PKI authentication require " errMsg = "HTTP PKI authentication require "
errMsg += "usage of option `--auth-pki`" errMsg += "usage of option `--auth-pki`"
@@ -1295,7 +1202,7 @@ def _setHTTPAuthentication():
conf.authUsername = aCredRegExp.group(1) conf.authUsername = aCredRegExp.group(1)
conf.authPassword = aCredRegExp.group(2) conf.authPassword = aCredRegExp.group(2)
kb.passwordMgr = _urllib.request.HTTPPasswordMgrWithDefaultRealm() kb.passwordMgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
_setAuthCred() _setAuthCred()
@@ -1303,7 +1210,7 @@ def _setHTTPAuthentication():
authHandler = SmartHTTPBasicAuthHandler(kb.passwordMgr) authHandler = SmartHTTPBasicAuthHandler(kb.passwordMgr)
elif authType == AUTH_TYPE.DIGEST: elif authType == AUTH_TYPE.DIGEST:
authHandler = _urllib.request.HTTPDigestAuthHandler(kb.passwordMgr) authHandler = urllib2.HTTPDigestAuthHandler(kb.passwordMgr)
elif authType == AUTH_TYPE.NTLM: elif authType == AUTH_TYPE.NTLM:
try: try:
@@ -1351,6 +1258,14 @@ def _setHTTPExtraHeaders():
# Reference: http://stackoverflow.com/a/1383359 # Reference: http://stackoverflow.com/a/1383359
conf.httpHeaders.append((HTTP_HEADER.CACHE_CONTROL, "no-cache")) conf.httpHeaders.append((HTTP_HEADER.CACHE_CONTROL, "no-cache"))
def _defaultHTTPUserAgent():
"""
@return: default sqlmap HTTP User-Agent header
@rtype: C{str}
"""
return "%s (%s)" % (VERSION_STRING, SITE)
def _setHTTPUserAgent(): def _setHTTPUserAgent():
""" """
Set the HTTP User-Agent header. Set the HTTP User-Agent header.
@@ -1362,44 +1277,40 @@ def _setHTTPUserAgent():
file choosed as user option file choosed as user option
""" """
debugMsg = "setting the HTTP User-Agent header"
logger.debug(debugMsg)
if conf.mobile: if conf.mobile:
if conf.randomAgent: message = "which smartphone do you want sqlmap to imitate "
_ = random.sample([_[1] for _ in getPublicTypeMembers(MOBILES, True)], 1)[0] message += "through HTTP User-Agent header?\n"
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, _)) items = sorted(getPublicTypeMembers(MOBILES, True))
else:
message = "which smartphone do you want sqlmap to imitate "
message += "through HTTP User-Agent header?\n"
items = sorted(getPublicTypeMembers(MOBILES, True))
for count in xrange(len(items)): for count in xrange(len(items)):
item = items[count] item = items[count]
message += "[%d] %s%s\n" % (count + 1, item[0], " (default)" if item == MOBILES.IPHONE else "") message += "[%d] %s%s\n" % (count + 1, item[0], " (default)" if item == MOBILES.IPHONE else "")
test = readInput(message.rstrip('\n'), default=items.index(MOBILES.IPHONE) + 1) test = readInput(message.rstrip('\n'), default=items.index(MOBILES.IPHONE) + 1)
try: try:
item = items[int(test) - 1] item = items[int(test) - 1]
except: except:
item = MOBILES.IPHONE item = MOBILES.IPHONE
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, item[1])) conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, item[1]))
elif conf.agent: elif conf.agent:
debugMsg = "setting the HTTP User-Agent header"
logger.debug(debugMsg)
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, conf.agent)) conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, conf.agent))
elif not conf.randomAgent: elif not conf.randomAgent:
_ = True _ = True
for header, _ in conf.httpHeaders: for header, _ in conf.httpHeaders:
if header.upper() == HTTP_HEADER.USER_AGENT.upper(): if header == HTTP_HEADER.USER_AGENT:
_ = False _ = False
break break
if _: if _:
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, DEFAULT_USER_AGENT)) conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, _defaultHTTPUserAgent()))
else: else:
if not kb.userAgents: if not kb.userAgents:
@@ -1414,10 +1325,10 @@ def _setHTTPUserAgent():
warnMsg += "file '%s'" % paths.USER_AGENTS warnMsg += "file '%s'" % paths.USER_AGENTS
logger.warn(warnMsg) logger.warn(warnMsg)
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, DEFAULT_USER_AGENT)) conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, _defaultHTTPUserAgent()))
return return
userAgent = random.sample(kb.userAgents or [DEFAULT_USER_AGENT], 1)[0] userAgent = random.sample(kb.userAgents or [_defaultHTTPUserAgent()], 1)[0]
infoMsg = "fetched random HTTP User-Agent header value '%s' from " % userAgent infoMsg = "fetched random HTTP User-Agent header value '%s' from " % userAgent
infoMsg += "file '%s'" % paths.USER_AGENTS infoMsg += "file '%s'" % paths.USER_AGENTS
@@ -1458,19 +1369,6 @@ def _setHTTPCookies():
conf.httpHeaders.append((HTTP_HEADER.COOKIE, conf.cookie)) conf.httpHeaders.append((HTTP_HEADER.COOKIE, conf.cookie))
def _setHostname():
"""
Set value conf.hostname
"""
if conf.url:
try:
conf.hostname = _urllib.parse.urlsplit(conf.url).netloc.split(':')[0]
except ValueError as ex:
errMsg = "problem occurred while "
errMsg += "parsing an URL '%s' ('%s')" % (conf.url, getSafeExString(ex))
raise SqlmapDataException(errMsg)
def _setHTTPTimeout(): def _setHTTPTimeout():
""" """
Set the HTTP timeout Set the HTTP timeout
@@ -1501,41 +1399,6 @@ def _checkDependencies():
if conf.dependencies: if conf.dependencies:
checkDependencies() checkDependencies()
def _createHomeDirectories():
"""
Creates directories inside sqlmap's home directory
"""
for context in "output", "history":
directory = paths["SQLMAP_%s_PATH" % context.upper()]
try:
if not os.path.isdir(directory):
os.makedirs(directory)
_ = os.path.join(directory, randomStr())
open(_, "w+b").close()
os.remove(_)
if conf.outputDir and context == "output":
warnMsg = "using '%s' as the %s directory" % (directory, context)
logger.warn(warnMsg)
except (OSError, IOError) as ex:
try:
tempDir = tempfile.mkdtemp(prefix="sqlmap%s" % context)
except Exception as _:
errMsg = "unable to write to the temporary directory ('%s'). " % _
errMsg += "Please make sure that your disk is not full and "
errMsg += "that you have sufficient write permissions to "
errMsg += "create temporary files and/or directories"
raise SqlmapSystemException(errMsg)
warnMsg = "unable to %s %s directory " % ("create" if not os.path.isdir(directory) else "write to the", context)
warnMsg += "'%s' (%s). " % (directory, getUnicode(ex))
warnMsg += "Using temporary directory '%s' instead" % getUnicode(tempDir)
logger.warn(warnMsg)
paths["SQLMAP_%s_PATH" % context.upper()] = tempDir
def _createTemporaryDirectory(): def _createTemporaryDirectory():
""" """
Creates temporary directory for this run. Creates temporary directory for this run.
@@ -1555,7 +1418,7 @@ def _createTemporaryDirectory():
warnMsg = "using '%s' as the temporary directory" % conf.tmpDir warnMsg = "using '%s' as the temporary directory" % conf.tmpDir
logger.warn(warnMsg) logger.warn(warnMsg)
except (OSError, IOError) as ex: except (OSError, IOError), ex:
errMsg = "there has been a problem while accessing " errMsg = "there has been a problem while accessing "
errMsg += "temporary directory location(s) ('%s')" % getSafeExString(ex) errMsg += "temporary directory location(s) ('%s')" % getSafeExString(ex)
raise SqlmapSystemException(errMsg) raise SqlmapSystemException(errMsg)
@@ -1563,7 +1426,7 @@ def _createTemporaryDirectory():
try: try:
if not os.path.isdir(tempfile.gettempdir()): if not os.path.isdir(tempfile.gettempdir()):
os.makedirs(tempfile.gettempdir()) os.makedirs(tempfile.gettempdir())
except Exception as ex: except Exception, ex:
warnMsg = "there has been a problem while accessing " warnMsg = "there has been a problem while accessing "
warnMsg += "system's temporary directory location(s) ('%s'). Please " % getSafeExString(ex) warnMsg += "system's temporary directory location(s) ('%s'). Please " % getSafeExString(ex)
warnMsg += "make sure that there is enough disk space left. If problem persists, " warnMsg += "make sure that there is enough disk space left. If problem persists, "
@@ -1582,7 +1445,7 @@ def _createTemporaryDirectory():
if not os.path.isdir(tempfile.tempdir): if not os.path.isdir(tempfile.tempdir):
try: try:
os.makedirs(tempfile.tempdir) os.makedirs(tempfile.tempdir)
except Exception as ex: except Exception, ex:
errMsg = "there has been a problem while setting " errMsg = "there has been a problem while setting "
errMsg += "temporary directory location ('%s')" % getSafeExString(ex) errMsg += "temporary directory location ('%s')" % getSafeExString(ex)
raise SqlmapSystemException(errMsg) raise SqlmapSystemException(errMsg)
@@ -1625,8 +1488,11 @@ def _cleanupOptions():
else: else:
conf.rParam = [] conf.rParam = []
if conf.paramDel: if conf.paramDel and '\\' in conf.paramDel:
conf.paramDel = decodeStringEscape(conf.paramDel) try:
conf.paramDel = conf.paramDel.decode("string_escape")
except ValueError:
pass
if conf.skip: if conf.skip:
conf.skip = conf.skip.replace(" ", "") conf.skip = conf.skip.replace(" ", "")
@@ -1642,8 +1508,6 @@ def _cleanupOptions():
if conf.url: if conf.url:
conf.url = conf.url.strip() conf.url = conf.url.strip()
if not re.search(r"\A\w+://", conf.url):
conf.url = "http://%s" % conf.url
if conf.fileRead: if conf.fileRead:
conf.fileRead = ntToPosixSlashes(normalizePath(conf.fileRead)) conf.fileRead = ntToPosixSlashes(normalizePath(conf.fileRead))
@@ -1669,6 +1533,14 @@ def _cleanupOptions():
if conf.optimize: if conf.optimize:
setOptimize() setOptimize()
match = re.search(INJECT_HERE_REGEX, conf.data or "")
if match:
kb.customInjectionMark = match.group(0)
match = re.search(INJECT_HERE_REGEX, conf.url or "")
if match:
kb.customInjectionMark = match.group(0)
if conf.os: if conf.os:
conf.os = conf.os.capitalize() conf.os = conf.os.capitalize()
@@ -1693,23 +1565,6 @@ def _cleanupOptions():
except re.error: except re.error:
conf.testFilter = re.escape(conf.testFilter) conf.testFilter = re.escape(conf.testFilter)
if conf.csrfToken:
original = conf.csrfToken
try:
re.compile(conf.csrfToken)
if re.escape(conf.csrfToken) != conf.csrfToken:
message = "provided value for option '--csrf-token' is a regular expression? [y/N] "
if not readInput(message, default='N', boolean=True):
conf.csrfToken = re.escape(conf.csrfToken)
except re.error:
conf.csrfToken = re.escape(conf.csrfToken)
finally:
class _(unicode):
pass
conf.csrfToken = _(conf.csrfToken)
conf.csrfToken._original = original
if conf.testSkip: if conf.testSkip:
conf.testSkip = conf.testSkip.strip('*+') conf.testSkip = conf.testSkip.strip('*+')
conf.testSkip = re.sub(r"([^.])([*+])", r"\g<1>.\g<2>", conf.testSkip) conf.testSkip = re.sub(r"([^.])([*+])", r"\g<1>.\g<2>", conf.testSkip)
@@ -1738,9 +1593,9 @@ def _cleanupOptions():
conf.code = int(conf.code) conf.code = int(conf.code)
if conf.csvDel: if conf.csvDel:
conf.csvDel = decodeStringEscape(conf.csvDel) conf.csvDel = conf.csvDel.decode("string_escape") # e.g. '\\t' -> '\t'
if conf.torPort and hasattr(conf.torPort, "isdigit") and conf.torPort.isdigit(): if conf.torPort and isinstance(conf.torPort, basestring) and conf.torPort.isdigit():
conf.torPort = int(conf.torPort) conf.torPort = int(conf.torPort)
if conf.torType: if conf.torType:
@@ -1751,13 +1606,18 @@ def _cleanupOptions():
setPaths(paths.SQLMAP_ROOT_PATH) setPaths(paths.SQLMAP_ROOT_PATH)
if conf.string: if conf.string:
conf.string = decodeStringEscape(conf.string) try:
conf.string = conf.string.decode("unicode_escape")
except:
charset = string.whitespace.replace(" ", "")
for _ in charset:
conf.string = conf.string.replace(_.encode("string_escape"), _)
if conf.getAll: if conf.getAll:
map(lambda _: conf.__setitem__(_, True), WIZARD.ALL) map(lambda _: conf.__setitem__(_, True), WIZARD.ALL)
if conf.noCast: if conf.noCast:
for _ in list(DUMP_REPLACEMENTS.keys()): for _ in DUMP_REPLACEMENTS.keys():
del DUMP_REPLACEMENTS[_] del DUMP_REPLACEMENTS[_]
if conf.dumpFormat: if conf.dumpFormat:
@@ -1789,8 +1649,8 @@ def _cleanupEnvironment():
Cleanup environment (e.g. from leftovers after --sqlmap-shell). Cleanup environment (e.g. from leftovers after --sqlmap-shell).
""" """
if issubclass(_http_client.socket.socket, socks.socksocket): if issubclass(urllib2.socket.socket, socks.socksocket):
socks.unwrapmodule(_http_client) socks.unwrapmodule(urllib2)
if hasattr(socket, "_ready"): if hasattr(socket, "_ready"):
socket._ready.clear() socket._ready.clear()
@@ -1887,7 +1747,6 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.connErrorChoice = None kb.connErrorChoice = None
kb.connErrorCounter = 0 kb.connErrorCounter = 0
kb.cookieEncodeChoice = None kb.cookieEncodeChoice = None
kb.copyExecTest = None
kb.counters = {} kb.counters = {}
kb.customInjectionMark = CUSTOM_INJECTION_MARK_CHAR kb.customInjectionMark = CUSTOM_INJECTION_MARK_CHAR
kb.data = AttribDict() kb.data = AttribDict()
@@ -1947,6 +1806,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.matchRatio = None kb.matchRatio = None
kb.maxConnectionsFlag = False kb.maxConnectionsFlag = False
kb.mergeCookies = None kb.mergeCookies = None
kb.multiThreadMode = False
kb.negativeLogic = False kb.negativeLogic = False
kb.nullConnection = None kb.nullConnection = None
kb.oldMsf = None kb.oldMsf = None
@@ -1999,6 +1859,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.reduceTests = None kb.reduceTests = None
kb.tlsSNI = {} kb.tlsSNI = {}
kb.stickyDBMS = False kb.stickyDBMS = False
kb.stickyLevel = None
kb.storeCrawlingChoice = None kb.storeCrawlingChoice = None
kb.storeHashesChoice = None kb.storeHashesChoice = None
kb.suppressResumeInfo = False kb.suppressResumeInfo = False
@@ -2022,10 +1883,9 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.headerPaths = {} kb.headerPaths = {}
kb.keywords = set(getFileItems(paths.SQL_KEYWORDS)) kb.keywords = set(getFileItems(paths.SQL_KEYWORDS))
kb.passwordMgr = None kb.passwordMgr = None
kb.preprocessFunctions = []
kb.skipVulnHost = None kb.skipVulnHost = None
kb.tamperFunctions = [] kb.tamperFunctions = []
kb.targets = OrderedSet() kb.targets = oset()
kb.testedParams = set() kb.testedParams = set()
kb.userAgents = None kb.userAgents = None
kb.vainRun = True kb.vainRun = True
@@ -2253,9 +2113,9 @@ def _setDNSServer():
try: try:
conf.dnsServer = DNSServer() conf.dnsServer = DNSServer()
conf.dnsServer.run() conf.dnsServer.run()
except socket.error as ex: except socket.error, msg:
errMsg = "there was an error while setting up " errMsg = "there was an error while setting up "
errMsg += "DNS server instance ('%s')" % getSafeExString(ex) errMsg += "DNS server instance ('%s')" % msg
raise SqlmapGenericException(errMsg) raise SqlmapGenericException(errMsg)
else: else:
errMsg = "you need to run sqlmap as an administrator " errMsg = "you need to run sqlmap as an administrator "
@@ -2318,11 +2178,7 @@ def _setTorSocksProxySettings():
# SOCKS5 to prevent DNS leaks (http://en.wikipedia.org/wiki/Tor_%28anonymity_network%29) # SOCKS5 to prevent DNS leaks (http://en.wikipedia.org/wiki/Tor_%28anonymity_network%29)
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5 if conf.torType == PROXY_TYPE.SOCKS5 else socks.PROXY_TYPE_SOCKS4, LOCALHOST, port) socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5 if conf.torType == PROXY_TYPE.SOCKS5 else socks.PROXY_TYPE_SOCKS4, LOCALHOST, port)
socks.wrapmodule(_http_client) socks.wrapmodule(urllib2)
def _setHttpChunked():
if conf.chunked and conf.data:
_http_client.HTTPConnection._set_content_length = lambda self, a, b: None
def _checkWebSocket(): def _checkWebSocket():
if conf.url and (conf.url.startswith("ws:/") or conf.url.startswith("wss:/")): if conf.url and (conf.url.startswith("ws:/") or conf.url.startswith("wss:/")):
@@ -2395,10 +2251,6 @@ def _basicOptionValidation():
errMsg = "option '-d' is incompatible with option '-u' ('--url')" errMsg = "option '-d' is incompatible with option '-u' ('--url')"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if conf.direct and conf.dbms:
errMsg = "option '-d' is incompatible with option '--dbms'"
raise SqlmapSyntaxException(errMsg)
if conf.identifyWaf and conf.skipWaf: if conf.identifyWaf and conf.skipWaf:
errMsg = "switch '--identify-waf' is incompatible with switch '--skip-waf'" errMsg = "switch '--identify-waf' is incompatible with switch '--skip-waf'"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
@@ -2411,10 +2263,6 @@ def _basicOptionValidation():
errMsg = "switch '--dump' is incompatible with switch '--search'" errMsg = "switch '--dump' is incompatible with switch '--search'"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if conf.chunked and not any((conf.data, conf.requestFile, conf.forms)):
errMsg = "switch '--chunked' requires usage of (POST) options/switches '--data', '-r' or '--forms'"
raise SqlmapSyntaxException(errMsg)
if conf.api and not conf.configFile: if conf.api and not conf.configFile:
errMsg = "switch '--api' requires usage of option '-c'" errMsg = "switch '--api' requires usage of option '-c'"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
@@ -2431,7 +2279,7 @@ def _basicOptionValidation():
errMsg = "option '--not-string' is incompatible with switch '--null-connection'" errMsg = "option '--not-string' is incompatible with switch '--null-connection'"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if conf.tor and conf.osPwn: if conf.notString and conf.nullConnection:
errMsg = "option '--tor' is incompatible with switch '--os-pwn'" errMsg = "option '--tor' is incompatible with switch '--os-pwn'"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
@@ -2454,14 +2302,14 @@ def _basicOptionValidation():
if conf.regexp: if conf.regexp:
try: try:
re.compile(conf.regexp) re.compile(conf.regexp)
except Exception as ex: except Exception, ex:
errMsg = "invalid regular expression '%s' ('%s')" % (conf.regexp, getSafeExString(ex)) errMsg = "invalid regular expression '%s' ('%s')" % (conf.regexp, getSafeExString(ex))
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if conf.crawlExclude: if conf.crawlExclude:
try: try:
re.compile(conf.crawlExclude) re.compile(conf.crawlExclude)
except Exception as ex: except Exception, ex:
errMsg = "invalid regular expression '%s' ('%s')" % (conf.crawlExclude, getSafeExString(ex)) errMsg = "invalid regular expression '%s' ('%s')" % (conf.crawlExclude, getSafeExString(ex))
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
@@ -2550,14 +2398,8 @@ def _basicOptionValidation():
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if conf.skip and conf.testParameter: if conf.skip and conf.testParameter:
if intersect(conf.skip, conf.testParameter): errMsg = "option '--skip' is incompatible with option '-p'"
errMsg = "option '--skip' is incompatible with option '-p'" raise SqlmapSyntaxException(errMsg)
raise SqlmapSyntaxException(errMsg)
if conf.rParam and conf.testParameter:
if intersect(conf.rParam, conf.testParameter):
errMsg = "option '--randomize' is incompatible with option '-p'"
raise SqlmapSyntaxException(errMsg)
if conf.mobile and conf.agent: if conf.mobile and conf.agent:
errMsg = "switch '--mobile' is incompatible with option '--user-agent'" errMsg = "switch '--mobile' is incompatible with option '--user-agent'"
@@ -2575,11 +2417,7 @@ def _basicOptionValidation():
errMsg = "value for option '--union-char' must be an alpha-numeric value (e.g. 1)" errMsg = "value for option '--union-char' must be an alpha-numeric value (e.g. 1)"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if conf.hashFile and any((conf.direct, conf.url, conf.logFile, conf.bulkFile, conf.googleDork, conf.configFile, conf.requestFile, conf.updateAll, conf.smokeTest, conf.liveTest, conf.wizard, conf.dependencies, conf.purge, conf.sitemapUrl, conf.listTampers)): if isinstance(conf.uCols, basestring):
errMsg = "option '--crack' should be used as a standalone"
raise SqlmapSyntaxException(errMsg)
if isinstance(conf.uCols, six.string_types):
if not conf.uCols.isdigit() and ("-" not in conf.uCols or len(conf.uCols.split("-")) != 2): if not conf.uCols.isdigit() and ("-" not in conf.uCols or len(conf.uCols.split("-")) != 2):
errMsg = "value for option '--union-cols' must be a range with hyphon " errMsg = "value for option '--union-cols' must be a range with hyphon "
errMsg += "(e.g. 1-10) or integer value (e.g. 5)" errMsg += "(e.g. 1-10) or integer value (e.g. 5)"
@@ -2633,7 +2471,6 @@ def init():
_cleanupEnvironment() _cleanupEnvironment()
_purge() _purge()
_checkDependencies() _checkDependencies()
_createHomeDirectories()
_createTemporaryDirectory() _createTemporaryDirectory()
_basicOptionValidation() _basicOptionValidation()
_setProxyList() _setProxyList()
@@ -2643,18 +2480,16 @@ def init():
_setMultipleTargets() _setMultipleTargets()
_listTamperingFunctions() _listTamperingFunctions()
_setTamperingFunctions() _setTamperingFunctions()
_setPreprocessFunctions()
_setWafFunctions() _setWafFunctions()
_setTrafficOutputFP() _setTrafficOutputFP()
_setupHTTPCollector() _setupHTTPCollector()
_resolveCrossReferences() _resolveCrossReferences()
_setHttpChunked()
_checkWebSocket() _checkWebSocket()
parseTargetUrl()
parseTargetDirect() parseTargetDirect()
if any((conf.url, conf.logFile, conf.bulkFile, conf.sitemapUrl, conf.requestFile, conf.googleDork, conf.liveTest)): if any((conf.url, conf.logFile, conf.bulkFile, conf.sitemapUrl, conf.requestFile, conf.googleDork, conf.liveTest)):
_setHostname()
_setHTTPTimeout() _setHTTPTimeout()
_setHTTPExtraHeaders() _setHTTPExtraHeaders()
_setHTTPCookies() _setHTTPCookies()
+3 -5
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -61,7 +61,6 @@ optDict = {
"csrfToken": "string", "csrfToken": "string",
"csrfUrl": "string", "csrfUrl": "string",
"forceSSL": "boolean", "forceSSL": "boolean",
"chunked": "boolean",
"hpp": "boolean", "hpp": "boolean",
"evalCode": "string", "evalCode": "string",
}, },
@@ -193,6 +192,7 @@ optDict = {
}, },
"General": { "General": {
# "xmlFile": "string",
"trafficFile": "string", "trafficFile": "string",
"batch": "boolean", "batch": "boolean",
"binaryFields": "string", "binaryFields": "string",
@@ -211,8 +211,6 @@ optDict = {
"hexConvert": "boolean", "hexConvert": "boolean",
"outputDir": "string", "outputDir": "string",
"parseErrors": "boolean", "parseErrors": "boolean",
"preprocess": "string",
"repair": "boolean",
"saveConfig": "string", "saveConfig": "string",
"scope": "string", "scope": "string",
"testFilter": "string", "testFilter": "string",
+4 -12
View File
@@ -1,14 +1,14 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import codecs import codecs
import httplib
from lib.core.settings import IS_WIN from lib.core.settings import IS_WIN
from thirdparty.six.moves import http_client as _http_client
def dirtyPatches(): def dirtyPatches():
""" """
@@ -16,7 +16,7 @@ def dirtyPatches():
""" """
# accept overly long result lines (e.g. SQLi results in HTTP header responses) # accept overly long result lines (e.g. SQLi results in HTTP header responses)
_http_client._MAXLINE = 1 * 1024 * 1024 httplib._MAXLINE = 1 * 1024 * 1024
# add support for inet_pton() on Windows OS # add support for inet_pton() on Windows OS
if IS_WIN: if IS_WIN:
@@ -24,11 +24,3 @@ def dirtyPatches():
# Reference: https://github.com/nodejs/node/issues/12786#issuecomment-298652440 # Reference: https://github.com/nodejs/node/issues/12786#issuecomment-298652440
codecs.register(lambda name: codecs.lookup("utf-8") if name == "cp65001" else None) codecs.register(lambda name: codecs.lookup("utf-8") if name == "cp65001" else None)
# Reference: http://bugs.python.org/issue17849
if hasattr(_http_client, "LineAndFileWrapper"):
def _(self, *args):
return self._readline()
_http_client.LineAndFileWrapper._readline = _http_client.LineAndFileWrapper.readline
_http_client.LineAndFileWrapper.readline = _
+5 -5
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -9,7 +9,7 @@ import codecs
import os import os
import cProfile import cProfile
from lib.core.common import getSafeExString from lib.core.common import getUnicode
from lib.core.data import logger from lib.core.data import logger
from lib.core.data import paths from lib.core.data import paths
from lib.core.settings import UNICODE_ENCODING from lib.core.settings import UNICODE_ENCODING
@@ -25,8 +25,8 @@ def profile(profileOutputFile=None, dotOutputFile=None, imageOutputFile=None):
from thirdparty.xdot import xdot from thirdparty.xdot import xdot
import gtk import gtk
import pydot import pydot
except ImportError as ex: except ImportError, e:
errMsg = "profiling requires third-party libraries ('%s') " % getSafeExString(ex) errMsg = "profiling requires third-party libraries ('%s') " % getUnicode(e, UNICODE_ENCODING)
errMsg += "(Hint: 'sudo apt-get install python-pydot python-pyparsing python-profiler graphviz')" errMsg += "(Hint: 'sudo apt-get install python-pydot python-pyparsing python-profiler graphviz')"
logger.error(errMsg) logger.error(errMsg)
+5 -3
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -56,7 +56,9 @@ if PLATFORM == 'mac' and _readline:
# http://mail.python.org/pipermail/python-dev/2003-August/037845.html # http://mail.python.org/pipermail/python-dev/2003-August/037845.html
# has the original discussion. # has the original discussion.
if _readline: if _readline:
if not hasattr(_readline, "clear_history"): try:
_readline.clear_history()
except AttributeError:
def clear_history(): def clear_history():
pass pass
+5 -5
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -27,7 +27,7 @@ class Replication(object):
self.connection = sqlite3.connect(dbpath) self.connection = sqlite3.connect(dbpath)
self.connection.isolation_level = None self.connection.isolation_level = None
self.cursor = self.connection.cursor() self.cursor = self.connection.cursor()
except sqlite3.OperationalError as ex: except sqlite3.OperationalError, ex:
errMsg = "error occurred while opening a replication " errMsg = "error occurred while opening a replication "
errMsg += "file '%s' ('%s')" % (self.filepath, getSafeExString(ex)) errMsg += "file '%s' ('%s')" % (self.filepath, getSafeExString(ex))
raise SqlmapConnectionException(errMsg) raise SqlmapConnectionException(errMsg)
@@ -63,7 +63,7 @@ class Replication(object):
self.execute('CREATE TABLE "%s" (%s)' % (self.name, ','.join('"%s" %s' % (unsafeSQLIdentificatorNaming(colname), coltype) for colname, coltype in self.columns))) self.execute('CREATE TABLE "%s" (%s)' % (self.name, ','.join('"%s" %s' % (unsafeSQLIdentificatorNaming(colname), coltype) for colname, coltype in self.columns)))
else: else:
self.execute('CREATE TABLE "%s" (%s)' % (self.name, ','.join('"%s"' % unsafeSQLIdentificatorNaming(colname) for colname in self.columns))) self.execute('CREATE TABLE "%s" (%s)' % (self.name, ','.join('"%s"' % unsafeSQLIdentificatorNaming(colname) for colname in self.columns)))
except Exception as ex: except Exception, ex:
errMsg = "problem occurred ('%s') while initializing the sqlite database " % getSafeExString(ex, UNICODE_ENCODING) errMsg = "problem occurred ('%s') while initializing the sqlite database " % getSafeExString(ex, UNICODE_ENCODING)
errMsg += "located at '%s'" % self.parent.dbpath errMsg += "located at '%s'" % self.parent.dbpath
raise SqlmapGenericException(errMsg) raise SqlmapGenericException(errMsg)
@@ -82,7 +82,7 @@ class Replication(object):
def execute(self, sql, parameters=[]): def execute(self, sql, parameters=[]):
try: try:
self.parent.cursor.execute(sql, parameters) self.parent.cursor.execute(sql, parameters)
except sqlite3.OperationalError as ex: except sqlite3.OperationalError, ex:
errMsg = "problem occurred ('%s') while accessing sqlite database " % getSafeExString(ex, UNICODE_ENCODING) errMsg = "problem occurred ('%s') while accessing sqlite database " % getSafeExString(ex, UNICODE_ENCODING)
errMsg += "located at '%s'. Please make sure that " % self.parent.dbpath errMsg += "located at '%s'. Please make sure that " % self.parent.dbpath
errMsg += "it's not used by some other program" errMsg += "it's not used by some other program"
+6 -9
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -44,12 +44,9 @@ def getRevisionNumber():
break break
if not retVal: if not retVal:
try: process = subprocess.Popen("git rev-parse --verify HEAD", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
process = subprocess.Popen("git rev-parse --verify HEAD", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, _ = process.communicate()
stdout, _ = process.communicate() match = re.search(r"(?i)[0-9a-f]{32}", stdout or "")
match = re.search(r"(?i)[0-9a-f]{32}", stdout or "") retVal = match.group(0) if match else None
retVal = match.group(0) if match else None
except:
pass
return retVal[:7] if retVal else None return retVal[:7] if retVal else None
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+37 -62
View File
@@ -1,29 +1,30 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import codecs
import os import os
import random import random
import re import re
import subprocess
import string import string
import sys import sys
import types
from lib.core.datatype import AttribDict
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import DBMS_DIRECTORY_NAME from lib.core.enums import DBMS_DIRECTORY_NAME
from lib.core.enums import OS from lib.core.enums import OS
# sqlmap version (<major>.<minor>.<month>.<monthly commit>) # sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.3.4.0" VERSION = "1.2.10.0"
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE) VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
DESCRIPTION = "automatic SQL injection and database takeover tool" DESCRIPTION = "automatic SQL injection and database takeover tool"
SITE = "http://sqlmap.org" SITE = "http://sqlmap.org"
DEFAULT_USER_AGENT = "%s (%s)" % (VERSION_STRING, SITE)
DEV_EMAIL_ADDRESS = "[email protected]" DEV_EMAIL_ADDRESS = "[email protected]"
ISSUES_PAGE = "https://github.com/sqlmapproject/sqlmap/issues/new" ISSUES_PAGE = "https://github.com/sqlmapproject/sqlmap/issues/new"
GIT_REPOSITORY = "https://github.com/sqlmapproject/sqlmap.git" GIT_REPOSITORY = "https://github.com/sqlmapproject/sqlmap.git"
@@ -37,7 +38,7 @@ BANNER = """\033[01;33m\
___ ___[.]_____ ___ ___ \033[01;37m{\033[01;%dm%s\033[01;37m}\033[01;33m ___ ___[.]_____ ___ ___ \033[01;37m{\033[01;%dm%s\033[01;37m}\033[01;33m
|_ -| . [.] | .'| . | |_ -| . [.] | .'| . |
|___|_ [.]_|_|_|__,| _| |___|_ [.]_|_|_|__,| _|
|_|V... |_| \033[0m\033[4;37m%s\033[0m\n |_|V |_| \033[0m\033[4;37m%s\033[0m\n
""" % (TYPE_COLORS.get(TYPE, 31), VERSION_STRING.split('/')[-1], SITE) """ % (TYPE_COLORS.get(TYPE, 31), VERSION_STRING.split('/')[-1], SITE)
# Minimum distance of ratio from kb.matchRatio to result in True # Minimum distance of ratio from kb.matchRatio to result in True
@@ -70,7 +71,6 @@ RANDOM_INTEGER_MARKER = "[RANDINT]"
RANDOM_STRING_MARKER = "[RANDSTR]" RANDOM_STRING_MARKER = "[RANDSTR]"
SLEEP_TIME_MARKER = "[SLEEPTIME]" SLEEP_TIME_MARKER = "[SLEEPTIME]"
INFERENCE_MARKER = "[INFERENCE]" INFERENCE_MARKER = "[INFERENCE]"
SINGLE_QUOTE_MARKER = "[SINGLE_QUOTE]"
PAYLOAD_DELIMITER = "__PAYLOAD_DELIMITER__" PAYLOAD_DELIMITER = "__PAYLOAD_DELIMITER__"
CHAR_INFERENCE_MARK = "%c" CHAR_INFERENCE_MARK = "%c"
@@ -98,7 +98,7 @@ MAX_CONSECUTIVE_CONNECTION_ERRORS = 15
PRECONNECT_CANDIDATE_TIMEOUT = 10 PRECONNECT_CANDIDATE_TIMEOUT = 10
# Servers known to cause issue with pre-connection mechanism (because of lack of multi-threaded support) # Servers known to cause issue with pre-connection mechanism (because of lack of multi-threaded support)
PRECONNECT_INCOMPATIBLE_SERVERS = ("SimpleHTTP", "BaseHTTP") PRECONNECT_INCOMPATIBLE_SERVERS = ("SimpleHTTP",)
# Maximum sleep time in "Murphy" (testing) mode # Maximum sleep time in "Murphy" (testing) mode
MAX_MURPHY_SLEEP_TIME = 3 MAX_MURPHY_SLEEP_TIME = 3
@@ -107,7 +107,7 @@ MAX_MURPHY_SLEEP_TIME = 3
GOOGLE_REGEX = r"webcache\.googleusercontent\.com/search\?q=cache:[^:]+:([^+]+)\+&amp;cd=|url\?\w+=((?![^>]+webcache\.googleusercontent\.com)http[^>]+)&(sa=U|rct=j)" GOOGLE_REGEX = r"webcache\.googleusercontent\.com/search\?q=cache:[^:]+:([^+]+)\+&amp;cd=|url\?\w+=((?![^>]+webcache\.googleusercontent\.com)http[^>]+)&(sa=U|rct=j)"
# Regular expression used for extracting results from DuckDuckGo search # Regular expression used for extracting results from DuckDuckGo search
DUCKDUCKGO_REGEX = r'<a class="result__url" href="(htt[^"]+)' DUCKDUCKGO_REGEX = r'"u":"([^"]+)'
# Regular expression used for extracting results from Bing search # Regular expression used for extracting results from Bing search
BING_REGEX = r'<h2><a href="([^"]+)" h=' BING_REGEX = r'<h2><a href="([^"]+)" h='
@@ -164,9 +164,6 @@ MAX_TECHNIQUES_PER_VALUE = 2
# In case of missing piece of partial union dump, buffered array must be flushed after certain size # In case of missing piece of partial union dump, buffered array must be flushed after certain size
MAX_BUFFERED_PARTIAL_UNION_LENGTH = 1024 MAX_BUFFERED_PARTIAL_UNION_LENGTH = 1024
# Maximum size of cache used in @cachedmethod decorator
MAX_CACHE_ITEMS = 256
# Suffix used for naming meta databases in DBMS(es) without explicit database name # Suffix used for naming meta databases in DBMS(es) without explicit database name
METADB_SUFFIX = "_masterdb" METADB_SUFFIX = "_masterdb"
@@ -176,14 +173,11 @@ PUSH_VALUE_EXCEPTION_RETRY_COUNT = 3
# Minimum time response set needed for time-comparison based on standard deviation # Minimum time response set needed for time-comparison based on standard deviation
MIN_TIME_RESPONSES = 30 MIN_TIME_RESPONSES = 30
# Maximum time response set used during time-comparison based on standard deviation
MAX_TIME_RESPONSES = 200
# Minimum comparison ratio set needed for searching valid union column number based on standard deviation # Minimum comparison ratio set needed for searching valid union column number based on standard deviation
MIN_UNION_RESPONSES = 5 MIN_UNION_RESPONSES = 5
# After these number of blanks at the end inference should stop (just in case) # After these number of blanks at the end inference should stop (just in case)
INFERENCE_BLANK_BREAK = 5 INFERENCE_BLANK_BREAK = 10
# Use this replacement character for cases when inference is not able to retrieve the proper character value # Use this replacement character for cases when inference is not able to retrieve the proper character value
INFERENCE_UNKNOWN_CHAR = '?' INFERENCE_UNKNOWN_CHAR = '?'
@@ -216,24 +210,23 @@ DUMMY_USER_PREFIX = "__dummy__"
DEFAULT_PAGE_ENCODING = "iso-8859-1" DEFAULT_PAGE_ENCODING = "iso-8859-1"
try: try:
codecs.lookup(DEFAULT_PAGE_ENCODING) unicode(DEFAULT_PAGE_ENCODING, DEFAULT_PAGE_ENCODING)
except LookupError: except LookupError:
DEFAULT_PAGE_ENCODING = "utf8" DEFAULT_PAGE_ENCODING = "utf8"
# Marker for program piped input
STDIN_PIPE_DASH = '-'
# URL used in dummy runs # URL used in dummy runs
DUMMY_URL = "http://foo/bar?id=1" DUMMY_URL = "http://foo/bar?id=1"
# System variables
IS_WIN = subprocess.mswindows
# The name of the operating system dependent module imported. The following names have currently been registered: 'posix', 'nt', 'mac', 'os2', 'ce', 'java', 'riscos' # The name of the operating system dependent module imported. The following names have currently been registered: 'posix', 'nt', 'mac', 'os2', 'ce', 'java', 'riscos'
PLATFORM = os.name PLATFORM = os.name
PYVERSION = sys.version.split()[0] PYVERSION = sys.version.split()[0]
IS_WIN = PLATFORM == "nt"
# DBMS system databases # DBMS system databases
MSSQL_SYSTEM_DBS = ("Northwind", "master", "model", "msdb", "pubs", "tempdb") MSSQL_SYSTEM_DBS = ("Northwind", "master", "model", "msdb", "pubs", "tempdb")
MYSQL_SYSTEM_DBS = ("information_schema", "mysql", "performance_schema", "sys") MYSQL_SYSTEM_DBS = ("information_schema", "mysql", "performance_schema")
PGSQL_SYSTEM_DBS = ("information_schema", "pg_catalog", "pg_toast", "pgagent") PGSQL_SYSTEM_DBS = ("information_schema", "pg_catalog", "pg_toast", "pgagent")
ORACLE_SYSTEM_DBS = ('ANONYMOUS', 'APEX_030200', 'APEX_PUBLIC_USER', 'APPQOSSYS', 'BI', 'CTXSYS', 'DBSNMP', 'DIP', 'EXFSYS', 'FLOWS_%', 'FLOWS_FILES', 'HR', 'IX', 'LBACSYS', 'MDDATA', 'MDSYS', 'MGMT_VIEW', 'OC', 'OE', 'OLAPSYS', 'ORACLE_OCM', 'ORDDATA', 'ORDPLUGINS', 'ORDSYS', 'OUTLN', 'OWBSYS', 'PM', 'SCOTT', 'SH', 'SI_INFORMTN_SCHEMA', 'SPATIAL_CSW_ADMIN_USR', 'SPATIAL_WFS_ADMIN_USR', 'SYS', 'SYSMAN', 'SYSTEM', 'WKPROXY', 'WKSYS', 'WK_TEST', 'WMSYS', 'XDB', 'XS$NULL') ORACLE_SYSTEM_DBS = ('ANONYMOUS', 'APEX_030200', 'APEX_PUBLIC_USER', 'APPQOSSYS', 'BI', 'CTXSYS', 'DBSNMP', 'DIP', 'EXFSYS', 'FLOWS_%', 'FLOWS_FILES', 'HR', 'IX', 'LBACSYS', 'MDDATA', 'MDSYS', 'MGMT_VIEW', 'OC', 'OE', 'OLAPSYS', 'ORACLE_OCM', 'ORDDATA', 'ORDPLUGINS', 'ORDSYS', 'OUTLN', 'OWBSYS', 'PM', 'SCOTT', 'SH', 'SI_INFORMTN_SCHEMA', 'SPATIAL_CSW_ADMIN_USR', 'SPATIAL_WFS_ADMIN_USR', 'SYS', 'SYSMAN', 'SYSTEM', 'WKPROXY', 'WKSYS', 'WK_TEST', 'WMSYS', 'XDB', 'XS$NULL')
SQLITE_SYSTEM_DBS = ("sqlite_master", "sqlite_temp_master") SQLITE_SYSTEM_DBS = ("sqlite_master", "sqlite_temp_master")
@@ -243,7 +236,6 @@ MAXDB_SYSTEM_DBS = ("SYSINFO", "DOMAIN")
SYBASE_SYSTEM_DBS = ("master", "model", "sybsystemdb", "sybsystemprocs") SYBASE_SYSTEM_DBS = ("master", "model", "sybsystemdb", "sybsystemprocs")
DB2_SYSTEM_DBS = ("NULLID", "SQLJ", "SYSCAT", "SYSFUN", "SYSIBM", "SYSIBMADM", "SYSIBMINTERNAL", "SYSIBMTS", "SYSPROC", "SYSPUBLIC", "SYSSTAT", "SYSTOOLS") DB2_SYSTEM_DBS = ("NULLID", "SQLJ", "SYSCAT", "SYSFUN", "SYSIBM", "SYSIBMADM", "SYSIBMINTERNAL", "SYSIBMTS", "SYSPROC", "SYSPUBLIC", "SYSSTAT", "SYSTOOLS")
HSQLDB_SYSTEM_DBS = ("INFORMATION_SCHEMA", "SYSTEM_LOB") HSQLDB_SYSTEM_DBS = ("INFORMATION_SCHEMA", "SYSTEM_LOB")
H2_SYSTEM_DBS = ("INFORMATION_SCHEMA")
INFORMIX_SYSTEM_DBS = ("sysmaster", "sysutils", "sysuser", "sysadmin") INFORMIX_SYSTEM_DBS = ("sysmaster", "sysutils", "sysuser", "sysadmin")
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms") MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
@@ -257,21 +249,20 @@ MAXDB_ALIASES = ("maxdb", "sap maxdb", "sap db")
SYBASE_ALIASES = ("sybase", "sybase sql server") SYBASE_ALIASES = ("sybase", "sybase sql server")
DB2_ALIASES = ("db2", "ibm db2", "ibmdb2") DB2_ALIASES = ("db2", "ibm db2", "ibmdb2")
HSQLDB_ALIASES = ("hsql", "hsqldb", "hs", "hypersql") HSQLDB_ALIASES = ("hsql", "hsqldb", "hs", "hypersql")
H2_ALIASES = ("h2",)
INFORMIX_ALIASES = ("informix", "ibm informix", "ibminformix") INFORMIX_ALIASES = ("informix", "ibm informix", "ibminformix")
DBMS_DIRECTORY_DICT = dict((getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_")) DBMS_DIRECTORY_DICT = dict((getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_"))
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + H2_ALIASES + INFORMIX_ALIASES SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + INFORMIX_ALIASES
SUPPORTED_OS = ("linux", "windows") SUPPORTED_OS = ("linux", "windows")
DBMS_ALIASES = ((DBMS.MSSQL, MSSQL_ALIASES), (DBMS.MYSQL, MYSQL_ALIASES), (DBMS.PGSQL, PGSQL_ALIASES), (DBMS.ORACLE, ORACLE_ALIASES), (DBMS.SQLITE, SQLITE_ALIASES), (DBMS.ACCESS, ACCESS_ALIASES), (DBMS.FIREBIRD, FIREBIRD_ALIASES), (DBMS.MAXDB, MAXDB_ALIASES), (DBMS.SYBASE, SYBASE_ALIASES), (DBMS.DB2, DB2_ALIASES), (DBMS.HSQLDB, HSQLDB_ALIASES), (DBMS.H2, H2_ALIASES), (DBMS.INFORMIX, INFORMIX_ALIASES)) DBMS_ALIASES = ((DBMS.MSSQL, MSSQL_ALIASES), (DBMS.MYSQL, MYSQL_ALIASES), (DBMS.PGSQL, PGSQL_ALIASES), (DBMS.ORACLE, ORACLE_ALIASES), (DBMS.SQLITE, SQLITE_ALIASES), (DBMS.ACCESS, ACCESS_ALIASES), (DBMS.FIREBIRD, FIREBIRD_ALIASES), (DBMS.MAXDB, MAXDB_ALIASES), (DBMS.SYBASE, SYBASE_ALIASES), (DBMS.DB2, DB2_ALIASES), (DBMS.HSQLDB, HSQLDB_ALIASES))
USER_AGENT_ALIASES = ("ua", "useragent", "user-agent") USER_AGENT_ALIASES = ("ua", "useragent", "user-agent")
REFERER_ALIASES = ("ref", "referer", "referrer") REFERER_ALIASES = ("ref", "referer", "referrer")
HOST_ALIASES = ("host",) HOST_ALIASES = ("host",)
H2_DEFAULT_SCHEMA = HSQLDB_DEFAULT_SCHEMA = "PUBLIC" HSQLDB_DEFAULT_SCHEMA = "PUBLIC"
# Names that can't be used to name files on Windows OS # Names that can't be used to name files on Windows OS
WINDOWS_RESERVED_NAMES = ("CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9") WINDOWS_RESERVED_NAMES = ("CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9")
@@ -329,19 +320,18 @@ CURRENT_DB = "CD"
SESSION_SQLITE_FILE = "session.sqlite" SESSION_SQLITE_FILE = "session.sqlite"
# Regular expressions used for finding file paths in error messages # Regular expressions used for finding file paths in error messages
FILE_PATH_REGEXES = (r"<b>(?P<result>[^<>]+?)</b> on line \d+", r"\bin (?P<result>[^<>'\"]+?)['\"]? on line \d+", r"(?:[>(\[\s])(?P<result>[A-Za-z]:[\\/][\w. \\/-]*)", r"(?:[>(\[\s])(?P<result>/\w[/\w.~-]+)", r"\bhref=['\"]file://(?P<result>/[^'\"]+)", r"\bin <b>(?P<result>[^<]+): line \d+") FILE_PATH_REGEXES = (r"<b>(?P<result>[^<>]+?)</b> on line \d+", r"in (?P<result>[^<>'\"]+?)['\"]? on line \d+", r"(?:[>(\[\s])(?P<result>[A-Za-z]:[\\/][\w. \\/-]*)", r"(?:[>(\[\s])(?P<result>/\w[/\w.~-]+)", r"href=['\"]file://(?P<result>/[^'\"]+)")
# Regular expressions used for parsing error messages (--parse-errors) # Regular expressions used for parsing error messages (--parse-errors)
ERROR_PARSING_REGEXES = ( ERROR_PARSING_REGEXES = (
r"\[Microsoft\]\[ODBC SQL Server Driver\]\[SQL Server\](?P<result>[^<]+)", r"\[Microsoft\]\[ODBC SQL Server Driver\]\[SQL Server\](?P<result>[^<]+)",
r"<b>[^<]*(fatal|error|warning|exception)[^<]*</b>:?\s*(?P<result>[^<]+)", r"<b>[^<]*(fatal|error|warning|exception)[^<]*</b>:?\s*(?P<result>.+?)<br\s*/?\s*>",
r"(?m)^\s*(fatal|error|warning|exception):?\s*(?P<result>[^\n]+?)$", r"(?m)^\s*(fatal|error|warning|exception):?\s*(?P<result>[^\n]+?)$",
r"(?P<result>[^\n>]*SQL Syntax[^\n<]+)", r"(?P<result>[^\n>]*SQL Syntax[^\n<]+)",
r"(?s)<li>Error Type:<br>(?P<result>.+?)</li>", r"<li>Error Type:<br>(?P<result>.+?)</li>",
r"CDbCommand (?P<result>[^<>\n]*SQL[^<>\n]+)", r"CDbCommand (?P<result>[^<>\n]*SQL[^<>\n]+)",
r"error '[0-9a-f]{8}'((<[^>]+>)|\s)+(?P<result>[^<>]+)", r"error '[0-9a-f]{8}'((<[^>]+>)|\s)+(?P<result>[^<>]+)",
r"\[[^\n\]]+(ODBC|JDBC)[^\n\]]+\](\[[^\]]+\])?(?P<result>[^\n]+(in query expression|\(SQL| at /[^ ]+pdo)[^\n<]+)", r"\[[^\n\]]+(ODBC|JDBC)[^\n\]]+\](\[[^\]]+\])?(?P<result>[^\n]+(in query expression|\(SQL| at /[^ ]+pdo)[^\n<]+)"
r"(?P<result>query error: SELECT[^<>]+)"
) )
# Regular expression used for parsing charset info from meta html headers # Regular expression used for parsing charset info from meta html headers
@@ -363,7 +353,7 @@ COMMON_PASSWORD_SUFFIXES += ("!", ".", "*", "!!", "?", ";", "..", "!!!", ", ", "
WEBSCARAB_SPLITTER = "### Conversation" WEBSCARAB_SPLITTER = "### Conversation"
# Splitter used between requests in BURP log files # Splitter used between requests in BURP log files
BURP_REQUEST_REGEX = r"={10,}\s+([A-Z]{3,} .+?)\s+={10,}" BURP_REQUEST_REGEX = r"={10,}\s+[^=]+={10,}\s(.+?)\s={10,}"
# Regex used for parsing XML Burp saved history items # Regex used for parsing XML Burp saved history items
BURP_XML_HISTORY_REGEX = r'<port>(\d+)</port>.+?<request base64="true"><!\[CDATA\[([^]]+)' BURP_XML_HISTORY_REGEX = r'<port>(\d+)</port>.+?<request base64="true"><!\[CDATA\[([^]]+)'
@@ -378,7 +368,7 @@ URI_HTTP_HEADER = "URI"
URI_INJECTABLE_REGEX = r"//[^/]*/([^\.*?]+)\Z" URI_INJECTABLE_REGEX = r"//[^/]*/([^\.*?]+)\Z"
# Regex used for masking sensitive data # Regex used for masking sensitive data
SENSITIVE_DATA_REGEX = r"(\s|=)(?P<result>[^\s=]*\b%s\b[^\s]*)\s" SENSITIVE_DATA_REGEX = r"(\s|=)(?P<result>[^\s=]*%s[^\s]*)\s"
# Options to explicitly mask in anonymous (unhandled exception) reports (along with anything carrying the <hostname> inside) # Options to explicitly mask in anonymous (unhandled exception) reports (along with anything carrying the <hostname> inside)
SENSITIVE_OPTIONS = ("hostname", "answers", "data", "dnsDomain", "googleDork", "authCred", "proxyCred", "tbl", "db", "col", "user", "cookie", "proxy", "fileRead", "fileWrite", "fileDest", "testParameter", "authCred") SENSITIVE_OPTIONS = ("hostname", "answers", "data", "dnsDomain", "googleDork", "authCred", "proxyCred", "tbl", "db", "col", "user", "cookie", "proxy", "fileRead", "fileWrite", "fileDest", "testParameter", "authCred")
@@ -444,7 +434,7 @@ HASH_MOD_ITEM_DISPLAY = 11
HASH_EMPTY_PASSWORD_MARKER = "<empty>" HASH_EMPTY_PASSWORD_MARKER = "<empty>"
# Maximum integer value # Maximum integer value
MAX_INT = sys.maxsize MAX_INT = sys.maxint
# Replacement for unsafe characters in dump table filenames # Replacement for unsafe characters in dump table filenames
UNSAFE_DUMP_FILEPATH_REPLACEMENT = '_' UNSAFE_DUMP_FILEPATH_REPLACEMENT = '_'
@@ -509,6 +499,8 @@ HTML_TITLE_REGEX = r"<title>(?P<result>[^<]+)</title>"
# Table used for Base64 conversion in WordPress hash cracking routine # Table used for Base64 conversion in WordPress hash cracking routine
ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
PICKLE_REDUCE_WHITELIST = (types.BooleanType, types.DictType, types.FloatType, types.IntType, types.ListType, types.LongType, types.NoneType, types.StringType, types.TupleType, types.UnicodeType, types.XRangeType, type(AttribDict()), type(set()))
# Chars used to quickly distinguish if the user provided tainted parameter values # Chars used to quickly distinguish if the user provided tainted parameter values
DUMMY_SQL_INJECTION_CHARS = ";()'" DUMMY_SQL_INJECTION_CHARS = ";()'"
@@ -527,6 +519,9 @@ BRUTE_TABLE_EXISTS_TEMPLATE = "EXISTS(SELECT %d FROM %s)"
# Template used for common column existence check # Template used for common column existence check
BRUTE_COLUMN_EXISTS_TEMPLATE = "EXISTS(SELECT %s FROM %s)" BRUTE_COLUMN_EXISTS_TEMPLATE = "EXISTS(SELECT %s FROM %s)"
# Payload used for checking of existence of IDS/IPS/WAF (dummier the better)
IDS_WAF_CHECK_PAYLOAD = "AND 1=1 UNION ALL SELECT 1,NULL,'<script>alert(\"XSS\")</script>',table_name FROM information_schema.tables WHERE 2>1--/**/; EXEC xp_cmdshell('cat ../../../etc/passwd')#"
# Data inside shellcodeexec to be filled with random string # Data inside shellcodeexec to be filled with random string
SHELLCODEEXEC_RANDOM_STRING_MARKER = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" SHELLCODEEXEC_RANDOM_STRING_MARKER = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
@@ -536,16 +531,13 @@ CHECK_INTERNET_ADDRESS = "https://ipinfo.io/"
# Value to look for in response to CHECK_INTERNET_ADDRESS # Value to look for in response to CHECK_INTERNET_ADDRESS
CHECK_INTERNET_VALUE = "IP Address Details" CHECK_INTERNET_VALUE = "IP Address Details"
# Payload used for checking of existence of WAF/IPS (dummier the better)
IPS_WAF_CHECK_PAYLOAD = "AND 1=1 UNION ALL SELECT 1,NULL,'<script>alert(\"XSS\")</script>',table_name FROM information_schema.tables WHERE 2>1--/**/; EXEC xp_cmdshell('cat ../../../etc/passwd')#"
# Vectors used for provoking specific WAF/IPS behavior(s) # Vectors used for provoking specific WAF/IPS behavior(s)
WAF_ATTACK_VECTORS = ( WAF_ATTACK_VECTORS = (
"", # NIL "", # NIL
"search=<script>alert(1)</script>", "search=<script>alert(1)</script>",
"file=../../../../etc/passwd", "file=../../../../etc/passwd",
"q=<invalid>foobar", "q=<invalid>foobar",
"id=1 %s" % IPS_WAF_CHECK_PAYLOAD "id=1 %s" % IDS_WAF_CHECK_PAYLOAD
) )
# Used for status representation in dictionary attack phase # Used for status representation in dictionary attack phase
@@ -586,7 +578,7 @@ UNION_CHAR_REGEX = r"\A\w+\Z"
UNENCODED_ORIGINAL_VALUE = "original" UNENCODED_ORIGINAL_VALUE = "original"
# Common column names containing usernames (used for hash cracking in some cases) # Common column names containing usernames (used for hash cracking in some cases)
COMMON_USER_COLUMNS = ("login", "user", "username", "user_name", "user_login", "benutzername", "benutzer", "utilisateur", "usager", "consommateur", "utente", "utilizzatore", "utilizator", "utilizador", "usufrutuario", "korisnik", "uporabnik", "usuario", "consumidor", "client", "cuser") COMMON_USER_COLUMNS = ("login", "user", "username", "user_name", "user_login", "benutzername", "benutzer", "utilisateur", "usager", "consommateur", "utente", "utilizzatore", "usufrutuario", "korisnik", "usuario", "consumidor", "client", "cuser")
# Default delimiter in GET/POST values # Default delimiter in GET/POST values
DEFAULT_GET_POST_DELIMITER = '&' DEFAULT_GET_POST_DELIMITER = '&'
@@ -598,7 +590,7 @@ DEFAULT_COOKIE_DELIMITER = ';'
FORCE_COOKIE_EXPIRATION_TIME = "9999999999" FORCE_COOKIE_EXPIRATION_TIME = "9999999999"
# Github OAuth token used for creating an automatic Issue for unhandled exceptions # Github OAuth token used for creating an automatic Issue for unhandled exceptions
GITHUB_REPORT_OAUTH_TOKEN = "NTYzYjhmZWJjYzc0Njg2ODJhNzhmNDg1YzM0YzlkYjk3N2JiMzE3Nw==" GITHUB_REPORT_OAUTH_TOKEN = "NTMyNWNkMmZkMzRlMDZmY2JkMmY0MGI4NWI0MzVlM2Q5YmFjYWNhYQ=="
# Skip unforced HashDB flush requests below the threshold number of cached items # Skip unforced HashDB flush requests below the threshold number of cached items
HASHDB_FLUSH_THRESHOLD = 32 HASHDB_FLUSH_THRESHOLD = 32
@@ -676,10 +668,7 @@ VALID_TIME_CHARS_RUN_THRESHOLD = 100
CHECK_ZERO_COLUMNS_THRESHOLD = 10 CHECK_ZERO_COLUMNS_THRESHOLD = 10
# Boldify all logger messages containing these "patterns" # Boldify all logger messages containing these "patterns"
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA", "specific response", "NULL connection is supported", "PASSED", "FAILED") BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA", "specific response", "NULL connection is supported")
# TLDs used in randomization of email-alike parameter values
RANDOMIZATION_TLDS = ("com", "net", "ru", "org", "de", "jp", "cn", "fr", "it", "pl", "tv", "edu", "in", "ir", "es", "me", "info", "gr", "gov", "ca", "co", "se", "cz", "to", "vn", "nl", "cc", "az", "hu", "ua", "be", "no", "biz", "io", "ch", "ro", "sk", "eu", "us", "tw", "pt", "fi", "at", "lt", "kz", "cl", "hr", "pk", "lv", "la", "pe")
# Generic www root directory names # Generic www root directory names
GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "httpdocs", "public", "wwwroot", "www") GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "httpdocs", "public", "wwwroot", "www")
@@ -691,7 +680,7 @@ MAX_HELP_OPTION_LENGTH = 18
MAX_CONNECT_RETRIES = 100 MAX_CONNECT_RETRIES = 100
# Strings for detecting formatting errors # Strings for detecting formatting errors
FORMAT_EXCEPTION_STRINGS = ("Type mismatch", "Error converting", "Please enter a", "Conversion failed", "String or binary data would be truncated", "Failed to convert", "unable to interpret text value", "Input string was not in a correct format", "System.FormatException", "java.lang.NumberFormatException", "ValueError: invalid literal", "TypeMismatchException", "CF_SQL_INTEGER", "CF_SQL_NUMERIC", " for CFSQLTYPE ", "cfqueryparam cfsqltype", "InvalidParamTypeException", "Invalid parameter type", "Attribute validation error for tag", "is not of type numeric", "<cfif Not IsNumeric(", "invalid input syntax for integer", "invalid input syntax for type", "invalid number", "character to number conversion error", "unable to interpret text value", "String was not recognized as a valid", "Convert.ToInt", "cannot be converted to a ", "InvalidDataException") FORMAT_EXCEPTION_STRINGS = ("Type mismatch", "Error converting", "Conversion failed", "String or binary data would be truncated", "Failed to convert", "unable to interpret text value", "Input string was not in a correct format", "System.FormatException", "java.lang.NumberFormatException", "ValueError: invalid literal", "DataTypeMismatchException", "CF_SQL_INTEGER", " for CFSQLTYPE ", "cfqueryparam cfsqltype", "InvalidParamTypeException", "Invalid parameter type", "is not of type numeric", "<cfif Not IsNumeric(", "invalid input syntax for integer", "invalid input syntax for type", "invalid number", "character to number conversion error", "unable to interpret text value", "String was not recognized as a valid", "Convert.ToInt", "cannot be converted to a ", "InvalidDataException")
# Regular expression used for extracting ASP.NET view state values # Regular expression used for extracting ASP.NET view state values
VIEWSTATE_REGEX = r'(?i)(?P<name>__VIEWSTATE[^"]*)[^>]+value="(?P<result>[^"]+)' VIEWSTATE_REGEX = r'(?i)(?P<name>__VIEWSTATE[^"]*)[^>]+value="(?P<result>[^"]+)'
@@ -759,8 +748,8 @@ METASPLOIT_SESSION_TIMEOUT = 120
# Reference: http://www.postgresql.org/docs/9.0/static/catalog-pg-largeobject.html # Reference: http://www.postgresql.org/docs/9.0/static/catalog-pg-largeobject.html
LOBLKSIZE = 2048 LOBLKSIZE = 2048
# Prefix used to mark special variables (e.g. keywords, having special chars, etc.) # Suffix used to mark variables having keyword names
EVALCODE_ENCODED_PREFIX = "EVAL_" EVALCODE_KEYWORD_SUFFIX = "_KEYWORD"
# Reference: http://www.cookiecentral.com/faq/#3.5 # Reference: http://www.cookiecentral.com/faq/#3.5
NETSCAPE_FORMAT_HEADER_COOKIES = "# Netscape HTTP Cookie File." NETSCAPE_FORMAT_HEADER_COOKIES = "# Netscape HTTP Cookie File."
@@ -774,9 +763,6 @@ BRUTE_DOC_ROOT_PREFIXES = {
OS.WINDOWS: ("/xampp", "/Program Files/xampp", "/wamp", "/Program Files/wampp", "/apache", "/Program Files/Apache Group/Apache", "/Program Files/Apache Group/Apache2", "/Program Files/Apache Group/Apache2.2", "/Program Files/Apache Group/Apache2.4", "/Inetpub/wwwroot", "/Inetpub/wwwroot/%TARGET%", "/Inetpub/vhosts/%TARGET%") OS.WINDOWS: ("/xampp", "/Program Files/xampp", "/wamp", "/Program Files/wampp", "/apache", "/Program Files/Apache Group/Apache", "/Program Files/Apache Group/Apache2", "/Program Files/Apache Group/Apache2.2", "/Program Files/Apache Group/Apache2.4", "/Inetpub/wwwroot", "/Inetpub/wwwroot/%TARGET%", "/Inetpub/vhosts/%TARGET%")
} }
# Table prefix to use in "takeover" functionalities (i.e. auxiliary tables used by sqlmap at the vulnerable DBMS)
TAKEOVER_TABLE_PREFIX = "sqlmap"
# Suffixes used in brute force search for web server document root # Suffixes used in brute force search for web server document root
BRUTE_DOC_ROOT_SUFFIXES = ("", "html", "htdocs", "httpdocs", "php", "public", "src", "site", "build", "web", "www", "data", "sites/all", "www/build") BRUTE_DOC_ROOT_SUFFIXES = ("", "html", "htdocs", "httpdocs", "php", "public", "src", "site", "build", "web", "www", "data", "sites/all", "www/build")
@@ -789,9 +775,6 @@ KB_CHARS_BOUNDARY_CHAR = 'q'
# Letters of lower frequency used in kb.chars # Letters of lower frequency used in kb.chars
KB_CHARS_LOW_FREQUENCY_ALPHABET = "zqxjkvbp" KB_CHARS_LOW_FREQUENCY_ALPHABET = "zqxjkvbp"
# SQL keywords used for splitting in HTTP chunked transfer encoded requests (switch --chunk)
HTTP_CHUNKED_SPLIT_KEYWORDS = ("SELECT", "UPDATE", "INSERT", "FROM", "LOAD_FILE", "UNION", "information_schema", "sysdatabases", "msysaccessobjects", "msysqueries", "sysmodules")
# CSS style used in HTML dump format # CSS style used in HTML dump format
HTML_DUMP_CSS_STYLE = """<style> HTML_DUMP_CSS_STYLE = """<style>
table{ table{
@@ -816,11 +799,3 @@ th{
font-size:12px; font-size:12px;
} }
</style>""" </style>"""
# Leaving (dirty) possibility to change values from here (e.g. `export SQLMAP__MAX_NUMBER_OF_THREADS=20`)
for key, value in os.environ.items():
if key.upper().startswith("%s_" % SQLMAP_ENVIRONMENT_PREFIX):
_ = key[len(SQLMAP_ENVIRONMENT_PREFIX) + 1:].upper()
if _ in globals():
globals()[_] = value
+25 -29
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -9,7 +9,6 @@ import atexit
import os import os
from lib.core import readlineng as readline from lib.core import readlineng as readline
from lib.core.common import getSafeExString
from lib.core.data import logger from lib.core.data import logger
from lib.core.data import paths from lib.core.data import paths
from lib.core.enums import AUTOCOMPLETE_TYPE from lib.core.enums import AUTOCOMPLETE_TYPE
@@ -54,34 +53,31 @@ def clearHistory():
readline.clear_history() readline.clear_history()
def saveHistory(completion=None): def saveHistory(completion=None):
if not readlineAvailable():
return
if completion == AUTOCOMPLETE_TYPE.SQL:
historyPath = paths.SQL_SHELL_HISTORY
elif completion == AUTOCOMPLETE_TYPE.OS:
historyPath = paths.OS_SHELL_HISTORY
elif completion == AUTOCOMPLETE_TYPE.API:
historyPath = paths.API_SHELL_HISTORY
else:
historyPath = paths.SQLMAP_SHELL_HISTORY
try: try:
if not readlineAvailable(): with open(historyPath, "w+"):
return
if completion == AUTOCOMPLETE_TYPE.SQL:
historyPath = paths.SQL_SHELL_HISTORY
elif completion == AUTOCOMPLETE_TYPE.OS:
historyPath = paths.OS_SHELL_HISTORY
elif completion == AUTOCOMPLETE_TYPE.API:
historyPath = paths.API_SHELL_HISTORY
else:
historyPath = paths.SQLMAP_SHELL_HISTORY
try:
with open(historyPath, "w+"):
pass
except:
pass pass
except:
readline.set_history_length(MAX_HISTORY_LENGTH)
try:
readline.write_history_file(historyPath)
except IOError as ex:
warnMsg = "there was a problem writing the history file '%s' (%s)" % (historyPath, getSafeExString(ex))
logger.warn(warnMsg)
except KeyboardInterrupt:
pass pass
readline.set_history_length(MAX_HISTORY_LENGTH)
try:
readline.write_history_file(historyPath)
except IOError, msg:
warnMsg = "there was a problem writing the history file '%s' (%s)" % (historyPath, msg)
logger.warn(warnMsg)
def loadHistory(completion=None): def loadHistory(completion=None):
if not readlineAvailable(): if not readlineAvailable():
return return
@@ -100,8 +96,8 @@ def loadHistory(completion=None):
if os.path.exists(historyPath): if os.path.exists(historyPath):
try: try:
readline.read_history_file(historyPath) readline.read_history_file(historyPath)
except IOError as ex: except IOError, msg:
warnMsg = "there was a problem loading the history file '%s' (%s)" % (historyPath, getSafeExString(ex)) warnMsg = "there was a problem loading the history file '%s' (%s)" % (historyPath, msg)
logger.warn(warnMsg) logger.warn(warnMsg)
def autoCompletion(completion=None, os=None, commands=None): def autoCompletion(completion=None, os=None, commands=None):
+11 -11
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -31,7 +31,7 @@ def blockingReadFromFD(fd):
while True: while True:
try: try:
output += os.read(fd, 8192) output += os.read(fd, 8192)
except (OSError, IOError) as ioe: except (OSError, IOError), ioe:
if ioe.args[0] in (errno.EAGAIN, errno.EINTR): if ioe.args[0] in (errno.EAGAIN, errno.EINTR):
# Uncomment the following line if the process seems to # Uncomment the following line if the process seems to
# take a huge amount of cpu time # take a huge amount of cpu time
@@ -52,7 +52,7 @@ def blockingWriteToFD(fd, data):
try: try:
data_length = len(data) data_length = len(data)
wrote_data = os.write(fd, data) wrote_data = os.write(fd, data)
except (OSError, IOError) as io: except (OSError, IOError), io:
if io.errno in (errno.EAGAIN, errno.EINTR): if io.errno in (errno.EAGAIN, errno.EINTR):
continue continue
else: else:
@@ -85,7 +85,7 @@ class Popen(subprocess.Popen):
getattr(self, which).close() getattr(self, which).close()
setattr(self, which, None) setattr(self, which, None)
if IS_WIN: if subprocess.mswindows:
def send(self, input): def send(self, input):
if not self.stdin: if not self.stdin:
return None return None
@@ -95,8 +95,8 @@ class Popen(subprocess.Popen):
(errCode, written) = WriteFile(x, input) (errCode, written) = WriteFile(x, input)
except ValueError: except ValueError:
return self._close('stdin') return self._close('stdin')
except (subprocess.pywintypes.error, Exception) as ex: except (subprocess.pywintypes.error, Exception), why:
if ex[0] in (109, errno.ESHUTDOWN): if why[0] in (109, errno.ESHUTDOWN):
return self._close('stdin') return self._close('stdin')
raise raise
@@ -116,8 +116,8 @@ class Popen(subprocess.Popen):
(errCode, read) = ReadFile(x, nAvail, None) (errCode, read) = ReadFile(x, nAvail, None)
except (ValueError, NameError): except (ValueError, NameError):
return self._close(which) return self._close(which)
except (subprocess.pywintypes.error, Exception) as ex: except (subprocess.pywintypes.error, Exception), why:
if ex[0] in (109, errno.ESHUTDOWN): if why[0] in (109, errno.ESHUTDOWN):
return self._close(which) return self._close(which)
raise raise
@@ -134,8 +134,8 @@ class Popen(subprocess.Popen):
try: try:
written = os.write(self.stdin.fileno(), input) written = os.write(self.stdin.fileno(), input)
except OSError as ex: except OSError, why:
if ex[0] == errno.EPIPE: # broken pipe if why[0] == errno.EPIPE: # broken pipe
return self._close('stdin') return self._close('stdin')
raise raise
+53 -39
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -12,6 +12,7 @@ import subprocess
import sys import sys
import tempfile import tempfile
import time import time
import urlparse
from lib.core.common import Backend from lib.core.common import Backend
from lib.core.common import getSafeExString from lib.core.common import getSafeExString
@@ -26,7 +27,6 @@ from lib.core.common import randomStr
from lib.core.common import readInput from lib.core.common import readInput
from lib.core.common import resetCookieJar from lib.core.common import resetCookieJar
from lib.core.common import urldecode from lib.core.common import urldecode
from lib.core.compat import xrange
from lib.core.data import conf from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
@@ -44,7 +44,6 @@ from lib.core.enums import POST_HINT
from lib.core.exception import SqlmapFilePathException from lib.core.exception import SqlmapFilePathException
from lib.core.exception import SqlmapGenericException from lib.core.exception import SqlmapGenericException
from lib.core.exception import SqlmapMissingPrivileges from lib.core.exception import SqlmapMissingPrivileges
from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapSystemException from lib.core.exception import SqlmapSystemException
from lib.core.exception import SqlmapUserQuitException from lib.core.exception import SqlmapUserQuitException
from lib.core.option import _setDBMS from lib.core.option import _setDBMS
@@ -52,11 +51,9 @@ from lib.core.option import _setKnowledgeBaseAttributes
from lib.core.option import _setAuthCred from lib.core.option import _setAuthCred
from lib.core.settings import ASTERISK_MARKER from lib.core.settings import ASTERISK_MARKER
from lib.core.settings import CSRF_TOKEN_PARAMETER_INFIXES from lib.core.settings import CSRF_TOKEN_PARAMETER_INFIXES
from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR
from lib.core.settings import DEFAULT_GET_POST_DELIMITER from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import HOST_ALIASES from lib.core.settings import HOST_ALIASES
from lib.core.settings import ARRAY_LIKE_RECOGNITION_REGEX from lib.core.settings import ARRAY_LIKE_RECOGNITION_REGEX
from lib.core.settings import INJECT_HERE_REGEX
from lib.core.settings import JSON_RECOGNITION_REGEX from lib.core.settings import JSON_RECOGNITION_REGEX
from lib.core.settings import JSON_LIKE_RECOGNITION_REGEX from lib.core.settings import JSON_LIKE_RECOGNITION_REGEX
from lib.core.settings import MULTIPART_RECOGNITION_REGEX from lib.core.settings import MULTIPART_RECOGNITION_REGEX
@@ -73,8 +70,7 @@ from lib.core.settings import URI_INJECTABLE_REGEX
from lib.core.settings import USER_AGENT_ALIASES from lib.core.settings import USER_AGENT_ALIASES
from lib.core.settings import XML_RECOGNITION_REGEX from lib.core.settings import XML_RECOGNITION_REGEX
from lib.utils.hashdb import HashDB from lib.utils.hashdb import HashDB
from thirdparty.odict import OrderedDict from thirdparty.odict.odict import OrderedDict
from thirdparty.six.moves import urllib as _urllib
def _setRequestParams(): def _setRequestParams():
""" """
@@ -213,7 +209,7 @@ def _setRequestParams():
if not (kb.processUserMarks and kb.customInjectionMark in conf.data): if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data) conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data)
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER) conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER)
conf.data = re.sub(r"(?si)((Content-Disposition[^\n]+?name\s*=\s*[\"']?(?P<name>[^\"'\r\n]+)[\"']?).+?)((%s)+--)" % ("\r\n" if "\r\n" in conf.data else '\n'), functools.partial(process, repl=r"\g<1>%s\g<4>" % kb.customInjectionMark), conf.data) conf.data = re.sub(r"(?si)((Content-Disposition[^\n]+?name\s*=\s*[\"']?(?P<name>[^\"'\r\n]+)[\"']?).+?)(((\r)?\n)+--)", functools.partial(process, repl=r"\g<1>%s\g<4>" % kb.customInjectionMark), conf.data)
kb.postHint = POST_HINT.MULTIPART kb.postHint = POST_HINT.MULTIPART
@@ -277,7 +273,7 @@ def _setRequestParams():
if not kb.processUserMarks: if not kb.processUserMarks:
if place == PLACE.URI: if place == PLACE.URI:
query = _urllib.parse.urlsplit(value).query query = urlparse.urlsplit(value).query
if query: if query:
parameters = conf.parameters[PLACE.GET] = query parameters = conf.parameters[PLACE.GET] = query
paramDict = paramToDict(PLACE.GET, parameters) paramDict = paramToDict(PLACE.GET, parameters)
@@ -347,7 +343,7 @@ def _setRequestParams():
# Url encoding of the header values should be avoided # Url encoding of the header values should be avoided
# Reference: http://stackoverflow.com/questions/5085904/is-ok-to-urlencode-the-value-in-headerlocation-value # Reference: http://stackoverflow.com/questions/5085904/is-ok-to-urlencode-the-value-in-headerlocation-value
if httpHeader.upper() == HTTP_HEADER.USER_AGENT.upper(): if httpHeader.title() == HTTP_HEADER.USER_AGENT:
conf.parameters[PLACE.USER_AGENT] = urldecode(headerValue) conf.parameters[PLACE.USER_AGENT] = urldecode(headerValue)
condition = any((not conf.testParameter, intersect(conf.testParameter, USER_AGENT_ALIASES, True))) condition = any((not conf.testParameter, intersect(conf.testParameter, USER_AGENT_ALIASES, True)))
@@ -356,7 +352,7 @@ def _setRequestParams():
conf.paramDict[PLACE.USER_AGENT] = {PLACE.USER_AGENT: headerValue} conf.paramDict[PLACE.USER_AGENT] = {PLACE.USER_AGENT: headerValue}
testableParameters = True testableParameters = True
elif httpHeader.upper() == HTTP_HEADER.REFERER.upper(): elif httpHeader.title() == HTTP_HEADER.REFERER:
conf.parameters[PLACE.REFERER] = urldecode(headerValue) conf.parameters[PLACE.REFERER] = urldecode(headerValue)
condition = any((not conf.testParameter, intersect(conf.testParameter, REFERER_ALIASES, True))) condition = any((not conf.testParameter, intersect(conf.testParameter, REFERER_ALIASES, True)))
@@ -365,7 +361,7 @@ def _setRequestParams():
conf.paramDict[PLACE.REFERER] = {PLACE.REFERER: headerValue} conf.paramDict[PLACE.REFERER] = {PLACE.REFERER: headerValue}
testableParameters = True testableParameters = True
elif httpHeader.upper() == HTTP_HEADER.HOST.upper(): elif httpHeader.title() == HTTP_HEADER.HOST:
conf.parameters[PLACE.HOST] = urldecode(headerValue) conf.parameters[PLACE.HOST] = urldecode(headerValue)
condition = any((not conf.testParameter, intersect(conf.testParameter, HOST_ALIASES, True))) condition = any((not conf.testParameter, intersect(conf.testParameter, HOST_ALIASES, True)))
@@ -394,8 +390,8 @@ def _setRequestParams():
raise SqlmapGenericException(errMsg) raise SqlmapGenericException(errMsg)
if conf.csrfToken: if conf.csrfToken:
if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))) and not re.search(r"\b%s\b" % conf.csrfToken, conf.data or "") and conf.csrfToken not in set(_[0].lower() for _ in conf.httpHeaders) and conf.csrfToken not in conf.paramDict.get(PLACE.COOKIE, {}): if not any(conf.csrfToken in _ for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))) and not re.search(r"\b%s\b" % re.escape(conf.csrfToken), conf.data or "") and conf.csrfToken not in set(_[0].lower() for _ in conf.httpHeaders) and conf.csrfToken not in conf.paramDict.get(PLACE.COOKIE, {}):
errMsg = "anti-CSRF token parameter '%s' not " % conf.csrfToken._original errMsg = "anti-CSRF token parameter '%s' not " % conf.csrfToken
errMsg += "found in provided GET, POST, Cookie or header values" errMsg += "found in provided GET, POST, Cookie or header values"
raise SqlmapGenericException(errMsg) raise SqlmapGenericException(errMsg)
else: else:
@@ -409,10 +405,7 @@ def _setRequestParams():
message += "Do you want sqlmap to automatically update it in further requests? [y/N] " message += "Do you want sqlmap to automatically update it in further requests? [y/N] "
if readInput(message, default='N', boolean=True): if readInput(message, default='N', boolean=True):
class _(unicode): conf.csrfToken = getUnicode(parameter)
pass
conf.csrfToken = _(re.escape(getUnicode(parameter)))
conf.csrfToken._original = getUnicode(parameter)
break break
def _setHashDB(): def _setHashDB():
@@ -428,8 +421,8 @@ def _setHashDB():
try: try:
os.remove(conf.hashDBFile) os.remove(conf.hashDBFile)
logger.info("flushing session file") logger.info("flushing session file")
except OSError as ex: except OSError, msg:
errMsg = "unable to flush the session file ('%s')" % getSafeExString(ex) errMsg = "unable to flush the session file (%s)" % msg
raise SqlmapFilePathException(errMsg) raise SqlmapFilePathException(errMsg)
conf.hashDB = HashDB(conf.hashDBFile) conf.hashDB = HashDB(conf.hashDBFile)
@@ -473,13 +466,7 @@ def _resumeDBMS():
value = hashDBRetrieve(HASHDB_KEYS.DBMS) value = hashDBRetrieve(HASHDB_KEYS.DBMS)
if not value: if not value:
if conf.offline: return
errMsg = "unable to continue in offline mode "
errMsg += "because of lack of usable "
errMsg += "session data"
raise SqlmapNoneDataException(errMsg)
else:
return
dbms = value.lower() dbms = value.lower()
dbmsVersion = [UNKNOWN_DBMS_VERSION] dbmsVersion = [UNKNOWN_DBMS_VERSION]
@@ -559,7 +546,7 @@ def _setResultsFile():
conf.resultsFilename = os.path.join(paths.SQLMAP_OUTPUT_PATH, time.strftime(RESULTS_FILE_FORMAT).lower()) conf.resultsFilename = os.path.join(paths.SQLMAP_OUTPUT_PATH, time.strftime(RESULTS_FILE_FORMAT).lower())
try: try:
conf.resultsFP = openFile(conf.resultsFilename, "a", UNICODE_ENCODING, buffering=0) conf.resultsFP = openFile(conf.resultsFilename, "a", UNICODE_ENCODING, buffering=0)
except (OSError, IOError) as ex: except (OSError, IOError), ex:
try: try:
warnMsg = "unable to create results file '%s' ('%s'). " % (conf.resultsFilename, getUnicode(ex)) warnMsg = "unable to create results file '%s' ('%s'). " % (conf.resultsFilename, getUnicode(ex))
handle, conf.resultsFilename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.RESULTS, suffix=".csv") handle, conf.resultsFilename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.RESULTS, suffix=".csv")
@@ -567,7 +554,7 @@ def _setResultsFile():
conf.resultsFP = openFile(conf.resultsFilename, "w+", UNICODE_ENCODING, buffering=0) conf.resultsFP = openFile(conf.resultsFilename, "w+", UNICODE_ENCODING, buffering=0)
warnMsg += "Using temporary file '%s' instead" % conf.resultsFilename warnMsg += "Using temporary file '%s' instead" % conf.resultsFilename
logger.warn(warnMsg) logger.warn(warnMsg)
except IOError as _: except IOError, _:
errMsg = "unable to write to the temporary directory ('%s'). " % _ errMsg = "unable to write to the temporary directory ('%s'). " % _
errMsg += "Please make sure that your disk is not full and " errMsg += "Please make sure that your disk is not full and "
errMsg += "that you have sufficient write permissions to " errMsg += "that you have sufficient write permissions to "
@@ -591,7 +578,7 @@ def _createFilesDir():
if not os.path.isdir(conf.filePath): if not os.path.isdir(conf.filePath):
try: try:
os.makedirs(conf.filePath) os.makedirs(conf.filePath)
except OSError as ex: except OSError, ex:
tempDir = tempfile.mkdtemp(prefix="sqlmapfiles") tempDir = tempfile.mkdtemp(prefix="sqlmapfiles")
warnMsg = "unable to create files directory " warnMsg = "unable to create files directory "
warnMsg += "'%s' (%s). " % (conf.filePath, getUnicode(ex)) warnMsg += "'%s' (%s). " % (conf.filePath, getUnicode(ex))
@@ -613,7 +600,7 @@ def _createDumpDir():
if not os.path.isdir(conf.dumpPath): if not os.path.isdir(conf.dumpPath):
try: try:
os.makedirs(conf.dumpPath) os.makedirs(conf.dumpPath)
except OSError as ex: except OSError, ex:
tempDir = tempfile.mkdtemp(prefix="sqlmapdump") tempDir = tempfile.mkdtemp(prefix="sqlmapdump")
warnMsg = "unable to create dump directory " warnMsg = "unable to create dump directory "
warnMsg += "'%s' (%s). " % (conf.dumpPath, getUnicode(ex)) warnMsg += "'%s' (%s). " % (conf.dumpPath, getUnicode(ex))
@@ -631,15 +618,45 @@ def _createTargetDirs():
Create the output directory. Create the output directory.
""" """
for context in "output", "history":
directory = paths["SQLMAP_%s_PATH" % context.upper()]
try:
if not os.path.isdir(directory):
os.makedirs(directory)
_ = os.path.join(directory, randomStr())
open(_, "w+b").close()
os.remove(_)
if conf.outputDir and context == "output":
warnMsg = "using '%s' as the %s directory" % (directory, context)
logger.warn(warnMsg)
except (OSError, IOError), ex:
try:
tempDir = tempfile.mkdtemp(prefix="sqlmap%s" % context)
except Exception, _:
errMsg = "unable to write to the temporary directory ('%s'). " % _
errMsg += "Please make sure that your disk is not full and "
errMsg += "that you have sufficient write permissions to "
errMsg += "create temporary files and/or directories"
raise SqlmapSystemException(errMsg)
warnMsg = "unable to %s %s directory " % ("create" if not os.path.isdir(directory) else "write to the", context)
warnMsg += "'%s' (%s). " % (directory, getUnicode(ex))
warnMsg += "Using temporary directory '%s' instead" % getUnicode(tempDir)
logger.warn(warnMsg)
paths["SQLMAP_%s_PATH" % context.upper()] = tempDir
conf.outputPath = os.path.join(getUnicode(paths.SQLMAP_OUTPUT_PATH), normalizeUnicode(getUnicode(conf.hostname))) conf.outputPath = os.path.join(getUnicode(paths.SQLMAP_OUTPUT_PATH), normalizeUnicode(getUnicode(conf.hostname)))
try: try:
if not os.path.isdir(conf.outputPath): if not os.path.isdir(conf.outputPath):
os.makedirs(conf.outputPath) os.makedirs(conf.outputPath)
except (OSError, IOError, TypeError) as ex: except (OSError, IOError, TypeError), ex:
try: try:
tempDir = tempfile.mkdtemp(prefix="sqlmapoutput") tempDir = tempfile.mkdtemp(prefix="sqlmapoutput")
except Exception as _: except Exception, _:
errMsg = "unable to write to the temporary directory ('%s'). " % _ errMsg = "unable to write to the temporary directory ('%s'). " % _
errMsg += "Please make sure that your disk is not full and " errMsg += "Please make sure that your disk is not full and "
errMsg += "that you have sufficient write permissions to " errMsg += "that you have sufficient write permissions to "
@@ -662,7 +679,7 @@ def _createTargetDirs():
f.write(" # %s" % getUnicode(subprocess.list2cmdline(sys.argv), encoding=sys.stdin.encoding)) f.write(" # %s" % getUnicode(subprocess.list2cmdline(sys.argv), encoding=sys.stdin.encoding))
if conf.data: if conf.data:
f.write("\n\n%s" % getUnicode(conf.data)) f.write("\n\n%s" % getUnicode(conf.data))
except IOError as ex: except IOError, ex:
if "denied" in getUnicode(ex): if "denied" in getUnicode(ex):
errMsg = "you don't have enough permissions " errMsg = "you don't have enough permissions "
else: else:
@@ -728,9 +745,6 @@ def initTargetEnv():
setattr(conf.data, UNENCODED_ORIGINAL_VALUE, original) setattr(conf.data, UNENCODED_ORIGINAL_VALUE, original)
kb.postSpaceToPlus = '+' in original kb.postSpaceToPlus = '+' in original
match = re.search(INJECT_HERE_REGEX, conf.data or "") or re.search(INJECT_HERE_REGEX, conf.url or "")
kb.customInjectionMark = match.group(0) if match else CUSTOM_INJECTION_MARK_CHAR
def setupTargetEnv(): def setupTargetEnv():
_createTargetDirs() _createTargetDirs()
_setRequestParams() _setRequestParams()
@@ -738,4 +752,4 @@ def setupTargetEnv():
_resumeHashDBValues() _resumeHashDBValues()
_setResultsFile() _setResultsFile()
_setAuthCred() _setAuthCred()
_setAuxOptions() _setAuxOptions()
+8 -12
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -17,7 +17,6 @@ import traceback
from extra.beep.beep import beep from extra.beep.beep import beep
from lib.controller.controller import start from lib.controller.controller import start
from lib.core.common import checkIntegrity
from lib.core.common import clearConsoleLine from lib.core.common import clearConsoleLine
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import getUnicode from lib.core.common import getUnicode
@@ -52,9 +51,6 @@ def smokeTest():
retVal = True retVal = True
count, length = 0, 0 count, length = 0, 0
if not checkIntegrity():
retVal = False
for root, _, files in os.walk(paths.SQLMAP_ROOT_PATH): for root, _, files in os.walk(paths.SQLMAP_ROOT_PATH):
if any(_ in root for _ in ("thirdparty", "extra")): if any(_ in root for _ in ("thirdparty", "extra")):
continue continue
@@ -75,10 +71,10 @@ def smokeTest():
try: try:
__import__(path) __import__(path)
module = sys.modules[path] module = sys.modules[path]
except Exception as ex: except Exception, msg:
retVal = False retVal = False
dataToStdout("\r") dataToStdout("\r")
errMsg = "smoke test failed at importing module '%s' (%s):\n%s" % (path, os.path.join(root, filename), ex) errMsg = "smoke test failed at importing module '%s' (%s):\n%s" % (path, os.path.join(root, filename), msg)
logger.error(errMsg) logger.error(errMsg)
else: else:
# Run doc tests # Run doc tests
@@ -275,10 +271,10 @@ def runCase(parse):
result = start() result = start()
except KeyboardInterrupt: except KeyboardInterrupt:
pass pass
except SqlmapBaseException as ex: except SqlmapBaseException, e:
handled_exception = ex handled_exception = e
except Exception as ex: except Exception, e:
unhandled_exception = ex unhandled_exception = e
finally: finally:
sys.stdout.seek(0) sys.stdout.seek(0)
console = sys.stdout.read() console = sys.stdout.read()
+15 -18
View File
@@ -1,25 +1,21 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
from __future__ import print_function
import difflib import difflib
import random
import threading import threading
import time import time
import traceback import traceback
from lib.core.compat import WichmannHill
from lib.core.compat import xrange
from lib.core.data import conf from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.datatype import AttribDict from lib.core.datatype import AttribDict
from lib.core.enums import PAYLOAD from lib.core.enums import PAYLOAD
from lib.core.exception import SqlmapBaseException
from lib.core.exception import SqlmapConnectionException from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapThreadException from lib.core.exception import SqlmapThreadException
from lib.core.exception import SqlmapUserQuitException from lib.core.exception import SqlmapUserQuitException
@@ -58,7 +54,7 @@ class _ThreadData(threading.local):
self.lastRequestMsg = None self.lastRequestMsg = None
self.lastRequestUID = 0 self.lastRequestUID = 0
self.lastRedirectURL = None self.lastRedirectURL = None
self.random = WichmannHill() self.random = random.WichmannHill()
self.resumed = False self.resumed = False
self.retriesCount = 0 self.retriesCount = 0
self.seqMatcher = difflib.SequenceMatcher(None) self.seqMatcher = difflib.SequenceMatcher(None)
@@ -95,10 +91,9 @@ def exceptionHandledFunction(threadFunction, silent=False):
kb.threadContinue = False kb.threadContinue = False
kb.threadException = True kb.threadException = True
raise raise
except Exception as ex: except Exception, ex:
if not silent and kb.get("threadContinue"): if not silent:
errMsg = ex.message if isinstance(ex, SqlmapBaseException) else "%s: %s" % (type(ex).__name__, ex.message) logger.error("thread %s: %s" % (threading.currentThread().getName(), ex.message))
logger.error("thread %s: '%s'" % (threading.currentThread().getName(), errMsg))
if conf.get("verbose") > 1: if conf.get("verbose") > 1:
traceback.print_exc() traceback.print_exc()
@@ -113,6 +108,7 @@ def setDaemon(thread):
def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardException=True, threadChoice=False, startThreadMsg=True): def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardException=True, threadChoice=False, startThreadMsg=True):
threads = [] threads = []
kb.multiThreadMode = True
kb.threadContinue = True kb.threadContinue = True
kb.threadException = False kb.threadException = False
@@ -154,7 +150,7 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
try: try:
thread.start() thread.start()
except Exception as ex: except Exception, ex:
errMsg = "error occurred while starting new thread ('%s')" % ex.message errMsg = "error occurred while starting new thread ('%s')" % ex.message
logger.critical(errMsg) logger.critical(errMsg)
break break
@@ -170,8 +166,8 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
alive = True alive = True
time.sleep(0.1) time.sleep(0.1)
except (KeyboardInterrupt, SqlmapUserQuitException) as ex: except (KeyboardInterrupt, SqlmapUserQuitException), ex:
print() print
kb.prependFlag = False kb.prependFlag = False
kb.threadContinue = False kb.threadContinue = False
kb.threadException = True kb.threadException = True
@@ -188,8 +184,8 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
if forwardException: if forwardException:
raise raise
except (SqlmapConnectionException, SqlmapValueException) as ex: except (SqlmapConnectionException, SqlmapValueException), ex:
print() print
kb.threadException = True kb.threadException = True
logger.error("thread %s: %s" % (threading.currentThread().getName(), ex.message)) logger.error("thread %s: %s" % (threading.currentThread().getName(), ex.message))
@@ -199,13 +195,14 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
except: except:
from lib.core.common import unhandledExceptionMessage from lib.core.common import unhandledExceptionMessage
print() print
kb.threadException = True kb.threadException = True
errMsg = unhandledExceptionMessage() errMsg = unhandledExceptionMessage()
logger.error("thread %s: %s" % (threading.currentThread().getName(), errMsg)) logger.error("thread %s: %s" % (threading.currentThread().getName(), errMsg))
traceback.print_exc() traceback.print_exc()
finally: finally:
kb.multiThreadMode = False
kb.bruteMode = False kb.bruteMode = False
kb.threadContinue = True kb.threadContinue = True
kb.threadException = False kb.threadException = False
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+6 -6
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -51,7 +51,7 @@ def update():
try: try:
open(os.path.join(directory, "sqlmap.py"), "w+b") open(os.path.join(directory, "sqlmap.py"), "w+b")
except Exception as ex: except Exception, ex:
errMsg = "unable to update content of directory '%s' ('%s')" % (directory, getSafeExString(ex)) errMsg = "unable to update content of directory '%s' ('%s')" % (directory, getSafeExString(ex))
logger.error(errMsg) logger.error(errMsg)
else: else:
@@ -85,7 +85,7 @@ def update():
version = re.search(r"(?m)^VERSION\s*=\s*['\"]([^'\"]+)", f.read()).group(1) version = re.search(r"(?m)^VERSION\s*=\s*['\"]([^'\"]+)", f.read()).group(1)
logger.info("updated to the latest version '%s#dev'" % version) logger.info("updated to the latest version '%s#dev'" % version)
success = True success = True
except Exception as ex: except Exception, ex:
logger.error("update could not be completed ('%s')" % getSafeExString(ex)) logger.error("update could not be completed ('%s')" % getSafeExString(ex))
else: else:
if not success: if not success:
@@ -103,14 +103,14 @@ def update():
debugMsg = "sqlmap will try to update itself using 'git' command" debugMsg = "sqlmap will try to update itself using 'git' command"
logger.debug(debugMsg) logger.debug(debugMsg)
dataToStdout("\r[%s] [INFO] update in progress" % time.strftime("%X")) dataToStdout("\r[%s] [INFO] update in progress " % time.strftime("%X"))
try: try:
process = subprocess.Popen("git checkout . && git pull %s HEAD" % GIT_REPOSITORY, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=paths.SQLMAP_ROOT_PATH.encode(sys.getfilesystemencoding() or UNICODE_ENCODING)) process = subprocess.Popen("git checkout . && git pull %s HEAD" % GIT_REPOSITORY, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=paths.SQLMAP_ROOT_PATH.encode(sys.getfilesystemencoding() or UNICODE_ENCODING))
pollProcess(process, True) pollProcess(process, True)
stdout, stderr = process.communicate() stdout, stderr = process.communicate()
success = not process.returncode success = not process.returncode
except (IOError, OSError) as ex: except (IOError, OSError), ex:
success = False success = False
stderr = getSafeExString(ex) stderr = getSafeExString(ex)
+6 -6
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -43,7 +43,7 @@ class Wordlist(object):
if os.path.splitext(self.current)[1].lower() == ".zip": if os.path.splitext(self.current)[1].lower() == ".zip":
try: try:
_ = zipfile.ZipFile(self.current, 'r') _ = zipfile.ZipFile(self.current, 'r')
except zipfile.error as ex: except zipfile.error, ex:
errMsg = "something appears to be wrong with " errMsg = "something appears to be wrong with "
errMsg += "the file '%s' ('%s'). Please make " % (self.current, getSafeExString(ex)) errMsg += "the file '%s' ('%s'). Please make " % (self.current, getSafeExString(ex))
errMsg += "sure that you haven't made any changes to it" errMsg += "sure that you haven't made any changes to it"
@@ -68,15 +68,15 @@ class Wordlist(object):
while True: while True:
self.counter += 1 self.counter += 1
try: try:
retVal = next(self.iter).rstrip() retVal = self.iter.next().rstrip()
except zipfile.error as ex: except zipfile.error, ex:
errMsg = "something appears to be wrong with " errMsg = "something appears to be wrong with "
errMsg += "the file '%s' ('%s'). Please make " % (self.current, getSafeExString(ex)) errMsg += "the file '%s' ('%s'). Please make " % (self.current, getSafeExString(ex))
errMsg += "sure that you haven't made any changes to it" errMsg += "sure that you haven't made any changes to it"
raise SqlmapInstallationException(errMsg) raise SqlmapInstallationException(errMsg)
except StopIteration: except StopIteration:
self.adjust() self.adjust()
retVal = next(self.iter).rstrip() retVal = self.iter.next().rstrip()
if not self.proc_count or self.counter % self.proc_count == self.proc_id: if not self.proc_count or self.counter % self.proc_count == self.proc_id:
break break
return retVal return retVal
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+17 -34
View File
@@ -1,12 +1,10 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
from __future__ import print_function
import os import os
import re import re
import shlex import shlex
@@ -22,7 +20,6 @@ from lib.core.common import checkSystemEncoding
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import expandMnemonics from lib.core.common import expandMnemonics
from lib.core.common import getUnicode from lib.core.common import getUnicode
from lib.core.compat import xrange
from lib.core.data import cmdLineOptions from lib.core.data import cmdLineOptions
from lib.core.data import conf from lib.core.data import conf
from lib.core.data import logger from lib.core.data import logger
@@ -32,7 +29,6 @@ from lib.core.exception import SqlmapShellQuitException
from lib.core.exception import SqlmapSyntaxException from lib.core.exception import SqlmapSyntaxException
from lib.core.settings import BASIC_HELP_ITEMS from lib.core.settings import BASIC_HELP_ITEMS
from lib.core.settings import DUMMY_URL from lib.core.settings import DUMMY_URL
from lib.core.settings import INFERENCE_UNKNOWN_CHAR
from lib.core.settings import IS_WIN from lib.core.settings import IS_WIN
from lib.core.settings import MAX_HELP_OPTION_LENGTH from lib.core.settings import MAX_HELP_OPTION_LENGTH
from lib.core.settings import VERSION_STRING from lib.core.settings import VERSION_STRING
@@ -103,16 +99,16 @@ def cmdLineParser(argv=None):
help="Force usage of given HTTP method (e.g. PUT)") help="Force usage of given HTTP method (e.g. PUT)")
request.add_option("--data", dest="data", request.add_option("--data", dest="data",
help="Data string to be sent through POST (e.g. \"id=1\")") help="Data string to be sent through POST")
request.add_option("--param-del", dest="paramDel", request.add_option("--param-del", dest="paramDel",
help="Character used for splitting parameter values (e.g. &)") help="Character used for splitting parameter values")
request.add_option("--cookie", dest="cookie", request.add_option("--cookie", dest="cookie",
help="HTTP Cookie header value (e.g. \"PHPSESSID=a8d127e..\")") help="HTTP Cookie header value")
request.add_option("--cookie-del", dest="cookieDel", request.add_option("--cookie-del", dest="cookieDel",
help="Character used for splitting cookie values (e.g. ;)") help="Character used for splitting cookie values")
request.add_option("--load-cookies", dest="loadCookies", request.add_option("--load-cookies", dest="loadCookies",
help="File containing cookies in Netscape/wget format") help="File containing cookies in Netscape/wget format")
@@ -148,7 +144,7 @@ def cmdLineParser(argv=None):
help="HTTP authentication PEM cert/private key file") help="HTTP authentication PEM cert/private key file")
request.add_option("--ignore-code", dest="ignoreCode", type="int", request.add_option("--ignore-code", dest="ignoreCode", type="int",
help="Ignore (problematic) HTTP error code (e.g. 401)") help="Ignore HTTP error code (e.g. 401)")
request.add_option("--ignore-proxy", dest="ignoreProxy", action="store_true", request.add_option("--ignore-proxy", dest="ignoreProxy", action="store_true",
help="Ignore system default proxy settings") help="Ignore system default proxy settings")
@@ -216,15 +212,12 @@ def cmdLineParser(argv=None):
request.add_option("--force-ssl", dest="forceSSL", action="store_true", request.add_option("--force-ssl", dest="forceSSL", action="store_true",
help="Force usage of SSL/HTTPS") help="Force usage of SSL/HTTPS")
request.add_option("--chunked", dest="chunked", action="store_true",
help="Use HTTP chunked transfer encoded (POST) requests")
request.add_option("--hpp", dest="hpp", action="store_true", request.add_option("--hpp", dest="hpp", action="store_true",
help="Use HTTP parameter pollution method") help="Use HTTP parameter pollution method")
request.add_option("--eval", dest="evalCode", request.add_option("--eval", dest="evalCode",
help="Evaluate provided Python code before the request (e.g. \"import hashlib;id2=hashlib.md5(id).hexdigest()\")") help="Evaluate provided Python code before the request (e.g. \"import hashlib;id2=hashlib.md5(id).hexdigest()\")")
# Optimization options # Optimization options
optimization = OptionGroup(parser, "Optimization", "These options can be used to optimize the performance of sqlmap") optimization = OptionGroup(parser, "Optimization", "These options can be used to optimize the performance of sqlmap")
@@ -599,12 +592,6 @@ def cmdLineParser(argv=None):
general.add_option("--parse-errors", dest="parseErrors", action="store_true", general.add_option("--parse-errors", dest="parseErrors", action="store_true",
help="Parse and display DBMS error messages from responses") help="Parse and display DBMS error messages from responses")
general.add_option("--preprocess", dest="preprocess",
help="Use given script(s) for preprocessing of response data")
general.add_option("--repair", dest="repair", action="store_true",
help="Redump entries having unknown character marker (%s)" % INFERENCE_UNKNOWN_CHAR)
general.add_option("--save", dest="saveConfig", general.add_option("--save", dest="saveConfig",
help="Save options to a configuration INI file") help="Save options to a configuration INI file")
@@ -630,7 +617,7 @@ def cmdLineParser(argv=None):
help="Run host OS command(s) when SQL injection is found") help="Run host OS command(s) when SQL injection is found")
miscellaneous.add_option("--answers", dest="answers", miscellaneous.add_option("--answers", dest="answers",
help="Set predefined answers (e.g. \"quit=N,follow=N\")") help="Set question answers (e.g. \"quit=N,follow=N\")")
miscellaneous.add_option("--beep", dest="beep", action="store_true", miscellaneous.add_option("--beep", dest="beep", action="store_true",
help="Beep on question and/or when SQL injection is found") help="Beep on question and/or when SQL injection is found")
@@ -639,7 +626,7 @@ def cmdLineParser(argv=None):
help="Clean up the DBMS from sqlmap specific UDF and tables") help="Clean up the DBMS from sqlmap specific UDF and tables")
miscellaneous.add_option("--dependencies", dest="dependencies", action="store_true", miscellaneous.add_option("--dependencies", dest="dependencies", action="store_true",
help="Check for missing (optional) sqlmap dependencies") help="Check for missing (non-core) sqlmap dependencies")
miscellaneous.add_option("--disable-coloring", dest="disableColoring", action="store_true", miscellaneous.add_option("--disable-coloring", dest="disableColoring", action="store_true",
help="Disable console output coloring") help="Disable console output coloring")
@@ -681,10 +668,6 @@ def cmdLineParser(argv=None):
help="Simple wizard interface for beginner users") help="Simple wizard interface for beginner users")
# Hidden and/or experimental options # Hidden and/or experimental options
parser.add_option("--crack", dest="hashFile",
help=SUPPRESS_HELP)
# help="Load and crack hashes from a file (standalone)")
parser.add_option("--dummy", dest="dummy", action="store_true", parser.add_option("--dummy", dest="dummy", action="store_true",
help=SUPPRESS_HELP) help=SUPPRESS_HELP)
@@ -805,7 +788,7 @@ def cmdLineParser(argv=None):
command = raw_input("sqlmap-shell> ").strip() command = raw_input("sqlmap-shell> ").strip()
command = getUnicode(command, encoding=sys.stdin.encoding) command = getUnicode(command, encoding=sys.stdin.encoding)
except (KeyboardInterrupt, EOFError): except (KeyboardInterrupt, EOFError):
print() print
raise SqlmapShellQuitException raise SqlmapShellQuitException
if not command: if not command:
@@ -827,7 +810,7 @@ def cmdLineParser(argv=None):
try: try:
for arg in shlex.split(command): for arg in shlex.split(command):
argv.append(getUnicode(arg, encoding=sys.stdin.encoding)) argv.append(getUnicode(arg, encoding=sys.stdin.encoding))
except ValueError as ex: except ValueError, ex:
raise SqlmapSyntaxException("something went wrong during command line parsing ('%s')" % ex.message) raise SqlmapSyntaxException("something went wrong during command line parsing ('%s')" % ex.message)
for i in xrange(len(argv)): for i in xrange(len(argv)):
@@ -855,7 +838,7 @@ def cmdLineParser(argv=None):
argv[i] = argv[i][:-1] argv[i] = argv[i][:-1]
conf.skipThreadCheck = True conf.skipThreadCheck = True
elif argv[i] == "--version": elif argv[i] == "--version":
print(VERSION_STRING.split('/')[-1]) print VERSION_STRING.split('/')[-1]
raise SystemExit raise SystemExit
elif argv[i] in ("-h", "--help"): elif argv[i] in ("-h", "--help"):
advancedHelp = False advancedHelp = False
@@ -879,7 +862,7 @@ def cmdLineParser(argv=None):
try: try:
(args, _) = parser.parse_args(argv) (args, _) = parser.parse_args(argv)
except UnicodeEncodeError as ex: except UnicodeEncodeError, ex:
dataToStdout("\n[!] %s\n" % ex.object.encode("unicode-escape")) dataToStdout("\n[!] %s\n" % ex.object.encode("unicode-escape"))
raise SystemExit raise SystemExit
except SystemExit: except SystemExit:
@@ -901,15 +884,15 @@ def cmdLineParser(argv=None):
if args.dummy: if args.dummy:
args.url = args.url or DUMMY_URL args.url = args.url or DUMMY_URL
if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.liveTest, args.wizard, args.dependencies, args.purge, args.sitemapUrl, args.listTampers, args.hashFile)): if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.liveTest, args.wizard, args.dependencies, args.purge, args.sitemapUrl, args.listTampers)):
errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, -x, --list-tampers, --wizard, --update, --purge or --dependencies). " errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, -x, --list-tampers, --wizard, --update, --purge or --dependencies). "
errMsg += "Use -h for basic and -hh for advanced help\n" errMsg += "Use -h for basic and -hh for advanced help\n"
parser.error(errMsg) parser.error(errMsg)
return args return args
except (OptionError, TypeError) as ex: except (OptionError, TypeError), e:
parser.error(ex) parser.error(e)
except SystemExit: except SystemExit:
# Protection against Windows dummy double clicking # Protection against Windows dummy double clicking
+4 -4
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -39,7 +39,7 @@ def configFileProxy(section, option, datatype):
value = config.getfloat(section, option) if config.get(section, option) else 0.0 value = config.getfloat(section, option) if config.get(section, option) else 0.0
else: else:
value = config.get(section, option) value = config.get(section, option)
except ValueError as ex: except ValueError, ex:
errMsg = "error occurred while processing the option " errMsg = "error occurred while processing the option "
errMsg += "'%s' in provided configuration file ('%s')" % (option, getUnicode(ex)) errMsg += "'%s' in provided configuration file ('%s')" % (option, getUnicode(ex))
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
@@ -71,7 +71,7 @@ def configFileParser(configFile):
try: try:
config = UnicodeRawConfigParser() config = UnicodeRawConfigParser()
config.readfp(configFP) config.readfp(configFP)
except Exception as ex: except Exception, ex:
errMsg = "you have provided an invalid and/or unreadable configuration file ('%s')" % getSafeExString(ex) errMsg = "you have provided an invalid and/or unreadable configuration file ('%s')" % getSafeExString(ex)
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
+3 -3
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -35,7 +35,7 @@ class FingerprintHandler(ContentHandler):
if key == "dbmsVersion": if key == "dbmsVersion":
self._info[key] = value self._info[key] = value
else: else:
if key not in self._info: if key not in self._info.keys():
self._info[key] = set() self._info[key] = set()
for _ in value.split("|"): for _ in value.split("|"):
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+6 -7
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -11,7 +11,6 @@ import re
from xml.etree import ElementTree as et from xml.etree import ElementTree as et
from lib.core.common import getSafeExString from lib.core.common import getSafeExString
from lib.core.compat import xrange
from lib.core.data import conf from lib.core.data import conf
from lib.core.data import paths from lib.core.data import paths
from lib.core.datatype import AttribDict from lib.core.datatype import AttribDict
@@ -25,8 +24,8 @@ def cleanupVals(text, tag):
if tag in ("clause", "where"): if tag in ("clause", "where"):
text = text.split(',') text = text.split(',')
if hasattr(text, "isdigit") and text.isdigit(): if isinstance(text, basestring):
text = int(text) text = int(text) if text.isdigit() else text
elif isinstance(text, list): elif isinstance(text, list):
count = 0 count = 0
@@ -79,7 +78,7 @@ def parseXmlNode(node):
def loadBoundaries(): def loadBoundaries():
try: try:
doc = et.parse(paths.BOUNDARIES_XML) doc = et.parse(paths.BOUNDARIES_XML)
except Exception as ex: except Exception, ex:
errMsg = "something appears to be wrong with " errMsg = "something appears to be wrong with "
errMsg += "the file '%s' ('%s'). Please make " % (paths.BOUNDARIES_XML, getSafeExString(ex)) errMsg += "the file '%s' ('%s'). Please make " % (paths.BOUNDARIES_XML, getSafeExString(ex))
errMsg += "sure that you haven't made any changes to it" errMsg += "sure that you haven't made any changes to it"
@@ -94,7 +93,7 @@ def loadPayloads():
try: try:
doc = et.parse(payloadFilePath) doc = et.parse(payloadFilePath)
except Exception as ex: except Exception, ex:
errMsg = "something appears to be wrong with " errMsg = "something appears to be wrong with "
errMsg += "the file '%s' ('%s'). Please make " % (payloadFilePath, getSafeExString(ex)) errMsg += "the file '%s' ('%s'). Please make " % (payloadFilePath, getSafeExString(ex))
errMsg += "sure that you haven't made any changes to it" errMsg += "sure that you haven't made any changes to it"
+6 -6
View File
@@ -1,19 +1,19 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import httplib
import re import re
from lib.core.common import readInput from lib.core.common import readInput
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.datatype import OrderedSet
from lib.core.exception import SqlmapSyntaxException from lib.core.exception import SqlmapSyntaxException
from lib.request.connect import Connect as Request from lib.request.connect import Connect as Request
from thirdparty.six.moves import http_client as _http_client from thirdparty.oset.pyoset import oset
abortedFlag = None abortedFlag = None
@@ -26,11 +26,11 @@ def parseSitemap(url, retVal=None):
try: try:
if retVal is None: if retVal is None:
abortedFlag = False abortedFlag = False
retVal = OrderedSet() retVal = oset()
try: try:
content = Request.getPage(url=url, raise404=True)[0] if not abortedFlag else "" content = Request.getPage(url=url, raise404=True)[0] if not abortedFlag else ""
except _http_client.InvalidURL: except httplib.InvalidURL:
errMsg = "invalid URL given for sitemap ('%s')" % url errMsg = "invalid URL given for sitemap ('%s')" % url
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+42 -41
View File
@@ -1,24 +1,22 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import codecs import codecs
import gzip import gzip
import io
import logging import logging
import re import re
import StringIO
import struct import struct
import zlib import zlib
from lib.core.common import Backend from lib.core.common import Backend
from lib.core.common import extractErrorMessage from lib.core.common import extractErrorMessage
from lib.core.common import extractRegexResult from lib.core.common import extractRegexResult
from lib.core.common import filterNone
from lib.core.common import getPublicTypeMembers from lib.core.common import getPublicTypeMembers
from lib.core.common import getSafeExString
from lib.core.common import getUnicode from lib.core.common import getUnicode
from lib.core.common import isListLike from lib.core.common import isListLike
from lib.core.common import randomStr from lib.core.common import randomStr
@@ -48,7 +46,7 @@ from lib.parse.headers import headersParser
from lib.parse.html import htmlParser from lib.parse.html import htmlParser
from lib.utils.htmlentities import htmlEntities from lib.utils.htmlentities import htmlEntities
from thirdparty.chardet import detect from thirdparty.chardet import detect
from thirdparty.odict import OrderedDict from thirdparty.odict.odict import OrderedDict
def forgeHeaders(items=None, base=None): def forgeHeaders(items=None, base=None):
""" """
@@ -58,7 +56,7 @@ def forgeHeaders(items=None, base=None):
items = items or {} items = items or {}
for _ in list(items.keys()): for _ in items.keys():
if items[_] is None: if items[_] is None:
del items[_] del items[_]
@@ -101,7 +99,7 @@ def forgeHeaders(items=None, base=None):
if ("%s=" % getUnicode(cookie.name)) in getUnicode(headers[HTTP_HEADER.COOKIE]): if ("%s=" % getUnicode(cookie.name)) in getUnicode(headers[HTTP_HEADER.COOKIE]):
if conf.loadCookies: if conf.loadCookies:
conf.httpHeaders = filterNone((item if item[0] != HTTP_HEADER.COOKIE else None) for item in conf.httpHeaders) conf.httpHeaders = filter(None, ((item if item[0] != HTTP_HEADER.COOKIE else None) for item in conf.httpHeaders))
elif kb.mergeCookies is None: elif kb.mergeCookies is None:
message = "you provided a HTTP %s header value. " % HTTP_HEADER.COOKIE message = "you provided a HTTP %s header value. " % HTTP_HEADER.COOKIE
message += "The target URL provided its own cookies within " message += "The target URL provided its own cookies within "
@@ -258,12 +256,12 @@ def decodePage(page, contentEncoding, contentType):
if not page or (conf.nullConnection and len(page) < 2): if not page or (conf.nullConnection and len(page) < 2):
return getUnicode(page) return getUnicode(page)
if hasattr(contentEncoding, "lower"): if isinstance(contentEncoding, basestring) and contentEncoding:
contentEncoding = contentEncoding.lower() contentEncoding = contentEncoding.lower()
else: else:
contentEncoding = "" contentEncoding = ""
if hasattr(contentType, "lower"): if isinstance(contentType, basestring) and contentType:
contentType = contentType.lower() contentType = contentType.lower()
else: else:
contentType = "" contentType = ""
@@ -274,18 +272,18 @@ def decodePage(page, contentEncoding, contentType):
try: try:
if contentEncoding == "deflate": if contentEncoding == "deflate":
data = io.BytesIO(zlib.decompress(page, -15)) # Reference: http://stackoverflow.com/questions/1089662/python-inflate-and-deflate-implementations data = StringIO.StringIO(zlib.decompress(page, -15)) # Reference: http://stackoverflow.com/questions/1089662/python-inflate-and-deflate-implementations
else: else:
data = gzip.GzipFile("", "rb", 9, io.BytesIO(page)) data = gzip.GzipFile("", "rb", 9, StringIO.StringIO(page))
size = struct.unpack("<l", page[-4:])[0] # Reference: http://pydoc.org/get.cgi/usr/local/lib/python2.5/gzip.py size = struct.unpack("<l", page[-4:])[0] # Reference: http://pydoc.org/get.cgi/usr/local/lib/python2.5/gzip.py
if size > MAX_CONNECTION_TOTAL_SIZE: if size > MAX_CONNECTION_TOTAL_SIZE:
raise Exception("size too large") raise Exception("size too large")
page = data.read() page = data.read()
except Exception as ex: except Exception, msg:
if "<html" not in page: # in some cases, invalid "Content-Encoding" appears for plain HTML (should be ignored) if "<html" not in page: # in some cases, invalid "Content-Encoding" appears for plain HTML (should be ignored)
errMsg = "detected invalid data for declared content " errMsg = "detected invalid data for declared content "
errMsg += "encoding '%s' ('%s')" % (contentEncoding, getSafeExString(ex)) errMsg += "encoding '%s' ('%s')" % (contentEncoding, msg)
singleTimeLogMessage(errMsg, logging.ERROR) singleTimeLogMessage(errMsg, logging.ERROR)
warnMsg = "turning off page compression" warnMsg = "turning off page compression"
@@ -314,40 +312,43 @@ def decodePage(page, contentEncoding, contentType):
# can't do for all responses because we need to support binary files too # can't do for all responses because we need to support binary files too
if not isinstance(page, unicode) and "text/" in contentType: if not isinstance(page, unicode) and "text/" in contentType:
# e.g. &#x9;&#195;&#235;&#224;&#226;&#224; if kb.heuristicMode:
if "&#" in page: kb.pageEncoding = kb.pageEncoding or checkCharEncoding(getHeuristicCharEncoding(page))
page = re.sub(r"&#x([0-9a-f]{1,2});", lambda _: (_.group(1) if len(_.group(1)) == 2 else "0%s" % _.group(1)).decode("hex"), page) page = getUnicode(page, kb.pageEncoding)
page = re.sub(r"&#(\d{1,3});", lambda _: chr(int(_.group(1))) if int(_.group(1)) < 256 else _.group(0), page) else:
# e.g. &#195;&#235;&#224;&#226;&#224;
if "&#" in page:
page = re.sub(r"&#(\d{1,3});", lambda _: chr(int(_.group(1))) if int(_.group(1)) < 256 else _.group(0), page)
# e.g. %20%28%29 # e.g. %20%28%29
if "%" in page: if "%" in page:
page = re.sub(r"%([0-9a-fA-F]{2})", lambda _: _.group(1).decode("hex"), page) page = re.sub(r"%([0-9a-fA-F]{2})", lambda _: _.group(1).decode("hex"), page)
# e.g. &amp; # e.g. &amp;
page = re.sub(r"&([^;]+);", lambda _: chr(htmlEntities[_.group(1)]) if htmlEntities.get(_.group(1), 256) < 256 else _.group(0), page) page = re.sub(r"&([^;]+);", lambda _: chr(htmlEntities[_.group(1)]) if htmlEntities.get(_.group(1), 256) < 256 else _.group(0), page)
kb.pageEncoding = kb.pageEncoding or checkCharEncoding(getHeuristicCharEncoding(page)) kb.pageEncoding = kb.pageEncoding or checkCharEncoding(getHeuristicCharEncoding(page))
if (kb.pageEncoding or "").lower() == "utf-8-sig": if (kb.pageEncoding or "").lower() == "utf-8-sig":
kb.pageEncoding = "utf-8" kb.pageEncoding = "utf-8"
if page and page.startswith("\xef\xbb\xbf"): # Reference: https://docs.python.org/2/library/codecs.html (Note: noticed problems when "utf-8-sig" is left to Python for handling) if page and page.startswith("\xef\xbb\xbf"): # Reference: https://docs.python.org/2/library/codecs.html (Note: noticed problems when "utf-8-sig" is left to Python for handling)
page = page[3:] page = page[3:]
page = getUnicode(page, kb.pageEncoding) page = getUnicode(page, kb.pageEncoding)
# e.g. &#8217;&#8230;&#8482; # e.g. &#8217;&#8230;&#8482;
if "&#" in page: if "&#" in page:
def _(match): def _(match):
retVal = match.group(0) retVal = match.group(0)
try: try:
retVal = unichr(int(match.group(1))) retVal = unichr(int(match.group(1)))
except (ValueError, OverflowError): except ValueError:
pass pass
return retVal return retVal
page = re.sub(r"&#(\d+);", _, page) page = re.sub(r"&#(\d+);", _, page)
# e.g. &zeta; # e.g. &zeta;
page = re.sub(r"&([^;]+);", lambda _: unichr(htmlEntities[_.group(1)]) if htmlEntities.get(_.group(1), 0) > 255 else _.group(0), page) page = re.sub(r"&([^;]+);", lambda _: unichr(htmlEntities[_.group(1)]) if htmlEntities.get(_.group(1), 0) > 255 else _.group(0), page)
return page return page
+7 -7
View File
@@ -1,19 +1,19 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
from thirdparty.six.moves import urllib as _urllib import urllib2
class SmartHTTPBasicAuthHandler(_urllib.request.HTTPBasicAuthHandler): class SmartHTTPBasicAuthHandler(urllib2.HTTPBasicAuthHandler):
""" """
Reference: http://selenic.com/hg/rev/6c51a5056020 Reference: http://selenic.com/hg/rev/6c51a5056020
Fix for a: http://bugs.python.org/issue8797 Fix for a: http://bugs.python.org/issue8797
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
_urllib.request.HTTPBasicAuthHandler.__init__(self, *args, **kwargs) urllib2.HTTPBasicAuthHandler.__init__(self, *args, **kwargs)
self.retried_req = set() self.retried_req = set()
self.retried_count = 0 self.retried_count = 0
@@ -30,8 +30,8 @@ class SmartHTTPBasicAuthHandler(_urllib.request.HTTPBasicAuthHandler):
self.retried_count = 0 self.retried_count = 0
else: else:
if self.retried_count > 5: if self.retried_count > 5:
raise _urllib.error.HTTPError(req.get_full_url(), 401, "basic auth failed", headers, None) raise urllib2.HTTPError(req.get_full_url(), 401, "basic auth failed", headers, None)
else: else:
self.retried_count += 1 self.retried_count += 1
return _urllib.request.HTTPBasicAuthHandler.http_error_auth_reqed(self, auth_header, host, req, headers) return urllib2.HTTPBasicAuthHandler.http_error_auth_reqed(self, auth_header, host, req, headers)
-43
View File
@@ -1,43 +0,0 @@
#!/usr/bin/env python2
"""
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from lib.core.data import conf
from thirdparty.six.moves import urllib as _urllib
class ChunkedHandler(_urllib.request.HTTPHandler):
"""
Ensures that HTTPHandler is working properly in case of Chunked Transfer-Encoding
"""
def _http_request(self, request):
host = request.get_host()
if not host:
raise _urllib.error.URLError("no host given")
if request.has_data(): # POST
data = request.get_data()
if not request.has_header("Content-type"):
request.add_unredirected_header(
"Content-type",
"application/x-www-form-urlencoded")
if not request.has_header("Content-length") and not conf.chunked:
request.add_unredirected_header(
"Content-length", "%d" % len(data))
sel_host = host
if request.has_proxy():
sel_host = _urllib.parse.urlsplit(request.get_selector()).netloc
if not request.has_header("Host"):
request.add_unredirected_header("Host", sel_host)
for name, value in self.parent.addheaders:
name = name.capitalize()
if not request.has_header(name):
request.add_unredirected_header(name, value)
return request
http_request = _http_request
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+138 -189
View File
@@ -1,11 +1,14 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import binascii import binascii
import compiler
import httplib
import keyword
import logging import logging
import re import re
import socket import socket
@@ -13,6 +16,9 @@ import string
import struct import struct
import time import time
import traceback import traceback
import urllib
import urllib2
import urlparse
try: try:
import websocket import websocket
@@ -26,13 +32,11 @@ from lib.core.agent import agent
from lib.core.common import asciifyUrl from lib.core.common import asciifyUrl
from lib.core.common import calculateDeltaSeconds from lib.core.common import calculateDeltaSeconds
from lib.core.common import checkSameHost from lib.core.common import checkSameHost
from lib.core.common import chunkSplitPostData
from lib.core.common import clearConsoleLine from lib.core.common import clearConsoleLine
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import escapeJsonValue from lib.core.common import escapeJsonValue
from lib.core.common import evaluateCode from lib.core.common import evaluateCode
from lib.core.common import extractRegexResult from lib.core.common import extractRegexResult
from lib.core.common import filterNone
from lib.core.common import findMultipartPostBoundary from lib.core.common import findMultipartPostBoundary
from lib.core.common import getCurrentThreadData from lib.core.common import getCurrentThreadData
from lib.core.common import getHeader from lib.core.common import getHeader
@@ -40,7 +44,6 @@ from lib.core.common import getHostHeader
from lib.core.common import getRequestHeader from lib.core.common import getRequestHeader
from lib.core.common import getSafeExString from lib.core.common import getSafeExString
from lib.core.common import getUnicode from lib.core.common import getUnicode
from lib.core.common import isMultiThreadMode
from lib.core.common import logHTTPTraffic from lib.core.common import logHTTPTraffic
from lib.core.common import pushValue from lib.core.common import pushValue
from lib.core.common import popValue from lib.core.common import popValue
@@ -58,17 +61,14 @@ from lib.core.common import unicodeencode
from lib.core.common import unsafeVariableNaming from lib.core.common import unsafeVariableNaming
from lib.core.common import urldecode from lib.core.common import urldecode
from lib.core.common import urlencode from lib.core.common import urlencode
from lib.core.compat import xrange
from lib.core.data import conf from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.datatype import AttribDict
from lib.core.decorators import stackedmethod from lib.core.decorators import stackedmethod
from lib.core.dicts import POST_HINT_CONTENT_TYPES from lib.core.dicts import POST_HINT_CONTENT_TYPES
from lib.core.enums import ADJUST_TIME_DELAY from lib.core.enums import ADJUST_TIME_DELAY
from lib.core.enums import AUTH_TYPE from lib.core.enums import AUTH_TYPE
from lib.core.enums import CUSTOM_LOGGING from lib.core.enums import CUSTOM_LOGGING
from lib.core.enums import HINT
from lib.core.enums import HTTP_HEADER from lib.core.enums import HTTP_HEADER
from lib.core.enums import HTTPMETHOD from lib.core.enums import HTTPMETHOD
from lib.core.enums import NULLCONNECTION from lib.core.enums import NULLCONNECTION
@@ -76,7 +76,7 @@ from lib.core.enums import PAYLOAD
from lib.core.enums import PLACE from lib.core.enums import PLACE
from lib.core.enums import POST_HINT from lib.core.enums import POST_HINT
from lib.core.enums import REDIRECTION from lib.core.enums import REDIRECTION
from lib.core.enums import WEB_PLATFORM from lib.core.enums import WEB_API
from lib.core.exception import SqlmapCompressionException from lib.core.exception import SqlmapCompressionException
from lib.core.exception import SqlmapConnectionException from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapGenericException from lib.core.exception import SqlmapGenericException
@@ -88,8 +88,7 @@ from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
from lib.core.settings import DEFAULT_CONTENT_TYPE from lib.core.settings import DEFAULT_CONTENT_TYPE
from lib.core.settings import DEFAULT_COOKIE_DELIMITER from lib.core.settings import DEFAULT_COOKIE_DELIMITER
from lib.core.settings import DEFAULT_GET_POST_DELIMITER from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import DEFAULT_USER_AGENT from lib.core.settings import EVALCODE_KEYWORD_SUFFIX
from lib.core.settings import EVALCODE_ENCODED_PREFIX
from lib.core.settings import HTTP_ACCEPT_HEADER_VALUE from lib.core.settings import HTTP_ACCEPT_HEADER_VALUE
from lib.core.settings import HTTP_ACCEPT_ENCODING_HEADER_VALUE from lib.core.settings import HTTP_ACCEPT_ENCODING_HEADER_VALUE
from lib.core.settings import MAX_CONNECTION_CHUNK_SIZE from lib.core.settings import MAX_CONNECTION_CHUNK_SIZE
@@ -99,8 +98,7 @@ from lib.core.settings import MAX_CONSECUTIVE_CONNECTION_ERRORS
from lib.core.settings import MAX_MURPHY_SLEEP_TIME from lib.core.settings import MAX_MURPHY_SLEEP_TIME
from lib.core.settings import META_REFRESH_REGEX from lib.core.settings import META_REFRESH_REGEX
from lib.core.settings import MIN_TIME_RESPONSES from lib.core.settings import MIN_TIME_RESPONSES
from lib.core.settings import MAX_TIME_RESPONSES from lib.core.settings import IDS_WAF_CHECK_PAYLOAD
from lib.core.settings import IPS_WAF_CHECK_PAYLOAD
from lib.core.settings import IS_WIN from lib.core.settings import IS_WIN
from lib.core.settings import LARGE_CHUNK_TRIM_MARKER from lib.core.settings import LARGE_CHUNK_TRIM_MARKER
from lib.core.settings import PAYLOAD_DELIMITER from lib.core.settings import PAYLOAD_DELIMITER
@@ -120,10 +118,7 @@ from lib.request.basic import processResponse
from lib.request.direct import direct from lib.request.direct import direct
from lib.request.comparison import comparison from lib.request.comparison import comparison
from lib.request.methodrequest import MethodRequest from lib.request.methodrequest import MethodRequest
from thirdparty import six from thirdparty.odict.odict import OrderedDict
from thirdparty.odict import OrderedDict
from thirdparty.six.moves import http_client as _http_client
from thirdparty.six.moves import urllib as _urllib
from thirdparty.socks.socks import ProxyError from thirdparty.socks.socks import ProxyError
class Connect(object): class Connect(object):
@@ -175,11 +170,9 @@ class Connect(object):
warnMsg += "(e.g. 'https://help.ubuntu.com/community/Tor')" warnMsg += "(e.g. 'https://help.ubuntu.com/community/Tor')"
else: else:
warnMsg = "if the problem persists please check that the provided " warnMsg = "if the problem persists please check that the provided "
warnMsg += "target URL is reachable. In case that it is, " warnMsg += "target URL is valid. In case that it is, you can try to rerun "
warnMsg += "you can try to rerun with " warnMsg += "with the switch '--random-agent' turned on "
if not conf.randomAgent: warnMsg += "and/or proxy switches ('--ignore-proxy', '--proxy',...)"
warnMsg += "switch '--random-agent' and/or "
warnMsg += "proxy switches ('--ignore-proxy', '--proxy',...)"
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
elif conf.threads > 1: elif conf.threads > 1:
@@ -271,20 +264,14 @@ class Connect(object):
crawling = kwargs.get("crawling", False) crawling = kwargs.get("crawling", False)
checking = kwargs.get("checking", False) checking = kwargs.get("checking", False)
skipRead = kwargs.get("skipRead", False) skipRead = kwargs.get("skipRead", False)
finalCode = kwargs.get("finalCode", False)
chunked = kwargs.get("chunked", False) or conf.chunked
if multipart: if multipart:
post = multipart post = multipart
if chunked and post:
post = _urllib.parse.unquote(post)
post = chunkSplitPostData(post)
websocket_ = url.lower().startswith("ws") websocket_ = url.lower().startswith("ws")
if not _urllib.parse.urlsplit(url).netloc: if not urlparse.urlsplit(url).netloc:
url = _urllib.parse.urljoin(conf.url, url) url = urlparse.urljoin(conf.url, url)
# flag to know if we are dealing with the same target host # flag to know if we are dealing with the same target host
target = checkSameHost(url, conf.url) target = checkSameHost(url, conf.url)
@@ -305,7 +292,7 @@ class Connect(object):
code = None code = None
status = None status = None
_ = _urllib.parse.urlsplit(url) _ = urlparse.urlsplit(url)
requestMsg = u"HTTP request [#%d]:\r\n%s " % (threadData.lastRequestUID, method or (HTTPMETHOD.POST if post is not None else HTTPMETHOD.GET)) requestMsg = u"HTTP request [#%d]:\r\n%s " % (threadData.lastRequestUID, method or (HTTPMETHOD.POST if post is not None else HTTPMETHOD.GET))
requestMsg += getUnicode(("%s%s" % (_.path or "/", ("?%s" % _.query) if _.query else "")) if not any((refreshing, crawling, checking)) else url) requestMsg += getUnicode(("%s%s" % (_.path or "/", ("?%s" % _.query) if _.query else "")) if not any((refreshing, crawling, checking)) else url)
responseMsg = u"HTTP response " responseMsg = u"HTTP response "
@@ -333,7 +320,7 @@ class Connect(object):
pass pass
elif target: elif target:
if conf.forceSSL and _urllib.parse.urlparse(url).scheme != "https": if conf.forceSSL and urlparse.urlparse(url).scheme != "https":
url = re.sub(r"(?i)\Ahttp:", "https:", url) url = re.sub(r"(?i)\Ahttp:", "https:", url)
url = re.sub(r"(?i):80/", ":443/", url) url = re.sub(r"(?i):80/", ":443/", url)
@@ -358,7 +345,7 @@ class Connect(object):
url = "%s?%s" % (url, get) url = "%s?%s" % (url, get)
requestMsg += "?%s" % get requestMsg += "?%s" % get
requestMsg += " %s" % _http_client.HTTPConnection._http_vsn_str requestMsg += " %s" % httplib.HTTPConnection._http_vsn_str
# Prepare HTTP headers # Prepare HTTP headers
headers = forgeHeaders({HTTP_HEADER.COOKIE: cookie, HTTP_HEADER.USER_AGENT: ua, HTTP_HEADER.REFERER: referer, HTTP_HEADER.HOST: host}, base=None if target else {}) headers = forgeHeaders({HTTP_HEADER.COOKIE: cookie, HTTP_HEADER.USER_AGENT: ua, HTTP_HEADER.REFERER: referer, HTTP_HEADER.HOST: host}, base=None if target else {})
@@ -372,21 +359,14 @@ class Connect(object):
if kb.proxyAuthHeader: if kb.proxyAuthHeader:
headers[HTTP_HEADER.PROXY_AUTHORIZATION] = kb.proxyAuthHeader headers[HTTP_HEADER.PROXY_AUTHORIZATION] = kb.proxyAuthHeader
if not conf.requestFile or not target: if not getHeader(headers, HTTP_HEADER.ACCEPT):
if not getHeader(headers, HTTP_HEADER.HOST): headers[HTTP_HEADER.ACCEPT] = HTTP_ACCEPT_HEADER_VALUE
headers[HTTP_HEADER.HOST] = getHostHeader(url)
if not getHeader(headers, HTTP_HEADER.ACCEPT): if not getHeader(headers, HTTP_HEADER.HOST) or not target:
headers[HTTP_HEADER.ACCEPT] = HTTP_ACCEPT_HEADER_VALUE headers[HTTP_HEADER.HOST] = getHostHeader(url)
if not getHeader(headers, HTTP_HEADER.ACCEPT_ENCODING): if not getHeader(headers, HTTP_HEADER.ACCEPT_ENCODING):
headers[HTTP_HEADER.ACCEPT_ENCODING] = HTTP_ACCEPT_ENCODING_HEADER_VALUE if kb.pageCompress else "identity" headers[HTTP_HEADER.ACCEPT_ENCODING] = HTTP_ACCEPT_ENCODING_HEADER_VALUE if kb.pageCompress else "identity"
elif conf.requestFile and getHeader(headers, HTTP_HEADER.USER_AGENT) == DEFAULT_USER_AGENT:
for header in headers:
if header.upper() == HTTP_HEADER.USER_AGENT.upper():
del headers[header]
break
if post is not None and not multipart and not getHeader(headers, HTTP_HEADER.CONTENT_TYPE): if post is not None and not multipart and not getHeader(headers, HTTP_HEADER.CONTENT_TYPE):
headers[HTTP_HEADER.CONTENT_TYPE] = POST_HINT_CONTENT_TYPES.get(kb.postHint, DEFAULT_CONTENT_TYPE) headers[HTTP_HEADER.CONTENT_TYPE] = POST_HINT_CONTENT_TYPES.get(kb.postHint, DEFAULT_CONTENT_TYPE)
@@ -402,9 +382,10 @@ class Connect(object):
if conf.keepAlive: if conf.keepAlive:
headers[HTTP_HEADER.CONNECTION] = "keep-alive" headers[HTTP_HEADER.CONNECTION] = "keep-alive"
if chunked: # Reset header values to original in case of provided request file
headers[HTTP_HEADER.TRANSFER_ENCODING] = "chunked" if target and conf.requestFile:
headers = forgeHeaders({HTTP_HEADER.COOKIE: cookie})
if auxHeaders: if auxHeaders:
headers = forgeHeaders(auxHeaders, headers) headers = forgeHeaders(auxHeaders, headers)
@@ -427,7 +408,7 @@ class Connect(object):
page = ws.recv() page = ws.recv()
ws.close() ws.close()
code = ws.status code = ws.status
status = _http_client.responses[code] status = httplib.responses[code]
class _(dict): class _(dict):
pass pass
@@ -435,7 +416,7 @@ class Connect(object):
responseHeaders = _(ws.getheaders()) responseHeaders = _(ws.getheaders())
responseHeaders.headers = ["%s: %s\r\n" % (_[0].capitalize(), _[1]) for _ in responseHeaders.items()] responseHeaders.headers = ["%s: %s\r\n" % (_[0].capitalize(), _[1]) for _ in responseHeaders.items()]
requestHeaders += "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if hasattr(key, "capitalize") else key), getUnicode(value)) for (key, value) in responseHeaders.items()]) requestHeaders += "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()])
requestMsg += "\r\n%s" % requestHeaders requestMsg += "\r\n%s" % requestHeaders
if post is not None: if post is not None:
@@ -452,11 +433,11 @@ class Connect(object):
req = MethodRequest(url, post, headers) req = MethodRequest(url, post, headers)
req.set_method(method) req.set_method(method)
elif url is not None: elif url is not None:
req = _urllib.request.Request(url, post, headers) req = urllib2.Request(url, post, headers)
else: else:
return None, None, None return None, None, None
requestHeaders += "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if hasattr(key, "capitalize") else key), getUnicode(value)) for (key, value) in req.header_items()]) requestHeaders += "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in req.header_items()])
if not getRequestHeader(req, HTTP_HEADER.COOKIE) and conf.cj: if not getRequestHeader(req, HTTP_HEADER.COOKIE) and conf.cj:
conf.cj._policy._now = conf.cj._now = int(time.time()) conf.cj._policy._now = conf.cj._now = int(time.time())
@@ -464,7 +445,7 @@ class Connect(object):
requestHeaders += "\r\n%s" % ("Cookie: %s" % ";".join("%s=%s" % (getUnicode(cookie.name), getUnicode(cookie.value)) for cookie in cookies)) requestHeaders += "\r\n%s" % ("Cookie: %s" % ";".join("%s=%s" % (getUnicode(cookie.name), getUnicode(cookie.value)) for cookie in cookies))
if post is not None: if post is not None:
if not getRequestHeader(req, HTTP_HEADER.CONTENT_LENGTH) and not chunked: if not getRequestHeader(req, HTTP_HEADER.CONTENT_LENGTH):
requestHeaders += "\r\n%s: %d" % (string.capwords(HTTP_HEADER.CONTENT_LENGTH), len(post)) requestHeaders += "\r\n%s: %d" % (string.capwords(HTTP_HEADER.CONTENT_LENGTH), len(post))
if not getRequestHeader(req, HTTP_HEADER.CONNECTION): if not getRequestHeader(req, HTTP_HEADER.CONNECTION):
@@ -475,8 +456,7 @@ class Connect(object):
if post is not None: if post is not None:
requestMsg += "\r\n\r\n%s" % getUnicode(post) requestMsg += "\r\n\r\n%s" % getUnicode(post)
if not chunked: requestMsg += "\r\n"
requestMsg += "\r\n"
if not multipart: if not multipart:
threadData.lastRequestMsg = requestMsg threadData.lastRequestMsg = requestMsg
@@ -491,7 +471,7 @@ class Connect(object):
for char in (r"\r", r"\n"): for char in (r"\r", r"\n"):
cookie.value = re.sub(r"(%s)([^ \t])" % char, r"\g<1>\t\g<2>", cookie.value) cookie.value = re.sub(r"(%s)([^ \t])" % char, r"\g<1>\t\g<2>", cookie.value)
conn = _urllib.request.urlopen(req) conn = urllib2.urlopen(req)
if not kb.authHeader and getRequestHeader(req, HTTP_HEADER.AUTHORIZATION) and (conf.authType or "").lower() == AUTH_TYPE.BASIC.lower(): if not kb.authHeader and getRequestHeader(req, HTTP_HEADER.AUTHORIZATION) and (conf.authType or "").lower() == AUTH_TYPE.BASIC.lower():
kb.authHeader = getRequestHeader(req, HTTP_HEADER.AUTHORIZATION) kb.authHeader = getRequestHeader(req, HTTP_HEADER.AUTHORIZATION)
@@ -507,7 +487,7 @@ class Connect(object):
if hasattr(conn, "redurl"): if hasattr(conn, "redurl"):
page = (threadData.lastRedirectMsg[1] if kb.redirectChoice == REDIRECTION.NO else Connect._connReadProxy(conn)) if not skipRead else None page = (threadData.lastRedirectMsg[1] if kb.redirectChoice == REDIRECTION.NO else Connect._connReadProxy(conn)) if not skipRead else None
skipLogTraffic = kb.redirectChoice == REDIRECTION.NO skipLogTraffic = kb.redirectChoice == REDIRECTION.NO
code = conn.redcode if not finalCode else code code = conn.redcode
else: else:
page = Connect._connReadProxy(conn) if not skipRead else None page = Connect._connReadProxy(conn) if not skipRead else None
@@ -547,7 +527,7 @@ class Connect(object):
if re.search(r"\Ahttps?://", refresh, re.I): if re.search(r"\Ahttps?://", refresh, re.I):
url = refresh url = refresh
else: else:
url = _urllib.parse.urljoin(url, refresh) url = urlparse.urljoin(url, refresh)
threadData.lastRedirectMsg = (threadData.lastRequestUID, page) threadData.lastRedirectMsg = (threadData.lastRequestUID, page)
kwargs["refreshing"] = True kwargs["refreshing"] = True
@@ -566,11 +546,11 @@ class Connect(object):
if hasattr(conn.fp, '_sock'): if hasattr(conn.fp, '_sock'):
conn.fp._sock.close() conn.fp._sock.close()
conn.close() conn.close()
except Exception as ex: except Exception, ex:
warnMsg = "problem occurred during connection closing ('%s')" % getSafeExString(ex) warnMsg = "problem occurred during connection closing ('%s')" % getSafeExString(ex)
logger.warn(warnMsg) logger.warn(warnMsg)
except SqlmapConnectionException as ex: except SqlmapConnectionException, ex:
if conf.proxyList and not kb.threadException: if conf.proxyList and not kb.threadException:
warnMsg = "unable to connect to the target URL ('%s')" % ex warnMsg = "unable to connect to the target URL ('%s')" % ex
logger.critical(warnMsg) logger.critical(warnMsg)
@@ -579,7 +559,7 @@ class Connect(object):
else: else:
raise raise
except _urllib.error.HTTPError as ex: except urllib2.HTTPError, ex:
page = None page = None
responseHeaders = None responseHeaders = None
@@ -601,7 +581,7 @@ class Connect(object):
except: except:
pass pass
finally: finally:
page = getUnicode(page) page = page if isinstance(page, unicode) else getUnicode(page)
code = ex.code code = ex.code
status = getSafeExString(ex) status = getSafeExString(ex)
@@ -610,10 +590,10 @@ class Connect(object):
threadData.lastHTTPError = (threadData.lastRequestUID, code, status) threadData.lastHTTPError = (threadData.lastRequestUID, code, status)
kb.httpErrorCodes[code] = kb.httpErrorCodes.get(code, 0) + 1 kb.httpErrorCodes[code] = kb.httpErrorCodes.get(code, 0) + 1
responseMsg += "[#%d] (%s %s):\r\n" % (threadData.lastRequestUID, code, status) responseMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, code, status)
if responseHeaders: if responseHeaders:
logHeaders = getUnicode("".join(responseHeaders.headers).strip()) logHeaders = "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()])
logHTTPTraffic(requestMsg, "%s%s\r\n\r\n%s" % (responseMsg, logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE]), start, time.time()) logHTTPTraffic(requestMsg, "%s%s\r\n\r\n%s" % (responseMsg, logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE]), start, time.time())
@@ -628,22 +608,22 @@ class Connect(object):
logger.log(CUSTOM_LOGGING.TRAFFIC_IN, responseMsg) logger.log(CUSTOM_LOGGING.TRAFFIC_IN, responseMsg)
if ex.code != conf.ignoreCode: if ex.code != conf.ignoreCode:
if ex.code == _http_client.UNAUTHORIZED: if ex.code == httplib.UNAUTHORIZED:
errMsg = "not authorized, try to provide right HTTP " errMsg = "not authorized, try to provide right HTTP "
errMsg += "authentication type and valid credentials (%d)" % code errMsg += "authentication type and valid credentials (%d)" % code
raise SqlmapConnectionException(errMsg) raise SqlmapConnectionException(errMsg)
elif ex.code == _http_client.NOT_FOUND: elif ex.code == httplib.NOT_FOUND:
if raise404: if raise404:
errMsg = "page not found (%d)" % code errMsg = "page not found (%d)" % code
raise SqlmapConnectionException(errMsg) raise SqlmapConnectionException(errMsg)
else: else:
debugMsg = "page not found (%d)" % code debugMsg = "page not found (%d)" % code
singleTimeLogMessage(debugMsg, logging.DEBUG) singleTimeLogMessage(debugMsg, logging.DEBUG)
elif ex.code == _http_client.GATEWAY_TIMEOUT: elif ex.code == httplib.GATEWAY_TIMEOUT:
if ignoreTimeout: if ignoreTimeout:
return None if not conf.ignoreTimeouts else "", None, None return None if not conf.ignoreTimeouts else "", None, None
else: else:
warnMsg = "unable to connect to the target URL (%d - %s)" % (ex.code, _http_client.responses[ex.code]) warnMsg = "unable to connect to the target URL (%d - %s)" % (ex.code, httplib.responses[ex.code])
if threadData.retriesCount < conf.retries and not kb.threadException: if threadData.retriesCount < conf.retries and not kb.threadException:
warnMsg += ". sqlmap is going to retry the request" warnMsg += ". sqlmap is going to retry the request"
logger.critical(warnMsg) logger.critical(warnMsg)
@@ -657,7 +637,7 @@ class Connect(object):
debugMsg = "got HTTP error code: %d (%s)" % (code, status) debugMsg = "got HTTP error code: %d (%s)" % (code, status)
logger.debug(debugMsg) logger.debug(debugMsg)
except (_urllib.error.URLError, socket.error, socket.timeout, _http_client.HTTPException, struct.error, binascii.Error, ProxyError, SqlmapCompressionException, WebSocketException, TypeError, ValueError, OverflowError): except (urllib2.URLError, socket.error, socket.timeout, httplib.HTTPException, struct.error, binascii.Error, ProxyError, SqlmapCompressionException, WebSocketException, TypeError, ValueError):
tbMsg = traceback.format_exc() tbMsg = traceback.format_exc()
if checking: if checking:
@@ -741,36 +721,24 @@ class Connect(object):
else: else:
logger.debug(warnMsg) logger.debug(warnMsg)
return Connect._retryProxy(**kwargs) return Connect._retryProxy(**kwargs)
elif kb.testMode or isMultiThreadMode(): elif kb.testMode or kb.multiThreadMode:
logger.critical(warnMsg) logger.critical(warnMsg)
return None, None, None return None, None, None
else: else:
raise SqlmapConnectionException(warnMsg) raise SqlmapConnectionException(warnMsg)
finally: finally:
if isinstance(page, six.binary_type): if isinstance(page, basestring) and not isinstance(page, unicode):
if HTTP_HEADER.CONTENT_TYPE in (responseHeaders or {}) and not re.search(TEXT_CONTENT_TYPE_REGEX, responseHeaders[HTTP_HEADER.CONTENT_TYPE]): if HTTP_HEADER.CONTENT_TYPE in (responseHeaders or {}) and not re.search(TEXT_CONTENT_TYPE_REGEX, responseHeaders[HTTP_HEADER.CONTENT_TYPE]):
page = six.text_type(page, errors="ignore") page = unicode(page, errors="ignore")
else: else:
page = getUnicode(page) page = getUnicode(page)
for function in kb.preprocessFunctions:
try:
page, responseHeaders, code = function(page, responseHeaders, code)
except Exception as ex:
errMsg = "error occurred while running preprocess "
errMsg += "function '%s' ('%s')" % (function.__name__, getSafeExString(ex))
raise SqlmapGenericException(errMsg)
threadData.lastPage = page
threadData.lastCode = code
socket.setdefaulttimeout(conf.timeout) socket.setdefaulttimeout(conf.timeout)
processResponse(page, responseHeaders, status) processResponse(page, responseHeaders, status)
if conn and getattr(conn, "redurl", None): if conn and getattr(conn, "redurl", None):
_ = _urllib.parse.urlsplit(conn.redurl) _ = urlparse.urlsplit(conn.redurl)
_ = ("%s%s" % (_.path or "/", ("?%s" % _.query) if _.query else "")) _ = ("%s%s" % (_.path or "/", ("?%s" % _.query) if _.query else ""))
requestMsg = re.sub(r"(\n[A-Z]+ ).+?( HTTP/\d)", r"\g<1>%s\g<2>" % getUnicode(_).replace("\\", "\\\\"), requestMsg, 1) requestMsg = re.sub(r"(\n[A-Z]+ ).+?( HTTP/\d)", r"\g<1>%s\g<2>" % getUnicode(_).replace("\\", "\\\\"), requestMsg, 1)
@@ -779,12 +747,12 @@ class Connect(object):
requestMsg = re.sub(r"(?i)Content-length: \d+\n", "", requestMsg) requestMsg = re.sub(r"(?i)Content-length: \d+\n", "", requestMsg)
requestMsg = re.sub(r"(?s)\n\n.+", "\n", requestMsg) requestMsg = re.sub(r"(?s)\n\n.+", "\n", requestMsg)
responseMsg += "[#%d] (%s %s):\r\n" % (threadData.lastRequestUID, conn.code, status) responseMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, conn.code, status)
else: else:
responseMsg += "[#%d] (%s %s):\r\n" % (threadData.lastRequestUID, code, status) responseMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, code, status)
if responseHeaders: if responseHeaders:
logHeaders = getUnicode("".join(responseHeaders.headers).strip()) logHeaders = "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()])
if not skipLogTraffic: if not skipLogTraffic:
logHTTPTraffic(requestMsg, "%s%s\r\n\r\n%s" % (responseMsg, logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE]), start, time.time()) logHTTPTraffic(requestMsg, "%s%s\r\n\r\n%s" % (responseMsg, logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE]), start, time.time())
@@ -839,7 +807,7 @@ class Connect(object):
if conf.httpHeaders: if conf.httpHeaders:
headers = OrderedDict(conf.httpHeaders) headers = OrderedDict(conf.httpHeaders)
contentType = max(headers[_] if _.upper() == HTTP_HEADER.CONTENT_TYPE.upper() else None for _ in headers) contentType = max(headers[_] if _.upper() == HTTP_HEADER.CONTENT_TYPE.upper() else None for _ in headers.keys())
if (kb.postHint or conf.skipUrlEncode) and postUrlEncode: if (kb.postHint or conf.skipUrlEncode) and postUrlEncode:
postUrlEncode = False postUrlEncode = False
@@ -848,38 +816,22 @@ class Connect(object):
conf.httpHeaders.append((HTTP_HEADER.CONTENT_TYPE, contentType)) conf.httpHeaders.append((HTTP_HEADER.CONTENT_TYPE, contentType))
if payload: if payload:
delimiter = conf.paramDel or (DEFAULT_GET_POST_DELIMITER if place != PLACE.COOKIE else DEFAULT_COOKIE_DELIMITER)
if not disableTampering and kb.tamperFunctions: if not disableTampering and kb.tamperFunctions:
for function in kb.tamperFunctions: for function in kb.tamperFunctions:
hints = {}
try: try:
payload = function(payload=payload, headers=auxHeaders, delimiter=delimiter, hints=hints) payload = function(payload=payload, headers=auxHeaders)
except Exception as ex: except Exception, ex:
errMsg = "error occurred while running tamper " errMsg = "error occurred while running tamper "
errMsg += "function '%s' ('%s')" % (function.__name__, getSafeExString(ex)) errMsg += "function '%s' ('%s')" % (function.func_name, getSafeExString(ex))
raise SqlmapGenericException(errMsg) raise SqlmapGenericException(errMsg)
if not isinstance(payload, six.string_types): if not isinstance(payload, basestring):
errMsg = "tamper function '%s' returns " % function.__name__ errMsg = "tamper function '%s' returns " % function.func_name
errMsg += "invalid payload type ('%s')" % type(payload) errMsg += "invalid payload type ('%s')" % type(payload)
raise SqlmapValueException(errMsg) raise SqlmapValueException(errMsg)
value = agent.replacePayload(value, payload) value = agent.replacePayload(value, payload)
if hints:
if HINT.APPEND in hints:
value = "%s%s%s" % (value, delimiter, hints[HINT.APPEND])
if HINT.PREPEND in hints:
if place == PLACE.URI:
match = re.search(r"\w+\s*=\s*%s" % PAYLOAD_DELIMITER, value) or re.search(r"[^?%s/]=\s*%s" % (re.escape(delimiter), PAYLOAD_DELIMITER), value)
if match:
value = value.replace(match.group(0), "%s%s%s" % (hints[HINT.PREPEND], delimiter, match.group(0)))
else:
value = "%s%s%s" % (hints[HINT.PREPEND], delimiter, value)
logger.log(CUSTOM_LOGGING.PAYLOAD, safecharencode(payload.replace('\\', BOUNDARY_BACKSLASH_MARKER)).replace(BOUNDARY_BACKSLASH_MARKER, '\\')) logger.log(CUSTOM_LOGGING.PAYLOAD, safecharencode(payload.replace('\\', BOUNDARY_BACKSLASH_MARKER)).replace(BOUNDARY_BACKSLASH_MARKER, '\\'))
if place == PLACE.CUSTOM_POST and kb.postHint: if place == PLACE.CUSTOM_POST and kb.postHint:
@@ -896,10 +848,10 @@ class Connect(object):
value = agent.replacePayload(value, payload) value = agent.replacePayload(value, payload)
else: else:
# GET, POST, URI and Cookie payload needs to be thoroughly URL encoded # GET, POST, URI and Cookie payload needs to be thoroughly URL encoded
if (place in (PLACE.GET, PLACE.URI, PLACE.COOKIE) or place == PLACE.CUSTOM_HEADER and value.split(',')[0].upper() == HTTP_HEADER.COOKIE.upper()) and not conf.skipUrlEncode or place in (PLACE.POST, PLACE.CUSTOM_POST) and postUrlEncode: if (place in (PLACE.GET, PLACE.URI, PLACE.COOKIE) or place == PLACE.CUSTOM_HEADER and value.split(',')[0] == HTTP_HEADER.COOKIE) and not conf.skipUrlEncode or place in (PLACE.POST, PLACE.CUSTOM_POST) and postUrlEncode:
skip = False skip = False
if place == PLACE.COOKIE or place == PLACE.CUSTOM_HEADER and value.split(',')[0].upper() == HTTP_HEADER.COOKIE.upper(): if place == PLACE.COOKIE or place == PLACE.CUSTOM_HEADER and value.split(',')[0] == HTTP_HEADER.COOKIE:
if kb.cookieEncodeChoice is None: if kb.cookieEncodeChoice is None:
msg = "do you want to URL encode cookie values (implementation specific)? %s" % ("[Y/n]" if not conf.url.endswith(".aspx") else "[y/N]") # Reference: https://support.microsoft.com/en-us/kb/313282 msg = "do you want to URL encode cookie values (implementation specific)? %s" % ("[Y/n]" if not conf.url.endswith(".aspx") else "[y/N]") # Reference: https://support.microsoft.com/en-us/kb/313282
kb.cookieEncodeChoice = readInput(msg, default='Y' if not conf.url.endswith(".aspx") else 'N', boolean=True) kb.cookieEncodeChoice = readInput(msg, default='Y' if not conf.url.endswith(".aspx") else 'N', boolean=True)
@@ -914,7 +866,7 @@ class Connect(object):
postUrlEncode = False postUrlEncode = False
if conf.hpp: if conf.hpp:
if not any(conf.url.lower().endswith(_.lower()) for _ in (WEB_PLATFORM.ASP, WEB_PLATFORM.ASPX)): if not any(conf.url.lower().endswith(_.lower()) for _ in (WEB_API.ASP, WEB_API.ASPX)):
warnMsg = "HTTP parameter pollution should work only against " warnMsg = "HTTP parameter pollution should work only against "
warnMsg += "ASP(.NET) targets" warnMsg += "ASP(.NET) targets"
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
@@ -986,92 +938,83 @@ class Connect(object):
if conf.csrfToken: if conf.csrfToken:
def _adjustParameter(paramString, parameter, newValue): def _adjustParameter(paramString, parameter, newValue):
retVal = paramString retVal = paramString
match = re.search(r"%s=[^&]*" % re.escape(parameter), paramString)
if urlencode(parameter) in paramString:
parameter = urlencode(parameter)
match = re.search(r"%s=[^&]*" % re.escape(parameter), paramString, re.I)
if match: if match:
retVal = re.sub("(?i)%s" % re.escape(match.group(0)), ("%s=%s" % (parameter, newValue)).replace('\\', r'\\'), paramString) retVal = re.sub(re.escape(match.group(0)), "%s=%s" % (parameter, newValue), paramString)
else: else:
match = re.search(r"(%s[\"']:[\"'])([^\"']+)" % re.escape(parameter), paramString, re.I) match = re.search(r"(%s[\"']:[\"'])([^\"']+)" % re.escape(parameter), paramString)
if match: if match:
retVal = re.sub("(?i)%s" % re.escape(match.group(0)), "%s%s" % (match.group(1), newValue), paramString) retVal = re.sub(re.escape(match.group(0)), "%s%s" % (match.group(1), newValue), paramString)
return retVal return retVal
token = AttribDict()
page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.data if conf.csrfUrl == conf.url else None, method=conf.method if conf.csrfUrl == conf.url else None, cookie=conf.parameters.get(PLACE.COOKIE), direct=True, silent=True, ua=conf.parameters.get(PLACE.USER_AGENT), referer=conf.parameters.get(PLACE.REFERER), host=conf.parameters.get(PLACE.HOST)) page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.data if conf.csrfUrl == conf.url else None, method=conf.method if conf.csrfUrl == conf.url else None, cookie=conf.parameters.get(PLACE.COOKIE), direct=True, silent=True, ua=conf.parameters.get(PLACE.USER_AGENT), referer=conf.parameters.get(PLACE.REFERER), host=conf.parameters.get(PLACE.HOST))
page = urldecode(page) # for anti-CSRF tokens with special characters in their name (e.g. 'foo:bar=...') token = extractRegexResult(r"(?i)<input[^>]+\bname=[\"']?%s\b[^>]*\bvalue=[\"']?(?P<result>[^>'\"]*)" % re.escape(conf.csrfToken), page or "")
match = re.search(r"(?i)<input[^>]+\bname=[\"']?(?P<name>%s)\b[^>]*\bvalue=[\"']?(?P<value>[^>'\"]*)" % conf.csrfToken, page or "", re.I)
if not match:
match = re.search(r"(?i)<input[^>]+\bvalue=[\"']?(?P<value>[^>'\"]*)[\"']?[^>]*\bname=[\"']?(?P<name>%s)\b" % conf.csrfToken, page or "", re.I)
if not match:
match = re.search(r"(?P<name>%s)[\"']:[\"'](?P<value>[^\"']+)" % conf.csrfToken, page or "", re.I)
if not match:
match = re.search(r"\b(?P<name>%s)\s*[:=]\s*(?P<value>\w+)" % conf.csrfToken, str(headers), re.I)
if not match:
match = re.search(r"\b(?P<name>%s)\s*=\s*['\"]?(?P<value>[^;'\"]+)" % conf.csrfToken, page or "", re.I)
if match:
token.name, token.value = match.group("name"), match.group("value")
match = re.search(r"String\.fromCharCode\(([\d+, ]+)\)", token.value)
if match:
token.value = "".join(chr(int(_)) for _ in match.group(1).replace(' ', "").split(','))
if not token: if not token:
if conf.csrfUrl and conf.csrfToken and conf.csrfUrl != conf.url and code == _http_client.OK: token = extractRegexResult(r"(?i)<input[^>]+\bvalue=[\"']?(?P<result>[^>'\"]*)[\"']?[^>]*\bname=[\"']?%s\b" % re.escape(conf.csrfToken), page or "")
if headers and "text/plain" in headers.get(HTTP_HEADER.CONTENT_TYPE, ""):
token.name = conf.csrfToken
token.value = page
if not token and conf.cj and any(re.search(conf.csrfToken, _.name, re.I) for _ in conf.cj): if not token:
match = re.search(r"%s[\"']:[\"']([^\"']+)" % re.escape(conf.csrfToken), page or "")
token = match.group(1) if match else None
if not token:
token = extractRegexResult(r"\b%s\s*[:=]\s*(?P<result>\w+)" % re.escape(conf.csrfToken), str(headers))
if not token:
token = extractRegexResult(r"\b%s\s*=\s*['\"]?(?P<result>[^;'\"]+)" % re.escape(conf.csrfToken), page or "")
if token:
match = re.search(r"String\.fromCharCode\(([\d+, ]+)\)", token)
if match:
token = "".join(chr(int(_)) for _ in match.group(1).replace(' ', "").split(','))
if not token:
if conf.csrfUrl != conf.url and code == httplib.OK:
if headers and "text/plain" in headers.get(HTTP_HEADER.CONTENT_TYPE, ""):
token = page
if not token and conf.cj and any(_.name == conf.csrfToken for _ in conf.cj):
for _ in conf.cj: for _ in conf.cj:
if re.search(conf.csrfToken, _.name, re.I): if _.name == conf.csrfToken:
token.name, token.value = _.name, _.value token = _.value
if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))): if not any(conf.csrfToken in _ for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))):
if post: if post:
post = "%s%s%s=%s" % (post, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value) post = "%s%s%s=%s" % (post, conf.paramDel or DEFAULT_GET_POST_DELIMITER, conf.csrfToken, token)
elif get: elif get:
get = "%s%s%s=%s" % (get, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value) get = "%s%s%s=%s" % (get, conf.paramDel or DEFAULT_GET_POST_DELIMITER, conf.csrfToken, token)
else: else:
get = "%s=%s" % (token.name, token.value) get = "%s=%s" % (conf.csrfToken, token)
break break
if not token: if not token:
errMsg = "anti-CSRF token '%s' can't be found at '%s'" % (conf.csrfToken._original, conf.csrfUrl or conf.url) errMsg = "anti-CSRF token '%s' can't be found at '%s'" % (conf.csrfToken, conf.csrfUrl or conf.url)
if not conf.csrfUrl: if not conf.csrfUrl:
errMsg += ". You can try to rerun by providing " errMsg += ". You can try to rerun by providing "
errMsg += "a valid value for option '--csrf-url'" errMsg += "a valid value for option '--csrf-url'"
raise SqlmapTokenException(errMsg) raise SqlmapTokenException(errMsg)
if token: if token:
token.value = token.value.strip("'\"") token = token.strip("'\"")
for place in (PLACE.GET, PLACE.POST): for place in (PLACE.GET, PLACE.POST):
if place in conf.parameters: if place in conf.parameters:
if place == PLACE.GET and get: if place == PLACE.GET and get:
get = _adjustParameter(get, token.name, token.value) get = _adjustParameter(get, conf.csrfToken, token)
elif place == PLACE.POST and post: elif place == PLACE.POST and post:
post = _adjustParameter(post, token.name, token.value) post = _adjustParameter(post, conf.csrfToken, token)
for i in xrange(len(conf.httpHeaders)): for i in xrange(len(conf.httpHeaders)):
if conf.httpHeaders[i][0].lower() == token.name.lower(): if conf.httpHeaders[i][0].lower() == conf.csrfToken.lower():
conf.httpHeaders[i] = (conf.httpHeaders[i][0], token.value) conf.httpHeaders[i] = (conf.httpHeaders[i][0], token)
if conf.rParam: if conf.rParam:
def _randomizeParameter(paramString, randomParameter): def _randomizeParameter(paramString, randomParameter):
retVal = paramString retVal = paramString
match = re.search(r"(\A|\b)%s=(?P<value>[^&;]*)" % re.escape(randomParameter), paramString) match = re.search(r"(\A|\b)%s=(?P<value>[^&;]+)" % re.escape(randomParameter), paramString)
if match: if match:
origValue = match.group("value") origValue = match.group("value")
retVal = re.sub(r"(\A|\b)%s=[^&;]*" % re.escape(randomParameter), "%s=%s" % (randomParameter, randomizeParameterValue(origValue)), paramString) retVal = re.sub(r"(\A|\b)%s=[^&;]+" % re.escape(randomParameter), "%s=%s" % (randomParameter, randomizeParameterValue(origValue)), paramString)
return retVal return retVal
for randomParameter in conf.rParam: for randomParameter in conf.rParam:
@@ -1090,13 +1033,14 @@ class Connect(object):
delimiter = conf.paramDel or DEFAULT_GET_POST_DELIMITER delimiter = conf.paramDel or DEFAULT_GET_POST_DELIMITER
variables = {"uri": uri, "lastPage": threadData.lastPage, "_locals": locals()} variables = {"uri": uri, "lastPage": threadData.lastPage, "_locals": locals()}
originals = {} originals = {}
keywords = keyword.kwlist
if not get and PLACE.URI in conf.parameters: if not get and PLACE.URI in conf.parameters:
query = _urllib.parse.urlsplit(uri).query or "" query = urlparse.urlsplit(uri).query or ""
else: else:
query = None query = None
for item in filterNone((get, post if not kb.postHint else None, query)): for item in filter(None, (get, post if not kb.postHint else None, query)):
for part in item.split(delimiter): for part in item.split(delimiter):
if '=' in part: if '=' in part:
name, value = part.split('=', 1) name, value = part.split('=', 1)
@@ -1104,6 +1048,8 @@ class Connect(object):
if safeVariableNaming(name) != name: if safeVariableNaming(name) != name:
conf.evalCode = re.sub(r"\b%s\b" % re.escape(name), safeVariableNaming(name), conf.evalCode) conf.evalCode = re.sub(r"\b%s\b" % re.escape(name), safeVariableNaming(name), conf.evalCode)
name = safeVariableNaming(name) name = safeVariableNaming(name)
elif name in keywords:
name = "%s%s" % (name, EVALCODE_KEYWORD_SUFFIX)
value = urldecode(value, convall=True, spaceplus=(item == post and kb.postSpaceToPlus)) value = urldecode(value, convall=True, spaceplus=(item == post and kb.postSpaceToPlus))
variables[name] = value variables[name] = value
@@ -1115,29 +1061,31 @@ class Connect(object):
if safeVariableNaming(name) != name: if safeVariableNaming(name) != name:
conf.evalCode = re.sub(r"\b%s\b" % re.escape(name), safeVariableNaming(name), conf.evalCode) conf.evalCode = re.sub(r"\b%s\b" % re.escape(name), safeVariableNaming(name), conf.evalCode)
name = safeVariableNaming(name) name = safeVariableNaming(name)
elif name in keywords:
name = "%s%s" % (name, EVALCODE_KEYWORD_SUFFIX)
value = urldecode(value, convall=True) value = urldecode(value, convall=True)
variables[name] = value variables[name] = value
while True: while True:
try: try:
compile(unicodeencode(conf.evalCode.replace(';', '\n')), "", "exec") compiler.parse(unicodeencode(conf.evalCode.replace(';', '\n')))
except SyntaxError as ex: except SyntaxError, ex:
if ex.text: if ex.text:
original = replacement = ex.text.strip() original = replacement = ex.text.strip()
if '=' in original: if '=' in original:
name, value = original.split('=', 1) name, value = original.split('=', 1)
name = name.strip() name = name.strip()
if safeVariableNaming(name) != name: if safeVariableNaming(name) != name:
replacement = re.sub(r"\b%s\b" % re.escape(name), safeVariableNaming(name), replacement) replacement = re.sub(r"\b%s\b" % re.escape(name), safeVariableNaming(name), replacement)
elif name in keywords:
replacement = re.sub(r"\b%s\b" % re.escape(name), "%s%s" % (name, EVALCODE_KEYWORD_SUFFIX), replacement)
else: else:
for _ in re.findall(r"[A-Za-z_]+", original)[::-1]: for _ in re.findall(r"[A-Za-z_]+", original)[::-1]:
if safeVariableNaming(_) != _: if _ in keywords:
replacement = replacement.replace(_, safeVariableNaming(_)) replacement = replacement.replace(_, "%s%s" % (_, EVALCODE_KEYWORD_SUFFIX))
break break
if original == replacement: if original == replacement:
conf.evalCode = conf.evalCode.replace(EVALCODE_ENCODED_PREFIX, "") conf.evalCode = conf.evalCode.replace(EVALCODE_KEYWORD_SUFFIX, "")
break break
else: else:
conf.evalCode = conf.evalCode.replace(getUnicode(ex.text.strip(), UNICODE_ENCODING), replacement) conf.evalCode = conf.evalCode.replace(getUnicode(ex.text.strip(), UNICODE_ENCODING), replacement)
@@ -1149,7 +1097,12 @@ class Connect(object):
originals.update(variables) originals.update(variables)
evaluateCode(conf.evalCode, variables) evaluateCode(conf.evalCode, variables)
for variable in list(variables.keys()): for variable in variables.keys():
if variable.endswith(EVALCODE_KEYWORD_SUFFIX):
value = variables[variable]
del variables[variable]
variables[variable.replace(EVALCODE_KEYWORD_SUFFIX, "")] = value
if unsafeVariableNaming(variable) != variable: if unsafeVariableNaming(variable) != variable:
value = variables[variable] value = variables[variable]
del variables[variable] del variables[variable]
@@ -1159,7 +1112,7 @@ class Connect(object):
for name, value in variables.items(): for name, value in variables.items():
if name != "__builtins__" and originals.get(name, "") != value: if name != "__builtins__" and originals.get(name, "") != value:
if isinstance(value, (int, six.string_types)): if isinstance(value, (basestring, int)):
found = False found = False
value = getUnicode(value, UNICODE_ENCODING) value = getUnicode(value, UNICODE_ENCODING)
@@ -1279,17 +1232,14 @@ class Connect(object):
_, headers, code = Connect.getPage(url=uri, get=get, post=post, method=method, cookie=cookie, ua=ua, referer=referer, host=host, silent=silent, auxHeaders=auxHeaders, raise404=raise404, skipRead=(kb.nullConnection == NULLCONNECTION.SKIP_READ)) _, headers, code = Connect.getPage(url=uri, get=get, post=post, method=method, cookie=cookie, ua=ua, referer=referer, host=host, silent=silent, auxHeaders=auxHeaders, raise404=raise404, skipRead=(kb.nullConnection == NULLCONNECTION.SKIP_READ))
if headers: if headers:
try: if kb.nullConnection in (NULLCONNECTION.HEAD, NULLCONNECTION.SKIP_READ) and headers.get(HTTP_HEADER.CONTENT_LENGTH):
if kb.nullConnection in (NULLCONNECTION.HEAD, NULLCONNECTION.SKIP_READ) and headers.get(HTTP_HEADER.CONTENT_LENGTH): pageLength = int(headers[HTTP_HEADER.CONTENT_LENGTH])
pageLength = int(headers[HTTP_HEADER.CONTENT_LENGTH].split(',')[0]) elif kb.nullConnection == NULLCONNECTION.RANGE and headers.get(HTTP_HEADER.CONTENT_RANGE):
elif kb.nullConnection == NULLCONNECTION.RANGE and headers.get(HTTP_HEADER.CONTENT_RANGE): pageLength = int(headers[HTTP_HEADER.CONTENT_RANGE][headers[HTTP_HEADER.CONTENT_RANGE].find('/') + 1:])
pageLength = int(headers[HTTP_HEADER.CONTENT_RANGE][headers[HTTP_HEADER.CONTENT_RANGE].find('/') + 1:])
except ValueError:
pass
finally: finally:
kb.pageCompress = popValue() kb.pageCompress = popValue()
if pageLength is None: if not pageLength:
try: try:
page, headers, code = Connect.getPage(url=uri, get=get, post=post, method=method, cookie=cookie, ua=ua, referer=referer, host=host, silent=silent, auxHeaders=auxHeaders, response=response, raise404=raise404, ignoreTimeout=timeBasedCompare) page, headers, code = Connect.getPage(url=uri, get=get, post=post, method=method, cookie=cookie, ua=ua, referer=referer, host=host, silent=silent, auxHeaders=auxHeaders, response=response, raise404=raise404, ignoreTimeout=timeBasedCompare)
except MemoryError: except MemoryError:
@@ -1302,7 +1252,7 @@ class Connect(object):
if conf.secondUrl: if conf.secondUrl:
page, headers, code = Connect.getPage(url=conf.secondUrl, cookie=cookie, ua=ua, silent=silent, auxHeaders=auxHeaders, response=response, raise404=False, ignoreTimeout=timeBasedCompare, refreshing=True) page, headers, code = Connect.getPage(url=conf.secondUrl, cookie=cookie, ua=ua, silent=silent, auxHeaders=auxHeaders, response=response, raise404=False, ignoreTimeout=timeBasedCompare, refreshing=True)
elif kb.secondReq and IPS_WAF_CHECK_PAYLOAD not in _urllib.parse.unquote(value or ""): elif kb.secondReq and IDS_WAF_CHECK_PAYLOAD not in urllib.unquote(value or ""):
def _(value): def _(value):
if kb.customInjectionMark in (value or ""): if kb.customInjectionMark in (value or ""):
if payload is None: if payload is None:
@@ -1313,9 +1263,10 @@ class Connect(object):
page, headers, code = Connect.getPage(url=_(kb.secondReq[0]), post=_(kb.secondReq[2]), method=kb.secondReq[1], cookie=kb.secondReq[3], silent=silent, auxHeaders=dict(auxHeaders, **dict(kb.secondReq[4])), response=response, raise404=False, ignoreTimeout=timeBasedCompare, refreshing=True) page, headers, code = Connect.getPage(url=_(kb.secondReq[0]), post=_(kb.secondReq[2]), method=kb.secondReq[1], cookie=kb.secondReq[3], silent=silent, auxHeaders=dict(auxHeaders, **dict(kb.secondReq[4])), response=response, raise404=False, ignoreTimeout=timeBasedCompare, refreshing=True)
threadData.lastQueryDuration = calculateDeltaSeconds(start) threadData.lastQueryDuration = calculateDeltaSeconds(start)
threadData.lastPage = page
threadData.lastCode = code
kb.originalCode = code if kb.originalCode is None else kb.originalCode kb.originalCode = kb.originalCode or code
kb.originalPage = page if kb.originalPage is None else kb.originalPage
if kb.testMode: if kb.testMode:
kb.testQueryCount += 1 kb.testQueryCount += 1
@@ -1325,8 +1276,6 @@ class Connect(object):
elif noteResponseTime: elif noteResponseTime:
kb.responseTimes.setdefault(kb.responseTimeMode, []) kb.responseTimes.setdefault(kb.responseTimeMode, [])
kb.responseTimes[kb.responseTimeMode].append(threadData.lastQueryDuration) kb.responseTimes[kb.responseTimeMode].append(threadData.lastQueryDuration)
if len(kb.responseTimes[kb.responseTimeMode]) > MAX_TIME_RESPONSES:
kb.responseTimes[kb.responseTimeMode] = kb.responseTimes[kb.responseTimeMode][-MAX_TIME_RESPONSES // 2:]
if not response and removeReflection: if not response and removeReflection:
page = removeReflectiveValues(page, payload) page = removeReflectiveValues(page, payload)
+3 -4
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -25,7 +25,6 @@ from lib.core.enums import CUSTOM_LOGGING
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import EXPECTED from lib.core.enums import EXPECTED
from lib.core.enums import TIMEOUT_STATE from lib.core.enums import TIMEOUT_STATE
from lib.core.settings import TAKEOVER_TABLE_PREFIX
from lib.core.settings import UNICODE_ENCODING from lib.core.settings import UNICODE_ENCODING
from lib.utils.timeout import timeout from lib.utils.timeout import timeout
@@ -54,7 +53,7 @@ def direct(query, content=True):
if not select and "EXEC " not in query.upper(): if not select and "EXEC " not in query.upper():
timeout(func=conf.dbmsConnector.execute, args=(query,), duration=conf.timeout, default=None) timeout(func=conf.dbmsConnector.execute, args=(query,), duration=conf.timeout, default=None)
elif not (output and ("%soutput" % TAKEOVER_TABLE_PREFIX) not in query and ("%sfile" % TAKEOVER_TABLE_PREFIX) not in query): elif not (output and "sqlmapoutput" not in query and "sqlmapfile" not in query):
output, state = timeout(func=conf.dbmsConnector.select, args=(query,), duration=conf.timeout, default=None) output, state = timeout(func=conf.dbmsConnector.select, args=(query,), duration=conf.timeout, default=None)
if state == TIMEOUT_STATE.NORMAL: if state == TIMEOUT_STATE.NORMAL:
hashDBWrite(query, output, True) hashDBWrite(query, output, True)
+5 -7
View File
@@ -1,12 +1,10 @@
#!/usr/bin/env python2 #!/usr/bin/env python
""" """
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
from __future__ import print_function
import os import os
import re import re
import socket import socket
@@ -147,13 +145,13 @@ if __name__ == "__main__":
if _ is None: if _ is None:
break break
else: else:
print("[i] %s" % _) print "[i] %s" % _
time.sleep(1) time.sleep(1)
except socket.error as ex: except socket.error, ex:
if 'Permission' in str(ex): if 'Permission' in str(ex):
print("[x] Please run with sudo/Administrator privileges") print "[x] Please run with sudo/Administrator privileges"
else: else:
raise raise
except KeyboardInterrupt: except KeyboardInterrupt:

Some files were not shown because too many files have changed in this diff Show More