Compare commits

...
56 Commits
Author SHA1 Message Date
Miroslav Stampar d465007dfe More drei updates 2019-05-02 00:45:44 +02:00
Miroslav Stampar 26c8423806 Fixes #3613 2019-04-30 14:23:28 +02:00
Miroslav Stampar 26cb07cc26 Bug fix (introduced in last hour or so) 2019-04-30 14:13:35 +02:00
Miroslav Stampar 48c55d15ea Minor update 2019-04-30 14:04:39 +02:00
Miroslav Stampar 1e03b23ccb Update (drei) 2019-04-30 13:20:31 +02:00
Miroslav Stampar 70168855f9 Update of drei testing functionality 2019-04-30 11:41:03 +02:00
Miroslav Stampar 7567ed2f71 Proper Python naming 2019-04-30 11:28:16 +02:00
Miroslav Stampar 33c110ac39 Minor drei stuff 2019-04-30 11:21:44 +02:00
Miroslav Stampar 43eedb63a8 Trivial update (unification of badges) 2019-04-30 10:31:03 +02:00
Miroslav Stampar 4eb5bbd75d Minor improvement of --parse-errors on generic SQL error messages 2019-04-30 01:33:37 +02:00
Miroslav Stampar 07e6a0a079 Adding support for multi-threading in (testing) vulnserver 2019-04-30 01:08:24 +02:00
Miroslav Stampar 4e938ea4fd Minor (testing) patch 2019-04-29 16:58:53 +02:00
Miroslav Stampar fcb31b85b6 Trivial (testing) update 2019-04-29 14:41:12 +02:00
Miroslav Stampar e0940438b3 Minor update 2019-04-29 14:19:56 +02:00
Miroslav Stampar 01e915e199 Minor (testing) update 2019-04-29 11:58:52 +02:00
Miroslav Stampar ba7ab21596 Minor update for vuln testing 2019-04-29 11:32:01 +02:00
Miroslav Stampar bbf7472b42 Adding aux (dev) script 2019-04-29 11:13:47 +02:00
Miroslav Stampar ff61417fc0 Trivial style update 2019-04-29 11:01:40 +02:00
gweeperx 14bf1e4ce7 Add INFERENCE_EQUALS_CHAR during the check for false positives (#3609)
* Update checks.py

* Update checks.py
2019-04-29 10:58:12 +02:00
Miroslav Stampar c4e3ce1dac Fixes #3598 2019-04-23 00:55:14 +02:00
Miroslav Stampar 9a0a803025 Adding new WAF script (based on identYwaf update) 2019-04-23 00:31:20 +02:00
Miroslav Stampar 9b46540e00 Adding exit code (1) in case of sqlmap fail 2019-04-19 14:36:23 +02:00
Miroslav Stampar e7469ab570 Trivial code style updates 2019-04-19 13:54:48 +02:00
Miroslav Stampar 10fe87fb4e Implementing additional self-test stuff (--vuln-test) 2019-04-19 13:28:11 +02:00
Miroslav Stampar bb7bd51d94 Some more DREI stuff 2019-04-19 11:24:34 +02:00
Miroslav Stampar da15701a55 Minor DREI updates 2019-04-18 16:06:19 +02:00
Miroslav Stampar 6b063e708e 50 bytes smaller PHP shell 2019-04-18 15:13:49 +02:00
Miroslav Stampar ba96261a28 Trivial update 2019-04-18 14:48:50 +02:00
Miroslav Stampar 552077f379 Minor patch 2019-04-18 12:05:59 +02:00
Miroslav Stampar 0f697418d9 Update regarding #545 2019-04-18 11:52:33 +02:00
Miroslav Stampar bc5b643700 One more improvement for #3587 2019-04-18 11:18:00 +02:00
Miroslav Stampar 282d4b2bea Minor cleanup 2019-04-18 11:09:17 +02:00
Miroslav Stampar 9289939ced Update for #3587 (multiple request files per option -r) 2019-04-18 11:07:58 +02:00
Miroslav Stampar 6831031cf7 Bug fix for displaying traffic output in higher verbosity levels 2019-04-18 10:55:58 +02:00
Miroslav Stampar 6dc37628a0 Minor patch for TRAFFIC messages 2019-04-18 10:42:11 +02:00
Miroslav Stampar 7c7ecc75ec Better implementation for #3592 2019-04-18 10:36:41 +02:00
Miroslav Stampar 77cb85f2b8 Update regarding #3592 2019-04-18 10:24:38 +02:00
Miroslav Stampar 9459d5ea15 Minor update 2019-04-17 17:35:44 +02:00
Miroslav Stampar 1eeb6c1f5b Related to the #3588 2019-04-17 17:20:04 +02:00
Miroslav Stampar bdf6452af6 'Safe' unicode decoding replacements 2019-04-17 17:19:22 +02:00
Miroslav Stampar 3127d5bf54 Initial support for #25 (and #1387) 2019-04-17 14:22:36 +02:00
Miroslav Stampar 9043d9dd05 Minor patching of logics in WAF scripts 2019-04-16 13:37:02 +02:00
Miroslav Stampar faf154d2b3 Update regarding #3553 2019-04-15 15:15:12 +02:00
Miroslav Stampar 9958d77572 Patch for #3583 2019-04-15 14:56:34 +02:00
Miroslav Stampar dcb8025f30 Fixes #3581 2019-04-15 13:15:21 +02:00
Miroslav Stampar 4b0edeb199 Minor name update (#3579) 2019-04-12 15:58:51 +02:00
Miroslav Stampar ef42495318 Patch regarding #3579 2019-04-12 15:54:08 +02:00
Miroslav Stampar 4d93712c4d As a matter of gratitude for #3579 2019-04-12 15:40:15 +02:00
Miroslav Stampar 1ed59267df Adding new WAF script (Issue #3579) 2019-04-12 15:35:13 +02:00
Miroslav Stampar 3cb48ffdc3 Minor adjustments for issue (hash) creation 2019-04-12 11:16:56 +02:00
tanaydin sirin 40393b29a0 Added some Turkish words for common columns. (#3573) 2019-04-12 10:23:53 +02:00
tanaydin sirin 1f0fb7ab48 Added some Turkish words for common tables. (#3575) 2019-04-12 10:22:21 +02:00
Miroslav Stampar 05f92d5d45 Fixes #3552 2019-04-08 23:49:55 +02:00
Miroslav Stampar 89c6cc725b Probably fixes #3570 2019-04-08 22:56:31 +02:00
Miroslav Stampar 3275d9c709 Minor patch (in case of continuous DROP) 2019-04-06 11:14:56 +02:00
Miroslav Stampar f445fbe75b Fixes #3566 2019-04-05 09:38:56 +02:00
147 changed files with 1013 additions and 574 deletions
+3 -1
View File
@@ -1,6 +1,8 @@
*.py[cod]
output/
__pycache__/
*.py[cod]
.sqlmap_history
traffic.txt
*~
req*.txt
.idea/
+3
View File
@@ -764,6 +764,9 @@ ultramegaman, <seclists(at)ultramegaman.com>
Vinicius, <viniciusmaxdaloop(at)gmail.com>
* for reporting a minor bug
virusdefender
* for contributing WAF scripts safeline.py
w8ay
* for contributing an implementation for chunked transfer-encoding (switch --chunked)
+1 -1
View File
@@ -1,6 +1,6 @@
# 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://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 e инструмент за тестване и проникване, с отворен код, който автоматизира процеса на откриване и използване на недостатъците на SQL база данните чрез SQL инжекция, която ги взима от сървъра. Снабден е с мощен детектор, множество специални функции за най-добрия тестер и широк спектър от функции, които могат да се използват за множество цели - извличане на данни от базата данни, достъп до основната файлова система и изпълняване на команди на операционната система.
+1 -1
View File
@@ -1,6 +1,6 @@
# 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://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 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
[![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://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** 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
[![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://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 Injection σε βάσεις δεδομένων. Έρχεται με μια δυνατή μηχανή αναγνώρισης ευπαθειών, πολλά εξειδικευμένα χαρακτηριστικά για τον απόλυτο penetration tester όπως και με ένα μεγάλο εύρος επιλογών αρχίζοντας από την αναγνώριση της βάσης δεδομένων, κατέβασμα δεδομένων της βάσης, μέχρι και πρόσβαση στο βαθύτερο σύστημα αρχείων και εκτέλεση εντολών στο απευθείας στο λειτουργικό μέσω εκτός ζώνης συνδέσεων.
+1 -1
View File
@@ -1,6 +1,6 @@
# 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://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 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
[![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://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 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
[![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://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 è 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
[![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://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インジェクションの脆弱性の検出、活用、そしてデータベースサーバ奪取のプロセスを自動化します。
強力な検出エンジン、ペネトレーションテスターのための多くのニッチ機能、持続的なデータベースのフィンガープリンティングから、データベースのデータ取得やアウトオブバンド接続を介したオペレーティング・システム上でのコマンド実行、ファイルシステムへのアクセスなどの広範囲に及ぶスイッチを提供します。
+1 -1
View File
@@ -1,6 +1,6 @@
# 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://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 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
[![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://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 é 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
[![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://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 соединение.
+1 -1
View File
@@ -1,6 +1,6 @@
# 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://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 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.
+1 -1
View File
@@ -1,6 +1,6 @@
# 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://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注入漏洞,获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的渗透测试的功能选项,包括获取数据库中存储的数据,访问操作系统文件甚至可以通过外带数据连接的方式执行操作系统命令。
+11 -6
View File
@@ -20,6 +20,11 @@ from optparse import OptionParser
if sys.version_info >= (3, 0):
xrange = range
text_type = str
string_types = (str,)
else:
text_type = unicode
string_types = (basestring,)
# Regex used for recognition of hex encoded characters
HEX_ENCODED_CHAR_REGEX = r"(?P<result>\\x[0-9A-Fa-f]{2})"
@@ -51,15 +56,15 @@ def safecharencode(value):
retVal = value
if isinstance(value, basestring):
if any([_ not in SAFE_CHARS for _ in value]):
if isinstance(value, string_types):
if any(_ not in SAFE_CHARS for _ in value):
retVal = retVal.replace(HEX_ENCODED_PREFIX, HEX_ENCODED_PREFIX_MARKER)
retVal = retVal.replace('\\', SLASH_MARKER)
for char in SAFE_ENCODE_SLASH_REPLACEMENTS:
retVal = retVal.replace(char, repr(char).strip('\''))
retVal = reduce(lambda x, y: x + (y if (y in string.printable or isinstance(value, unicode) and ord(y) >= 160) else '\\x%02x' % ord(y)), retVal, (unicode if isinstance(value, unicode) else str)())
retVal = reduce(lambda x, y: x + (y if (y in string.printable or isinstance(value, text_type) and ord(y) >= 160) else '\\x%02x' % ord(y)), retVal, type(value)())
retVal = retVal.replace(SLASH_MARKER, "\\\\")
retVal = retVal.replace(HEX_ENCODED_PREFIX_MARKER, HEX_ENCODED_PREFIX)
@@ -75,13 +80,13 @@ def safechardecode(value, binary=False):
"""
retVal = value
if isinstance(value, basestring):
if isinstance(value, string_types):
retVal = retVal.replace('\\\\', SLASH_MARKER)
while True:
match = re.search(HEX_ENCODED_CHAR_REGEX, retVal)
if match:
retVal = retVal.replace(match.group("result"), (unichr if isinstance(value, unicode) else chr)(ord(binascii.unhexlify(match.group("result").lstrip("\\x")))))
retVal = retVal.replace(match.group("result"), (unichr if isinstance(value, text_type) else chr)(ord(binascii.unhexlify(match.group("result").lstrip("\\x")))))
else:
break
@@ -91,7 +96,7 @@ def safechardecode(value, binary=False):
retVal = retVal.replace(SLASH_MARKER, '\\')
if binary:
if isinstance(retVal, unicode):
if isinstance(retVal, text_type):
retVal = retVal.encode("utf8")
elif isinstance(value, (list, tuple)):
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# Copyright (c) 2006-2013 sqlmap developers (http://sqlmap.org/)
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
# See the file 'LICENSE' for copying permission
# Removes trailing spaces from blank lines inside project files
+6 -2
View File
@@ -1,7 +1,11 @@
#!/bin/bash
# Copyright (c) 2006-2013 sqlmap developers (http://sqlmap.org/)
# Copyright (c) 2006-2019 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
export SQLMAP_DREI=1
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
unset SQLMAP_DREI
source `dirname "$0"`"/junk.sh"
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
# See the file 'LICENSE' for copying permission
find . -type d -name "__pycache__" -exec rm -rf {} \; &>/dev/null
find . -name "*.pyc" -exec rm -f {} \; &>/dev/null
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# Copyright (c) 2006-2013 sqlmap developers (http://sqlmap.org/)
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
# See the file 'LICENSE' for copying permission
# Runs py2diatra on all python files (prerequisite: pip install pydiatra)
+2 -2
View File
@@ -1,7 +1,7 @@
#!/bin/bash
# Copyright (c) 2006-2013 sqlmap developers (http://sqlmap.org/)
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
# See the file 'LICENSE' for copying permission
# Runs pyflakes on all python files (prerequisite: apt-get install pyflakes)
find . -wholename "./thirdparty" -prune -o -type f -iname "*.py" -exec pyflakes '{}' \;
find . -wholename "./thirdparty" -prune -o -type f -iname "*.py" -exec pyflakes '{}' \; | grep -v "redefines '_'"
+31 -5
View File
@@ -12,10 +12,12 @@ from __future__ import print_function
import re
import sqlite3
import sys
import threading
import traceback
if sys.version_info >= (3, 0):
from http.client import FOUND
from http.client import INTERNAL_SERVER_ERROR
from http.client import NOT_FOUND
from http.client import OK
from http.server import BaseHTTPRequestHandler
@@ -27,6 +29,7 @@ else:
from BaseHTTPServer import BaseHTTPRequestHandler
from BaseHTTPServer import HTTPServer
from httplib import FOUND
from httplib import INTERNAL_SERVER_ERROR
from httplib import NOT_FOUND
from httplib import OK
from SocketServer import ThreadingMixIn
@@ -41,7 +44,7 @@ SCHEMA = """
);
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 (3, 'wu', '179ad45c6ce2cb97cf1029e212046e81');
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');
"""
@@ -51,17 +54,28 @@ LISTEN_PORT = 8440
_conn = None
_cursor = None
_lock = None
_server = None
def init():
def init(quiet=False):
global _conn
global _cursor
global _lock
_conn = sqlite3.connect(":memory:", isolation_level=None, check_same_thread=False)
_cursor = _conn.cursor()
_lock = threading.Lock()
_cursor.executescript(SCHEMA)
if quiet:
global print
def _(*args, **kwargs):
pass
print = _
class ThreadingServer(ThreadingMixIn, HTTPServer):
def finish_request(self, *args, **kwargs):
try:
@@ -77,6 +91,13 @@ class ReqHandler(BaseHTTPRequestHandler):
if query:
params.update(parse_qs(query))
if "<script>" in unquote_plus(query):
self.send_response(INTERNAL_SERVER_ERROR)
self.send_header("Connection", "close")
self.end_headers()
self.wfile.write("CLOUDFLARE_ERROR_500S_BOX".encode("utf8"))
return
if hasattr(self, "data"):
params.update(parse_qs(self.data))
@@ -99,17 +120,19 @@ class ReqHandler(BaseHTTPRequestHandler):
self.end_headers()
try:
_cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % self.params.get("id", ""))
with _lock:
_cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % self.params.get("id", ""))
results = _cursor.fetchall()
output = "<b>SQL results:</b>\n"
output += "<table border=\"1\">\n"
for row in _cursor.fetchall():
for row in results:
output += "<tr>"
for value in row:
output += "<td>%s</td>" % value
output += "</tr>\n"
output += "</table>\n"
output += "</body></html>";
output += "</body></html>"
except Exception as ex:
output = "%s: %s" % (re.search(r"'([^']+)'", str(type(ex))).group(1), ex)
@@ -130,6 +153,9 @@ class ReqHandler(BaseHTTPRequestHandler):
self.data = data
self.do_REQUEST()
def log_message(self, format, *args):
return
def run(address=LISTEN_ADDRESS, port=LISTEN_PORT):
global _server
try:
+2 -2
View File
@@ -176,8 +176,8 @@ def action():
except:
raise
if conf.query:
conf.dumper.query(conf.query, conf.dbmsHandler.sqlQuery(conf.query))
if conf.sqlQuery:
conf.dumper.sqlQuery(conf.sqlQuery, conf.dbmsHandler.sqlQuery(conf.sqlQuery))
if conf.sqlShell:
conf.dbmsHandler.sqlShell()
+8 -9
View File
@@ -49,7 +49,6 @@ from lib.core.common import urlencode
from lib.core.common import wasLastResponseDBMSError
from lib.core.common import wasLastResponseHTTPError
from lib.core.compat import xrange
from lib.core.convert import unicodeencode
from lib.core.defaults import defaults
from lib.core.data import conf
from lib.core.data import kb
@@ -100,6 +99,7 @@ from lib.core.settings import SUPPORTED_DBMS
from lib.core.settings import UNICODE_ENCODING
from lib.core.settings import URI_HTTP_HEADER
from lib.core.settings import UPPER_RATIO_BOUND
from lib.core.settings import INFERENCE_EQUALS_CHAR
from lib.core.threads import getCurrentThreadData
from lib.request.connect import Connect as Request
from lib.request.comparison import comparison
@@ -916,27 +916,26 @@ def checkFalsePositives(injection):
if randInt3 > randInt2 > randInt1:
break
if not checkBooleanExpression("%d=%d" % (randInt1, randInt1)):
if not checkBooleanExpression("%d%s%d" % (randInt1, INFERENCE_EQUALS_CHAR, randInt1)):
retVal = False
break
# Just in case if DBMS hasn't properly recovered from previous delayed request
if PAYLOAD.TECHNIQUE.BOOLEAN not in injection.data:
checkBooleanExpression("%d=%d" % (randInt1, randInt2))
checkBooleanExpression("%d%s%d" % (randInt1, INFERENCE_EQUALS_CHAR, randInt2)) # just in case if DBMS hasn't properly recovered from previous delayed request
if checkBooleanExpression("%d=%d" % (randInt1, randInt3)): # this must not be evaluated to True
if checkBooleanExpression("%d%s%d" % (randInt1, INFERENCE_EQUALS_CHAR, randInt3)): # this must not be evaluated to True
retVal = False
break
elif checkBooleanExpression("%d=%d" % (randInt3, randInt2)): # this must not be evaluated to True
elif checkBooleanExpression("%d%s%d" % (randInt3, INFERENCE_EQUALS_CHAR, randInt2)): # this must not be evaluated to True
retVal = False
break
elif not checkBooleanExpression("%d=%d" % (randInt2, randInt2)): # this must be evaluated to True
elif not checkBooleanExpression("%d%s%d" % (randInt2, INFERENCE_EQUALS_CHAR, randInt2)): # this must be evaluated to True
retVal = False
break
elif checkBooleanExpression("%d %d" % (randInt3, randInt2)): # this must not be evaluated to True (invalid statement)
elif checkBooleanExpression("%d %d" % (randInt3, randInt2)): # this must not be evaluated to True (invalid statement)
retVal = False
break
@@ -1611,7 +1610,7 @@ def checkConnection(suppressOutput=False):
kb.errorIsNone = True
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 conf.hostname in getUnicode(threadData.lastRedirectURL[1]):
conf.url = re.sub(r"https?://", "https://", conf.url)
match = re.search(r":(\d+)", threadData.lastRedirectURL[1])
port = match.group(1) if match else 443
+9 -1
View File
@@ -48,6 +48,7 @@ from lib.core.decorators import stackedmethod
from lib.core.enums import CONTENT_TYPE
from lib.core.enums import HASHDB_KEYS
from lib.core.enums import HEURISTIC_TEST
from lib.core.enums import HTTP_HEADER
from lib.core.enums import HTTPMETHOD
from lib.core.enums import NOTE
from lib.core.enums import PAYLOAD
@@ -318,6 +319,13 @@ def start():
conf.cookie = targetCookie
conf.httpHeaders = list(initialHeaders)
conf.httpHeaders.extend(targetHeaders or [])
if conf.randomAgent or conf.mobile:
for header, value in initialHeaders:
if header.upper() == HTTP_HEADER.USER_AGENT.upper():
conf.httpHeaders.append((header, value))
break
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()
@@ -325,7 +333,7 @@ def start():
testSqlInj = False
if PLACE.GET in conf.parameters and not any([conf.data, conf.testParameter]):
if PLACE.GET in conf.parameters and not any((conf.data, conf.testParameter)):
for parameter in re.findall(r"([^=]+)=([^%s]+%s?|\Z)" % (re.escape(conf.paramDel or "") or DEFAULT_GET_POST_DELIMITER, re.escape(conf.paramDel or "") or DEFAULT_GET_POST_DELIMITER), conf.parameters[PLACE.GET]):
paramKey = (conf.hostname, conf.path, PLACE.GET, parameter[0])
+1 -1
View File
@@ -75,7 +75,7 @@ def setHandler():
(DBMS.INFORMIX, INFORMIX_ALIASES, InformixMap, InformixConn),
]
_ = max(_ if (conf.get("dbms") or Backend.getIdentifiedDbms() or kb.heuristicExtendedDbms or "").lower() in _[1] else None for _ in items)
_ = max(_ if (conf.get("dbms") or Backend.getIdentifiedDbms() or kb.heuristicExtendedDbms or "").lower() in _[1] else "" for _ in items) or None
if _:
items.remove(_)
items.insert(0, _)
+20 -12
View File
@@ -5,6 +5,7 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import base64
import re
from lib.core.common import Backend
@@ -164,6 +165,11 @@ class Agent(object):
newValue = self.cleanupPayload(newValue, origValue)
if re.sub(r" \(.+", "", parameter) in conf.base64Parameter:
# TODO: support for POST_HINT
newValue = base64.b64encode(newValue)
origValue = base64.b64encode(origValue)
if place in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER):
_ = "%s%s" % (origValue, kb.customInjectionMark)
if kb.postHint == POST_HINT.JSON and not isNumber(newValue) and not '"%s"' % _ in paramString:
@@ -300,16 +306,19 @@ class Agent(object):
if payload is None:
return
replacements = (
("[DELIMITER_START]", kb.chars.start),
("[DELIMITER_STOP]", kb.chars.stop),
("[AT_REPLACE]", kb.chars.at),
("[SPACE_REPLACE]", kb.chars.space),
("[DOLLAR_REPLACE]", kb.chars.dollar),
("[HASH_REPLACE]", kb.chars.hash_),
("[GENERIC_SQL_COMMENT]", GENERIC_SQL_COMMENT)
)
payload = reduce(lambda x, y: x.replace(y[0], y[1]), replacements, payload)
replacements = {
"[DELIMITER_START]": kb.chars.start,
"[DELIMITER_STOP]": kb.chars.stop,
"[AT_REPLACE]": kb.chars.at,
"[SPACE_REPLACE]": kb.chars.space,
"[DOLLAR_REPLACE]": kb.chars.dollar,
"[HASH_REPLACE]": kb.chars.hash_,
"[GENERIC_SQL_COMMENT]": GENERIC_SQL_COMMENT
}
for value in re.findall(r"\[[A-Z_]+\]", payload):
if value in replacements:
payload = payload.replace(value, replacements[value])
for _ in set(re.findall(r"(?i)\[RANDNUM(?:\d+)?\]", payload)):
payload = payload.replace(_, str(randomInt()))
@@ -980,8 +989,7 @@ class Agent(object):
limitedQuery = limitedQuery.replace(" (SELECT TOP %s" % startTopNums, " (SELECT TOP %d" % num)
forgeNotIn = False
else:
topNum = re.search(r"TOP\s+([\d]+)\s+", limitedQuery, re.I).group(1)
limitedQuery = limitedQuery.replace("TOP %s " % topNum, "")
limitedQuery = re.sub(r"\bTOP\s+\d+\s*", "", limitedQuery, flags=re.I)
if forgeNotIn:
limitedQuery = limitedQuery.replace("SELECT ", (limitStr % 1), 1)
+219 -128
View File
@@ -52,7 +52,6 @@ from lib.core.convert import base64unpickle
from lib.core.convert import hexdecode
from lib.core.convert import htmlunescape
from lib.core.convert import stdoutencode
from lib.core.convert import unicodeencode
from lib.core.convert import utf8encode
from lib.core.data import conf
from lib.core.data import kb
@@ -124,7 +123,7 @@ from lib.core.settings import HOST_ALIASES
from lib.core.settings import HTTP_CHUNKED_SPLIT_KEYWORDS
from lib.core.settings import IGNORE_SAVE_OPTIONS
from lib.core.settings import INFERENCE_UNKNOWN_CHAR
from lib.core.settings import INVALID_UNICODE_CHAR_FORMAT
from lib.core.settings import INVALID_UNICODE_PRIVATE_AREA
from lib.core.settings import IP_ADDRESS_REGEX
from lib.core.settings import ISSUES_PAGE
from lib.core.settings import IS_WIN
@@ -153,6 +152,7 @@ from lib.core.settings import REFLECTED_REPLACEMENT_REGEX
from lib.core.settings import REFLECTED_REPLACEMENT_TIMEOUT
from lib.core.settings import REFLECTED_VALUE_MARKER
from lib.core.settings import REFLECTIVE_MISS_THRESHOLD
from lib.core.settings import SAFE_HEX_MARKER
from lib.core.settings import SENSITIVE_DATA_REGEX
from lib.core.settings import SENSITIVE_OPTIONS
from lib.core.settings import STDIN_PIPE_DASH
@@ -177,6 +177,7 @@ from thirdparty.magic import magic
from thirdparty.odict import OrderedDict
from thirdparty.six.moves import configparser as _configparser
from thirdparty.six.moves import http_client as _http_client
from thirdparty.six.moves import input as _input
from thirdparty.six.moves import urllib as _urllib
from thirdparty.termcolor.termcolor import colored
@@ -603,7 +604,20 @@ def paramToDict(place, parameters=None):
condition |= place == PLACE.COOKIE and len(intersect((PLACE.COOKIE,), conf.testParameter, True)) > 0
if condition:
testableParameters[parameter] = "=".join(parts[1:])
value = "=".join(parts[1:])
if parameter in (conf.base64Parameter or []):
try:
oldValue = value
value = value.decode("base64")
parameters = re.sub(r"\b%s\b" % re.escape(oldValue), value, parameters)
except:
errMsg = "parameter '%s' does not contain " % parameter
errMsg += "valid Base64 encoded value ('%s')" % value
raise SqlmapValueException(errMsg)
testableParameters[parameter] = value
if not conf.multipleTargets and not (conf.csrfToken and re.search(conf.csrfToken, parameter, re.I)):
_ = urldecode(testableParameters[parameter], convall=True)
if (_.endswith("'") and _.count("'") == 1 or re.search(r'\A9{3,}', _) or re.search(r'\A-\d+\Z', _) or re.search(DUMMY_USER_INJECTION, _)) and not parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX):
@@ -868,26 +882,43 @@ def singleTimeLogMessage(message, level=logging.INFO, flag=None):
kb.singleLogFlags.add(flag)
logger.log(level, message)
def boldifyMessage(message):
def boldifyMessage(message, istty=None):
"""
Sets ANSI bold marking on entire message if parts found in predefined BOLD_PATTERNS
>>> boldifyMessage("Hello World", istty=True)
'Hello World'
>>> boldifyMessage("GET parameter id is not injectable", istty=True)
'\\x1b[1mGET parameter id is not injectable\\x1b[0m'
"""
retVal = message
if any(_ in message for _ in BOLD_PATTERNS):
retVal = setColor(message, bold=True)
retVal = setColor(message, bold=True, istty=istty)
return retVal
def setColor(message, color=None, bold=False, level=None):
def setColor(message, color=None, bold=False, level=None, istty=None):
"""
Sets ANSI color codes
>>> setColor("Hello World", color="red", istty=True)
'\\x1b[31mHello World\\x1b[0m'
"""
retVal = message
level = level or extractRegexResult(r"\[(?P<result>%s)\]" % '|'.join(_[0] for _ in getPublicTypeMembers(LOGGING_LEVELS)), message)
if isinstance(level, unicode):
level = unicodeencode(level)
if message and getattr(LOGGER_HANDLER, "is_tty", False): # colorizing handler
if message and getattr(LOGGER_HANDLER, "is_tty", False) or istty: # colorizing handler
if bold or color:
retVal = colored(message, color=color, on_color=None, attrs=("bold",) if bold else None)
elif level:
level = getattr(logging, level, None) if isinstance(level, six.string_types) else level
try:
level = getattr(logging, level, None)
except UnicodeError:
level = None
retVal = LOGGER_HANDLER.colorize(message, level)
return retVal
@@ -912,24 +943,17 @@ def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=
Writes text to the stdout (console) stream
"""
message = ""
if not kb.get("threadException"):
if forceOutput or not (getCurrentThreadData().disableStdOut or kb.get("wizardMode")):
multiThreadMode = isMultiThreadMode()
if multiThreadMode:
logging._acquireLock()
if isinstance(data, unicode):
message = stdoutencode(data)
else:
message = data
try:
if conf.get("api"):
sys.stdout.write(clearColors(message), status, content_type)
sys.stdout.write(stdoutencode(clearColors(data)), status, content_type)
else:
sys.stdout.write(setColor(message, bold=bold))
sys.stdout.write(stdoutencode(setColor(data, bold=bold)))
sys.stdout.flush()
except IOError:
@@ -975,7 +999,7 @@ def dataToOutFile(filename, data):
try:
with open(retVal, "w+b") as f: # has to stay as non-codecs because data is raw ASCII encoded data
f.write(unicodeencode(data))
f.write(getBytes(data))
except UnicodeEncodeError as ex:
_ = normalizeUnicode(filename)
if filename != _:
@@ -1039,7 +1063,7 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
elif default:
options = getUnicode(default, UNICODE_ENCODING)
else:
options = unicode()
options = six.text_type()
dataToStdout("%s%s\n" % (message, options), forceOutput=not kb.wizardMode, bold=True)
@@ -1057,7 +1081,7 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
dataToStdout("%s" % message, forceOutput=not kb.wizardMode, bold=True)
kb.prependFlag = False
retVal = raw_input().strip() or default
retVal = _input().strip() or default
retVal = getUnicode(retVal, encoding=sys.stdin.encoding) if retVal else retVal
except:
try:
@@ -1083,9 +1107,8 @@ def randomRange(start=0, stop=1000, seed=None):
"""
Returns random integer value in given range
>>> random.seed(0)
>>> randomRange(1, 500)
423
>>> randomRange(1, 500, seed=0)
9
"""
if seed is not None:
@@ -1101,9 +1124,8 @@ def randomInt(length=4, seed=None):
"""
Returns random integer value with provided number of digits
>>> random.seed(0)
>>> randomInt(6)
874254
>>> randomInt(6, seed=0)
181911
"""
if seed is not None:
@@ -1119,9 +1141,8 @@ def randomStr(length=4, lowercase=False, alphabet=None, seed=None):
"""
Returns random string value with provided number of characters
>>> random.seed(0)
>>> randomStr(6)
'RNvnAv'
>>> randomStr(6, seed=0)
'aUfWgj'
"""
if seed is not None:
@@ -1144,8 +1165,8 @@ def sanitizeStr(value):
"""
Sanitizes string value in respect to newline and line-feed characters
>>> sanitizeStr('foo\\n\\rbar')
u'foo bar'
>>> sanitizeStr('foo\\n\\rbar') == 'foo bar'
True
"""
return getUnicode(value).replace("\n", " ").replace("\r", "")
@@ -1332,7 +1353,8 @@ def weAreFrozen():
"""
Returns whether we are frozen via py2exe.
This will affect how we find out where we are located.
Reference: http://www.py2exe.org/index.cgi/WhereAmI
# Reference: http://www.py2exe.org/index.cgi/WhereAmI
"""
return hasattr(sys, "frozen")
@@ -1569,7 +1591,7 @@ def expandAsteriskForColumns(expression):
db, conf.tbl = _.split('.', 1) if '.' in _ else (None, _)
if db is None:
if expression != conf.query:
if expression != conf.sqlQuery:
conf.db = db
else:
expression = re.sub(r"([^\w])%s" % re.escape(conf.tbl), "\g<1>%s.%s" % (conf.db, conf.tbl), expression)
@@ -1827,7 +1849,7 @@ def safeFilepathEncode(filepath):
retVal = filepath
if filepath and isinstance(filepath, unicode):
if filepath and isinstance(filepath, six.text_type):
retVal = filepath.encode(sys.getfilesystemencoding() or UNICODE_ENCODING)
return retVal
@@ -1914,7 +1936,7 @@ def getFilteredPageContent(page, onlyText=True, split=" "):
retVal = page
# only if the page's charset has been successfully identified
if isinstance(page, unicode):
if isinstance(page, six.text_type):
retVal = re.sub(r"(?si)<script.+?</script>|<!--.+?-->|<style.+?</style>%s" % (r"|<[^>]+>|\t|\n|\r" if onlyText else ""), split, page)
retVal = re.sub(r"%s{2,}" % split, split, retVal)
retVal = htmlunescape(retVal.strip().strip(split))
@@ -1932,7 +1954,7 @@ def getPageWordSet(page):
retVal = set()
# only if the page's charset has been successfully identified
if isinstance(page, unicode):
if isinstance(page, six.text_type):
retVal = set(_.group(0) for _ in re.finditer(r"\w+", getFilteredPageContent(page)))
return retVal
@@ -2061,6 +2083,19 @@ def getConsoleWidth(default=80):
return width or default
def shellExec(cmd):
"""
Executes arbitrary shell command
>>> shellExec('echo 1').strip() == b'1'
True
"""
try:
return subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0] or ""
except Exception as ex:
return six.text_type(ex)
def clearConsoleLine(forceOutput=False):
"""
Clears current console line
@@ -2176,7 +2211,8 @@ def average(values):
def stdev(values):
"""
Computes standard deviation of a list of numbers.
Reference: http://www.goldb.org/corestats.html
# Reference: http://www.goldb.org/corestats.html
>>> stdev([0.9, 0.9, 0.9, 1.0, 0.8, 0.9])
0.06324555320336757
@@ -2375,12 +2411,10 @@ def getUnicode(value, encoding=None, noneToNull=False):
"""
Return the unicode representation of the supplied value:
>>> getUnicode(u'test')
u'test'
>>> getUnicode('test')
u'test'
>>> getUnicode(1)
u'1'
>>> getUnicode('test') == u'test'
True
>>> getUnicode(1) == u'1'
True
"""
if noneToNull and value is None:
@@ -2391,11 +2425,11 @@ def getUnicode(value, encoding=None, noneToNull=False):
elif isinstance(value, six.binary_type):
# Heuristics (if encoding not explicitly specified)
candidates = filterNone((encoding, kb.get("pageEncoding") if kb.get("originalPage") else None, conf.get("encoding"), UNICODE_ENCODING, sys.getfilesystemencoding()))
if all(_ in value for _ in ('<', '>')):
if all(_ in value for _ in (b'<', b'>')):
pass
elif any(_ in value for _ in (":\\", '/', '.')) and '\n' not in value:
elif any(_ in value for _ in (b":\\", b'/', b'.')) and b'\n' not in value:
candidates = filterNone((encoding, sys.getfilesystemencoding(), kb.get("pageEncoding") if kb.get("originalPage") else None, UNICODE_ENCODING, conf.get("encoding")))
elif conf.get("encoding") and '\n' not in value:
elif conf.get("encoding") and b'\n' not in value:
candidates = filterNone((encoding, conf.get("encoding"), kb.get("pageEncoding") if kb.get("originalPage") else None, sys.getfilesystemencoding(), UNICODE_ENCODING))
for candidate in candidates:
@@ -2404,14 +2438,10 @@ def getUnicode(value, encoding=None, noneToNull=False):
except UnicodeDecodeError:
pass
while True:
try:
return six.text_type(value, encoding or (kb.get("pageEncoding") if kb.get("originalPage") else None) or UNICODE_ENCODING)
except UnicodeDecodeError as ex:
try:
return six.text_type(value, UNICODE_ENCODING)
except:
value = value[:ex.start] + "".join(INVALID_UNICODE_CHAR_FORMAT % ord(_) for _ in value[ex.start:ex.end]) + value[ex.end:]
try:
return six.text_type(value, encoding or (kb.get("pageEncoding") if kb.get("originalPage") else None) or UNICODE_ENCODING)
except UnicodeDecodeError:
return six.text_type(value, UNICODE_ENCODING, errors="reversible")
elif isListLike(value):
value = list(getUnicode(_, encoding, noneToNull) for _ in value)
return value
@@ -2421,10 +2451,44 @@ def getUnicode(value, encoding=None, noneToNull=False):
except UnicodeDecodeError:
return six.text_type(str(value), errors="ignore") # encoding ignored for non-basestring instances
def decodeHex(value):
"""
Returns byte representation of provided hexadecimal value
>>> decodeHex("313233") == b"123"
True
"""
return bytes.fromhex(value) if hasattr(bytes, "fromhex") else value.decode("hex")
def getBytes(value, encoding=UNICODE_ENCODING, errors="strict"):
"""
Returns byte representation of provided Unicode value
>>> getBytes(getUnicode("foo\x01\x83\xffbar")) == b"foo\x01\x83\xffbar"
True
"""
retVal = value
if isinstance(value, six.text_type):
if INVALID_UNICODE_PRIVATE_AREA:
for char in xrange(0xF0000, 0xF00FF + 1):
value = value.replace(unichr(char), "%s%02x" % (SAFE_HEX_MARKER, char - 0xF0000))
retVal = value.encode(encoding, errors)
retVal = re.sub(r"%s([0-9a-f]{2})" % SAFE_HEX_MARKER, lambda _: decodeHex(_.group(1)), retVal)
else:
retVal = value.encode(encoding, errors)
retVal = re.sub(b"\\\\x([0-9a-f]{2})", lambda _: decodeHex(_.group(1)), retVal)
return retVal
def longestCommonPrefix(*sequences):
"""
Returns longest common prefix occuring in given sequences
Reference: http://boredzo.org/blog/archives/2007-01-06/longest-common-prefix-in-python-2
# Reference: http://boredzo.org/blog/archives/2007-01-06/longest-common-prefix-in-python-2
>>> longestCommonPrefix('foobar', 'fobar')
'fo'
@@ -2547,11 +2611,12 @@ def adjustTimeDelay(lastQueryDuration, lowerStdLimit):
kb.delayCandidates = [candidate] + kb.delayCandidates[:-1]
if all((_ == candidate for _ in kb.delayCandidates)) and candidate < conf.timeSec:
conf.timeSec = candidate
if lastQueryDuration / (1.0 * conf.timeSec / candidate) > MIN_VALID_DELAYED_RESPONSE: # Note: to prevent problems with fast responses for heavy-queries like RANDOMBLOB
conf.timeSec = candidate
infoMsg = "adjusting time delay to "
infoMsg += "%d second%s due to good response times" % (conf.timeSec, 's' if conf.timeSec > 1 else '')
logger.info(infoMsg)
infoMsg = "adjusting time delay to "
infoMsg += "%d second%s due to good response times" % (conf.timeSec, 's' if conf.timeSec > 1 else '')
logger.info(infoMsg)
def getLastRequestHTTPError():
"""
@@ -2641,6 +2706,8 @@ def urldecode(value, encoding=None, unsafe="%%&=;+%s" % CUSTOM_INJECTION_MARK_CH
>>> urldecode('AND%201%3E%282%2B3%29%23', convall=True)
u'AND 1>(2+3)#'
>>> urldecode('AND%201%3E%282%2B3%29%23', convall=False)
u'AND 1>(2%2B3)#'
"""
result = value
@@ -2655,17 +2722,19 @@ def urldecode(value, encoding=None, unsafe="%%&=;+%s" % CUSTOM_INJECTION_MARK_CH
if convall:
result = _urllib.parse.unquote_plus(value) if spaceplus else _urllib.parse.unquote(value)
else:
result = value
charset = set(string.printable) - set(unsafe)
def _(match):
charset = reduce(lambda x, y: x.replace(y, ""), unsafe, string.printable)
char = chr(ord(match.group(1).decode("hex")))
return char if char in charset else match.group(0)
result = value
if spaceplus:
result = result.replace('+', ' ') # plus sign has a special meaning in URL encoded data (hence the usage of _urllib.parse.unquote_plus in convall case)
result = re.sub(r"%([0-9a-fA-F]{2})", _, result)
if isinstance(result, str):
result = unicode(result, encoding or UNICODE_ENCODING, "replace")
result = getUnicode(result, encoding or UNICODE_ENCODING)
return result
@@ -2815,6 +2884,9 @@ def extractRegexResult(regex, content, flags=0):
retVal = None
if regex and content and "?P<result>" in regex:
if isinstance(content, six.binary_type) and isinstance(regex, six.text_type):
regex = getBytes(regex)
match = re.search(regex, content, flags)
if match:
@@ -2826,8 +2898,8 @@ def extractTextTagContent(page):
"""
Returns list containing content from "textual" tags
>>> extractTextTagContent(u'<html><head><title>Title</title></head><body><pre>foobar</pre><a href="#link">Link</a></body></html>')
[u'Title', u'foobar']
>>> extractTextTagContent('<html><head><title>Title</title></head><body><pre>foobar</pre><a href="#link">Link</a></body></html>')
['Title', 'foobar']
"""
page = page or ""
@@ -2844,8 +2916,8 @@ def trimAlphaNum(value):
"""
Trims alpha numeric characters from start and ending of a given value
>>> trimAlphaNum(u'AND 1>(2+3)-- foobar')
u' 1>(2+3)-- '
>>> trimAlphaNum('AND 1>(2+3)-- foobar')
' 1>(2+3)-- '
"""
while value and value[-1].isalnum():
@@ -2976,8 +3048,8 @@ def filterStringValue(value, charRegex, replacement=""):
Returns string value consisting only of chars satisfying supplied
regular expression (note: it has to be in form [...])
>>> filterStringValue(u'wzydeadbeef0123#', r'[0-9a-f]')
u'deadbeef0123'
>>> filterStringValue('wzydeadbeef0123#', r'[0-9a-f]')
'deadbeef0123'
"""
retVal = value
@@ -2991,8 +3063,8 @@ def filterControlChars(value, replacement=' '):
"""
Returns string value with control chars being supstituted with replacement character
>>> filterControlChars(u'AND 1>(2+3)\\n--')
u'AND 1>(2+3) --'
>>> filterControlChars('AND 1>(2+3)\\n--')
'AND 1>(2+3) --'
"""
return filterStringValue(value, PRINTABLE_CHAR_REGEX, replacement)
@@ -3214,8 +3286,8 @@ def arrayizeValue(value):
"""
Makes a list out of value if it is not already a list or tuple itself
>>> arrayizeValue(u'1')
[u'1']
>>> arrayizeValue('1')
['1']
"""
if not isListLike(value):
@@ -3227,8 +3299,8 @@ def unArrayizeValue(value):
"""
Makes a value out of iterable if it is a list or tuple itself
>>> unArrayizeValue([u'1'])
u'1'
>>> unArrayizeValue(['1'])
'1'
"""
if isListLike(value):
@@ -3246,8 +3318,8 @@ def flattenValue(value):
"""
Returns an iterator representing flat representation of a given value
>>> [_ for _ in flattenValue([[u'1'], [[u'2'], u'3']])]
[u'1', u'2', u'3']
>>> [_ for _ in flattenValue([['1'], [['2'], '3']])]
['1', '2', '3']
"""
for i in iter(value):
@@ -3263,7 +3335,7 @@ def isListLike(value):
>>> isListLike([1, 2, 3])
True
>>> isListLike(u'2')
>>> isListLike('2')
False
"""
@@ -3306,7 +3378,7 @@ def filterListValue(value, regex):
"""
if isinstance(value, list) and regex:
retVal = filter(lambda _: re.search(regex, _, re.I), value)
retVal = [_ for _ in value if re.search(regex, _, re.I)]
else:
retVal = value
@@ -3326,7 +3398,7 @@ def showHttpErrorCodes():
msg += "could mean that some kind of protection is involved (e.g. WAF)"
logger.debug(msg)
def openFile(filename, mode='r', encoding=UNICODE_ENCODING, errors="replace", buffering=1): # "buffering=1" means line buffered (Reference: http://stackoverflow.com/a/3168436)
def openFile(filename, mode='r', encoding=UNICODE_ENCODING, errors="reversible", buffering=1): # "buffering=1" means line buffered (Reference: http://stackoverflow.com/a/3168436)
"""
Returns file handle of a given filename
"""
@@ -3349,10 +3421,10 @@ def decodeIntToUnicode(value):
"""
Decodes inferenced integer value to an unicode character
>>> decodeIntToUnicode(35)
u'#'
>>> decodeIntToUnicode(64)
u'@'
>>> decodeIntToUnicode(35) == '#'
True
>>> decodeIntToUnicode(64) == '@'
True
"""
retVal = value
@@ -3383,7 +3455,8 @@ def decodeIntToUnicode(value):
def md5File(filename):
"""
Calculates MD5 digest of a file
Reference: http://stackoverflow.com/a/3431838
# Reference: http://stackoverflow.com/a/3431838
"""
checkFile(filename)
@@ -3418,6 +3491,16 @@ def checkIntegrity():
return retVal
def getDaysFromLastUpdate():
"""
Get total number of days from last update
"""
if not paths:
return
return int(time.time() - os.path.getmtime(paths.SQLMAP_SETTINGS_PATH)) // (3600 * 24)
def unhandledExceptionMessage():
"""
Returns detailed message about occurred unhandled exception
@@ -3452,7 +3535,7 @@ def getLatestRevision():
"""
Retrieves latest revision from the offical repository
>>> from lib.core.settings import VERSION; getLatestRevision() == VERSION
>>> (getLatestRevision() or " ")[0].isdigit()
True
"""
@@ -3483,6 +3566,9 @@ def createGithubIssue(errMsg, excMsg):
_ = re.sub(r"\s+line \d+", "", _)
_ = re.sub(r'File ".+?/(\w+\.py)', r"\g<1>", _)
_ = re.sub(r".+\Z", "", _)
_ = re.sub(r"(Unicode[^:]*Error:).+", r"\g<1>", _)
_ = re.sub(r"= _", "= ", _)
key = hashlib.md5(_).hexdigest()[:8]
if key in issues:
@@ -3619,21 +3705,23 @@ def decodeStringEscape(value):
retVal = value
if value and '\\' in value:
if isinstance(value, unicode):
retVal = retVal.encode(UNICODE_ENCODING)
charset = "\\%s" % string.whitespace.replace(" ", "")
for _ in charset:
retVal = retVal.replace(repr(_).strip("'"), _)
try:
retVal = codecs.escape_decode(retVal)[0]
except:
try:
retVal = retVal.decode("string_escape")
except:
charset = string.whitespace.replace(" ", "")
for _ in charset:
retVal = retVal.replace(repr(_).strip("'"), _)
return retVal
if isinstance(value, unicode):
retVal = getUnicode(retVal)
def encodeStringEscape(value):
"""
Encodes escaped string values (e.g. "\t" -> "\\t")
"""
retVal = value
if value:
charset = "\\%s" % string.whitespace.replace(" ", "")
for _ in charset:
retVal = retVal.replace(_, repr(_).strip("'"))
return retVal
@@ -3646,14 +3734,14 @@ def removeReflectiveValues(content, payload, suppressWarning=False):
retVal = content
try:
if all((content, payload)) and isinstance(content, unicode) and kb.reflectiveMechanism and not kb.heuristicMode:
if all((content, payload)) and isinstance(content, six.text_type) and kb.reflectiveMechanism and not kb.heuristicMode:
def _(value):
while 2 * REFLECTED_REPLACEMENT_REGEX in value:
value = value.replace(2 * REFLECTED_REPLACEMENT_REGEX, REFLECTED_REPLACEMENT_REGEX)
return value
payload = getUnicode(urldecode(payload.replace(PAYLOAD_DELIMITER, ""), convall=True))
regex = _(filterStringValue(payload, r"[A-Za-z0-9]", REFLECTED_REPLACEMENT_REGEX.encode("string_escape")))
regex = _(filterStringValue(payload, r"[A-Za-z0-9]", encodeStringEscape(REFLECTED_REPLACEMENT_REGEX)))
if regex != payload:
if all(part.lower() in content.lower() for part in filterNone(regex.split(REFLECTED_REPLACEMENT_REGEX))[1:]): # fast optimization check
@@ -3732,18 +3820,20 @@ def removeReflectiveValues(content, payload, suppressWarning=False):
def normalizeUnicode(value):
"""
Does an ASCII normalization of unicode strings
Reference: http://www.peterbe.com/plog/unicode-to-ascii
>>> normalizeUnicode(u'\u0161u\u0107uraj')
'sucuraj'
# Reference: http://www.peterbe.com/plog/unicode-to-ascii
>>> normalizeUnicode(u'\u0161u\u0107uraj') == u'sucuraj'
True
"""
return unicodedata.normalize("NFKD", value).encode("ascii", "ignore") if isinstance(value, unicode) else value
return getUnicode(unicodedata.normalize("NFKD", value).encode("ascii", "ignore")) if isinstance(value, six.text_type) else value
def safeSQLIdentificatorNaming(name, isTable=False):
"""
Returns a safe representation of SQL identificator name (internal data format)
Reference: http://stackoverflow.com/questions/954884/what-special-characters-are-allowed-in-t-sql-column-retVal
# Reference: http://stackoverflow.com/questions/954884/what-special-characters-are-allowed-in-t-sql-column-retVal
"""
retVal = name
@@ -3929,12 +4019,13 @@ def expandMnemonics(mnemonics, parser, args):
def safeCSValue(value):
"""
Returns value safe for CSV dumping
Reference: http://tools.ietf.org/html/rfc4180
>>> safeCSValue(u'foo, bar')
u'"foo, bar"'
>>> safeCSValue(u'foobar')
u'foobar'
# Reference: http://tools.ietf.org/html/rfc4180
>>> safeCSValue('foo, bar')
'"foo, bar"'
>>> safeCSValue('foobar')
'foobar'
"""
retVal = value
@@ -3957,7 +4048,7 @@ def filterPairValues(values):
retVal = []
if not isNoneValue(values) and hasattr(values, '__iter__'):
retVal = filter(lambda x: isinstance(x, (tuple, list, set)) and len(x) == 2, values)
retVal = [value for value in values if isinstance(value, (tuple, list, set)) and len(value) == 2]
return retVal
@@ -4027,7 +4118,7 @@ def asciifyUrl(url, forceQuote=False):
See also RFC 3987.
Reference: http://blog.elsdoerfer.name/2008/12/12/opening-iris-in-python/
# Reference: http://blog.elsdoerfer.name/2008/12/12/opening-iris-in-python/
>>> asciifyUrl(u'http://www.\u0161u\u0107uraj.com')
u'http://www.xn--uuraj-gxa24d.com'
@@ -4057,7 +4148,7 @@ def asciifyUrl(url, forceQuote=False):
# _urllib.parse.quote(s.replace('%', '')) != s.replace('%', '')
# which would trigger on all %-characters, e.g. "&".
if getUnicode(s).encode("ascii", "replace") != s or forceQuote:
return _urllib.parse.quote(s.encode(UNICODE_ENCODING) if isinstance(s, unicode) else s, safe=safe)
return _urllib.parse.quote(s.encode(UNICODE_ENCODING) if isinstance(s, six.text_type) else s, safe=safe)
return s
username = quote(parts.username, '')
@@ -4122,7 +4213,7 @@ def findPageForms(content, url, raise_=False, addToTargets=False):
class _(io.BytesIO):
def __init__(self, content, url):
io.BytesIO.__init__(self, unicodeencode(content, kb.pageEncoding) if isinstance(content, unicode) else content)
io.BytesIO.__init__(self, getBytes(content, kb.pageEncoding))
self._url = url
def geturl(self):
@@ -4383,10 +4474,10 @@ def decodeHexValue(value, raw=False):
"""
Returns value decoded from DBMS specific hexadecimal representation
>>> decodeHexValue('3132332031')
u'123 1'
>>> decodeHexValue(['0x31', '0x32'])
[u'1', u'2']
>>> decodeHexValue('3132332031') == u'123 1'
True
>>> decodeHexValue(['0x31', '0x32']) == [u'1', u'2']
True
"""
retVal = value
@@ -4411,8 +4502,8 @@ def decodeHexValue(value, raw=False):
retVal = retVal.decode("utf-16-be")
except UnicodeDecodeError:
pass
if not isinstance(retVal, unicode):
retVal = getUnicode(retVal, conf.encoding or "utf8")
if not isinstance(retVal, six.text_type):
retVal = getUnicode(retVal, conf.encoding or UNICODE_ENCODING)
return retVal
@@ -4569,14 +4660,14 @@ def getRequestHeader(request, name):
"""
Solving an issue with an urllib2 Request header case sensitivity
Reference: http://bugs.python.org/issue2275
# Reference: http://bugs.python.org/issue2275
"""
retVal = None
if request and request.headers and name:
_ = name.upper()
retVal = max(value if _ == key.upper() else None for key, value in request.header_items())
retVal = max(value if _ == key.upper() else "" for key, value in request.header_items()) or None
return retVal
@@ -4844,8 +4935,8 @@ def getSafeExString(ex, encoding=None):
Safe way how to get the proper exception represtation as a string
(Note: errors to be avoided: 1) "%s" % Exception(u'\u0161') and 2) "%s" % str(Exception(u'\u0161'))
>>> getSafeExString(SqlmapBaseException('foobar'))
u'foobar'
>>> getSafeExString(SqlmapBaseException('foobar')) == 'foobar'
True
"""
retVal = None
+4 -4
View File
@@ -37,7 +37,7 @@ class WichmannHill(random.Random):
a = int(binascii.hexlify(os.urandom(16)), 16)
except NotImplementedError:
import time
a = int(time.time() * 256) # use fractional seconds
a = int(time.time() * 256) # use fractional seconds
if not isinstance(a, int):
a = hash(a)
@@ -45,7 +45,7 @@ class WichmannHill(random.Random):
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._seed = int(x) + 1, int(y) + 1, int(z) + 1
self.gauss_next = None
@@ -78,7 +78,7 @@ class WichmannHill(random.Random):
# 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
return (x / 30269.0 + y / 30307.0 + z / 30323.0) % 1.0
def getstate(self):
"""Return internal state; can be passed to setstate() later."""
@@ -130,7 +130,7 @@ class WichmannHill(random.Random):
# Initialize from current time
import time
t = int(time.time() * 256)
t = int((t&0xffffff) ^ (t>>24))
t = int((t & 0xffffff) ^ (t >> 24))
t, x = divmod(t, 256)
t, y = divmod(t, 256)
t, z = divmod(t, 256)
+21 -18
View File
@@ -163,8 +163,10 @@ def htmlunescape(value):
retVal = value
if value and isinstance(value, six.string_types):
codes = (("&lt;", '<'), ("&gt;", '>'), ("&quot;", '"'), ("&nbsp;", ' '), ("&amp;", '&'), ("&apos;", "'"))
retVal = reduce(lambda x, y: x.replace(y[0], y[1]), codes, retVal)
replacements = (("&lt;", '<'), ("&gt;", '>'), ("&quot;", '"'), ("&nbsp;", ' '), ("&amp;", '&'), ("&apos;", "'"))
for code, value in replacements:
retVal = retVal.replace(code, value)
try:
retVal = re.sub(r"&#x([^ ;]+);", lambda match: unichr(int(match.group(1), 16)), retVal)
except ValueError:
@@ -177,25 +179,26 @@ def singleTimeWarnMessage(message): # Cross-referenced function
sys.stdout.flush()
def stdoutencode(data):
retVal = None
retVal = data
try:
retVal = unicodeencode(data or "", sys.stdout.encoding)
if six.PY2:
try:
retVal = unicodeencode(data or "", sys.stdout.encoding)
# Reference: http://bugs.python.org/issue1602
if IS_WIN:
if '?' in retVal and '?' not in retVal:
warnMsg = "cannot properly display Unicode characters "
warnMsg += "inside Windows OS command prompt "
warnMsg += "(http://bugs.python.org/issue1602). All "
warnMsg += "unhandled occurrences will result in "
warnMsg += "replacement with '?' character. Please, find "
warnMsg += "proper character representation inside "
warnMsg += "corresponding output files. "
singleTimeWarnMessage(warnMsg)
# Reference: http://bugs.python.org/issue1602
if IS_WIN:
if '?' in retVal and '?' not in retVal:
warnMsg = "cannot properly display Unicode characters "
warnMsg += "inside Windows OS command prompt "
warnMsg += "(http://bugs.python.org/issue1602). All "
warnMsg += "unhandled occurrences will result in "
warnMsg += "replacement with '?' character. Please, find "
warnMsg += "proper character representation inside "
warnMsg += "corresponding output files. "
singleTimeWarnMessage(warnMsg)
except:
retVal = unicodeencode(data or "")
except:
retVal = unicodeencode(data or "")
return retVal
+2 -1
View File
@@ -10,6 +10,7 @@ import hashlib
import threading
from lib.core.settings import MAX_CACHE_ITEMS
from lib.core.settings import UNICODE_ENCODING
from lib.core.datatype import LRUDict
from lib.core.threads import getCurrentThreadData
@@ -24,7 +25,7 @@ def cachedmethod(f, cache=LRUDict(capacity=MAX_CACHE_ITEMS)):
@functools.wraps(f)
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)).encode(UNICODE_ENCODING)).hexdigest(), 16) & 0x7fffffffffffffff
try:
with _lock:
+10 -10
View File
@@ -17,6 +17,7 @@ from lib.core.common import Backend
from lib.core.common import checkFile
from lib.core.common import dataToDumpFile
from lib.core.common import dataToStdout
from lib.core.common import getBytes
from lib.core.common import getSafeExString
from lib.core.common import getUnicode
from lib.core.common import isListLike
@@ -26,7 +27,6 @@ from lib.core.common import openFile
from lib.core.common import prioritySortColumns
from lib.core.common import randomInt
from lib.core.common import safeCSValue
from lib.core.common import unicodeencode
from lib.core.common import unsafeSQLIdentificatorNaming
from lib.core.compat import xrange
from lib.core.data import conf
@@ -242,7 +242,7 @@ class Dump(object):
if table and isListLike(table):
table = table[0]
maxlength = max(maxlength, len(unsafeSQLIdentificatorNaming(normalizeUnicode(table) or unicode(table))))
maxlength = max(maxlength, len(unsafeSQLIdentificatorNaming(normalizeUnicode(table) or getUnicode(table))))
lines = "-" * (int(maxlength) + 2)
@@ -263,7 +263,7 @@ class Dump(object):
table = table[0]
table = unsafeSQLIdentificatorNaming(table)
blank = " " * (maxlength - len(normalizeUnicode(table) or unicode(table)))
blank = " " * (maxlength - len(normalizeUnicode(table) or getUnicode(table)))
self._write("| %s%s |" % (table, blank))
self._write("+%s+\n" % lines)
@@ -358,7 +358,7 @@ class Dump(object):
for ctables in dbTables.values():
for tables in ctables.values():
for table in tables:
maxlength1 = max(maxlength1, len(normalizeUnicode(table) or unicode(table)))
maxlength1 = max(maxlength1, len(normalizeUnicode(table) or getUnicode(table)))
for db, counts in dbTables.items():
self._write("Database: %s" % unsafeSQLIdentificatorNaming(db) if db else "Current database")
@@ -384,7 +384,7 @@ class Dump(object):
tables.sort(key=lambda _: _.lower() if hasattr(_, "lower") else _)
for table in tables:
blank1 = " " * (maxlength1 - len(normalizeUnicode(table) or unicode(table)))
blank1 = " " * (maxlength1 - len(normalizeUnicode(table) or getUnicode(table)))
blank2 = " " * (maxlength2 - len(str(count)))
self._write("| %s%s | %d%s |" % (table, blank1, count, blank2))
@@ -422,8 +422,8 @@ class Dump(object):
except:
warnFile = True
_ = unicodeencode(re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, unsafeSQLIdentificatorNaming(db)))
dumpDbPath = os.path.join(conf.dumpPath, "%s-%s" % (_, hashlib.md5(unicodeencode(db)).hexdigest()[:8]))
_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, unsafeSQLIdentificatorNaming(db))
dumpDbPath = os.path.join(conf.dumpPath, "%s-%s" % (_, hashlib.md5(getBytes(db)).hexdigest()[:8]))
if not os.path.isdir(dumpDbPath):
try:
@@ -456,8 +456,8 @@ class Dump(object):
_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, normalizeUnicode(unsafeSQLIdentificatorNaming(table)))
if len(_) < len(table) or IS_WIN and table.upper() in WINDOWS_RESERVED_NAMES:
_ = unicodeencode(re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, unsafeSQLIdentificatorNaming(table)))
dumpFileName = os.path.join(dumpDbPath, "%s-%s.%s" % (_, hashlib.md5(unicodeencode(table)).hexdigest()[:8], conf.dumpFormat.lower()))
_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, unsafeSQLIdentificatorNaming(table))
dumpFileName = os.path.join(dumpDbPath, "%s-%s.%s" % (_, hashlib.md5(getBytes(table)).hexdigest()[:8], conf.dumpFormat.lower()))
else:
dumpFileName = os.path.join(dumpDbPath, "%s.%s" % (_, conf.dumpFormat.lower()))
else:
@@ -704,7 +704,7 @@ class Dump(object):
self.dbTableColumns(_)
def query(self, query, queryRes):
def sqlQuery(self, query, queryRes):
self.string(query, queryRes, content_type=CONTENT_TYPE.SQL_QUERY)
def rFile(self, fileData):
+25 -14
View File
@@ -293,22 +293,25 @@ def _setRequestFromFile():
"""
if conf.requestFile:
conf.requestFile = safeExpandUser(conf.requestFile)
seen = set()
for requestFile in re.split(PARAMETER_SPLITTING_REGEX, conf.requestFile):
requestFile = safeExpandUser(requestFile)
seen = set()
if not checkFile(conf.requestFile, False):
errMsg = "specified HTTP request file '%s' " % conf.requestFile
errMsg += "does not exist"
raise SqlmapFilePathException(errMsg)
if not checkFile(requestFile, False):
errMsg = "specified HTTP request file '%s' " % requestFile
errMsg += "does not exist"
raise SqlmapFilePathException(errMsg)
infoMsg = "parsing HTTP request from '%s'" % conf.requestFile
logger.info(infoMsg)
infoMsg = "parsing HTTP request from '%s'" % requestFile
logger.info(infoMsg)
for target in parseRequestFile(conf.requestFile):
url = target[0]
if url not in seen:
kb.targets.add(target)
seen.add(url)
for target in parseRequestFile(requestFile):
url = target[0]
if url not in seen:
kb.targets.add(target)
if len(kb.targets) > 1:
conf.multipleTargets = True
seen.add(url)
if conf.secondReq:
conf.secondReq = safeExpandUser(conf.secondReq)
@@ -1140,6 +1143,7 @@ def _setHTTPHandlers():
handlers.append(keepAliveHandler)
opener = _urllib.request.build_opener(*handlers)
opener.addheaders = [] # Note: clearing default "User-Agent: Python-urllib/X.Y"
_urllib.request.install_opener(opener)
def _setSafeVisit():
@@ -1613,6 +1617,13 @@ def _cleanupOptions():
else:
conf.testParameter = []
if conf.base64Parameter:
conf.base64Parameter = urldecode(conf.base64Parameter)
conf.base64Parameter = conf.base64Parameter.replace(" ", "")
conf.base64Parameter = re.split(PARAMETER_SPLITTING_REGEX, conf.base64Parameter)
else:
conf.base64Parameter = []
if conf.agent:
conf.agent = re.sub(r"[\r\n]", "", conf.agent)
@@ -1705,7 +1716,7 @@ def _cleanupOptions():
except re.error:
conf.csrfToken = re.escape(conf.csrfToken)
finally:
class _(unicode):
class _(six.text_type):
pass
conf.csrfToken = _(conf.csrfToken)
conf.csrfToken._original = original
+1 -1
View File
@@ -150,7 +150,7 @@ optDict = {
"limitStop": "integer",
"firstChar": "integer",
"lastChar": "integer",
"query": "string",
"sqlQuery": "string",
"sqlShell": "boolean",
"sqlFile": "string",
},
+21 -4
View File
@@ -17,7 +17,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
from lib.core.enums import OS
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.3.4.0"
VERSION = "1.3.5.0"
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
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)
@@ -65,6 +65,7 @@ ASTERISK_MARKER = "__ASTERISK_MARK__"
REPLACEMENT_MARKER = "__REPLACEMENT_MARK__"
BOUNDED_INJECTION_MARKER = "__BOUNDED_INJECTION_MARK__"
SAFE_VARIABLE_MARKER = "__SAFE__"
SAFE_HEX_MARKER = "__SAFE_HEX__"
RANDOM_INTEGER_MARKER = "[RANDINT]"
RANDOM_STRING_MARKER = "[RANDSTR]"
@@ -336,6 +337,7 @@ ERROR_PARSING_REGEXES = (
r"\[Microsoft\]\[ODBC SQL Server Driver\]\[SQL Server\](?P<result>[^<]+)",
r"<b>[^<]*(fatal|error|warning|exception)[^<]*</b>:?\s*(?P<result>[^<]+)",
r"(?m)^\s*(fatal|error|warning|exception):?\s*(?P<result>[^\n]+?)$",
r"(sql|dbc)[^>'\"]{0,32}(fatal|error|warning|exception)(</b>)?:\s*(?P<result>[^<>]+)",
r"(?P<result>[^\n>]*SQL Syntax[^\n<]+)",
r"(?s)<li>Error Type:<br>(?P<result>.+?)</li>",
r"CDbCommand (?P<result>[^<>\n]*SQL[^<>\n]+)",
@@ -381,7 +383,7 @@ URI_INJECTABLE_REGEX = r"//[^/]*/([^\.*?]+)\Z"
SENSITIVE_DATA_REGEX = r"(\s|=)(?P<result>[^\s=]*\b%s\b[^\s]*)\s"
# 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", "sqlQuery")
# Maximum number of threads (avoiding connection issues and/or DoS)
MAX_NUMBER_OF_THREADS = 10
@@ -530,6 +532,9 @@ BRUTE_COLUMN_EXISTS_TEMPLATE = "EXISTS(SELECT %s FROM %s)"
# Data inside shellcodeexec to be filled with random string
SHELLCODEEXEC_RANDOM_STRING_MARKER = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
# Period after last-update to start nagging about the old revision
LAST_UPDATE_NAGGING_DAYS = 60
# Generic address for checking the Internet connection while using switch --check-internet
CHECK_INTERNET_ADDRESS = "https://ipinfo.io/"
@@ -676,7 +681,7 @@ VALID_TIME_CHARS_RUN_THRESHOLD = 100
CHECK_ZERO_COLUMNS_THRESHOLD = 10
# 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", "PASSED", "FAILED", "for more than")
# 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")
@@ -711,6 +716,9 @@ RESTAPI_DEFAULT_ADDRESS = "127.0.0.1"
# Default REST-JSON API server listen port
RESTAPI_DEFAULT_PORT = 8775
# Use "Supplementary Private Use Area-A"
INVALID_UNICODE_PRIVATE_AREA = False
# Format used for representing invalid unicode characters
INVALID_UNICODE_CHAR_FORMAT = r"\x%02x"
@@ -818,9 +826,18 @@ th{
</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
# Installing "reversible" unicode (decoding) error handler
def _reversible(ex):
if isinstance(ex, UnicodeDecodeError):
if INVALID_UNICODE_PRIVATE_AREA:
return ("".join(unichr(int('000f00%2x' % ord(_), 16)) for _ in ex.object[ex.start:ex.end]), ex.end)
else:
return ("".join(INVALID_UNICODE_CHAR_FORMAT % ord(_) for _ in ex.object[ex.start:ex.end]).decode(UNICODE_ENCODING), ex.end)
codecs.register_error("reversible", _reversible)
+4 -3
View File
@@ -73,6 +73,7 @@ from lib.core.settings import URI_INJECTABLE_REGEX
from lib.core.settings import USER_AGENT_ALIASES
from lib.core.settings import XML_RECOGNITION_REGEX
from lib.utils.hashdb import HashDB
from thirdparty import six
from thirdparty.odict import OrderedDict
from thirdparty.six.moves import urllib as _urllib
@@ -409,7 +410,7 @@ def _setRequestParams():
message += "Do you want sqlmap to automatically update it in further requests? [y/N] "
if readInput(message, default='N', boolean=True):
class _(unicode):
class _(six.text_type):
pass
conf.csrfToken = _(re.escape(getUnicode(parameter)))
conf.csrfToken._original = getUnicode(parameter)
@@ -712,7 +713,7 @@ def initTargetEnv():
_setDBMS()
if conf.data:
class _(unicode):
class _(six.text_type):
pass
kb.postUrlEncode = True
@@ -728,7 +729,7 @@ def initTargetEnv():
setattr(conf.data, UNENCODED_ORIGINAL_VALUE, original)
kb.postSpaceToPlus = '+' in original
match = re.search(INJECT_HERE_REGEX, conf.data or "") or re.search(INJECT_HERE_REGEX, conf.url or "")
match = re.search(INJECT_HERE_REGEX, "%s %s %s" % (conf.url, conf.data, conf.httpHeaders))
kb.customInjectionMark = match.group(0) if match else CUSTOM_INJECTION_MARK_CHAR
def setupTargetEnv():
+47 -4
View File
@@ -8,21 +8,24 @@ See the file 'LICENSE' for copying permission
import codecs
import doctest
import os
import random
import re
import shutil
import sys
import tempfile
import threading
import time
import traceback
from extra.beep.beep import beep
from extra.vulnserver import vulnserver
from lib.controller.controller import start
from lib.core.common import checkIntegrity
from lib.core.common import clearConsoleLine
from lib.core.common import dataToStdout
from lib.core.common import getUnicode
from lib.core.common import randomStr
from lib.core.common import readXmlFile
from lib.core.common import shellExec
from lib.core.data import conf
from lib.core.data import logger
from lib.core.data import paths
@@ -44,6 +47,49 @@ class Failures(object):
_failures = Failures()
def vulnTest():
"""
Runs the testing against 'vulnserver'
"""
retVal = True
count, length = 0, 6
address, port = "127.0.0.10", random.randint(1025, 65535)
def _thread():
vulnserver.init(quiet=True)
vulnserver.run(address=address, port=port)
thread = threading.Thread(target=_thread)
thread.daemon = True
thread.start()
for options, checks in (
("--flush-session --identify-waf", ("CloudFlare",)),
("--flush-session --parse-errors", (": syntax error", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "back-end DBMS: SQLite", "3 columns")),
("--banner --schema --dump -T users --binary-fields=surname --where 'id>3'", ("banner: '3", "INTEGER", "TEXT", "id", "name", "surname", "2 entries", "6E616D6569736E756C6C")),
("--all --tamper=between,randomcase", ("5 entries", "luther", "blisset", "fluffy", "179ad45c6ce2cb97cf1029e212046e81", "NULL", "nameisnull", "testpass")),
("--technique=B --hex --fresh-queries --threads=4 --sql-query='SELECT 987654321'", ("length of query output", ": '987654321'",)),
("--technique=T --fresh-queries --sql-query='SELECT 1234'", (": '1234'",)),
):
output = shellExec("%s %s -u http://%s:%d/?id=1 --batch %s" % (sys.executable, os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py"), address, port, options))
output = getUnicode(output)
if not all(check in output for check in checks):
retVal = False
count += 1
status = '%d/%d (%d%%) ' % (count, length, round(100.0 * count / length))
dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status))
clearConsoleLine()
if retVal:
logger.info("vuln test final result: PASSED")
else:
logger.error("vuln test final result: FAILED")
return retVal
def smokeTest():
"""
Runs the basic smoke testing of a program
@@ -52,9 +98,6 @@ def smokeTest():
retVal = True
count, length = 0, 0
if not checkIntegrity():
retVal = False
for root, _, files in os.walk(paths.SQLMAP_ROOT_PATH):
if any(_ in root for _ in ("thirdparty", "extra")):
continue
+1 -1
View File
@@ -100,7 +100,7 @@ def exceptionHandledFunction(threadFunction, silent=False):
errMsg = ex.message if isinstance(ex, SqlmapBaseException) else "%s: %s" % (type(ex).__name__, ex.message)
logger.error("thread %s: '%s'" % (threading.currentThread().getName(), errMsg))
if conf.get("verbose") > 1:
if conf.get("verbose") > 1 and not isinstance(ex, (SqlmapUserQuitException,)):
traceback.print_exc()
def setDaemon(thread):
+24 -8
View File
@@ -40,6 +40,7 @@ from lib.core.shell import autoCompletion
from lib.core.shell import clearHistory
from lib.core.shell import loadHistory
from lib.core.shell import saveHistory
from thirdparty.six.moves import input as _input
def cmdLineParser(argv=None):
"""
@@ -54,7 +55,7 @@ def cmdLineParser(argv=None):
# Reference: https://stackoverflow.com/a/4012683 (Note: previously used "...sys.getfilesystemencoding() or UNICODE_ENCODING")
_ = getUnicode(os.path.basename(argv[0]), encoding=sys.stdin.encoding)
usage = "%s%s [options]" % ("python " if not IS_WIN else "", "\"%s\"" % _ if " " in _ else _)
usage = "%s%s [options]" % ("%s " % os.path.basename(sys.executable) if not IS_WIN else "", "\"%s\"" % _ if " " in _ else _)
parser = OptionParser(usage=usage)
try:
@@ -224,7 +225,7 @@ def cmdLineParser(argv=None):
request.add_option("--eval", dest="evalCode",
help="Evaluate provided Python code before the request (e.g. \"import hashlib;id2=hashlib.md5(id).hexdigest()\")")
# Optimization options
optimization = OptionGroup(parser, "Optimization", "These options can be used to optimize the performance of sqlmap")
@@ -448,7 +449,7 @@ def cmdLineParser(argv=None):
enumeration.add_option("--last", dest="lastChar", type="int",
help="Last query output word character to retrieve")
enumeration.add_option("--sql-query", dest="query",
enumeration.add_option("--sql-query", dest="sqlQuery",
help="SQL statement to be executed")
enumeration.add_option("--sql-shell", dest="sqlShell", action="store_true",
@@ -600,7 +601,7 @@ def cmdLineParser(argv=None):
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")
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)
@@ -681,6 +682,10 @@ def cmdLineParser(argv=None):
help="Simple wizard interface for beginner users")
# Hidden and/or experimental options
parser.add_option("--base64", dest="base64Parameter",
help=SUPPRESS_HELP)
# help="Parameter(s) containing Base64 encoded values")
parser.add_option("--crack", dest="hashFile",
help=SUPPRESS_HELP)
# help="Load and crack hashes from a file (standalone)")
@@ -718,6 +723,9 @@ def cmdLineParser(argv=None):
parser.add_option("--live-test", dest="liveTest", action="store_true",
help=SUPPRESS_HELP)
parser.add_option("--vuln-test", dest="vulnTest", action="store_true",
help=SUPPRESS_HELP)
parser.add_option("--stop-fail", dest="stopFail", action="store_true",
help=SUPPRESS_HELP)
@@ -755,7 +763,7 @@ def cmdLineParser(argv=None):
return retVal
parser.formatter._format_option_strings = parser.formatter.format_option_strings
parser.formatter.format_option_strings = type(parser.formatter.format_option_strings)(_, parser, type(parser))
parser.formatter.format_option_strings = type(parser.formatter.format_option_strings)(_, parser)
# Dirty hack for making a short option '-hh'
option = parser.get_option("--hh")
@@ -802,7 +810,7 @@ def cmdLineParser(argv=None):
command = None
try:
command = raw_input("sqlmap-shell> ").strip()
command = _input("sqlmap-shell> ").strip()
command = getUnicode(command, encoding=sys.stdin.encoding)
except (KeyboardInterrupt, EOFError):
print()
@@ -851,6 +859,14 @@ def cmdLineParser(argv=None):
elif argv[i] == "-H":
if i + 1 < len(argv):
extraHeaders.append(argv[i + 1])
elif argv[i] == "-r":
for j in xrange(i + 2, len(argv)):
value = argv[j]
if os.path.isfile(value):
argv[i + 1] += ",%s" % value
argv[j] = ''
else:
break
elif re.match(r"\A\d+!\Z", argv[i]) and argv[max(0, i - 1)] == "--threads" or re.match(r"\A--threads.+\d+!\Z", argv[i]):
argv[i] = argv[i][:-1]
conf.skipThreadCheck = True
@@ -901,7 +917,7 @@ def cmdLineParser(argv=None):
if args.dummy:
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.vulnTest, args.liveTest, args.wizard, args.dependencies, args.purge, args.sitemapUrl, args.listTampers, args.hashFile)):
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"
parser.error(errMsg)
@@ -915,7 +931,7 @@ def cmdLineParser(argv=None):
# Protection against Windows dummy double clicking
if IS_WIN:
dataToStdout("\nPress Enter to continue...")
raw_input()
_input()
raise
debugMsg = "parsing command line"
+2 -2
View File
@@ -5,13 +5,13 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import itertools
import os
from lib.core.common import parseXmlFile
from lib.core.data import kb
from lib.core.data import paths
from lib.parse.handler import FingerprintHandler
from thirdparty.six.moves import filter as _filter
def headersParser(headers):
"""
@@ -30,7 +30,7 @@ def headersParser(headers):
"x-powered-by": os.path.join(paths.SQLMAP_XML_BANNER_PATH, "x-powered-by.xml"),
}
for header in itertools.ifilter(lambda _: _ in kb.headerPaths, headers):
for header in _filter(lambda _: _ in kb.headerPaths, headers):
value = headers[header]
xmlfile = kb.headerPaths[header]
handler = FingerprintHandler(value, kb.headersFp)
+16 -11
View File
@@ -14,9 +14,11 @@ import struct
import zlib
from lib.core.common import Backend
from lib.core.common import decodeHex
from lib.core.common import extractErrorMessage
from lib.core.common import extractRegexResult
from lib.core.common import filterNone
from lib.core.common import getBytes
from lib.core.common import getPublicTypeMembers
from lib.core.common import getSafeExString
from lib.core.common import getUnicode
@@ -42,11 +44,11 @@ from lib.core.settings import MAX_CONNECTION_TOTAL_SIZE
from lib.core.settings import META_CHARSET_REGEX
from lib.core.settings import PARSE_HEADERS_LIMIT
from lib.core.settings import SELECT_FROM_TABLE_REGEX
from lib.core.settings import UNICODE_ENCODING
from lib.core.settings import VIEWSTATE_REGEX
from lib.parse.headers import headersParser
from lib.parse.html import htmlParser
from lib.utils.htmlentities import htmlEntities
from thirdparty import six
from thirdparty.chardet import detect
from thirdparty.odict import OrderedDict
@@ -155,6 +157,9 @@ def checkCharEncoding(encoding, warn=True):
'utf8'
"""
if isinstance(encoding, six.binary_type):
encoding = getUnicode(encoding)
if isListLike(encoding):
encoding = unArrayizeValue(encoding)
@@ -219,13 +224,13 @@ def checkCharEncoding(encoding, warn=True):
# Reference: http://www.iana.org/assignments/character-sets
# Reference: http://docs.python.org/library/codecs.html
try:
codecs.lookup(encoding.encode(UNICODE_ENCODING) if isinstance(encoding, unicode) else encoding)
except (LookupError, ValueError):
codecs.lookup(encoding)
except:
encoding = None
if encoding:
try:
unicode(randomStr(), encoding)
six.text_type(getBytes(randomStr()), encoding)
except:
if warn:
warnMsg = "invalid web page charset '%s'" % encoding
@@ -313,18 +318,18 @@ def decodePage(page, contentEncoding, contentType):
kb.pageEncoding = conf.encoding
# can't do for all responses because we need to support binary files too
if not isinstance(page, unicode) and "text/" in contentType:
if isinstance(page, six.binary_type) and "text/" in contentType:
# e.g. &#x9;&#195;&#235;&#224;&#226;&#224;
if "&#" in 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 = re.sub(r"&#(\d{1,3});", lambda _: chr(int(_.group(1))) if int(_.group(1)) < 256 else _.group(0), page)
if b"&#" in page:
page = re.sub(b"&#x([0-9a-f]{1,2});", lambda _: decodeHex(_.group(1) if len(_.group(1)) == 2 else "0%s" % _.group(1)), page)
page = re.sub(b"&#(\d{1,3});", lambda _: chr(int(_.group(1))) if int(_.group(1)) < 256 else _.group(0), page)
# e.g. %20%28%29
if "%" in page:
page = re.sub(r"%([0-9a-fA-F]{2})", lambda _: _.group(1).decode("hex"), page)
if b"%" in page:
page = re.sub(b"%([0-9a-fA-F]{2})", lambda _: decodeHex(_.group(1)), page)
# 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(b"&([^;]+);", lambda _: chr(htmlEntities[_.group(1)]) if htmlEntities.get(_.group(1), 256) < 256 else _.group(0), page)
kb.pageEncoding = kb.pageEncoding or checkCharEncoding(getHeuristicCharEncoding(page))
+6 -4
View File
@@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
import re
from lib.core.common import extractRegexResult
from lib.core.common import getBytes
from lib.core.common import getFilteredPageContent
from lib.core.common import listToStrValue
from lib.core.common import removeDynamicContent
@@ -28,6 +29,7 @@ from lib.core.settings import LOWER_RATIO_BOUND
from lib.core.settings import UPPER_RATIO_BOUND
from lib.core.settings import URI_HTTP_HEADER
from lib.core.threads import getCurrentThreadData
from thirdparty import six
def comparison(page, headers, code=None, getRatioValue=False, pageLength=None):
_ = _adjust(_comparison(page, headers, code, getRatioValue, pageLength), getRatioValue)
@@ -105,10 +107,10 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
else:
# Preventing "Unicode equal comparison failed to convert both arguments to Unicode"
# (e.g. if one page is PDF and the other is HTML)
if isinstance(seqMatcher.a, str) and isinstance(page, unicode):
page = page.encode(kb.pageEncoding or DEFAULT_PAGE_ENCODING, "ignore")
elif isinstance(seqMatcher.a, unicode) and isinstance(page, str):
seqMatcher.a = seqMatcher.a.encode(kb.pageEncoding or DEFAULT_PAGE_ENCODING, "ignore")
if isinstance(seqMatcher.a, six.binary_type) and isinstance(page, six.text_type):
page = getBytes(page, kb.pageEncoding or DEFAULT_PAGE_ENCODING, "ignore")
elif isinstance(seqMatcher.a, six.text_type) and isinstance(page, six.binary_type):
seqMatcher.a = getBytes(seqMatcher.a, kb.pageEncoding or DEFAULT_PAGE_ENCODING, "ignore")
if any(_ is None for _ in (page, seqMatcher.a)):
return None
+50 -39
View File
@@ -34,6 +34,7 @@ from lib.core.common import evaluateCode
from lib.core.common import extractRegexResult
from lib.core.common import filterNone
from lib.core.common import findMultipartPostBoundary
from lib.core.common import getBytes
from lib.core.common import getCurrentThreadData
from lib.core.common import getHeader
from lib.core.common import getHostHeader
@@ -54,7 +55,6 @@ from lib.core.common import singleTimeLogMessage
from lib.core.common import singleTimeWarnMessage
from lib.core.common import stdev
from lib.core.common import wasLastResponseDelayed
from lib.core.common import unicodeencode
from lib.core.common import unsafeVariableNaming
from lib.core.common import urldecode
from lib.core.common import urlencode
@@ -82,6 +82,7 @@ from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapGenericException
from lib.core.exception import SqlmapSyntaxException
from lib.core.exception import SqlmapTokenException
from lib.core.exception import SqlmapUserQuitException
from lib.core.exception import SqlmapValueException
from lib.core.settings import ASTERISK_MARKER
from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
@@ -192,7 +193,7 @@ class Connect(object):
@staticmethod
def _connReadProxy(conn):
retVal = ""
retVal = b""
if not kb.dnsMode and conn:
headers = conn.info()
@@ -277,7 +278,10 @@ class Connect(object):
if multipart:
post = multipart
if chunked and post:
if not post:
chunked = False
elif chunked:
post = _urllib.parse.unquote(post)
post = chunkSplitPostData(post)
@@ -402,22 +406,20 @@ class Connect(object):
if conf.keepAlive:
headers[HTTP_HEADER.CONNECTION] = "keep-alive"
if chunked:
headers[HTTP_HEADER.TRANSFER_ENCODING] = "chunked"
if auxHeaders:
headers = forgeHeaders(auxHeaders, headers)
for key, value in headers.items():
for key, value in list(headers.items()):
del headers[key]
value = unicodeencode(value, kb.pageEncoding)
for char in (r"\r", r"\n"):
value = re.sub(r"(%s)([^ \t])" % char, r"\g<1>\t\g<2>", value)
headers[unicodeencode(key, kb.pageEncoding)] = value.strip("\r\n")
headers[getBytes(key)] = getBytes(value.strip("\r\n"))
url = unicodeencode(url)
post = unicodeencode(post)
post = getBytes(post)
if websocket_:
ws = websocket.WebSocket()
@@ -448,7 +450,7 @@ class Connect(object):
logger.log(CUSTOM_LOGGING.TRAFFIC_OUT, requestMsg)
else:
if method and method not in (HTTPMETHOD.GET, HTTPMETHOD.POST):
method = unicodeencode(method)
method = getBytes(method)
req = MethodRequest(url, post, headers)
req.set_method(method)
elif url is not None:
@@ -604,7 +606,7 @@ class Connect(object):
page = getUnicode(page)
code = ex.code
status = getSafeExString(ex)
status = getattr(ex, "reason", None) or getSafeExString(ex).split(": ", 1)[-1]
kb.originalCode = kb.originalCode or code
threadData.lastHTTPError = (threadData.lastRequestUID, code, status)
@@ -632,6 +634,12 @@ class Connect(object):
errMsg = "not authorized, try to provide right HTTP "
errMsg += "authentication type and valid credentials (%d)" % code
raise SqlmapConnectionException(errMsg)
elif chunked and ex.code in (_http_client.METHOD_NOT_ALLOWED, _http_client.LENGTH_REQUIRED):
warnMsg = "turning off HTTP chunked transfer encoding "
warnMsg += "as it seems that the target site doesn't support it (%d)" % code
singleTimeWarnMessage(warnMsg)
conf.chunked = kwargs["chunked"] = False
return Connect.getPage(**kwargs)
elif ex.code == _http_client.NOT_FOUND:
if raise404:
errMsg = "page not found (%d)" % code
@@ -725,8 +733,11 @@ class Connect(object):
kb.connErrorChoice = readInput(message, default='N', boolean=True)
if kb.connErrorChoice is False:
raise SqlmapConnectionException(warnMsg)
if kb.connErrorChoice is not None:
if kb.connErrorChoice:
raise SqlmapConnectionException(warnMsg)
else:
raise SqlmapUserQuitException
if "forcibly closed" in tbMsg:
logger.critical(warnMsg)
@@ -769,33 +780,33 @@ class Connect(object):
processResponse(page, responseHeaders, status)
if conn and getattr(conn, "redurl", None):
_ = _urllib.parse.urlsplit(conn.redurl)
_ = ("%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)
if kb.resendPostOnRedirect is False:
requestMsg = re.sub(r"(\[#\d+\]:\n)POST ", r"\g<1>GET ", requestMsg)
requestMsg = re.sub(r"(?i)Content-length: \d+\n", "", requestMsg)
requestMsg = re.sub(r"(?s)\n\n.+", "\n", requestMsg)
responseMsg += "[#%d] (%s %s):\r\n" % (threadData.lastRequestUID, conn.code, status)
else:
responseMsg += "[#%d] (%s %s):\r\n" % (threadData.lastRequestUID, code, status)
if responseHeaders:
logHeaders = getUnicode("".join(responseHeaders.headers).strip())
if not skipLogTraffic:
if conn and getattr(conn, "redurl", None):
_ = _urllib.parse.urlsplit(conn.redurl)
_ = ("%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)
if kb.resendPostOnRedirect is False:
requestMsg = re.sub(r"(\[#\d+\]:\n)POST ", r"\g<1>GET ", requestMsg)
requestMsg = re.sub(r"(?i)Content-length: \d+\n", "", requestMsg)
requestMsg = re.sub(r"(?s)\n\n.+", "\n", requestMsg)
responseMsg += "[#%d] (%s %s):\r\n" % (threadData.lastRequestUID, conn.code, status)
elif "\n" not in responseMsg:
responseMsg += "[#%d] (%s %s):\r\n" % (threadData.lastRequestUID, code, status)
if responseHeaders:
logHeaders = getUnicode("".join(responseHeaders.headers).strip() if six.PY2 else responseHeaders.__bytes__())
logHTTPTraffic(requestMsg, "%s%s\r\n\r\n%s" % (responseMsg, logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE]), start, time.time())
if conf.verbose <= 5:
responseMsg += getUnicode(logHeaders)
elif conf.verbose > 5:
responseMsg += "%s\r\n\r\n%s" % (logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE])
if conf.verbose <= 5:
responseMsg += getUnicode(logHeaders)
elif conf.verbose > 5:
responseMsg += "%s\r\n\r\n%s" % (logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE])
if not multipart:
logger.log(CUSTOM_LOGGING.TRAFFIC_IN, responseMsg)
if not multipart:
logger.log(CUSTOM_LOGGING.TRAFFIC_IN, responseMsg)
return page, responseHeaders, code
@@ -839,7 +850,7 @@ class Connect(object):
if 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 "" for _ in headers) or None
if (kb.postHint or conf.skipUrlEncode) and postUrlEncode:
postUrlEncode = False
@@ -1120,7 +1131,7 @@ class Connect(object):
while True:
try:
compile(unicodeencode(conf.evalCode.replace(';', '\n')), "", "exec")
compile(getBytes(conf.evalCode.replace(';', '\n')), "", "exec")
except SyntaxError as ex:
if ex.text:
original = replacement = ex.text.strip()
@@ -1254,7 +1265,7 @@ class Connect(object):
warnMsg += "10 or more)"
logger.critical(warnMsg)
if conf.safeFreq > 0:
if (conf.safeFreq or 0) > 0:
kb.queryCounter += 1
if kb.queryCounter % conf.safeFreq == 0:
if conf.safeUrl:
+1 -1
View File
@@ -486,7 +486,7 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
singleTimeWarnMessage(warnMsg)
# Dirty patch (safe-encoded unicode characters)
if isinstance(value, unicode) and "\\x" in value:
if isinstance(value, six.text_type) and "\\x" in value:
try:
candidate = eval(repr(value).replace("\\\\x", "\\x").replace("u'", "'", 1)).decode(conf.encoding or UNICODE_ENCODING)
if "\\x" not in candidate:
+2 -1
View File
@@ -28,6 +28,7 @@ from lib.request import inject
from lib.takeover.udf import UDF
from lib.takeover.web import Web
from lib.takeover.xp_cmdshell import XP_cmdshell
from thirdparty.six.moves import input as _input
class Abstraction(Web, UDF, XP_cmdshell):
"""
@@ -139,7 +140,7 @@ class Abstraction(Web, UDF, XP_cmdshell):
command = None
try:
command = raw_input("os-shell> ")
command = _input("os-shell> ")
command = getUnicode(command, encoding=sys.stdin.encoding)
except KeyboardInterrupt:
print()
+3 -2
View File
@@ -21,6 +21,8 @@ from lib.core.common import dataToStdout
from lib.core.common import extractRegexResult
from lib.core.common import firstNotNone
from lib.core.common import flattenValue
from lib.core.common import safeStringFormat
from lib.core.common import getBytes
from lib.core.common import getConsoleWidth
from lib.core.common import getPartRun
from lib.core.common import getUnicode
@@ -54,7 +56,6 @@ from lib.core.settings import MAX_BUFFERED_PARTIAL_UNION_LENGTH
from lib.core.settings import NULL
from lib.core.settings import SQL_SCALAR_REGEX
from lib.core.settings import TURN_OFF_RESUME_INFO_LIMIT
from lib.core.settings import UNICODE_ENCODING
from lib.core.threads import getCurrentThreadData
from lib.core.threads import runThreads
from lib.core.unescaper import unescaper
@@ -109,7 +110,7 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
output = extractRegexResult(r"(?P<result>(<row.+?/>)+)", page)
if output:
try:
root = xml.etree.ElementTree.fromstring("<root>%s</root>" % output.encode(UNICODE_ENCODING))
root = xml.etree.ElementTree.fromstring(safeStringFormat("<root>%s</root>", getBytes(output)))
retVal = ""
for column in kb.dumpColumns:
base64 = True
+2 -1
View File
@@ -57,6 +57,7 @@ from thirdparty.bottle.bottle import response
from thirdparty.bottle.bottle import run
from thirdparty.bottle.bottle import server_names
from thirdparty.six.moves import http_client as _http_client
from thirdparty.six.moves import input as _input
from thirdparty.six.moves import urllib as _urllib
# Global data storage
@@ -762,7 +763,7 @@ def client(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, username=Non
while True:
try:
command = raw_input("api%s> " % (" (%s)" % taskid if taskid else "")).strip()
command = _input("api%s> " % (" (%s)" % taskid if taskid else "")).strip()
command = re.sub(r"\A(\w+)", lambda match: match.group(1).lower(), command)
except (EOFError, KeyboardInterrupt):
print()
+2 -1
View File
@@ -32,6 +32,7 @@ from lib.core.threads import getCurrentThreadData
from lib.core.threads import runThreads
from lib.parse.sitemap import parseSitemap
from lib.request.connect import Connect as Request
from thirdparty import six
from thirdparty.beautifulsoup.beautifulsoup import BeautifulSoup
from thirdparty.six.moves import http_client as _http_client
from thirdparty.six.moves import urllib as _urllib
@@ -79,7 +80,7 @@ def crawl(target):
if not kb.threadContinue:
break
if isinstance(content, unicode):
if isinstance(content, six.text_type):
try:
match = re.search(r"(?si)<html[^>]*>(.+)</html>", content)
if match:
+33 -76
View File
@@ -50,6 +50,7 @@ from lib.core.common import Backend
from lib.core.common import checkFile
from lib.core.common import clearConsoleLine
from lib.core.common import dataToStdout
from lib.core.common import getBytes
from lib.core.common import getFileItems
from lib.core.common import getPublicTypeMembers
from lib.core.common import getSafeExString
@@ -102,8 +103,7 @@ def mysql_passwd(password, uppercase=True):
'*00E247AC5F9AF26AE0194B41E1E769DEE1429A29'
"""
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
password = getBytes(password)
retVal = "*%s" % sha1(sha1(password).digest()).hexdigest()
@@ -143,11 +143,8 @@ def postgres_passwd(password, username, uppercase=False):
'md599e5ea7a6f7c3269995cba3927fd0093'
"""
if isinstance(username, six.text_type):
username = username.encode(UNICODE_ENCODING)
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
username = getBytes(username)
password = getBytes(password)
retVal = "md5%s" % md5(password + username).hexdigest()
@@ -232,11 +229,8 @@ def oracle_old_passwd(password, username, uppercase=True): # prior to version '
IV, pad = "\0" * 8, "\0"
if isinstance(username, six.text_type):
username = username.encode(UNICODE_ENCODING)
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
username = getBytes(username)
password = getBytes(password)
unistr = "".join("\0%s" % c for c in (username + password).upper())
@@ -255,8 +249,7 @@ def md5_generic_passwd(password, uppercase=False):
'179ad45c6ce2cb97cf1029e212046e81'
"""
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
password = getBytes(password)
retVal = md5(password).hexdigest()
@@ -268,8 +261,7 @@ def sha1_generic_passwd(password, uppercase=False):
'206c80413b9a96c1312cc346b7d2517b84463edd'
"""
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
password = getBytes(password)
retVal = sha1(password).hexdigest()
@@ -281,8 +273,7 @@ def apache_sha1_passwd(password, **kwargs):
'{SHA}IGyAQTualsExLMNGt9JRe4RGPt0='
"""
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
password = getBytes(password)
return "{SHA}%s" % base64.b64encode(sha1(password).digest())
@@ -292,11 +283,8 @@ def ssha_passwd(password, salt, **kwargs):
'{SSHA}mU1HPTvnmoXOhE4ROHP6sWfbfoRzYWx0'
"""
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
if isinstance(salt, six.text_type):
salt = salt.encode(UNICODE_ENCODING)
password = getBytes(password)
salt = getBytes(salt)
return "{SSHA}%s" % base64.b64encode(sha1(password + salt).digest() + salt)
@@ -306,11 +294,8 @@ def ssha256_passwd(password, salt, **kwargs):
'{SSHA256}hhubsLrO/Aje9F/kJrgv5ZLE40UmTrVWvI7Dt6InP99zYWx0'
"""
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
if isinstance(salt, six.text_type):
salt = salt.encode(UNICODE_ENCODING)
password = getBytes(password)
salt = getBytes(salt)
return "{SSHA256}%s" % base64.b64encode(sha256(password + salt).digest() + salt)
@@ -320,11 +305,8 @@ def ssha512_passwd(password, salt, **kwargs):
'{SSHA512}mCUSLfPMhXCQOJl9WHW/QMn9v9sjq7Ht/Wk7iVau8vLOfh+PeynkGMikqIE8sStFd0khdfcCD8xZmC6UyjTxsHNhbHQ='
"""
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
if isinstance(salt, six.text_type):
salt = salt.encode(UNICODE_ENCODING)
password = getBytes(password)
salt = getBytes(salt)
return "{SSHA512}%s" % base64.b64encode(sha512(password + salt).digest() + salt)
@@ -334,8 +316,7 @@ def sha224_generic_passwd(password, uppercase=False):
'648db6019764b598f75ab6b7616d2e82563a00eb1531680e19ac4c6f'
"""
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
password = getBytes(password)
retVal = sha224(password).hexdigest()
@@ -347,8 +328,7 @@ def sha256_generic_passwd(password, uppercase=False):
'13d249f2cb4127b40cfa757866850278793f814ded3c587fe5889e889a7a9f6c'
"""
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
password = getBytes(password)
retVal = sha256(password).hexdigest()
@@ -360,8 +340,7 @@ def sha384_generic_passwd(password, uppercase=False):
'6823546e56adf46849343be991d4b1be9b432e42ed1b4bb90635a0e4b930e49b9ca007bc3e04bf0a4e0df6f1f82769bf'
"""
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
password = getBytes(password)
retVal = sha384(password).hexdigest()
@@ -373,8 +352,7 @@ def sha512_generic_passwd(password, uppercase=False):
'78ddc8555bb1677ff5af75ba5fc02cb30bb592b0610277ae15055e189b77fe3fda496e5027a3d99ec85d54941adee1cc174b50438fdc21d82d0a79f85b58cf44'
"""
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
password = getBytes(password)
retVal = sha512(password).hexdigest()
@@ -392,11 +370,8 @@ def crypt_generic_passwd(password, salt, **kwargs):
'rl.3StKT.4T8M'
"""
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
if isinstance(salt, six.text_type):
salt = salt.encode(UNICODE_ENCODING)
password = getBytes(password)
salt = getBytes(salt)
return crypt(password, salt)
@@ -419,14 +394,9 @@ def unix_md5_passwd(password, salt, magic="$1$", **kwargs):
return output
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
if isinstance(magic, six.text_type):
magic = magic.encode(UNICODE_ENCODING)
if isinstance(salt, six.text_type):
salt = salt.encode(UNICODE_ENCODING)
password = getBytes(password)
magic = getBytes(magic)
salt = getBytes(salt)
salt = salt[:8]
ctx = password + magic + salt
@@ -486,11 +456,8 @@ def joomla_passwd(password, salt, **kwargs):
'e3d5794da74e917637332e0d21b76328:6GGlnaquVXI80b3HRmSyE3K1wEFFaBIf'
"""
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
if isinstance(salt, six.text_type):
salt = salt.encode(UNICODE_ENCODING)
password = getBytes(password)
salt = getBytes(salt)
return "%s:%s" % (md5("%s%s" % (password, salt)).hexdigest(), salt)
@@ -502,11 +469,8 @@ def django_md5_passwd(password, salt, **kwargs):
'md5$salt$972141bcbcb6a0acc96e92309175b3c5'
"""
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
if isinstance(salt, six.text_type):
salt = salt.encode(UNICODE_ENCODING)
password = getBytes(password)
salt = getBytes(salt)
return "md5$%s$%s" % (salt, md5("%s%s" % (salt, password)).hexdigest())
@@ -518,11 +482,8 @@ def django_sha1_passwd(password, salt, **kwargs):
'sha1$salt$6ce0e522aba69d8baa873f01420fccd0250fc5b2'
"""
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
if isinstance(salt, six.text_type):
salt = salt.encode(UNICODE_ENCODING)
password = getBytes(password)
salt = getBytes(salt)
return "sha1$%s$%s" % (salt, sha1("%s%s" % (salt, password)).hexdigest())
@@ -534,11 +495,8 @@ def vbulletin_passwd(password, salt, **kwargs):
'85c4d8ea77ebef2236fb7e9d24ba9482:salt'
"""
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
if isinstance(salt, six.text_type):
salt = salt.encode(UNICODE_ENCODING)
password = getBytes(password)
salt = getBytes(salt)
return "%s:%s" % (md5("%s%s" % (md5(password).hexdigest(), salt)).hexdigest(), salt)
@@ -583,8 +541,7 @@ def wordpress_passwd(password, salt, count, prefix, **kwargs):
return output
if isinstance(password, six.text_type):
password = password.encode(UNICODE_ENCODING)
password = getBytes(password)
cipher = md5(salt)
cipher.update(password)
+3 -2
View File
@@ -11,6 +11,7 @@ import sqlite3
import threading
import time
from lib.core.common import getBytes
from lib.core.common import getSafeExString
from lib.core.common import getUnicode
from lib.core.common import serializeObject
@@ -23,9 +24,9 @@ from lib.core.settings import HASHDB_END_TRANSACTION_RETRIES
from lib.core.settings import HASHDB_FLUSH_RETRIES
from lib.core.settings import HASHDB_FLUSH_THRESHOLD
from lib.core.settings import HASHDB_RETRIEVE_RETRIES
from lib.core.settings import UNICODE_ENCODING
from lib.core.threads import getCurrentThreadData
from lib.core.threads import getCurrentThreadName
from thirdparty import six
class HashDB(object):
def __init__(self, filepath):
@@ -67,7 +68,7 @@ class HashDB(object):
@staticmethod
def hashKey(key):
key = key.encode(UNICODE_ENCODING) if isinstance(key, unicode) else repr(key)
key = getBytes(key if isinstance(key, six.text_type) else repr(key))
retVal = int(hashlib.md5(key).hexdigest(), 16) & 0x7fffffffffffffff # Reference: http://stackoverflow.com/a/4448400
return retVal
+56 -37
View File
@@ -21,9 +21,9 @@ __all__ = ["SGMLParser", "SGMLParseError"]
interesting = re.compile('[&<]')
incomplete = re.compile('&([a-zA-Z][a-zA-Z0-9]*|#[0-9]*)?|'
'<([a-zA-Z][^<>]*|'
'/([a-zA-Z][^<>]*)?|'
'![^<>]*)?')
'<([a-zA-Z][^<>]*|'
'/([a-zA-Z][^<>]*)?|'
'![^<>]*)?')
entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]')
charref = re.compile('&#([0-9]+)[^0-9]')
@@ -58,8 +58,8 @@ class SGMLParseError(RuntimeError):
class SGMLParser(_markupbase.ParserBase):
# Definition of entities -- derived classes may override
entity_or_charref = re.compile('&(?:'
'([a-zA-Z][-.a-zA-Z0-9]*)|#([0-9]+)'
')(;?)')
'([a-zA-Z][-.a-zA-Z0-9]*)|#([0-9]+)'
')(;?)')
def __init__(self, verbose=0):
"""Initialize and reset this instance."""
@@ -121,32 +121,37 @@ class SGMLParser(_markupbase.ParserBase):
i = n
break
match = interesting.search(rawdata, i)
if match: j = match.start()
else: j = n
if match:
j = match.start()
else:
j = n
if i < j:
self.handle_data(rawdata[i:j])
i = j
if i == n: break
if i == n:
break
if rawdata[i] == '<':
if starttagopen.match(rawdata, i):
if self.literal:
self.handle_data(rawdata[i])
i = i+1
i = i + 1
continue
k = self.parse_starttag(i)
if k < 0: break
if k < 0:
break
i = k
continue
if rawdata.startswith("</", i):
k = self.parse_endtag(i)
if k < 0: break
if k < 0:
break
i = k
self.literal = 0
continue
if self.literal:
if n > (i + 1):
self.handle_data("<")
i = i+1
i = i + 1
else:
# incomplete
break
@@ -157,12 +162,14 @@ class SGMLParser(_markupbase.ParserBase):
# This should be removed,
# and comments handled only in parse_declaration.
k = self.parse_comment(i)
if k < 0: break
if k < 0:
break
i = k
continue
if rawdata.startswith("<?", i):
k = self.parse_pi(i)
if k < 0: break
if k < 0:
break
i = i+k
continue
if rawdata.startswith("<!", i):
@@ -170,27 +177,30 @@ class SGMLParser(_markupbase.ParserBase):
# deployed," this should only be the document type
# declaration ("<!DOCTYPE html...>").
k = self.parse_declaration(i)
if k < 0: break
if k < 0:
break
i = k
continue
elif rawdata[i] == '&':
if self.literal:
self.handle_data(rawdata[i])
i = i+1
i = i + 1
continue
match = charref.match(rawdata, i)
if match:
name = match.group(1)
self.handle_charref(name)
i = match.end(0)
if rawdata[i-1] != ';': i = i-1
if rawdata[i-1] != ';':
i = i-1
continue
match = entityref.match(rawdata, i)
if match:
name = match.group(1)
self.handle_entityref(name)
i = match.end(0)
if rawdata[i-1] != ';': i = i-1
if rawdata[i-1] != ';':
i = i-1
continue
else:
self.error('neither < nor & ??')
@@ -199,11 +209,11 @@ class SGMLParser(_markupbase.ParserBase):
match = incomplete.match(rawdata, i)
if not match:
self.handle_data(rawdata[i])
i = i+1
i = i + 1
continue
j = match.end(0)
if j == n:
break # Really incomplete
break # Really incomplete
self.handle_data(rawdata[i:j])
i = j
# end while
@@ -256,32 +266,33 @@ class SGMLParser(_markupbase.ParserBase):
# As a shortcut way to exit, this isn't so bad, but shouldn't
# be used to locate the actual end of the start tag since the
# < or > characters may be embedded in an attribute value.
match = endbracket.search(rawdata, i+1)
match = endbracket.search(rawdata, i + 1)
if not match:
return -1
j = match.start(0)
# Now parse the data between i+1 and j into a tag and attrs
# Now parse the data between i + 1 and j into a tag and attrs
attrs = []
if rawdata[i:i+2] == '<>':
# SGML shorthand: <> == <last open tag seen>
k = j
tag = self.lasttag
else:
match = tagfind.match(rawdata, i+1)
match = tagfind.match(rawdata, i + 1)
if not match:
self.error('unexpected call to parse_starttag')
k = match.end(0)
tag = rawdata[i+1:k].lower()
tag = rawdata[i + 1:k].lower()
self.lasttag = tag
while k < j:
match = attrfind.match(rawdata, k)
if not match: break
if not match:
break
attrname, rest, attrvalue = match.group(1, 2, 3)
if not rest:
attrvalue = attrname
else:
if (attrvalue[:1] == "'" == attrvalue[-1:] or
attrvalue[:1] == '"' == attrvalue[-1:]):
attrvalue[:1] == '"' == attrvalue[-1:]):
# strip quotes
attrvalue = attrvalue[1:-1]
attrvalue = self.entity_or_charref.sub(
@@ -289,7 +300,7 @@ class SGMLParser(_markupbase.ParserBase):
attrs.append((attrname.lower(), attrvalue))
k = match.end(0)
if rawdata[j] == '>':
j = j+1
j = j + 1
self.__starttag_text = rawdata[start_pos:j]
self.finish_starttag(tag, attrs)
return j
@@ -308,13 +319,13 @@ class SGMLParser(_markupbase.ParserBase):
# Internal -- parse endtag
def parse_endtag(self, i):
rawdata = self.rawdata
match = endbracket.search(rawdata, i+1)
match = endbracket.search(rawdata, i + 1)
if not match:
return -1
j = match.start(0)
tag = rawdata[i+2:j].strip().lower()
if rawdata[j] == '>':
j = j+1
j = j + 1
self.finish_endtag(tag)
return j
@@ -361,7 +372,8 @@ class SGMLParser(_markupbase.ParserBase):
return
found = len(self.stack)
for i in range(found):
if self.stack[i] == tag: found = i
if self.stack[i] == tag:
found = i
while len(self.stack) > found:
tag = self.stack[-1]
try:
@@ -411,7 +423,7 @@ class SGMLParser(_markupbase.ParserBase):
# Definition of entities -- derived classes may override
entitydefs = \
{'lt': '<', 'gt': '>', 'amp': '&', 'quot': '"', 'apos': '\''}
{'lt': '<', 'gt': '>', 'amp': '&', 'quot': '"', 'apos': '\''}
def convert_entityref(self, name):
"""Convert entity references.
@@ -450,10 +462,17 @@ class SGMLParser(_markupbase.ParserBase):
pass
# To be overridden -- handlers for unknown objects
def unknown_starttag(self, tag, attrs): pass
def unknown_endtag(self, tag): pass
def unknown_charref(self, ref): pass
def unknown_entityref(self, ref): pass
def unknown_starttag(self, tag, attrs):
pass
def unknown_endtag(self, tag):
pass
def unknown_charref(self, ref):
pass
def unknown_entityref(self, ref):
pass
class TestSGMLParser(SGMLParser):
@@ -511,7 +530,7 @@ class TestSGMLParser(SGMLParser):
self.flush()
def test(args = None):
def test(args=None):
import sys
if args is None:
@@ -548,4 +567,4 @@ def test(args = None):
if __name__ == '__main__':
test()
test()
+2 -1
View File
@@ -5,12 +5,13 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import os
import sys
import time
PYVERSION = sys.version.split()[0]
if PYVERSION >= "3" or PYVERSION < "2.6":
if (PYVERSION >= "3" or PYVERSION < "2.6") and not int(os.environ.get("SQLMAP_DREI", 0)):
sys.exit("[%s] [CRITICAL] incompatible Python version detected ('%s'). To successfully run sqlmap you'll have to use version 2.6.x or 2.7.x (visit 'https://www.python.org/downloads/')" % (time.strftime("%X"), PYVERSION))
errors = []
+7 -7
View File
@@ -12,19 +12,19 @@ class xrange(object):
Advanced (re)implementation of xrange (supports slice/copy/etc.)
Reference: http://code.activestate.com/recipes/521885-a-pythonic-implementation-of-xrange/
>>> list(xrange(1, 9)) == range(1, 9)
>>> list(xrange(1, 9)) == list(range(1, 9))
True
>>> list(xrange(8, 0, -16)) == range(8, 0, -16)
>>> list(xrange(8, 0, -16)) == list(range(8, 0, -16))
True
>>> list(xrange(0, 8, 16)) == range(0, 8, 16)
>>> list(xrange(0, 8, 16)) == list(range(0, 8, 16))
True
>>> list(xrange(0, 4, 5)) == range(0, 4, 5)
>>> list(xrange(0, 4, 5)) == list(range(0, 4, 5))
True
>>> list(xrange(4, 0, 3)) == range(4, 0, 3)
>>> list(xrange(4, 0, 3)) == list(range(4, 0, 3))
True
>>> list(xrange(0, -3)) == range(0, -3)
>>> list(xrange(0, -3)) == list(range(0, -3))
True
>>> list(xrange(0, 7, 2)) == range(0, 7, 2)
>>> list(xrange(0, 7, 2)) == list(range(0, 7, 2))
True
>>> foobar = xrange(1, 10)
>>> 7 in foobar
+1 -1
View File
@@ -8,4 +8,4 @@ See the file 'LICENSE' for copying permission
from plugins.generic.filesystem import Filesystem as GenericFilesystem
class Filesystem(GenericFilesystem):
pass
pass
+1 -1
View File
@@ -8,4 +8,4 @@ See the file 'LICENSE' for copying permission
from plugins.generic.filesystem import Filesystem as GenericFilesystem
class Filesystem(GenericFilesystem):
pass
pass
+1 -1
View File
@@ -8,4 +8,4 @@ See the file 'LICENSE' for copying permission
from plugins.generic.enumeration import Enumeration as GenericEnumeration
class Enumeration(GenericEnumeration):
pass
pass
+2 -2
View File
@@ -7,8 +7,8 @@ See the file 'LICENSE' for copying permission
import binascii
from lib.core.common import getBytes
from lib.core.common import isDBMSVersionAtLeast
from lib.core.settings import UNICODE_ENCODING
from plugins.generic.syntax import Syntax as GenericSyntax
class Syntax(GenericSyntax):
@@ -28,7 +28,7 @@ class Syntax(GenericSyntax):
def escaper(value):
# Reference: http://stackoverflow.com/questions/3444335/how-do-i-quote-a-utf-8-string-literal-in-sqlite3
return "CAST(X'%s' AS TEXT)" % binascii.hexlify(value.encode(UNICODE_ENCODING) if isinstance(value, unicode) else value)
return "CAST(X'%s' AS TEXT)" % binascii.hexlify(getBytes(value))
retVal = expression
+5 -4
View File
@@ -24,6 +24,7 @@ from lib.core.settings import NULL
from lib.core.settings import PARAMETER_SPLITTING_REGEX
from lib.core.shell import autoCompletion
from lib.request import inject
from thirdparty.six.moves import input as _input
class Custom:
"""
@@ -88,7 +89,7 @@ class Custom:
query = None
try:
query = raw_input("sql-shell> ")
query = _input("sql-shell> ")
query = getUnicode(query, encoding=sys.stdin.encoding)
query = query.strip("; ")
except KeyboardInterrupt:
@@ -110,7 +111,7 @@ class Custom:
output = self.sqlQuery(query)
if output and output != "Quit":
conf.dumper.query(query, output)
conf.dumper.sqlQuery(query, output)
elif not output:
pass
@@ -134,6 +135,6 @@ class Custom:
for query in (_ for _ in snippet.split(';' if ';' in snippet else '\n') if _):
query = query.strip()
if query:
conf.dumper.query(query, self.sqlQuery(query))
conf.dumper.sqlQuery(query, self.sqlQuery(query))
else:
conf.dumper.query(snippet, self.sqlQuery(snippet))
conf.dumper.sqlQuery(snippet, self.sqlQuery(snippet))
+1 -1
View File
@@ -597,7 +597,7 @@ class Databases:
kb.dumpColumns = []
kb.rowXmlMode = True
for column in extractRegexResult(r"SELECT (?P<result>.+?) FROM", query).split(','):
for column in (extractRegexResult(r"SELECT (?P<result>.+?) FROM", query) or "").split(','):
kb.dumpColumns.append(randomStr().lower())
expression = expression.replace(column, "%s AS %s" % (column, kb.dumpColumns[-1]), 1)
Binary file not shown.
+1 -1
View File
@@ -544,7 +544,7 @@ lastChar = 0
# SQL statement to be executed.
# Example: SELECT 'foo', 'bar'
query =
sqlQuery =
# Prompt for an interactive SQL shell.
# Valid: True or False
+20 -3
View File
@@ -43,6 +43,7 @@ try:
from lib.core.common import createGithubIssue
from lib.core.common import dataToStdout
from lib.core.common import filterNone
from lib.core.common import getDaysFromLastUpdate
from lib.core.common import getSafeExString
from lib.core.common import getUnicode
from lib.core.common import maskSensitiveData
@@ -64,6 +65,7 @@ try:
from lib.core.patch import dirtyPatches
from lib.core.settings import GIT_PAGE
from lib.core.settings import IS_WIN
from lib.core.settings import LAST_UPDATE_NAGGING_DAYS
from lib.core.settings import LEGAL_DISCLAIMER
from lib.core.settings import THREAD_FINALIZATION_TIMEOUT
from lib.core.settings import UNICODE_ENCODING
@@ -157,10 +159,13 @@ def main():
# Postponed imports (faster start)
if conf.smokeTest:
from lib.core.testing import smokeTest
smokeTest()
os._exitcode = 1 - (smokeTest() or 0)
elif conf.vulnTest:
from lib.core.testing import vulnTest
os._exitcode = 1 - (vulnTest() or 0)
elif conf.liveTest:
from lib.core.testing import liveTest
liveTest()
os._exitcode = 1 - (liveTest() or 0)
else:
from lib.controller.controller import start
if conf.profile and PY2:
@@ -171,6 +176,8 @@ def main():
try:
start()
except Exception as ex:
os._exitcode = 1
if "can't start new thread" in getSafeExString(ex):
errMsg = "unable to start new threads. Please check OS (u)limits"
logger.critical(errMsg)
@@ -351,6 +358,11 @@ def main():
finally:
kb.threadContinue = False
_ = getDaysFromLastUpdate()
if _ > LAST_UPDATE_NAGGING_DAYS:
warnMsg = "you haven't updated sqlmap for more than %d days!!!" % _
logger.warn(warnMsg)
if conf.get("showTime"):
dataToStdout("\n[*] ending @ %s\n\n" % time.strftime("%X /%Y-%m-%d/"), forceOutput=True)
@@ -396,10 +408,15 @@ if __name__ == "__main__":
main()
except KeyboardInterrupt:
pass
except:
if int(os.environ.get("SQLMAP_DREI", 0)):
traceback.print_exc()
finally:
# Reference: http://stackoverflow.com/questions/1635080/terminate-a-multi-thread-python-program
if threading.activeCount() > 1:
os._exit(0)
os._exit(getattr(os, "_exitcode", 0))
else:
sys.exit(getattr(os, "_exitcode", 0))
else:
# cancelling postponed imports (because of Travis CI checks)
from lib.controller.controller import start
+3 -2
View File
@@ -7,6 +7,7 @@ See the file 'LICENSE' for copying permission
import re
from lib.core.common import decodeHex
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL
@@ -36,9 +37,9 @@ def tamper(payload, **kwargs):
if payload:
for match in re.finditer(r"\b0x([0-9a-f]+)\b", retVal):
if len(match.group(1)) > 2:
result = "CONCAT(%s)" % ','.join("CHAR(%d)" % ord(_) for _ in match.group(1).decode("hex"))
result = "CONCAT(%s)" % ','.join("CHAR(%d)" % ord(_) for _ in decodeHex(match.group(1)))
else:
result = "CHAR(%d)" % ord(match.group(1).decode("hex"))
result = "CHAR(%d)" % ord(decodeHex(match.group(1)))
retVal = retVal.replace(match.group(0), result)
return retVal
+1 -1
View File
@@ -32,6 +32,6 @@ def tamper(payload, **kwargs):
hints = kwargs.get("hints", {})
delimiter = kwargs.get("delimiter", DEFAULT_GET_POST_DELIMITER)
hints[HINT.PREPEND] = delimiter.join("%s=" % "".join(random.sample(string.letters + string.digits, 2)) for _ in xrange(500))
hints[HINT.PREPEND] = delimiter.join("%s=" % "".join(random.sample(string.ascii_letters + string.digits, 2)) for _ in xrange(500))
return payload
+30 -31
View File
@@ -91,6 +91,11 @@ import sys
if sys.version_info >= (3, 0):
xrange = range
text_type = str
binary_type = bytes
else:
text_type = unicode
binary_type = str
try:
from htmlentitydefs import name2codepoint
@@ -434,19 +439,13 @@ class PageElement(object):
def toEncoding(self, s, encoding=None):
"""Encodes an object to a string in some encoding, or to Unicode.
."""
if isinstance(s, unicode):
if isinstance(s, text_type):
if encoding:
s = s.encode(encoding)
elif isinstance(s, str):
if encoding:
s = s.encode(encoding)
else:
s = unicode(s)
elif isinstance(s, binary_type):
s = s.encode(encoding or "utf8")
else:
if encoding:
s = self.toEncoding(str(s), encoding)
else:
s = unicode(s)
s = self.toEncoding(str(s), encoding or "utf8")
return s
BARE_AMPERSAND_OR_BRACKET = re.compile("([<>]|"
@@ -459,7 +458,7 @@ class PageElement(object):
return "&" + self.XML_SPECIAL_CHARS_TO_ENTITIES[x.group(0)[0]] + ";"
class NavigableString(unicode, PageElement):
class NavigableString(text_type, PageElement):
def __new__(cls, value):
"""Create a new NavigableString.
@@ -469,9 +468,9 @@ class NavigableString(unicode, PageElement):
passed in to the superclass's __new__ or the superclass won't know
how to handle non-ASCII characters.
"""
if isinstance(value, unicode):
return unicode.__new__(cls, value)
return unicode.__new__(cls, value, DEFAULT_OUTPUT_ENCODING)
if isinstance(value, text_type):
return text_type.__new__(cls, value)
return text_type.__new__(cls, value, DEFAULT_OUTPUT_ENCODING)
def __getnewargs__(self):
return (NavigableString.__str__(self),)
@@ -1006,7 +1005,7 @@ class SoupStrainer:
if isinstance(markup, Tag):
markup = markup.name
if markup and not isinstance(markup, basestring):
markup = unicode(markup)
markup = text_type(markup)
#Now we know that chunk is either a string, or None.
if hasattr(matchAgainst, 'match'):
# It's a regexp object.
@@ -1016,8 +1015,8 @@ class SoupStrainer:
elif hasattr(matchAgainst, 'items'):
result = markup.has_key(matchAgainst)
elif matchAgainst and isinstance(markup, basestring):
if isinstance(markup, unicode):
matchAgainst = unicode(matchAgainst)
if isinstance(markup, text_type):
matchAgainst = text_type(matchAgainst)
else:
matchAgainst = str(matchAgainst)
@@ -1181,7 +1180,7 @@ class BeautifulStoneSoup(Tag, sgmllib.SGMLParser):
def _feed(self, inDocumentEncoding=None, isHTML=False):
# Convert the document to Unicode.
markup = self.markup
if isinstance(markup, unicode):
if isinstance(markup, text_type):
if not hasattr(self, 'originalEncoding'):
self.originalEncoding = None
else:
@@ -1792,9 +1791,9 @@ class UnicodeDammit:
self._detectEncoding(markup, isHTML)
self.smartQuotesTo = smartQuotesTo
self.triedEncodings = []
if markup == '' or isinstance(markup, unicode):
if markup == '' or isinstance(markup, text_type):
self.originalEncoding = None
self.unicode = unicode(markup)
self.unicode = text_type(markup)
return
u = None
@@ -1807,7 +1806,7 @@ class UnicodeDammit:
if u: break
# If no luck and we have auto-detection library, try that:
if not u and chardet and not isinstance(self.markup, unicode):
if not u and chardet and not isinstance(self.markup, text_type):
u = self._convertFrom(chardet.detect(self.markup)['encoding'])
# As a last resort, try utf-8 and windows-1252:
@@ -1880,7 +1879,7 @@ class UnicodeDammit:
elif data[:4] == '\xff\xfe\x00\x00':
encoding = 'utf-32le'
data = data[4:]
newdata = unicode(data, encoding)
newdata = text_type(data, encoding)
return newdata
def _detectEncoding(self, xml_data, isHTML=False):
@@ -1893,41 +1892,41 @@ class UnicodeDammit:
elif xml_data[:4] == '\x00\x3c\x00\x3f':
# UTF-16BE
sniffed_xml_encoding = 'utf-16be'
xml_data = unicode(xml_data, 'utf-16be').encode('utf-8')
xml_data = text_type(xml_data, 'utf-16be').encode('utf-8')
elif (len(xml_data) >= 4) and (xml_data[:2] == '\xfe\xff') \
and (xml_data[2:4] != '\x00\x00'):
# UTF-16BE with BOM
sniffed_xml_encoding = 'utf-16be'
xml_data = unicode(xml_data[2:], 'utf-16be').encode('utf-8')
xml_data = text_type(xml_data[2:], 'utf-16be').encode('utf-8')
elif xml_data[:4] == '\x3c\x00\x3f\x00':
# UTF-16LE
sniffed_xml_encoding = 'utf-16le'
xml_data = unicode(xml_data, 'utf-16le').encode('utf-8')
xml_data = text_type(xml_data, 'utf-16le').encode('utf-8')
elif (len(xml_data) >= 4) and (xml_data[:2] == '\xff\xfe') and \
(xml_data[2:4] != '\x00\x00'):
# UTF-16LE with BOM
sniffed_xml_encoding = 'utf-16le'
xml_data = unicode(xml_data[2:], 'utf-16le').encode('utf-8')
xml_data = text_type(xml_data[2:], 'utf-16le').encode('utf-8')
elif xml_data[:4] == '\x00\x00\x00\x3c':
# UTF-32BE
sniffed_xml_encoding = 'utf-32be'
xml_data = unicode(xml_data, 'utf-32be').encode('utf-8')
xml_data = text_type(xml_data, 'utf-32be').encode('utf-8')
elif xml_data[:4] == '\x3c\x00\x00\x00':
# UTF-32LE
sniffed_xml_encoding = 'utf-32le'
xml_data = unicode(xml_data, 'utf-32le').encode('utf-8')
xml_data = text_type(xml_data, 'utf-32le').encode('utf-8')
elif xml_data[:4] == '\x00\x00\xfe\xff':
# UTF-32BE with BOM
sniffed_xml_encoding = 'utf-32be'
xml_data = unicode(xml_data[4:], 'utf-32be').encode('utf-8')
xml_data = text_type(xml_data[4:], 'utf-32be').encode('utf-8')
elif xml_data[:4] == '\xff\xfe\x00\x00':
# UTF-32LE with BOM
sniffed_xml_encoding = 'utf-32le'
xml_data = unicode(xml_data[4:], 'utf-32le').encode('utf-8')
xml_data = text_type(xml_data[4:], 'utf-32le').encode('utf-8')
elif xml_data[:3] == '\xef\xbb\xbf':
# UTF-8 with BOM
sniffed_xml_encoding = 'utf-8'
xml_data = unicode(xml_data[3:], 'utf-8').encode('utf-8')
xml_data = text_type(xml_data[3:], 'utf-8').encode('utf-8')
else:
sniffed_xml_encoding = 'ascii'
pass
+1 -1
View File
@@ -573,7 +573,7 @@ In practice, you would read the password using something like the
getpass module, and generate the salt randomly:
>>> import random, string
>>> saltchars = string.letters + string.digits + './'
>>> saltchars = string.ascii_letters + string.digits + './'
>>> salt = random.choice(saltchars) + random.choice(saltchars)
Note that other ASCII characters are accepted in the salt, but the
+6 -8
View File
@@ -21,16 +21,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
import io
import mimetools
import mimetypes
import os
import stat
import sys
import urllib
import urllib2
from lib.core.compat import choose_boundary
from lib.core.exception import SqlmapDataException
from thirdparty.six.moves import urllib as _urllib
class Callable:
def __init__(self, anycallable):
@@ -41,11 +39,11 @@ class Callable:
doseq = 1
class MultipartPostHandler(urllib2.BaseHandler):
handler_order = urllib2.HTTPHandler.handler_order - 10 # needs to run first
class MultipartPostHandler(_urllib.request.BaseHandler):
handler_order = _urllib.request.HTTPHandler.handler_order - 10 # needs to run first
def http_request(self, request):
data = request.get_data()
data = request.data
if isinstance(data, dict):
v_files = []
@@ -62,7 +60,7 @@ class MultipartPostHandler(urllib2.BaseHandler):
raise SqlmapDataException("not a valid non-string sequence or mapping object '%s'" % traceback)
if len(v_files) == 0:
data = urllib.urlencode(v_vars, doseq)
data = _urllib.parse.urlencode(v_vars, doseq)
else:
boundary, data = self.multipart_encode(v_vars, v_files)
contenttype = "multipart/form-data; boundary=%s" % boundary
@@ -70,7 +68,7 @@ class MultipartPostHandler(urllib2.BaseHandler):
# print "Replacing %s with %s" % (request.get_header("content-type"), "multipart/form-data")
request.add_unredirected_header("Content-Type", contenttype)
request.add_data(data)
request.data = data
return request
def multipart_encode(vars, files, boundary=None, buf=None):
+73
View File
@@ -531,6 +531,79 @@ sifra
lozinka
kljuc
# turkish
numara
sira
lokasyon
kullanici
kullanici_adi
sifre
giris
pasif
posta
adres
is_adres
ev_adres
is_adresi
ev_adresi
isadresi
evadresi
il
ilce
eposta
eposta_adres
epostaadres
eposta_adresi
epostaadresi
e-posta
e-posta_adres
e-postaadres
e-posta_adresi
e-postaadresi
e_posta
e_posta_adres
e_postaadres
e_posta_adresi
e_postaadresi
baglanti
gun
ay
yil
saat
tarih
guncelleme
guncellemetarih
guncelleme_tarih
guncellemetarihi
guncelleme_tarihi
yetki
cinsiyet
ulke
guncel
vergi
vergino
vergi_no
yas
dogum
dogumtarih
dogum_tarih
dogumtarihi
dogum_tarihi
telefon_is
telefon_ev
telefonis
telefonev
ev_telefonu
is_telefonu
ev_telefon
is_telefon
evtelefonu
istelefonu
evtelefon
istelefon
kontak
kontaklar
# List from schemafuzz.py (http://www.beenuarora.com/code/schemafuzz.py)
user
pass
+46
View File
@@ -3354,6 +3354,52 @@ aliastype
mymps_mail_sendlist
mymps_navurl
# site:tr
kullanici
kullanicilar
yonetici
yoneticiler
adres
adresler
yayincilar
yayinci
urun
urunler
kategori
kategoriler
ulke
ulkeler
siparis
siparisler
bayi
bayiler
stok
reklam
reklamlar
site
siteler
sayfa
sayfalar
icerik
icerikler
yazi
yazilar
genel
istatistik
istatistikler
duyuru
duyurular
haber
haberler
komisyon
ucret
ucretler
bilgi
basvuru
basvurular
kontak
kontaklar
# List provided by Pedrito Perez ([email protected])
adminstbl
admintbl
+1 -1
View File
@@ -14,7 +14,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, code = get_page(get=vector)
retval = headers.get("X-Powered-By-360wzb") is not None
retval |= headers.get("X-Powered-By-360wzb") is not None
retval |= code == 493 and "/wzws-waf-cgi/" in (page or "")
retval |= all(_ in (page or "") for _ in ("eventID", "If you are the Webmaster", "<title>493</title>"))
if retval:
+1 -1
View File
@@ -14,7 +14,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, _ = get_page(get=vector)
retval = headers.get("aeSecure-code") is not None
retval |= headers.get("aeSecure-code") is not None
retval |= all(_ in (page or "") for _ in ("aeSecure", "aesecure_denied.png"))
if retval:
break
+1 -1
View File
@@ -17,7 +17,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, _ = get_page(get=vector)
retval = re.search(r"\AAL[_-]?(SESS|LB)", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
retval |= re.search(r"\AAL[_-]?(SESS|LB)", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
retval |= all(_ in (page or "") for _ in ("The server detected a syntax error in your request", "Check your request and all parameters", "Bad Request", "Your request ID was"))
if retval:
break
+1 -1
View File
@@ -14,7 +14,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, code = get_page(get=vector)
retval = code == 405 and any(_ in (page or "") for _ in ("/aqb_cc/error/", "hidden_intercept_time"))
retval |= code == 405 and any(_ in (page or "") for _ in ("/aqb_cc/error/", "hidden_intercept_time"))
if retval:
break
+1 -1
View File
@@ -17,7 +17,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, code = get_page(get=vector)
retval = re.search(r"Approach Web Application Firewall", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
retval |= re.search(r"Approach Web Application Firewall", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
retval |= re.search(r"Approach(</b>)? Web Application Firewall", page or "", re.I) is not None
retval |= " Your IP address has been logged and this information could be used by authorities to track you." in (page or "")
retval |= all(_ in (page or "") for _ in ("Sorry for the inconvenience!", "If this was an legitimate request please contact us with details!"))
+1 -1
View File
@@ -14,7 +14,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, _, _ = get_page(get=vector)
retval = "This request has been blocked by website protection from Armor" in (page or "")
retval |= "This request has been blocked by website protection from Armor" in (page or "")
if retval:
break
+1 -1
View File
@@ -14,7 +14,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, code = get_page(get=vector)
retval = "The requested URL was rejected. Please consult with your administrator." in (page or "")
retval |= "The requested URL was rejected. Please consult with your administrator." in (page or "")
retval |= all(_ in (page or "") for _ in ("security.f5aas.com", "Please enable JavaScript to view the page content"))
if retval:
break
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/env python2
"""
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from lib.core.settings import WAF_ATTACK_VECTORS
__product__ = "Astra (Czar Securities)"
def detect(get_page):
retval = False
for vector in WAF_ATTACK_VECTORS:
page, headers, code = get_page(get=vector)
retval |= all(_ in (page or "") for _ in ("unfortunately our website protection system", "//www.getastra.com"))
if retval:
break
return retval
+1 -1
View File
@@ -17,7 +17,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, code = get_page(get=vector)
retval = code == 403 and re.search(r"\bAWS", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
retval |= code == 403 and re.search(r"\bAWS", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
if retval:
break
+1 -1
View File
@@ -17,7 +17,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, _ = get_page(get=vector)
retval = re.search(r"\Abarra_counter_session=", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
retval |= re.search(r"\Abarra_counter_session=", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
retval |= re.search(r"(\A|\b)barracuda_", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
retval |= "when this page occurred and the event ID found at the bottom of the page" in (page or "")
if retval:
+1 -1
View File
@@ -14,7 +14,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, _, _ = get_page(get=vector)
retval = any(_ in (page or "") for _ in ("<title>Bekchy - Access Denided</title>", "<a class=\"btn\" href=\"https://bekchy.com/report\">"))
retval |= any(_ in (page or "") for _ in ("<title>Bekchy - Access Denided</title>", "<a class=\"btn\" href=\"https://bekchy.com/report\">"))
if retval:
break
+1 -1
View File
@@ -14,7 +14,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, _, _ = get_page(get=vector)
retval = any(_ in (page or "") for _ in ("alt=\"BitNinja|Security check by BitNinja", "your IP will be removed from BitNinja", "<title>Visitor anti-robot validation</title>"))
retval |= any(_ in (page or "") for _ in ("alt=\"BitNinja|Security check by BitNinja", "your IP will be removed from BitNinja", "<title>Visitor anti-robot validation</title>"))
if retval:
break
+1 -1
View File
@@ -17,7 +17,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, code = get_page(get=vector)
retval = re.search(r"BDWAF", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
retval |= re.search(r"BDWAF", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
retval |= re.search(r"Bluedon Web Application Firewall", page or "", re.I) is not None
if retval:
break
+1 -1
View File
@@ -14,7 +14,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, _, _ = get_page(get=vector)
retval = any(_ in (page or "") for _ in ("We're sorry, you are not allowed to proceed", "Your request looks suspicious or similar to automated requests from spam posting software"))
retval |= any(_ in (page or "") for _ in ("We're sorry, you are not allowed to proceed", "Your request looks suspicious or similar to automated requests from spam posting software"))
if retval:
break
+2 -2
View File
@@ -14,9 +14,9 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, code = get_page(get=vector)
retval = code >= 400 and headers.get("Powered-By-ChinaCache") is not None
retval |= code >= 400 and headers.get("Powered-By-ChinaCache") is not None
if retval:
break
return retval
return retval
+1 -1
View File
@@ -17,7 +17,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
_, headers, _ = get_page(get=vector)
retval = re.search(r"ACE XML Gateway", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
retval |= re.search(r"ACE XML Gateway", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
if retval:
break
+3 -1
View File
@@ -14,6 +14,8 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, code = get_page(get=vector)
retval = code >= 400 and all(_ in (page or "") for _ in ("Cloudbric", "Malicious Code Detected"))
retval |= code >= 400 and all(_ in (page or "") for _ in ("Cloudbric", "Malicious Code Detected"))
if retval:
break
return retval
+1 -3
View File
@@ -14,9 +14,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, _ = get_page(get=vector)
retval = all(_ in (page or "") for _ in ("Generated by cloudfront", "Request blocked"))
retval |= all(_ in (page or "") for _ in ("Generated by cloudfront", "Request blocked"))
if retval:
break
+1 -1
View File
@@ -17,7 +17,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
_, headers, _ = get_page(get=vector)
retval = re.search(r"Protected by COMODO WAF", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
retval |= re.search(r"Protected by COMODO WAF", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
if retval:
break
+3 -1
View File
@@ -14,7 +14,9 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, _, code = get_page(get=vector)
retval = code >= 400 and "This site is protected by CrawlProtect" in (page or "")
retval |= code >= 400 and "This site is protected by CrawlProtect" in (page or "")
retval |= "<title>CrawlProtect" in (page or "")
if retval:
break
return retval
+1 -1
View File
@@ -14,7 +14,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, _ = get_page(get=vector)
retval = headers.get("x-distil-cs") is not None
retval |= headers.get("x-distil-cs") is not None
retval |= any(_ in (page or "") for _ in ("distilCaptchaForm", "distilCallbackGuard", "cdn.distilnetworks.com/images/anomaly-detected.png"))
if retval:
break
+1 -1
View File
@@ -14,7 +14,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, _ = get_page(get=vector)
retval = headers.get("X-dotDefender-denied", "") == "1"
retval |= headers.get("X-dotDefender-denied", "") == "1"
retval |= any(_ in (page or "") for _ in ("dotDefender Blocked Your Request", '<meta name="description" content="Applicure is the leading provider of web application security', "Please contact the site administrator, and provide the following Reference ID:"))
if retval:
break
+1 -1
View File
@@ -17,7 +17,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
_, headers, code = get_page(get=vector)
retval = code == 400 and re.search(r"\AECDF", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
retval |= code == 400 and re.search(r"\AECDF", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
if retval:
break
+1 -1
View File
@@ -17,7 +17,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, _ = get_page(get=vector)
retval = any((page or "").strip() == _ for _ in ("Invalid GET Data", "Invalid URI")) and re.search(r"\bexp_last_", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
retval |= any((page or "").strip() == _ for _ in ("Invalid GET Data", "Invalid URI")) and re.search(r"\bexp_last_", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
if retval:
break
+1 -1
View File
@@ -17,7 +17,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, _ = get_page(get=vector)
retval = re.search(r"\AFORTIWAFSID=", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
retval |= re.search(r"\AFORTIWAFSID=", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
retval |= all(_ in (page or "") for _ in (".fgd_icon", ".blocked", ".authenticate"))
if retval:
break
+2 -1
View File
@@ -7,6 +7,7 @@ See the file 'LICENSE' for copying permission
import re
from lib.core.common import getUnicode
from lib.core.data import kb
from lib.core.settings import GENERIC_PROTECTION_REGEX
from lib.core.settings import IPS_WAF_CHECK_PAYLOAD
@@ -26,7 +27,7 @@ def detect(get_page):
if code >= 400 or (IPS_WAF_CHECK_PAYLOAD in vector and (code is None or re.search(GENERIC_PROTECTION_REGEX, page or "") and not re.search(GENERIC_PROTECTION_REGEX, original or ""))):
if code is not None:
kb.wafSpecificResponse = "HTTP/1.1 %s\n%s\n%s" % (code, "".join(_ for _ in (headers.headers if headers else {}) or [] if not _.startswith("URI")), page)
kb.wafSpecificResponse = "HTTP/1.1 %s\n%s\n%s" % (code, "".join(getUnicode(_) for _ in (headers.headers if headers else {}) or [] if not _.startswith("URI")), getUnicode(page or ""))
retval = True
break
+3 -1
View File
@@ -14,6 +14,8 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, _, _ = get_page(get=vector)
retval = any(_ in (page or "") for _ in ("Access Denied - GoDaddy Website Firewall", "<title>GoDaddy Security - Access Denied</title>"))
retval |= any(_ in (page or "") for _ in ("Access Denied - GoDaddy Website Firewall", "<title>GoDaddy Security - Access Denied</title>"))
if retval:
break
return retval
+1 -1
View File
@@ -17,7 +17,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, _ = get_page(get=vector)
retval = re.search(r"\Agreywizard", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
retval |= re.search(r"\Agreywizard", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
retval |= any(_ in (page or "") for _ in ("We've detected attempted attack or non standard traffic from your IP address", "<title>Grey Wizard</title>"))
if retval:
break
+2 -2
View File
@@ -17,8 +17,8 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, _ = get_page(get=vector)
retval = re.search(r"\Aimunify360", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
retval = any(_ in (page or "") for _ in ("protected by Imunify360", "Powered by Imunify360", "imunify360 preloader"))
retval |= re.search(r"\Aimunify360", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
retval |= any(_ in (page or "") for _ in ("protected by Imunify360", "Powered by Imunify360", "imunify360 preloader"))
if retval:
break
+1 -1
View File
@@ -17,7 +17,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, headers, _ = get_page(get=vector)
retval = re.search(r"incap_ses|visid_incap", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
retval |= re.search(r"incap_ses|visid_incap", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
retval |= re.search(r"Incapsula", headers.get("X-CDN", ""), re.I) is not None
retval |= "Incapsula incident ID" in (page or "")
retval |= all(_ in (page or "") for _ in ("Error code 15", "This request was blocked by the security rules"))
+1 -1
View File
@@ -14,7 +14,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, _, _ = get_page(get=vector)
retval = all(_ in (page or "") for _ in ("Reason:", "by Janusec Application Gateway"))
retval |= all(_ in (page or "") for _ in ("Reason:", "by Janusec Application Gateway"))
if retval:
break

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