mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-12-06 12:41:30 +00:00
Compare commits
290 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4af65f6c41 | ||
|
|
acfe788c95 | ||
|
|
5ccb73a1ee | ||
|
|
6ac5b6b759 | ||
|
|
d82f20abc4 | ||
|
|
10eafa35fd | ||
|
|
9105f259cd | ||
|
|
7cca56edfa | ||
|
|
e21d751834 | ||
|
|
ebb73b71fa | ||
|
|
1ca633ae64 | ||
|
|
3e22cbfed7 | ||
|
|
c7f615f707 | ||
|
|
b83ee92cd1 | ||
|
|
571d669a09 | ||
|
|
e485531b71 | ||
|
|
7427b554e3 | ||
|
|
1a818ceccd | ||
|
|
7fea8d608e | ||
|
|
1e6191e3b1 | ||
|
|
c10b2825d7 | ||
|
|
c200b2cb19 | ||
|
|
071f4c8a2b | ||
|
|
5097a2c79e | ||
|
|
bce9db1af5 | ||
|
|
ca67456dbe | ||
|
|
6df4d73b09 | ||
|
|
2aaa486f7a | ||
|
|
47ba7d4705 | ||
|
|
6a8bfd5fd8 | ||
|
|
1df94747e1 | ||
|
|
4092c701fe | ||
|
|
4939bd49b0 | ||
|
|
c6fb3d35d8 | ||
|
|
aad0bd8705 | ||
|
|
b69f635a3f | ||
|
|
eeae696b1b | ||
|
|
e1c8bc0e01 | ||
|
|
4b0acee585 | ||
|
|
d74612eb4c | ||
|
|
88c33974ac | ||
|
|
e5d7bfe453 | ||
|
|
99d23237b4 | ||
|
|
08d750197c | ||
|
|
d35bdf6eaa | ||
|
|
d332e00eb0 | ||
|
|
9d5499597f | ||
|
|
c0f8bbbc72 | ||
|
|
1684d60782 | ||
|
|
af6a977c9a | ||
|
|
f20263f235 | ||
|
|
2e42afea6f | ||
|
|
292a28131d | ||
|
|
2e775fbb75 | ||
|
|
e1d7641b8a | ||
|
|
6b0951d1ee | ||
|
|
db1fc621b5 | ||
|
|
9351756c36 | ||
|
|
63b645c64c | ||
|
|
7ad49f4185 | ||
|
|
d9315830f9 | ||
|
|
2e2c62b6a7 | ||
|
|
53289b0234 | ||
|
|
dd082ef79d | ||
|
|
2c968f9a35 | ||
|
|
74d0315fef | ||
|
|
ae98159130 | ||
|
|
3a9e36c52b | ||
|
|
cb43c03712 | ||
|
|
65a0f15f69 | ||
|
|
98b77d32cc | ||
|
|
86a3569ccb | ||
|
|
17fca351d3 | ||
|
|
2614e7bec1 | ||
|
|
832c6e806f | ||
|
|
7b334b0808 | ||
|
|
aa9151785e | ||
|
|
6bdef1b7da | ||
|
|
8b4367d354 | ||
|
|
0a9d69a7d0 | ||
|
|
a4b60dc00f | ||
|
|
f91ae32284 | ||
|
|
53fc9d6720 | ||
|
|
0b31568306 | ||
|
|
e9407cf791 | ||
|
|
0175acd028 | ||
|
|
733a32de32 | ||
|
|
1b863ecf93 | ||
|
|
ec06037335 | ||
|
|
0cdb62a1b5 | ||
|
|
99454198b8 | ||
|
|
dd6287ace8 | ||
|
|
786460e3b4 | ||
|
|
419cf979f1 | ||
|
|
30be875304 | ||
|
|
7d011bc811 | ||
|
|
b2c4a3b247 | ||
|
|
9d9592a69b | ||
|
|
cb42294a7e | ||
|
|
146762c109 | ||
|
|
494b9d1586 | ||
|
|
2e95fdb52d | ||
|
|
46736cac7b | ||
|
|
041213f22d | ||
|
|
8ca45c5678 | ||
|
|
c6eec8db97 | ||
|
|
98fdc493f4 | ||
|
|
91372bff87 | ||
|
|
7fb9db42a7 | ||
|
|
82382957f9 | ||
|
|
f034122bd0 | ||
|
|
0df2456f34 | ||
|
|
78fdb27a0b | ||
|
|
350baf0a0a | ||
|
|
9886b646eb | ||
|
|
c5197b99a0 | ||
|
|
cc313280af | ||
|
|
f06ff42c58 | ||
|
|
4bc1cf4518 | ||
|
|
0e65043c84 | ||
|
|
d7d565415a | ||
|
|
0986ec8948 | ||
|
|
50bced511f | ||
|
|
e275e8c0b0 | ||
|
|
77dea38ac1 | ||
|
|
7dc2ec5fd8 | ||
|
|
4bf2e3b139 | ||
|
|
8114c14755 | ||
|
|
ec8cf6aadc | ||
|
|
d326965966 | ||
|
|
030df0353d | ||
|
|
5038d7a70a | ||
|
|
f0b8fbb7fd | ||
|
|
5810c2b199 | ||
|
|
77f0b5dfa8 | ||
|
|
b0ea74dc63 | ||
|
|
0c07c8942c | ||
|
|
7d1bdb35ca | ||
|
|
e823889819 | ||
|
|
680aedaefc | ||
|
|
afdca09ced | ||
|
|
ac89ee71c3 | ||
|
|
af7c8cff92 | ||
|
|
26d4dec5fb | ||
|
|
cf31d12528 | ||
|
|
b4c730f8c0 | ||
|
|
fba1720b31 | ||
|
|
9fad72f28b | ||
|
|
1782bf8e64 | ||
|
|
2d59a10515 | ||
|
|
21a25c4f00 | ||
|
|
6b5c16c22c | ||
|
|
2c6621c26a | ||
|
|
f0500b1d2f | ||
|
|
6a033bb58c | ||
|
|
2fa4b22645 | ||
|
|
229d3a7dd0 | ||
|
|
b965e5bf1c | ||
|
|
3bd74c5351 | ||
|
|
55624ec1a2 | ||
|
|
6885afe8c3 | ||
|
|
acc1277246 | ||
|
|
935cb9c8cb | ||
|
|
17a4ddad63 | ||
|
|
5264671f5b | ||
|
|
b4ebbae354 | ||
|
|
510197c39e | ||
|
|
b6a4bd91fe | ||
|
|
83b82a5e98 | ||
|
|
0b1efc0759 | ||
|
|
2b506d744d | ||
|
|
79d08906a4 | ||
|
|
d27b33e26c | ||
|
|
73d86f0fdd | ||
|
|
6327063bd0 | ||
|
|
69fd900108 | ||
|
|
f9d01f682b | ||
|
|
d7d3db415b | ||
|
|
608f141f52 | ||
|
|
31850e4544 | ||
|
|
de9f23939f | ||
|
|
154ed2c4e2 | ||
|
|
89dfe4e1ac | ||
|
|
b41b07ddd8 | ||
|
|
e36fc02282 | ||
|
|
49b41c1eca | ||
|
|
4cd9fdb7df | ||
|
|
5aab2d8fb5 | ||
|
|
210b65c02d | ||
|
|
7a2ac23f0b | ||
|
|
e435fb2e9e | ||
|
|
6892c94595 | ||
|
|
831c960216 | ||
|
|
43af2a4aee | ||
|
|
190819e85d | ||
|
|
1de6996c26 | ||
|
|
304f2ed308 | ||
|
|
148b35da4f | ||
|
|
3865b3a398 | ||
|
|
d6bcbbae1d | ||
|
|
04b3aefc5d | ||
|
|
a5f8cae599 | ||
|
|
29c3037512 | ||
|
|
d0d7d3a205 | ||
|
|
7ce36ea1b6 | ||
|
|
6f97f4796b | ||
|
|
39fe96009f | ||
|
|
b475a38895 | ||
|
|
42de887b05 | ||
|
|
28576bf08e | ||
|
|
c395958dff | ||
|
|
798b539eec | ||
|
|
70cf8edc75 | ||
|
|
a81ea88eb0 | ||
|
|
023dda26fc | ||
|
|
3e76895155 | ||
|
|
2c1bd7f034 | ||
|
|
f7cae68378 | ||
|
|
f6ff1a115a | ||
|
|
32ee586e2a | ||
|
|
b9e5655e3c | ||
|
|
6623c3f877 | ||
|
|
30a4173249 | ||
|
|
dbbe4c6ddd | ||
|
|
633e4dfe48 | ||
|
|
5e8b105677 | ||
|
|
414dd96bbd | ||
|
|
e857c2a88a | ||
|
|
e7aaea2b8e | ||
|
|
63d7cd607e | ||
|
|
d886b08dd9 | ||
|
|
72f3185ae7 | ||
|
|
03be9f9b65 | ||
|
|
d9d0865c13 | ||
|
|
e3f54bc226 | ||
|
|
9662f4a56a | ||
|
|
fea5cc8579 | ||
|
|
94091cd0e9 | ||
|
|
cc9f4b6102 | ||
|
|
cd7c99c752 | ||
|
|
75478c1181 | ||
|
|
ad0ca69579 | ||
|
|
2d801b7122 | ||
|
|
1e07269fe3 | ||
|
|
3b74e99576 | ||
|
|
439fff684e | ||
|
|
72cf06119c | ||
|
|
808068d70a | ||
|
|
f09072b2b6 | ||
|
|
be9381abc5 | ||
|
|
5d09f7b85f | ||
|
|
8bbfee7591 | ||
|
|
be26392057 | ||
|
|
263730f4ee | ||
|
|
5d7e1782d9 | ||
|
|
e27f590c2c | ||
|
|
7afe655561 | ||
|
|
3bf08290a4 | ||
|
|
34c2172391 | ||
|
|
48044f7a46 | ||
|
|
04e666182f | ||
|
|
c797129956 | ||
|
|
6928dae956 | ||
|
|
6db3bcbb51 | ||
|
|
d7f0b3566d | ||
|
|
0c67a90cc0 | ||
|
|
f06e498fb0 | ||
|
|
ad612bf9e4 | ||
|
|
9dd5cd8eb6 | ||
|
|
5ed3cdc819 | ||
|
|
e07c92bce5 | ||
|
|
0c5965c7b8 | ||
|
|
aa21550712 | ||
|
|
66061e8c5f | ||
|
|
c4b74c2e01 | ||
|
|
55b23e78ee | ||
|
|
a9526bda92 | ||
|
|
0901da3f83 | ||
|
|
8004652f7b | ||
|
|
c9b410c97f | ||
|
|
814d710320 | ||
|
|
38fcc5a35a | ||
|
|
674d516f3e | ||
|
|
8ceb4907a5 | ||
|
|
ce3749622a | ||
|
|
bcfae99701 | ||
|
|
44c1c2c6f0 | ||
|
|
ac08db82b2 | ||
|
|
305bfd9d30 | ||
|
|
f9aaec7b4a |
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -1,5 +1,6 @@
|
|||||||
*.py text eol=lf
|
|
||||||
*.conf text eol=lf
|
*.conf text eol=lf
|
||||||
|
*.md5 text eol=lf
|
||||||
|
*.py text eol=lf
|
||||||
|
|
||||||
*_ binary
|
*_ binary
|
||||||
*.dll binary
|
*.dll binary
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ To get a list of all options and switches use:
|
|||||||
|
|
||||||
python sqlmap.py -hh
|
python sqlmap.py -hh
|
||||||
|
|
||||||
You can find a sample run [here](https://gist.github.com/stamparm/5335217).
|
You can find a sample run [here](https://asciinema.org/a/46601).
|
||||||
To get an overview of sqlmap capabilities, list of supported features and description of all options and switches, along with examples, you are advised to consult the [user's manual](https://github.com/sqlmapproject/sqlmap/wiki).
|
To get an overview of sqlmap capabilities, list of supported features and description of all options and switches, along with examples, you are advised to consult the [user's manual](https://github.com/sqlmapproject/sqlmap/wiki).
|
||||||
|
|
||||||
Links
|
Links
|
||||||
@@ -57,8 +57,10 @@ Translations
|
|||||||
|
|
||||||
* [Chinese](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-zh-CN.md)
|
* [Chinese](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-zh-CN.md)
|
||||||
* [Croatian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-hr-HR.md)
|
* [Croatian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-hr-HR.md)
|
||||||
|
* [French](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-fr-FR.md)
|
||||||
* [Greek](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-gr-GR.md)
|
* [Greek](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-gr-GR.md)
|
||||||
* [Indonesian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-id-ID.md)
|
* [Indonesian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-id-ID.md)
|
||||||
|
* [Japanese](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ja-JP.md)
|
||||||
* [Portuguese](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-pt-BR.md)
|
* [Portuguese](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-pt-BR.md)
|
||||||
* [Spanish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-es-MX.md)
|
* [Spanish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-es-MX.md)
|
||||||
* [Turkish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-tr-TR.md)
|
* [Turkish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-tr-TR.md)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ Para obtener una lista de todas las opciones:
|
|||||||
|
|
||||||
python sqlmap.py -hh
|
python sqlmap.py -hh
|
||||||
|
|
||||||
Se puede encontrar una muestra de su funcionamiento [aquí](https://gist.github.com/stamparm/5335217).
|
Se puede encontrar una muestra de su funcionamiento [aquí](https://asciinema.org/a/46601).
|
||||||
Para obtener una visión general de las capacidades de sqlmap, así como un listado funciones soportadas y descripción de todas las opciones y modificadores, junto con ejemplos, se recomienda consultar el [manual de usuario](https://github.com/sqlmapproject/sqlmap/wiki).
|
Para obtener una visión general de las capacidades de sqlmap, así como un listado funciones soportadas y descripción de todas las opciones y modificadores, junto con ejemplos, se recomienda consultar el [manual de usuario](https://github.com/sqlmapproject/sqlmap/wiki).
|
||||||
|
|
||||||
Enlaces
|
Enlaces
|
||||||
|
|||||||
52
doc/translations/README-fr-FR.md
Normal file
52
doc/translations/README-fr-FR.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# sqlmap
|
||||||
|
|
||||||
|
[](https://api.travis-ci.org/sqlmapproject/sqlmap) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/doc/COPYING) [](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.
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Les captures d'écran disponible [ici](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) démontrent des fonctionnalités de __sqlmap__.
|
||||||
|
|
||||||
|
Installation
|
||||||
|
----
|
||||||
|
|
||||||
|
Vous pouvez télécharger le plus récent fichier tarball en cliquant [ici](https://github.com/sqlmapproject/sqlmap/tarball/master). Vous pouvez aussi télécharger le plus récent archive zip [ici](https://github.com/sqlmapproject/sqlmap/zipball/master).
|
||||||
|
|
||||||
|
De préférence, télécharger __sqlmap__ en le [clonant](https://github.com/sqlmapproject/sqlmap):
|
||||||
|
|
||||||
|
git clone https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
|
||||||
|
|
||||||
|
sqlmap fonctionne sur n'importe quel système d'exploitation avec la version **2.6.x** et **2.7.x** de [Python](http://www.python.org/download/)
|
||||||
|
|
||||||
|
Usage
|
||||||
|
----
|
||||||
|
|
||||||
|
Pour afficher une liste des fonctions de bases et des commutateurs (switches), tapez:
|
||||||
|
|
||||||
|
python sqlmap.py -h
|
||||||
|
|
||||||
|
Pour afficher une liste complète des options et des commutateurs (switches), tapez:
|
||||||
|
|
||||||
|
python sqlmap.py -hh
|
||||||
|
|
||||||
|
Vous pouvez regarder un vidéo [ici](https://asciinema.org/a/46601) pour plus d'exemples.
|
||||||
|
Pour obtenir un aperçu des ressources de __sqlmap__, une liste des fonctionnalités prises en charge et la description de toutes les options, ainsi que des exemples , nous vous recommandons de consulter [le wiki](https://github.com/sqlmapproject/sqlmap/wiki).
|
||||||
|
|
||||||
|
Liens
|
||||||
|
----
|
||||||
|
|
||||||
|
* Page d'acceuil: http://sqlmap.org
|
||||||
|
* Téléchargement: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) ou [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
|
||||||
|
* Commits RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom
|
||||||
|
* Issue tracker: https://github.com/sqlmapproject/sqlmap/issues
|
||||||
|
* Manuel de l'utilisateur: https://github.com/sqlmapproject/sqlmap/wiki
|
||||||
|
* Foire aux questions (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
|
||||||
|
* Mailing list subscription: https://lists.sourceforge.net/lists/listinfo/sqlmap-users
|
||||||
|
* Mailing list RSS feed: http://rss.gmane.org/messages/complete/gmane.comp.security.sqlmap
|
||||||
|
* Mailing list archive: http://news.gmane.org/gmane.comp.security.sqlmap
|
||||||
|
* Twitter: [@sqlmap](https://twitter.com/sqlmap)
|
||||||
|
* Démonstrations: [http://www.youtube.com/user/inquisb/videos](http://www.youtube.com/user/inquisb/videos)
|
||||||
|
* Les captures d'écran: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
python sqlmap.py -hh
|
python sqlmap.py -hh
|
||||||
|
|
||||||
Μπορείτε να δείτε ένα δείγμα λειτουργίας του προγράμματος [εδώ](https://gist.github.com/stamparm/5335217).
|
Μπορείτε να δείτε ένα δείγμα λειτουργίας του προγράμματος [εδώ](https://asciinema.org/a/46601).
|
||||||
Για μια γενικότερη άποψη των δυνατοτήτων του sqlmap, μια λίστα των υποστηριζόμενων χαρακτηριστικών και περιγραφή για όλες τις επιλογές, μαζί με παραδείγματα, καλείστε να συμβουλευτείτε το [εγχειρίδιο χρήστη](https://github.com/sqlmapproject/sqlmap/wiki).
|
Για μια γενικότερη άποψη των δυνατοτήτων του sqlmap, μια λίστα των υποστηριζόμενων χαρακτηριστικών και περιγραφή για όλες τις επιλογές, μαζί με παραδείγματα, καλείστε να συμβουλευτείτε το [εγχειρίδιο χρήστη](https://github.com/sqlmapproject/sqlmap/wiki).
|
||||||
|
|
||||||
Σύνδεσμοι
|
Σύνδεσμοι
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ Kako biste dobili listu svih opcija i prekidača koristite:
|
|||||||
|
|
||||||
python sqlmap.py -hh
|
python sqlmap.py -hh
|
||||||
|
|
||||||
Možete pronaći primjer izvršavanja [ovdje](https://gist.github.com/stamparm/5335217).
|
Možete pronaći primjer izvršavanja [ovdje](https://asciinema.org/a/46601).
|
||||||
Kako biste dobili pregled mogućnosti sqlmap-a, liste podržanih značajki te opis svih opcija i prekidača, zajedno s primjerima, preporučen je uvid u [korisnički priručnik](https://github.com/sqlmapproject/sqlmap/wiki).
|
Kako biste dobili pregled mogućnosti sqlmap-a, liste podržanih značajki te opis svih opcija i prekidača, zajedno s primjerima, preporučen je uvid u [korisnički priručnik](https://github.com/sqlmapproject/sqlmap/wiki).
|
||||||
|
|
||||||
Poveznice
|
Poveznice
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ Untuk mendapatkan daftar opsi lanjut gunakan:
|
|||||||
|
|
||||||
python sqlmap.py -hh
|
python sqlmap.py -hh
|
||||||
|
|
||||||
Anda dapat mendapatkan contoh penggunaan [di sini](https://gist.github.com/stamparm/5335217).
|
Anda dapat mendapatkan contoh penggunaan [di sini](https://asciinema.org/a/46601).
|
||||||
Untuk mendapatkan gambaran singkat kemampuan sqlmap, daftar fitur yang didukung, deskripsi dari semua opsi, berikut dengan contohnya, Anda disarankan untuk membaca [manual pengguna](https://github.com/sqlmapproject/sqlmap/wiki).
|
Untuk mendapatkan gambaran singkat kemampuan sqlmap, daftar fitur yang didukung, deskripsi dari semua opsi, berikut dengan contohnya, Anda disarankan untuk membaca [manual pengguna](https://github.com/sqlmapproject/sqlmap/wiki).
|
||||||
|
|
||||||
Tautan
|
Tautan
|
||||||
|
|||||||
54
doc/translations/README-ja-JP.md
Normal file
54
doc/translations/README-ja-JP.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# sqlmap
|
||||||
|
|
||||||
|
[](https://api.travis-ci.org/sqlmapproject/sqlmap) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/doc/COPYING) [](https://twitter.com/sqlmap)
|
||||||
|
|
||||||
|
sqlmapはオープンソースのペネトレーションテスティングツールです。SQLインジェクションの脆弱性の検出、活用、そしてデータベースサーバ奪取のプロセスを自動化します。
|
||||||
|
強力な検出エンジン、ペネトレーションテスターのための多くのニッチ機能、持続的なデータベースのフィンガープリンティングから、データベースのデータ取得やアウトオブバンド接続を介したオペレーティング・システム上でのコマンド実行、ファイルシステムへのアクセスなどの広範囲に及ぶスイッチを提供します。
|
||||||
|
|
||||||
|
スクリーンショット
|
||||||
|
----
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
wikiに載っているいくつかの機能のデモをスクリーンショットで見ることができます。 [スクリーンショット集](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots)
|
||||||
|
|
||||||
|
インストール
|
||||||
|
----
|
||||||
|
|
||||||
|
最新のtarballを [こちら](https://github.com/sqlmapproject/sqlmap/tarball/master) から、最新のzipballを [こちら](https://github.com/sqlmapproject/sqlmap/zipball/master) からダウンロードできます。
|
||||||
|
|
||||||
|
[Git](https://github.com/sqlmapproject/sqlmap) レポジトリをクローンして、sqlmapをダウンロードすることも可能です。:
|
||||||
|
|
||||||
|
git clone https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
|
||||||
|
|
||||||
|
sqlmapは、 [Python](http://www.python.org/download/) バージョン **2.6.x** または **2.7.x** がインストールされていれば、全てのプラットフォームですぐに使用できます。
|
||||||
|
|
||||||
|
使用法
|
||||||
|
----
|
||||||
|
|
||||||
|
基本的なオプションとスイッチの使用法をリストするには:
|
||||||
|
|
||||||
|
python sqlmap.py -h
|
||||||
|
|
||||||
|
全てのオプションとスイッチの使用法をリストするには:
|
||||||
|
|
||||||
|
python sqlmap.py -hh
|
||||||
|
|
||||||
|
実行例を [こちら](https://asciinema.org/a/46601) で見ることができます。
|
||||||
|
sqlmapの概要、機能の一覧、全てのオプションやスイッチの使用法を例とともに、 [ユーザーマニュアル](https://github.com/sqlmapproject/sqlmap/wiki) で確認することができます。
|
||||||
|
|
||||||
|
リンク
|
||||||
|
----
|
||||||
|
|
||||||
|
* ホームページ: http://sqlmap.org
|
||||||
|
* ダウンロード: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
|
||||||
|
* コミットのRSSフィード: https://github.com/sqlmapproject/sqlmap/commits/master.atom
|
||||||
|
* 課題管理: https://github.com/sqlmapproject/sqlmap/issues
|
||||||
|
* ユーザーマニュアル: https://github.com/sqlmapproject/sqlmap/wiki
|
||||||
|
* よくある質問 (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
|
||||||
|
* メーリングリストへの参加: https://lists.sourceforge.net/lists/listinfo/sqlmap-users
|
||||||
|
* メーリングリストのRSSフィード: http://rss.gmane.org/messages/complete/gmane.comp.security.sqlmap
|
||||||
|
* メーリングリストのアーカイブ: http://news.gmane.org/gmane.comp.security.sqlmap
|
||||||
|
* Twitter: [@sqlmap](https://twitter.com/sqlmap)
|
||||||
|
* デモ: [http://www.youtube.com/user/inquisb/videos](http://www.youtube.com/user/inquisb/videos)
|
||||||
|
* スクリーンショット: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
|
||||||
@@ -34,7 +34,7 @@ Para obter a lista completa de opções faça:
|
|||||||
|
|
||||||
python sqlmap.py -hh
|
python sqlmap.py -hh
|
||||||
|
|
||||||
Você pode encontrar alguns exemplos [aqui](https://gist.github.com/stamparm/5335217).
|
Você pode encontrar alguns exemplos [aqui](https://asciinema.org/a/46601).
|
||||||
Para ter uma visão geral dos recursos do sqlmap, lista de recursos suportados e a descrição de todas as opções, juntamente com exemplos, aconselhamos que você consulte o [manual do usuário](https://github.com/sqlmapproject/sqlmap/wiki).
|
Para ter uma visão geral dos recursos do sqlmap, lista de recursos suportados e a descrição de todas as opções, juntamente com exemplos, aconselhamos que você consulte o [manual do usuário](https://github.com/sqlmapproject/sqlmap/wiki).
|
||||||
|
|
||||||
Links
|
Links
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ Bütün seçenekleri gösterir
|
|||||||
|
|
||||||
python sqlmap.py -hh
|
python sqlmap.py -hh
|
||||||
|
|
||||||
Program ile ilgili örnekleri [burada](https://gist.github.com/stamparm/5335217) bulabilirsiniz. Daha fazlası içinsqlmap'in bütün açıklamaları ile birlikte bütün özelliklerinin, örnekleri ile bulunduğu [manuel sayfamıza](https://github.com/sqlmapproject/sqlmap/wiki) bakmanızı tavsiye ediyoruz
|
Program ile ilgili örnekleri [burada](https://asciinema.org/a/46601) bulabilirsiniz. Daha fazlası içinsqlmap'in bütün açıklamaları ile birlikte bütün özelliklerinin, örnekleri ile bulunduğu [manuel sayfamıza](https://github.com/sqlmapproject/sqlmap/wiki) bakmanızı tavsiye ediyoruz
|
||||||
|
|
||||||
Links
|
Links
|
||||||
----
|
----
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ sqlmap 可以运行在 [Python](http://www.python.org/download/) **2.6.x** 和
|
|||||||
|
|
||||||
python sqlmap.py -hh
|
python sqlmap.py -hh
|
||||||
|
|
||||||
你可以从 [这里](https://gist.github.com/stamparm/5335217) 看到一个sqlmap 的使用样例。除此以外,你还可以查看 [使用手册](https://github.com/sqlmapproject/sqlmap/wiki)。获取sqlmap所有支持的特性、参数、命令行选项开关及说明的使用帮助。
|
你可以从 [这里](https://asciinema.org/a/46601) 看到一个sqlmap 的使用样例。除此以外,你还可以查看 [使用手册](https://github.com/sqlmapproject/sqlmap/wiki)。获取sqlmap所有支持的特性、参数、命令行选项开关及说明的使用帮助。
|
||||||
|
|
||||||
链接
|
链接
|
||||||
----
|
----
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ void usage(char *path)
|
|||||||
printf(" -h this screen\n");
|
printf(" -h this screen\n");
|
||||||
printf(" -b num maximal number of blanks (unanswered icmp requests)\n");
|
printf(" -b num maximal number of blanks (unanswered icmp requests)\n");
|
||||||
printf(" before quitting\n");
|
printf(" before quitting\n");
|
||||||
printf(" -s bytes maximal data buffer size in bytes (default is 64 bytes)\n\n", DEFAULT_MAX_DATA_SIZE);
|
printf(" -s bytes maximal data buffer size in bytes (default is %u bytes)\n\n", DEFAULT_MAX_DATA_SIZE);
|
||||||
printf("In order to improve the speed, lower the delay (-d) between requests or\n");
|
printf("In order to improve the speed, lower the delay (-d) between requests or\n");
|
||||||
printf("increase the size (-s) of the data buffer\n");
|
printf("increase the size (-s) of the data buffer\n");
|
||||||
}
|
}
|
||||||
@@ -203,8 +203,6 @@ int main(int argc, char **argv)
|
|||||||
PROCESS_INFORMATION pi;
|
PROCESS_INFORMATION pi;
|
||||||
int status;
|
int status;
|
||||||
unsigned int max_data_size;
|
unsigned int max_data_size;
|
||||||
struct hostent *he;
|
|
||||||
|
|
||||||
|
|
||||||
// set defaults
|
// set defaults
|
||||||
target = 0;
|
target = 0;
|
||||||
|
|||||||
@@ -1,20 +1,27 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
PROJECT="../../"
|
||||||
SETTINGS="../../lib/core/settings.py"
|
SETTINGS="../../lib/core/settings.py"
|
||||||
|
CHECKSUM="../../txt/checksum.md5"
|
||||||
|
|
||||||
declare -x SCRIPTPATH="${0}"
|
declare -x SCRIPTPATH="${0}"
|
||||||
|
|
||||||
FULLPATH=${SCRIPTPATH%/*}/$SETTINGS
|
PROJECT_FULLPATH=${SCRIPTPATH%/*}/$PROJECT
|
||||||
|
SETTINGS_FULLPATH=${SCRIPTPATH%/*}/$SETTINGS
|
||||||
|
CHECKSUM_FULLPATH=${SCRIPTPATH%/*}/$CHECKSUM
|
||||||
|
|
||||||
if [ -f $FULLPATH ]
|
truncate -s 0 "$CHECKSUM_FULLPATH"
|
||||||
|
cd $PROJECT_FULLPATH && for i in $(find . -name "*.py" -o -name "*.xml" -o -iname "*_" | sort); do git ls-files $i --error-unmatch &>/dev/null && md5sum $i | sed 's/\.\///' >> "$CHECKSUM_FULLPATH"; git add "$CHECKSUM_FULLPATH"; done
|
||||||
|
|
||||||
|
if [ -f $SETTINGS_FULLPATH ]
|
||||||
then
|
then
|
||||||
LINE=$(grep -o ${FULLPATH} -e 'VERSION = "[0-9.]*"');
|
LINE=$(grep -o ${SETTINGS_FULLPATH} -e 'VERSION = "[0-9.]*"');
|
||||||
declare -a LINE;
|
declare -a LINE;
|
||||||
INCREMENTED=$(python -c "import re, sys, time; version = re.search('\"([0-9.]*)\"', sys.argv[1]).group(1); _ = version.split('.'); _.append(0) if len(_) < 3 else _; _[-1] = str(int(_[-1]) + 1); month = str(time.gmtime().tm_mon); _[-1] = '0' if _[-2] != month else _[-1]; _[-2] = month; print sys.argv[1].replace(version, '.'.join(_))" "$LINE")
|
INCREMENTED=$(python -c "import re, sys, time; version = re.search('\"([0-9.]*)\"', sys.argv[1]).group(1); _ = version.split('.'); _.append(0) if len(_) < 3 else _; _[-1] = str(int(_[-1]) + 1); month = str(time.gmtime().tm_mon); _[-1] = '0' if _[-2] != month else _[-1]; _[-2] = month; print sys.argv[1].replace(version, '.'.join(_))" "$LINE")
|
||||||
if [ -n "$INCREMENTED" ]
|
if [ -n "$INCREMENTED" ]
|
||||||
then
|
then
|
||||||
sed "s/${LINE}/${INCREMENTED}/" $FULLPATH > $FULLPATH.tmp && mv $FULLPATH.tmp $FULLPATH
|
sed "s/${LINE}/${INCREMENTED}/" $SETTINGS_FULLPATH > $SETTINGS_FULLPATH.tmp && mv $SETTINGS_FULLPATH.tmp $SETTINGS_FULLPATH
|
||||||
echo "Updated ${INCREMENTED} in ${FULLPATH}";
|
echo "Updated ${INCREMENTED} in ${SETTINGS_FULLPATH}";
|
||||||
else
|
else
|
||||||
echo "Something went wrong in VERSION increment"
|
echo "Something went wrong in VERSION increment"
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
56
extra/shutils/pypi.sh
Normal file
56
extra/shutils/pypi.sh
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
VERSION=1.0.8
|
||||||
|
TMP_DIR=/tmp/pypi
|
||||||
|
mkdir $TMP_DIR
|
||||||
|
cd $TMP_DIR
|
||||||
|
cat > $TMP_DIR/setup.py << EOF
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'doc/COPYING' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name='sqlmap',
|
||||||
|
version='$VERSION',
|
||||||
|
description="Automatic SQL injection and database takeover tool",
|
||||||
|
author='Bernardo Damele Assumpcao Guimaraes, Miroslav Stampar',
|
||||||
|
author_email='bernardo@sqlmap.org, miroslav@sqlmap.org',
|
||||||
|
url='https://sqlmap.org',
|
||||||
|
download_url='https://github.com/sqlmapproject/sqlmap/archive/$VERSION.zip',
|
||||||
|
license='GPLv2',
|
||||||
|
packages=find_packages(),
|
||||||
|
include_package_data=True,
|
||||||
|
zip_safe=False,
|
||||||
|
entry_points={
|
||||||
|
'console_scripts': [
|
||||||
|
'sqlmap = sqlmap.sqlmap:main',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
EOF
|
||||||
|
wget "https://github.com/sqlmapproject/sqlmap/archive/$VERSION.zip" -O sqlmap.zip
|
||||||
|
unzip sqlmap.zip
|
||||||
|
rm sqlmap.zip
|
||||||
|
mv "sqlmap-$VERSION" sqlmap
|
||||||
|
cat > sqlmap/__init__.py << EOF
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'doc/COPYING' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
EOF
|
||||||
|
for file in $(find sqlmap -type f | grep -v -E "\.(git|yml)"); do echo include $file >> MANIFEST.in; done
|
||||||
|
python setup.py sdist
|
||||||
|
python setup.py sdist upload
|
||||||
|
rm -rf $TMP_DIR
|
||||||
@@ -48,9 +48,6 @@ def action():
|
|||||||
elif kb.nullConnection:
|
elif kb.nullConnection:
|
||||||
errMsg += ". You can try to rerun without using optimization "
|
errMsg += ". You can try to rerun without using optimization "
|
||||||
errMsg += "switch '%s'" % ("-o" if conf.optimize else "--null-connection")
|
errMsg += "switch '%s'" % ("-o" if conf.optimize else "--null-connection")
|
||||||
else:
|
|
||||||
errMsg += ". Support for this DBMS will be implemented at "
|
|
||||||
errMsg += "some point"
|
|
||||||
|
|
||||||
raise SqlmapUnsupportedDBMSException(errMsg)
|
raise SqlmapUnsupportedDBMSException(errMsg)
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ See the file 'doc/COPYING' for copying permission
|
|||||||
|
|
||||||
import copy
|
import copy
|
||||||
import httplib
|
import httplib
|
||||||
|
import random
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
import time
|
import time
|
||||||
@@ -54,6 +55,7 @@ from lib.core.enums import HASHDB_KEYS
|
|||||||
from lib.core.enums import HEURISTIC_TEST
|
from lib.core.enums import HEURISTIC_TEST
|
||||||
from lib.core.enums import HTTP_HEADER
|
from lib.core.enums import HTTP_HEADER
|
||||||
from lib.core.enums import HTTPMETHOD
|
from lib.core.enums import HTTPMETHOD
|
||||||
|
from lib.core.enums import NOTE
|
||||||
from lib.core.enums import NULLCONNECTION
|
from lib.core.enums import NULLCONNECTION
|
||||||
from lib.core.enums import PAYLOAD
|
from lib.core.enums import PAYLOAD
|
||||||
from lib.core.enums import PLACE
|
from lib.core.enums import PLACE
|
||||||
@@ -62,14 +64,15 @@ from lib.core.exception import SqlmapConnectionException
|
|||||||
from lib.core.exception import SqlmapNoneDataException
|
from lib.core.exception import SqlmapNoneDataException
|
||||||
from lib.core.exception import SqlmapSilentQuitException
|
from lib.core.exception import SqlmapSilentQuitException
|
||||||
from lib.core.exception import SqlmapUserQuitException
|
from lib.core.exception import SqlmapUserQuitException
|
||||||
from lib.core.settings import CLOUDFLARE_SERVER_HEADER
|
|
||||||
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
|
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
|
||||||
from lib.core.settings import DUMMY_NON_SQLI_CHECK_APPENDIX
|
from lib.core.settings import DUMMY_NON_SQLI_CHECK_APPENDIX
|
||||||
|
from lib.core.settings import FI_ERROR_REGEX
|
||||||
from lib.core.settings import FORMAT_EXCEPTION_STRINGS
|
from lib.core.settings import FORMAT_EXCEPTION_STRINGS
|
||||||
from lib.core.settings import HEURISTIC_CHECK_ALPHABET
|
from lib.core.settings import HEURISTIC_CHECK_ALPHABET
|
||||||
from lib.core.settings import IDS_WAF_CHECK_PAYLOAD
|
from lib.core.settings import IDS_WAF_CHECK_PAYLOAD
|
||||||
from lib.core.settings import IDS_WAF_CHECK_RATIO
|
from lib.core.settings import IDS_WAF_CHECK_RATIO
|
||||||
from lib.core.settings import IDS_WAF_CHECK_TIMEOUT
|
from lib.core.settings import IDS_WAF_CHECK_TIMEOUT
|
||||||
|
from lib.core.settings import MAX_DIFFLIB_SEQUENCE_LENGTH
|
||||||
from lib.core.settings import NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH
|
from lib.core.settings import NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH
|
||||||
from lib.core.settings import SUHOSIN_MAX_VALUE_LENGTH
|
from lib.core.settings import SUHOSIN_MAX_VALUE_LENGTH
|
||||||
from lib.core.settings import SUPPORTED_DBMS
|
from lib.core.settings import SUPPORTED_DBMS
|
||||||
@@ -77,6 +80,7 @@ from lib.core.settings import URI_HTTP_HEADER
|
|||||||
from lib.core.settings import UPPER_RATIO_BOUND
|
from lib.core.settings import UPPER_RATIO_BOUND
|
||||||
from lib.core.threads import getCurrentThreadData
|
from lib.core.threads import getCurrentThreadData
|
||||||
from lib.request.connect import Connect as Request
|
from lib.request.connect import Connect as Request
|
||||||
|
from lib.request.comparison import comparison
|
||||||
from lib.request.inject import checkBooleanExpression
|
from lib.request.inject import checkBooleanExpression
|
||||||
from lib.request.templates import getPageTemplate
|
from lib.request.templates import getPageTemplate
|
||||||
from lib.techniques.union.test import unionTest
|
from lib.techniques.union.test import unionTest
|
||||||
@@ -97,6 +101,9 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
tests = getSortedInjectionTests()
|
tests = getSortedInjectionTests()
|
||||||
seenPayload = set()
|
seenPayload = set()
|
||||||
|
|
||||||
|
kb.data.setdefault("randomInt", str(randomInt(10)))
|
||||||
|
kb.data.setdefault("randomStr", str(randomStr(10)))
|
||||||
|
|
||||||
while tests:
|
while tests:
|
||||||
test = tests.pop(0)
|
test = tests.pop(0)
|
||||||
|
|
||||||
@@ -173,10 +180,11 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
lower, upper = int(match.group(1)), int(match.group(2))
|
lower, upper = int(match.group(1)), int(match.group(2))
|
||||||
for _ in (lower, upper):
|
for _ in (lower, upper):
|
||||||
if _ > 1:
|
if _ > 1:
|
||||||
|
__ = 2 * (_ - 1) + 1 if _ == lower else 2 * _
|
||||||
unionExtended = True
|
unionExtended = True
|
||||||
test.request.columns = re.sub(r"\b%d\b" % _, str(2 * _), test.request.columns)
|
test.request.columns = re.sub(r"\b%d\b" % _, str(__), test.request.columns)
|
||||||
title = re.sub(r"\b%d\b" % _, str(2 * _), title)
|
title = re.sub(r"\b%d\b" % _, str(__), title)
|
||||||
test.title = re.sub(r"\b%d\b" % _, str(2 * _), test.title)
|
test.title = re.sub(r"\b%d\b" % _, str(__), test.title)
|
||||||
|
|
||||||
# Skip test if the user's wants to test only for a specific
|
# Skip test if the user's wants to test only for a specific
|
||||||
# technique
|
# technique
|
||||||
@@ -380,8 +388,6 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
# Use different page template than the original
|
# Use different page template than the original
|
||||||
# one as we are changing parameters value, which
|
# one as we are changing parameters value, which
|
||||||
# will likely result in a different content
|
# will likely result in a different content
|
||||||
kb.data.setdefault("randomInt", str(randomInt(10)))
|
|
||||||
kb.data.setdefault("randomStr", str(randomStr(10)))
|
|
||||||
|
|
||||||
if conf.invalidLogical:
|
if conf.invalidLogical:
|
||||||
_ = int(kb.data.randomInt[:2])
|
_ = int(kb.data.randomInt[:2])
|
||||||
@@ -441,11 +447,13 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
kb.matchRatio = None
|
kb.matchRatio = None
|
||||||
kb.negativeLogic = (where == PAYLOAD.WHERE.NEGATIVE)
|
kb.negativeLogic = (where == PAYLOAD.WHERE.NEGATIVE)
|
||||||
Request.queryPage(genCmpPayload(), place, raise404=False)
|
Request.queryPage(genCmpPayload(), place, raise404=False)
|
||||||
falsePage = threadData.lastComparisonPage or ""
|
falsePage, falseHeaders, falseCode = threadData.lastComparisonPage or "", threadData.lastComparisonHeaders, threadData.lastComparisonCode
|
||||||
|
falseRawResponse = "%s%s" % (falseHeaders, falsePage)
|
||||||
|
|
||||||
# Perform the test's True request
|
# Perform the test's True request
|
||||||
trueResult = Request.queryPage(reqPayload, place, raise404=False)
|
trueResult = Request.queryPage(reqPayload, place, raise404=False)
|
||||||
truePage = threadData.lastComparisonPage or ""
|
truePage, trueHeaders, trueCode = threadData.lastComparisonPage or "", threadData.lastComparisonHeaders, threadData.lastComparisonCode
|
||||||
|
trueRawResponse = "%s%s" % (trueHeaders, truePage)
|
||||||
|
|
||||||
if trueResult and not(truePage == falsePage and not kb.nullConnection):
|
if trueResult and not(truePage == falsePage and not kb.nullConnection):
|
||||||
# Perform the test's False request
|
# Perform the test's False request
|
||||||
@@ -460,23 +468,58 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
errorResult = Request.queryPage(errorPayload, place, raise404=False)
|
errorResult = Request.queryPage(errorPayload, place, raise404=False)
|
||||||
if errorResult:
|
if errorResult:
|
||||||
continue
|
continue
|
||||||
|
elif not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
|
||||||
infoMsg = "%s parameter '%s' seems to be '%s' injectable " % (paramType, parameter, title)
|
_ = comparison(kb.heuristicPage, None, getRatioValue=True)
|
||||||
logger.info(infoMsg)
|
if _ > kb.matchRatio:
|
||||||
|
kb.matchRatio = _
|
||||||
|
logger.debug("adjusting match ratio for current parameter to %.3f" % kb.matchRatio)
|
||||||
|
|
||||||
injectable = True
|
injectable = True
|
||||||
|
|
||||||
if not injectable and not any((conf.string, conf.notString, conf.regexp)) and kb.pageStable:
|
if injectable:
|
||||||
trueSet = set(extractTextTagContent(truePage))
|
if kb.pageStable and not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
|
||||||
falseSet = set(extractTextTagContent(falsePage))
|
if all((falseCode, trueCode)) and falseCode != trueCode:
|
||||||
candidates = filter(None, (_.strip() if _.strip() in (kb.pageTemplate or "") and _.strip() not in falsePage and _.strip() not in threadData.lastComparisonHeaders else None for _ in (trueSet - falseSet)))
|
conf.code = trueCode
|
||||||
|
|
||||||
|
infoMsg = "%s parameter '%s' appears to be '%s' injectable (with --code=%d)" % (paramType, parameter, title, conf.code)
|
||||||
|
logger.info(infoMsg)
|
||||||
|
else:
|
||||||
|
trueSet = set(extractTextTagContent(trueRawResponse))
|
||||||
|
trueSet = trueSet.union(__ for _ in trueSet for __ in _.split())
|
||||||
|
|
||||||
|
falseSet = set(extractTextTagContent(falseRawResponse))
|
||||||
|
falseSet = falseSet.union(__ for _ in falseSet for __ in _.split())
|
||||||
|
|
||||||
|
candidates = filter(None, (_.strip() if _.strip() in trueRawResponse and _.strip() not in falseRawResponse else None for _ in (trueSet - falseSet)))
|
||||||
|
|
||||||
if candidates:
|
if candidates:
|
||||||
conf.string = candidates[0]
|
candidates = sorted(candidates, key=lambda _: len(_))
|
||||||
infoMsg = "%s parameter '%s' seems to be '%s' injectable (with --string=\"%s\")" % (paramType, parameter, title, repr(conf.string).lstrip('u').strip("'"))
|
for candidate in candidates:
|
||||||
|
if re.match(r"\A\w+\Z", candidate):
|
||||||
|
break
|
||||||
|
|
||||||
|
conf.string = candidate
|
||||||
|
|
||||||
|
infoMsg = "%s parameter '%s' appears to be '%s' injectable (with --string=\"%s\")" % (paramType, parameter, title, repr(conf.string).lstrip('u').strip("'"))
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
injectable = True
|
if not any((conf.string, conf.notString)):
|
||||||
|
candidates = filter(None, (_.strip() if _.strip() in falseRawResponse and _.strip() not in trueRawResponse else None for _ in (falseSet - trueSet)))
|
||||||
|
|
||||||
|
if candidates:
|
||||||
|
candidates = sorted(candidates, key=lambda _: len(_))
|
||||||
|
for candidate in candidates:
|
||||||
|
if re.match(r"\A\w+\Z", candidate):
|
||||||
|
break
|
||||||
|
|
||||||
|
conf.notString = candidate
|
||||||
|
|
||||||
|
infoMsg = "%s parameter '%s' appears to be '%s' injectable (with --not-string=\"%s\")" % (paramType, parameter, title, repr(conf.notString).lstrip('u').strip("'"))
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
if not any((conf.string, conf.notString, conf.code)):
|
||||||
|
infoMsg = "%s parameter '%s' appears to be '%s' injectable " % (paramType, parameter, title)
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
# In case of error-based SQL injection
|
# In case of error-based SQL injection
|
||||||
elif method == PAYLOAD.METHOD.GREP:
|
elif method == PAYLOAD.METHOD.GREP:
|
||||||
@@ -518,7 +561,7 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
trueResult = Request.queryPage(reqPayload, place, timeBasedCompare=True, raise404=False)
|
trueResult = Request.queryPage(reqPayload, place, timeBasedCompare=True, raise404=False)
|
||||||
|
|
||||||
if trueResult:
|
if trueResult:
|
||||||
infoMsg = "%s parameter '%s' seems to be '%s' injectable " % (paramType, parameter, title)
|
infoMsg = "%s parameter '%s' appears to be '%s' injectable " % (paramType, parameter, title)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
injectable = True
|
injectable = True
|
||||||
@@ -538,7 +581,7 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
warnMsg = "using unescaped version of the test "
|
warnMsg = "using unescaped version of the test "
|
||||||
warnMsg += "because of zero knowledge of the "
|
warnMsg += "because of zero knowledge of the "
|
||||||
warnMsg += "back-end DBMS. You can try to "
|
warnMsg += "back-end DBMS. You can try to "
|
||||||
warnMsg += "explicitly set it using option '--dbms'"
|
warnMsg += "explicitly set it with option '--dbms'"
|
||||||
singleTimeWarnMessage(warnMsg)
|
singleTimeWarnMessage(warnMsg)
|
||||||
else:
|
else:
|
||||||
Backend.forceDbms(kb.heuristicDbms)
|
Backend.forceDbms(kb.heuristicDbms)
|
||||||
@@ -627,6 +670,7 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
|
|
||||||
injection.conf.textOnly = conf.textOnly
|
injection.conf.textOnly = conf.textOnly
|
||||||
injection.conf.titles = conf.titles
|
injection.conf.titles = conf.titles
|
||||||
|
injection.conf.code = conf.code
|
||||||
injection.conf.string = conf.string
|
injection.conf.string = conf.string
|
||||||
injection.conf.notString = conf.notString
|
injection.conf.notString = conf.notString
|
||||||
injection.conf.regexp = conf.regexp
|
injection.conf.regexp = conf.regexp
|
||||||
@@ -691,19 +735,20 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
# Return the injection object
|
# Return the injection object
|
||||||
if injection.place is not None and injection.parameter is not None:
|
if injection.place is not None and injection.parameter is not None:
|
||||||
if not conf.dropSetCookie and PAYLOAD.TECHNIQUE.BOOLEAN in injection.data and injection.data[PAYLOAD.TECHNIQUE.BOOLEAN].vector.startswith('OR'):
|
if not conf.dropSetCookie and PAYLOAD.TECHNIQUE.BOOLEAN in injection.data and injection.data[PAYLOAD.TECHNIQUE.BOOLEAN].vector.startswith('OR'):
|
||||||
warnMsg = "in OR boolean-based injections, please consider usage "
|
warnMsg = "in OR boolean-based injection cases, please consider usage "
|
||||||
warnMsg += "of switch '--drop-set-cookie' if you experience any "
|
warnMsg += "of switch '--drop-set-cookie' if you experience any "
|
||||||
warnMsg += "problems during data retrieval"
|
warnMsg += "problems during data retrieval"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
injection = checkFalsePositives(injection)
|
if not checkFalsePositives(injection):
|
||||||
|
|
||||||
if not injection:
|
|
||||||
kb.vulnHosts.remove(conf.hostname)
|
kb.vulnHosts.remove(conf.hostname)
|
||||||
|
if NOTE.FALSE_POSITIVE_OR_UNEXPLOITABLE not in injection.notes:
|
||||||
|
injection.notes.append(NOTE.FALSE_POSITIVE_OR_UNEXPLOITABLE)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
injection = None
|
injection = None
|
||||||
|
|
||||||
if injection:
|
if injection and NOTE.FALSE_POSITIVE_OR_UNEXPLOITABLE not in injection.notes:
|
||||||
checkSuhosinPatch(injection)
|
checkSuhosinPatch(injection)
|
||||||
checkFilteredChars(injection)
|
checkFilteredChars(injection)
|
||||||
|
|
||||||
@@ -748,7 +793,7 @@ def checkFalsePositives(injection):
|
|||||||
Checks for false positives (only in single special cases)
|
Checks for false positives (only in single special cases)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
retVal = injection
|
retVal = True
|
||||||
|
|
||||||
if all(_ in (PAYLOAD.TECHNIQUE.BOOLEAN, PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED) for _ in injection.data) or\
|
if all(_ in (PAYLOAD.TECHNIQUE.BOOLEAN, PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED) for _ in injection.data) or\
|
||||||
(len(injection.data) == 1 and PAYLOAD.TECHNIQUE.UNION in injection.data and "Generic" in injection.data[PAYLOAD.TECHNIQUE.UNION].title):
|
(len(injection.data) == 1 and PAYLOAD.TECHNIQUE.UNION in injection.data and "Generic" in injection.data[PAYLOAD.TECHNIQUE.UNION].title):
|
||||||
@@ -774,7 +819,7 @@ def checkFalsePositives(injection):
|
|||||||
break
|
break
|
||||||
|
|
||||||
if not checkBooleanExpression("%d=%d" % (randInt1, randInt1)):
|
if not checkBooleanExpression("%d=%d" % (randInt1, randInt1)):
|
||||||
retVal = None
|
retVal = False
|
||||||
break
|
break
|
||||||
|
|
||||||
# Just in case if DBMS hasn't properly recovered from previous delayed request
|
# Just in case if DBMS hasn't properly recovered from previous delayed request
|
||||||
@@ -782,22 +827,22 @@ def checkFalsePositives(injection):
|
|||||||
checkBooleanExpression("%d=%d" % (randInt1, randInt2))
|
checkBooleanExpression("%d=%d" % (randInt1, randInt2))
|
||||||
|
|
||||||
if checkBooleanExpression("%d=%d" % (randInt1, randInt3)): # this must not be evaluated to True
|
if checkBooleanExpression("%d=%d" % (randInt1, randInt3)): # this must not be evaluated to True
|
||||||
retVal = None
|
retVal = False
|
||||||
break
|
break
|
||||||
|
|
||||||
elif checkBooleanExpression("%d=%d" % (randInt3, randInt2)): # this must not be evaluated to True
|
elif checkBooleanExpression("%d=%d" % (randInt3, randInt2)): # this must not be evaluated to True
|
||||||
retVal = None
|
retVal = False
|
||||||
break
|
break
|
||||||
|
|
||||||
elif not checkBooleanExpression("%d=%d" % (randInt2, randInt2)): # this must be evaluated to True
|
elif not checkBooleanExpression("%d=%d" % (randInt2, randInt2)): # this must be evaluated to True
|
||||||
retVal = None
|
retVal = False
|
||||||
break
|
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 = None
|
retVal = False
|
||||||
break
|
break
|
||||||
|
|
||||||
if retVal is None:
|
if not retVal:
|
||||||
warnMsg = "false positive or unexploitable injection point detected"
|
warnMsg = "false positive or unexploitable injection point detected"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
@@ -885,6 +930,7 @@ def heuristicCheckSqlInjection(place, parameter):
|
|||||||
payload = agent.payload(place, parameter, newValue=payload)
|
payload = agent.payload(place, parameter, newValue=payload)
|
||||||
page, _ = Request.queryPage(payload, place, content=True, raise404=False)
|
page, _ = Request.queryPage(payload, place, content=True, raise404=False)
|
||||||
|
|
||||||
|
kb.heuristicPage = page
|
||||||
kb.heuristicMode = False
|
kb.heuristicMode = False
|
||||||
|
|
||||||
parseFilePaths(page)
|
parseFilePaths(page)
|
||||||
@@ -906,7 +952,7 @@ def heuristicCheckSqlInjection(place, parameter):
|
|||||||
|
|
||||||
if not result:
|
if not result:
|
||||||
randStr = randomStr()
|
randStr = randomStr()
|
||||||
payload = "%s%s%s" % (prefix, "%s%s" % (origValue, randStr), suffix)
|
payload = "%s%s%s" % (prefix, "%s.%d%s" % (origValue, random.randint(1, 9), randStr), suffix)
|
||||||
payload = agent.payload(place, parameter, newValue=payload, where=PAYLOAD.WHERE.REPLACE)
|
payload = agent.payload(place, parameter, newValue=payload, where=PAYLOAD.WHERE.REPLACE)
|
||||||
casting = Request.queryPage(payload, place, raise404=False)
|
casting = Request.queryPage(payload, place, raise404=False)
|
||||||
|
|
||||||
@@ -947,7 +993,7 @@ def heuristicCheckSqlInjection(place, parameter):
|
|||||||
infoMsg += "'%s' might be vulnerable to cross-site scripting attacks" % parameter
|
infoMsg += "'%s' might be vulnerable to cross-site scripting attacks" % parameter
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
for match in re.finditer("(?i)[^\n]*(no such file|failed (to )?open)[^\n]*", page or ""):
|
for match in re.finditer(FI_ERROR_REGEX, page or ""):
|
||||||
if randStr1.lower() in match.group(0).lower():
|
if randStr1.lower() in match.group(0).lower():
|
||||||
infoMsg = "heuristic (FI) test shows that %s parameter " % paramType
|
infoMsg = "heuristic (FI) test shows that %s parameter " % paramType
|
||||||
infoMsg += "'%s' might be vulnerable to file inclusion attacks" % parameter
|
infoMsg += "'%s' might be vulnerable to file inclusion attacks" % parameter
|
||||||
@@ -1013,12 +1059,22 @@ def checkDynamicContent(firstPage, secondPage):
|
|||||||
logger.critical(warnMsg)
|
logger.critical(warnMsg)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if firstPage and secondPage and any(len(_) > MAX_DIFFLIB_SEQUENCE_LENGTH for _ in (firstPage, secondPage)):
|
||||||
|
ratio = None
|
||||||
|
else:
|
||||||
|
try:
|
||||||
seqMatcher = getCurrentThreadData().seqMatcher
|
seqMatcher = getCurrentThreadData().seqMatcher
|
||||||
seqMatcher.set_seq1(firstPage)
|
seqMatcher.set_seq1(firstPage)
|
||||||
seqMatcher.set_seq2(secondPage)
|
seqMatcher.set_seq2(secondPage)
|
||||||
|
ratio = seqMatcher.quick_ratio()
|
||||||
|
except MemoryError:
|
||||||
|
ratio = None
|
||||||
|
|
||||||
|
if ratio is None:
|
||||||
|
kb.skipSeqMatcher = True
|
||||||
|
|
||||||
# In case of an intolerable difference turn on dynamicity removal engine
|
# In case of an intolerable difference turn on dynamicity removal engine
|
||||||
if seqMatcher.quick_ratio() <= UPPER_RATIO_BOUND:
|
elif ratio <= UPPER_RATIO_BOUND:
|
||||||
findDynamicContent(firstPage, secondPage)
|
findDynamicContent(firstPage, secondPage)
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
@@ -1235,6 +1291,9 @@ def identifyWaf():
|
|||||||
if not conf.identifyWaf:
|
if not conf.identifyWaf:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
if not kb.wafFunctions:
|
||||||
|
setWafFunctions()
|
||||||
|
|
||||||
kb.testMode = True
|
kb.testMode = True
|
||||||
|
|
||||||
infoMsg = "using WAF scripts to detect "
|
infoMsg = "using WAF scripts to detect "
|
||||||
@@ -1276,7 +1335,7 @@ def identifyWaf():
|
|||||||
break
|
break
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
errMsg = "WAF/IDS/IPS identified '%s'. Please " % retVal
|
errMsg = "WAF/IDS/IPS identified as '%s'. Please " % retVal
|
||||||
errMsg += "consider usage of tamper scripts (option '--tamper')"
|
errMsg += "consider usage of tamper scripts (option '--tamper')"
|
||||||
logger.critical(errMsg)
|
logger.critical(errMsg)
|
||||||
|
|
||||||
@@ -1287,7 +1346,7 @@ def identifyWaf():
|
|||||||
if output and output[0] not in ("Y", "y"):
|
if output and output[0] not in ("Y", "y"):
|
||||||
raise SqlmapUserQuitException
|
raise SqlmapUserQuitException
|
||||||
else:
|
else:
|
||||||
warnMsg = "no WAF/IDS/IPS product has been identified (this doesn't mean that there is none)"
|
warnMsg = "WAF/IDS/IPS product hasn't been identified"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
kb.testType = None
|
kb.testType = None
|
||||||
@@ -1383,10 +1442,6 @@ def checkConnection(suppressOutput=False):
|
|||||||
else:
|
else:
|
||||||
kb.errorIsNone = True
|
kb.errorIsNone = True
|
||||||
|
|
||||||
if headers and headers.get("Server", "") == CLOUDFLARE_SERVER_HEADER:
|
|
||||||
warnMsg = "CloudFlare response detected"
|
|
||||||
logger.warn(warnMsg)
|
|
||||||
|
|
||||||
except SqlmapConnectionException, ex:
|
except SqlmapConnectionException, ex:
|
||||||
if conf.ipv6:
|
if conf.ipv6:
|
||||||
warnMsg = "check connection to a provided "
|
warnMsg = "check connection to a provided "
|
||||||
@@ -1415,3 +1470,6 @@ def checkConnection(suppressOutput=False):
|
|||||||
|
|
||||||
def setVerbosity(): # Cross-linked function
|
def setVerbosity(): # Cross-linked function
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def setWafFunctions(): # Cross-linked function
|
||||||
|
raise NotImplementedError
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ from lib.core.enums import CONTENT_TYPE
|
|||||||
from lib.core.enums import HASHDB_KEYS
|
from lib.core.enums import HASHDB_KEYS
|
||||||
from lib.core.enums import HEURISTIC_TEST
|
from lib.core.enums import HEURISTIC_TEST
|
||||||
from lib.core.enums import HTTPMETHOD
|
from lib.core.enums import HTTPMETHOD
|
||||||
|
from lib.core.enums import NOTE
|
||||||
from lib.core.enums import PAYLOAD
|
from lib.core.enums import PAYLOAD
|
||||||
from lib.core.enums import PLACE
|
from lib.core.enums import PLACE
|
||||||
from lib.core.exception import SqlmapBaseException
|
from lib.core.exception import SqlmapBaseException
|
||||||
@@ -225,23 +226,23 @@ def _saveToResultsFile():
|
|||||||
results = {}
|
results = {}
|
||||||
techniques = dict(map(lambda x: (x[1], x[0]), getPublicTypeMembers(PAYLOAD.TECHNIQUE)))
|
techniques = dict(map(lambda x: (x[1], x[0]), getPublicTypeMembers(PAYLOAD.TECHNIQUE)))
|
||||||
|
|
||||||
for inj in kb.injections:
|
for injection in kb.injections + kb.falsePositives:
|
||||||
if inj.place is None or inj.parameter is None:
|
if injection.place is None or injection.parameter is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
key = (inj.place, inj.parameter)
|
key = (injection.place, injection.parameter, ';'.join(injection.notes))
|
||||||
if key not in results:
|
if key not in results:
|
||||||
results[key] = []
|
results[key] = []
|
||||||
|
|
||||||
results[key].extend(inj.data.keys())
|
results[key].extend(injection.data.keys())
|
||||||
|
|
||||||
for key, value in results.items():
|
for key, value in results.items():
|
||||||
place, parameter = key
|
place, parameter, notes = key
|
||||||
line = "%s,%s,%s,%s%s" % (safeCSValue(kb.originalUrls.get(conf.url) or conf.url), place, parameter, "".join(map(lambda x: techniques[x][0].upper(), sorted(value))), os.linesep)
|
line = "%s,%s,%s,%s,%s%s" % (safeCSValue(kb.originalUrls.get(conf.url) or conf.url), place, parameter, "".join(map(lambda x: techniques[x][0].upper(), sorted(value))), notes, os.linesep)
|
||||||
conf.resultsFP.writelines(line)
|
conf.resultsFP.writelines(line)
|
||||||
|
|
||||||
if not results:
|
if not results:
|
||||||
line = "%s,,,%s" % (conf.url, os.linesep)
|
line = "%s,,,,%s" % (conf.url, os.linesep)
|
||||||
conf.resultsFP.writelines(line)
|
conf.resultsFP.writelines(line)
|
||||||
|
|
||||||
def start():
|
def start():
|
||||||
@@ -463,7 +464,7 @@ def start():
|
|||||||
infoMsg = "skipping randomizing %s parameter '%s'" % (paramType, parameter)
|
infoMsg = "skipping randomizing %s parameter '%s'" % (paramType, parameter)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
elif parameter in conf.skip:
|
elif parameter in conf.skip or kb.postHint and parameter.split(' ')[-1] in conf.skip:
|
||||||
testSqlInj = False
|
testSqlInj = False
|
||||||
|
|
||||||
infoMsg = "skipping %s parameter '%s'" % (paramType, parameter)
|
infoMsg = "skipping %s parameter '%s'" % (paramType, parameter)
|
||||||
@@ -520,8 +521,14 @@ def start():
|
|||||||
|
|
||||||
injection = checkSqlInjection(place, parameter, value)
|
injection = checkSqlInjection(place, parameter, value)
|
||||||
proceed = not kb.endDetection
|
proceed = not kb.endDetection
|
||||||
|
injectable = False
|
||||||
|
|
||||||
|
if getattr(injection, "place", None) is not None:
|
||||||
|
if NOTE.FALSE_POSITIVE_OR_UNEXPLOITABLE in injection.notes:
|
||||||
|
kb.falsePositives.append(injection)
|
||||||
|
else:
|
||||||
|
injectable = True
|
||||||
|
|
||||||
if injection is not None and injection.place is not None:
|
|
||||||
kb.injections.append(injection)
|
kb.injections.append(injection)
|
||||||
|
|
||||||
# In case when user wants to end detection phase (Ctrl+C)
|
# In case when user wants to end detection phase (Ctrl+C)
|
||||||
@@ -536,7 +543,8 @@ def start():
|
|||||||
proceed = False
|
proceed = False
|
||||||
paramKey = (conf.hostname, conf.path, None, None)
|
paramKey = (conf.hostname, conf.path, None, None)
|
||||||
kb.testedParams.add(paramKey)
|
kb.testedParams.add(paramKey)
|
||||||
else:
|
|
||||||
|
if not injectable:
|
||||||
warnMsg = "%s parameter '%s' is not " % (paramType, parameter)
|
warnMsg = "%s parameter '%s' is not " % (paramType, parameter)
|
||||||
warnMsg += "injectable"
|
warnMsg += "injectable"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
@@ -585,24 +593,24 @@ def start():
|
|||||||
if not conf.string and not conf.notString and not conf.regexp:
|
if not conf.string and not conf.notString and not conf.regexp:
|
||||||
errMsg += " Also, you can try to rerun by providing "
|
errMsg += " Also, you can try to rerun by providing "
|
||||||
errMsg += "either a valid value for option '--string' "
|
errMsg += "either a valid value for option '--string' "
|
||||||
errMsg += "(or '--regexp')"
|
errMsg += "(or '--regexp')."
|
||||||
elif conf.string:
|
elif conf.string:
|
||||||
errMsg += " Also, you can try to rerun by providing a "
|
errMsg += " Also, you can try to rerun by providing a "
|
||||||
errMsg += "valid value for option '--string' as perhaps the string you "
|
errMsg += "valid value for option '--string' as perhaps the string you "
|
||||||
errMsg += "have chosen does not match "
|
errMsg += "have chosen does not match "
|
||||||
errMsg += "exclusively True responses"
|
errMsg += "exclusively True responses."
|
||||||
elif conf.regexp:
|
elif conf.regexp:
|
||||||
errMsg += " Also, you can try to rerun by providing a "
|
errMsg += " Also, you can try to rerun by providing a "
|
||||||
errMsg += "valid value for option '--regexp' as perhaps the regular "
|
errMsg += "valid value for option '--regexp' as perhaps the regular "
|
||||||
errMsg += "expression that you have chosen "
|
errMsg += "expression that you have chosen "
|
||||||
errMsg += "does not match exclusively True responses"
|
errMsg += "does not match exclusively True responses."
|
||||||
|
|
||||||
if not conf.tamper:
|
if not conf.tamper:
|
||||||
errMsg += " If you suspect that there is some kind of protection mechanism "
|
errMsg += " If you suspect that there is some kind of protection mechanism "
|
||||||
errMsg += "involved (e.g. WAF) maybe you could retry "
|
errMsg += "involved (e.g. WAF) maybe you could retry "
|
||||||
errMsg += "with an option '--tamper' (e.g. '--tamper=space2comment')"
|
errMsg += "with an option '--tamper' (e.g. '--tamper=space2comment')"
|
||||||
|
|
||||||
raise SqlmapNotVulnerableException(errMsg)
|
raise SqlmapNotVulnerableException(errMsg.rstrip('.'))
|
||||||
else:
|
else:
|
||||||
# Flush the flag
|
# Flush the flag
|
||||||
kb.testMode = False
|
kb.testMode = False
|
||||||
@@ -651,6 +659,8 @@ def start():
|
|||||||
errMsg = getSafeExString(ex)
|
errMsg = getSafeExString(ex)
|
||||||
|
|
||||||
if conf.multipleTargets:
|
if conf.multipleTargets:
|
||||||
|
_saveToResultsFile()
|
||||||
|
|
||||||
errMsg += ", skipping to the next %s" % ("form" if conf.forms else "URL")
|
errMsg += ", skipping to the next %s" % ("form" if conf.forms else "URL")
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
else:
|
else:
|
||||||
@@ -669,7 +679,8 @@ def start():
|
|||||||
if kb.dataOutputFlag and not conf.multipleTargets:
|
if kb.dataOutputFlag and not conf.multipleTargets:
|
||||||
logger.info("fetched data logged to text files under '%s'" % conf.outputPath)
|
logger.info("fetched data logged to text files under '%s'" % conf.outputPath)
|
||||||
|
|
||||||
if conf.multipleTargets and conf.resultsFilename:
|
if conf.multipleTargets:
|
||||||
|
if conf.resultsFilename:
|
||||||
infoMsg = "you can find results of scanning in multiple targets "
|
infoMsg = "you can find results of scanning in multiple targets "
|
||||||
infoMsg += "mode inside the CSV file '%s'" % conf.resultsFilename
|
infoMsg += "mode inside the CSV file '%s'" % conf.resultsFilename
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ See the file 'doc/COPYING' for copying permission
|
|||||||
|
|
||||||
from lib.core.common import Backend
|
from lib.core.common import Backend
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.core.dicts import DBMS_DICT
|
from lib.core.dicts import DBMS_DICT
|
||||||
from lib.core.enums import DBMS
|
from lib.core.enums import DBMS
|
||||||
@@ -101,6 +102,9 @@ def setHandler():
|
|||||||
conf.dbmsConnector.connect()
|
conf.dbmsConnector.connect()
|
||||||
|
|
||||||
if handler.checkDbms():
|
if handler.checkDbms():
|
||||||
|
if kb.resolutionDbms:
|
||||||
|
conf.dbmsHandler = max(_ for _ in items if _[0] == kb.resolutionDbms)[2]()
|
||||||
|
else:
|
||||||
conf.dbmsHandler = handler
|
conf.dbmsHandler = handler
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -35,10 +35,12 @@ from lib.core.enums import PLACE
|
|||||||
from lib.core.enums import POST_HINT
|
from lib.core.enums import POST_HINT
|
||||||
from lib.core.exception import SqlmapNoneDataException
|
from lib.core.exception import SqlmapNoneDataException
|
||||||
from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
|
from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
|
||||||
|
from lib.core.settings import BOUNDED_INJECTION_MARKER
|
||||||
from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR
|
from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR
|
||||||
from lib.core.settings import DEFAULT_COOKIE_DELIMITER
|
from lib.core.settings import DEFAULT_COOKIE_DELIMITER
|
||||||
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
|
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
|
||||||
from lib.core.settings import GENERIC_SQL_COMMENT
|
from lib.core.settings import GENERIC_SQL_COMMENT
|
||||||
|
from lib.core.settings import NULL
|
||||||
from lib.core.settings import PAYLOAD_DELIMITER
|
from lib.core.settings import PAYLOAD_DELIMITER
|
||||||
from lib.core.settings import REPLACEMENT_MARKER
|
from lib.core.settings import REPLACEMENT_MARKER
|
||||||
from lib.core.unescaper import unescaper
|
from lib.core.unescaper import unescaper
|
||||||
@@ -95,9 +97,12 @@ class Agent(object):
|
|||||||
paramDict = conf.paramDict[place]
|
paramDict = conf.paramDict[place]
|
||||||
origValue = getUnicode(paramDict[parameter])
|
origValue = getUnicode(paramDict[parameter])
|
||||||
|
|
||||||
if place == PLACE.URI:
|
if place == PLACE.URI or BOUNDED_INJECTION_MARKER in origValue:
|
||||||
paramString = origValue
|
paramString = origValue
|
||||||
|
if place == PLACE.URI:
|
||||||
origValue = origValue.split(CUSTOM_INJECTION_MARK_CHAR)[0]
|
origValue = origValue.split(CUSTOM_INJECTION_MARK_CHAR)[0]
|
||||||
|
else:
|
||||||
|
origValue = filter(None, (re.search(_, origValue.split(BOUNDED_INJECTION_MARKER)[0]) for _ in (r"\w+\Z", r"[^\"'><]+\Z", r"[^ ]+\Z")))[0].group(0)
|
||||||
origValue = origValue[origValue.rfind('/') + 1:]
|
origValue = origValue[origValue.rfind('/') + 1:]
|
||||||
for char in ('?', '=', ':'):
|
for char in ('?', '=', ':'):
|
||||||
if char in origValue:
|
if char in origValue:
|
||||||
@@ -115,7 +120,7 @@ class Agent(object):
|
|||||||
elif place == PLACE.CUSTOM_HEADER:
|
elif place == PLACE.CUSTOM_HEADER:
|
||||||
paramString = origValue
|
paramString = origValue
|
||||||
origValue = origValue.split(CUSTOM_INJECTION_MARK_CHAR)[0]
|
origValue = origValue.split(CUSTOM_INJECTION_MARK_CHAR)[0]
|
||||||
origValue = origValue[origValue.index(',') + 1:]
|
origValue = origValue[origValue.find(',') + 1:]
|
||||||
match = re.search(r"([^;]+)=(?P<value>[^;]+);?\Z", origValue)
|
match = re.search(r"([^;]+)=(?P<value>[^;]+);?\Z", origValue)
|
||||||
if match:
|
if match:
|
||||||
origValue = match.group("value")
|
origValue = match.group("value")
|
||||||
@@ -161,6 +166,9 @@ class Agent(object):
|
|||||||
newValue = newValue.replace(CUSTOM_INJECTION_MARK_CHAR, REPLACEMENT_MARKER)
|
newValue = newValue.replace(CUSTOM_INJECTION_MARK_CHAR, REPLACEMENT_MARKER)
|
||||||
retVal = paramString.replace(_, self.addPayloadDelimiters(newValue))
|
retVal = paramString.replace(_, self.addPayloadDelimiters(newValue))
|
||||||
retVal = retVal.replace(CUSTOM_INJECTION_MARK_CHAR, "").replace(REPLACEMENT_MARKER, CUSTOM_INJECTION_MARK_CHAR)
|
retVal = retVal.replace(CUSTOM_INJECTION_MARK_CHAR, "").replace(REPLACEMENT_MARKER, CUSTOM_INJECTION_MARK_CHAR)
|
||||||
|
elif BOUNDED_INJECTION_MARKER in paramDict[parameter]:
|
||||||
|
_ = "%s%s" % (origValue, BOUNDED_INJECTION_MARKER)
|
||||||
|
retVal = "%s=%s" % (re.sub(r" (\#\d\*|\(.+\))\Z", "", parameter), paramString.replace(_, self.addPayloadDelimiters(newValue)))
|
||||||
elif place in (PLACE.USER_AGENT, PLACE.REFERER, PLACE.HOST):
|
elif place in (PLACE.USER_AGENT, PLACE.REFERER, PLACE.HOST):
|
||||||
retVal = paramString.replace(origValue, self.addPayloadDelimiters(newValue))
|
retVal = paramString.replace(origValue, self.addPayloadDelimiters(newValue))
|
||||||
else:
|
else:
|
||||||
@@ -273,7 +281,7 @@ class Agent(object):
|
|||||||
where = kb.injection.data[kb.technique].where if where is None else where
|
where = kb.injection.data[kb.technique].where if where is None else where
|
||||||
comment = kb.injection.data[kb.technique].comment if comment is None else comment
|
comment = kb.injection.data[kb.technique].comment if comment is None else comment
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() == DBMS.ACCESS and comment == GENERIC_SQL_COMMENT:
|
if Backend.getIdentifiedDbms() == DBMS.ACCESS and any((comment or "").startswith(_) for _ in ("--", "[GENERIC_SQL_COMMENT]")):
|
||||||
comment = queries[DBMS.ACCESS].comment.query
|
comment = queries[DBMS.ACCESS].comment.query
|
||||||
|
|
||||||
if comment is not None:
|
if comment is not None:
|
||||||
@@ -296,7 +304,7 @@ class Agent(object):
|
|||||||
_ = (
|
_ = (
|
||||||
("[DELIMITER_START]", kb.chars.start), ("[DELIMITER_STOP]", kb.chars.stop),\
|
("[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),\
|
("[AT_REPLACE]", kb.chars.at), ("[SPACE_REPLACE]", kb.chars.space), ("[DOLLAR_REPLACE]", kb.chars.dollar),\
|
||||||
("[HASH_REPLACE]", kb.chars.hash_),
|
("[HASH_REPLACE]", kb.chars.hash_), ("[GENERIC_SQL_COMMENT]", GENERIC_SQL_COMMENT)
|
||||||
)
|
)
|
||||||
payload = reduce(lambda x, y: x.replace(y[0], y[1]), _, payload)
|
payload = reduce(lambda x, y: x.replace(y[0], y[1]), _, payload)
|
||||||
|
|
||||||
@@ -713,8 +721,11 @@ class Agent(object):
|
|||||||
|
|
||||||
if conf.uFrom:
|
if conf.uFrom:
|
||||||
fromTable = " FROM %s" % conf.uFrom
|
fromTable = " FROM %s" % conf.uFrom
|
||||||
|
elif not fromTable:
|
||||||
|
if kb.tableFrom:
|
||||||
|
fromTable = " FROM %s" % kb.tableFrom
|
||||||
else:
|
else:
|
||||||
fromTable = fromTable or FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms(), "")
|
fromTable = FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms(), "")
|
||||||
|
|
||||||
if query.startswith("SELECT "):
|
if query.startswith("SELECT "):
|
||||||
query = query[len("SELECT "):]
|
query = query[len("SELECT "):]
|
||||||
@@ -747,6 +758,9 @@ class Agent(object):
|
|||||||
intoRegExp = intoRegExp.group(1)
|
intoRegExp = intoRegExp.group(1)
|
||||||
query = query[:query.index(intoRegExp)]
|
query = query[:query.index(intoRegExp)]
|
||||||
|
|
||||||
|
position = 0
|
||||||
|
char = NULL
|
||||||
|
|
||||||
for element in xrange(0, count):
|
for element in xrange(0, count):
|
||||||
if element > 0:
|
if element > 0:
|
||||||
unionQuery += ','
|
unionQuery += ','
|
||||||
@@ -985,12 +999,13 @@ class Agent(object):
|
|||||||
|
|
||||||
def forgeQueryOutputLength(self, expression):
|
def forgeQueryOutputLength(self, expression):
|
||||||
lengthQuery = queries[Backend.getIdentifiedDbms()].length.query
|
lengthQuery = queries[Backend.getIdentifiedDbms()].length.query
|
||||||
select = re.search("\ASELECT\s+", expression, re.I)
|
select = re.search(r"\ASELECT\s+", expression, re.I)
|
||||||
selectTopExpr = re.search("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", expression, re.I)
|
selectTopExpr = re.search(r"\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", expression, re.I)
|
||||||
|
selectMinMaxExpr = re.search(r"\ASELECT\s+(MIN|MAX)\(.+?\)\s+FROM", expression, re.I)
|
||||||
|
|
||||||
_, _, _, _, _, _, fieldsStr, _ = self.getFields(expression)
|
_, _, _, _, _, _, fieldsStr, _ = self.getFields(expression)
|
||||||
|
|
||||||
if selectTopExpr:
|
if selectTopExpr or selectMinMaxExpr:
|
||||||
lengthExpr = lengthQuery % ("(%s)" % expression)
|
lengthExpr = lengthQuery % ("(%s)" % expression)
|
||||||
elif select:
|
elif select:
|
||||||
lengthExpr = expression.replace(fieldsStr, lengthQuery % fieldsStr, 1)
|
lengthExpr = expression.replace(fieldsStr, lengthQuery % fieldsStr, 1)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
from lib.core.enums import MKSTEMP_PREFIX
|
||||||
from lib.core.exception import SqlmapSystemException
|
from lib.core.exception import SqlmapSystemException
|
||||||
from lib.core.settings import BIGARRAY_CHUNK_SIZE
|
from lib.core.settings import BIGARRAY_CHUNK_SIZE
|
||||||
|
|
||||||
@@ -91,7 +92,7 @@ class BigArray(list):
|
|||||||
|
|
||||||
def _dump(self, chunk):
|
def _dump(self, chunk):
|
||||||
try:
|
try:
|
||||||
handle, filename = tempfile.mkstemp()
|
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.BIG_ARRAY)
|
||||||
self.filenames.add(filename)
|
self.filenames.add(filename)
|
||||||
os.close(handle)
|
os.close(handle)
|
||||||
with open(filename, "w+b") as fp:
|
with open(filename, "w+b") as fp:
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ from lib.core.enums import EXPECTED
|
|||||||
from lib.core.enums import HEURISTIC_TEST
|
from lib.core.enums import HEURISTIC_TEST
|
||||||
from lib.core.enums import HTTP_HEADER
|
from lib.core.enums import HTTP_HEADER
|
||||||
from lib.core.enums import HTTPMETHOD
|
from lib.core.enums import HTTPMETHOD
|
||||||
|
from lib.core.enums import MKSTEMP_PREFIX
|
||||||
from lib.core.enums import OS
|
from lib.core.enums import OS
|
||||||
from lib.core.enums import PLACE
|
from lib.core.enums import PLACE
|
||||||
from lib.core.enums import PAYLOAD
|
from lib.core.enums import PAYLOAD
|
||||||
@@ -91,6 +92,7 @@ from lib.core.log import LOGGER_HANDLER
|
|||||||
from lib.core.optiondict import optDict
|
from lib.core.optiondict import optDict
|
||||||
from lib.core.settings import BANNER
|
from lib.core.settings import BANNER
|
||||||
from lib.core.settings import BOLD_PATTERNS
|
from lib.core.settings import BOLD_PATTERNS
|
||||||
|
from lib.core.settings import BOUNDED_INJECTION_MARKER
|
||||||
from lib.core.settings import BRUTE_DOC_ROOT_PREFIXES
|
from lib.core.settings import BRUTE_DOC_ROOT_PREFIXES
|
||||||
from lib.core.settings import BRUTE_DOC_ROOT_SUFFIXES
|
from lib.core.settings import BRUTE_DOC_ROOT_SUFFIXES
|
||||||
from lib.core.settings import BRUTE_DOC_ROOT_TARGET_MARK
|
from lib.core.settings import BRUTE_DOC_ROOT_TARGET_MARK
|
||||||
@@ -102,6 +104,7 @@ from lib.core.settings import DEFAULT_MSSQL_SCHEMA
|
|||||||
from lib.core.settings import DUMMY_USER_INJECTION
|
from lib.core.settings import DUMMY_USER_INJECTION
|
||||||
from lib.core.settings import DYNAMICITY_MARK_LENGTH
|
from lib.core.settings import DYNAMICITY_MARK_LENGTH
|
||||||
from lib.core.settings import ERROR_PARSING_REGEXES
|
from lib.core.settings import ERROR_PARSING_REGEXES
|
||||||
|
from lib.core.settings import FILE_PATH_REGEXES
|
||||||
from lib.core.settings import FORCE_COOKIE_EXPIRATION_TIME
|
from lib.core.settings import FORCE_COOKIE_EXPIRATION_TIME
|
||||||
from lib.core.settings import FORM_SEARCH_REGEX
|
from lib.core.settings import FORM_SEARCH_REGEX
|
||||||
from lib.core.settings import GENERIC_DOC_ROOT_DIRECTORY_NAMES
|
from lib.core.settings import GENERIC_DOC_ROOT_DIRECTORY_NAMES
|
||||||
@@ -151,6 +154,7 @@ from lib.core.threads import getCurrentThreadData
|
|||||||
from lib.utils.sqlalchemy import _sqlalchemy
|
from lib.utils.sqlalchemy import _sqlalchemy
|
||||||
from thirdparty.clientform.clientform import ParseResponse
|
from thirdparty.clientform.clientform import ParseResponse
|
||||||
from thirdparty.clientform.clientform import ParseError
|
from thirdparty.clientform.clientform import ParseError
|
||||||
|
from thirdparty.colorama.initialise import init as coloramainit
|
||||||
from thirdparty.magic import magic
|
from thirdparty.magic import magic
|
||||||
from thirdparty.odict.odict import OrderedDict
|
from thirdparty.odict.odict import OrderedDict
|
||||||
from thirdparty.termcolor.termcolor import colored
|
from thirdparty.termcolor.termcolor import colored
|
||||||
@@ -302,7 +306,7 @@ class Backend:
|
|||||||
|
|
||||||
# Little precaution, in theory this condition should always be false
|
# Little precaution, in theory this condition should always be false
|
||||||
elif kb.dbms is not None and kb.dbms != dbms:
|
elif kb.dbms is not None and kb.dbms != dbms:
|
||||||
warnMsg = "there seems to be a high probability that "
|
warnMsg = "there appears to be a high probability that "
|
||||||
warnMsg += "this could be a false positive case"
|
warnMsg += "this could be a false positive case"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
@@ -316,6 +320,8 @@ class Backend:
|
|||||||
_ = readInput(msg, default=kb.dbms)
|
_ = readInput(msg, default=kb.dbms)
|
||||||
|
|
||||||
if aliasToDbmsEnum(_) == kb.dbms:
|
if aliasToDbmsEnum(_) == kb.dbms:
|
||||||
|
kb.dbmsVersion = []
|
||||||
|
kb.resolutionDbms = kb.dbms
|
||||||
break
|
break
|
||||||
elif aliasToDbmsEnum(_) == dbms:
|
elif aliasToDbmsEnum(_) == dbms:
|
||||||
kb.dbms = aliasToDbmsEnum(_)
|
kb.dbms = aliasToDbmsEnum(_)
|
||||||
@@ -579,7 +585,7 @@ def paramToDict(place, parameters=None):
|
|||||||
if not conf.multipleTargets and not (conf.csrfToken and parameter == conf.csrfToken):
|
if not conf.multipleTargets and not (conf.csrfToken and parameter == conf.csrfToken):
|
||||||
_ = urldecode(testableParameters[parameter], convall=True)
|
_ = urldecode(testableParameters[parameter], convall=True)
|
||||||
if (_.endswith("'") and _.count("'") == 1
|
if (_.endswith("'") and _.count("'") == 1
|
||||||
or re.search(r'\A9{3,}', _) or re.search(DUMMY_USER_INJECTION, _))\
|
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):
|
and not parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX):
|
||||||
warnMsg = "it appears that you have provided tainted parameter values "
|
warnMsg = "it appears that you have provided tainted parameter values "
|
||||||
warnMsg += "('%s') with most probably leftover " % element
|
warnMsg += "('%s') with most probably leftover " % element
|
||||||
@@ -598,7 +604,58 @@ def paramToDict(place, parameters=None):
|
|||||||
warnMsg += "so sqlmap could be able to run properly"
|
warnMsg += "so sqlmap could be able to run properly"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
if conf.testParameter and not testableParameters:
|
if place in (PLACE.POST, PLACE.GET):
|
||||||
|
for regex in (r"\A((?:<[^>]+>)+\w+)((?:<[^>]+>)+)\Z", r"\A([^\w]+.*\w+)([^\w]+)\Z"):
|
||||||
|
match = re.search(regex, testableParameters[parameter])
|
||||||
|
if match:
|
||||||
|
try:
|
||||||
|
candidates = OrderedDict()
|
||||||
|
|
||||||
|
def walk(head, current=None):
|
||||||
|
current = current or head
|
||||||
|
if isListLike(current):
|
||||||
|
for _ in current:
|
||||||
|
walk(head, _)
|
||||||
|
elif isinstance(current, dict):
|
||||||
|
for key in current.keys():
|
||||||
|
value = current[key]
|
||||||
|
if isinstance(value, (list, tuple, set, dict)):
|
||||||
|
walk(head, value)
|
||||||
|
elif isinstance(value, (bool, int, float, basestring)):
|
||||||
|
original = current[key]
|
||||||
|
if isinstance(value, bool):
|
||||||
|
current[key] = "%s%s" % (str(value).lower(), BOUNDED_INJECTION_MARKER)
|
||||||
|
else:
|
||||||
|
current[key] = "%s%s" % (value, BOUNDED_INJECTION_MARKER)
|
||||||
|
candidates["%s (%s)" % (parameter, key)] = json.dumps(deserialized)
|
||||||
|
current[key] = original
|
||||||
|
|
||||||
|
deserialized = json.loads(testableParameters[parameter])
|
||||||
|
walk(deserialized)
|
||||||
|
|
||||||
|
if candidates:
|
||||||
|
message = "it appears that provided value for %s parameter '%s' " % (place, parameter)
|
||||||
|
message += "is JSON deserializable. Do you want to inject inside? [y/N] "
|
||||||
|
test = readInput(message, default="N")
|
||||||
|
if test[0] in ("y", "Y"):
|
||||||
|
del testableParameters[parameter]
|
||||||
|
testableParameters.update(candidates)
|
||||||
|
break
|
||||||
|
except (KeyboardInterrupt, SqlmapUserQuitException):
|
||||||
|
raise
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
_ = re.sub(regex, "\g<1>%s\g<%d>" % (CUSTOM_INJECTION_MARK_CHAR, len(match.groups())), testableParameters[parameter])
|
||||||
|
message = "it appears that provided value for %s parameter '%s' " % (place, parameter)
|
||||||
|
message += "has boundaries. Do you want to inject inside? ('%s') [y/N] " % _
|
||||||
|
test = readInput(message, default="N")
|
||||||
|
if test[0] in ("y", "Y"):
|
||||||
|
testableParameters[parameter] = re.sub(regex, "\g<1>%s\g<2>" % BOUNDED_INJECTION_MARKER, testableParameters[parameter])
|
||||||
|
break
|
||||||
|
|
||||||
|
if conf.testParameter:
|
||||||
|
if not testableParameters:
|
||||||
paramStr = ", ".join(test for test in conf.testParameter)
|
paramStr = ", ".join(test for test in conf.testParameter)
|
||||||
|
|
||||||
if len(conf.testParameter) > 1:
|
if len(conf.testParameter) > 1:
|
||||||
@@ -628,7 +685,7 @@ def paramToDict(place, parameters=None):
|
|||||||
decoded = value.decode(encoding)
|
decoded = value.decode(encoding)
|
||||||
if len(decoded) > MIN_ENCODED_LEN_CHECK and all(_ in string.printable for _ in decoded):
|
if len(decoded) > MIN_ENCODED_LEN_CHECK and all(_ in string.printable for _ in decoded):
|
||||||
warnMsg = "provided parameter '%s' " % parameter
|
warnMsg = "provided parameter '%s' " % parameter
|
||||||
warnMsg += "seems to be '%s' encoded" % encoding
|
warnMsg += "appears to be '%s' encoded" % encoding
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
break
|
break
|
||||||
except:
|
except:
|
||||||
@@ -638,8 +695,6 @@ def paramToDict(place, parameters=None):
|
|||||||
|
|
||||||
def getManualDirectories():
|
def getManualDirectories():
|
||||||
directories = None
|
directories = None
|
||||||
pagePath = directoryPath(conf.path)
|
|
||||||
|
|
||||||
defaultDocRoot = DEFAULT_DOC_ROOTS.get(Backend.getOs(), DEFAULT_DOC_ROOTS[OS.LINUX])
|
defaultDocRoot = DEFAULT_DOC_ROOTS.get(Backend.getOs(), DEFAULT_DOC_ROOTS[OS.LINUX])
|
||||||
|
|
||||||
if kb.absFilePaths:
|
if kb.absFilePaths:
|
||||||
@@ -657,17 +712,17 @@ def getManualDirectories():
|
|||||||
windowsDriveLetter, absFilePath = absFilePath[:2], absFilePath[2:]
|
windowsDriveLetter, absFilePath = absFilePath[:2], absFilePath[2:]
|
||||||
absFilePath = ntToPosixSlashes(posixToNtSlashes(absFilePath))
|
absFilePath = ntToPosixSlashes(posixToNtSlashes(absFilePath))
|
||||||
|
|
||||||
if any("/%s/" % _ in absFilePath for _ in GENERIC_DOC_ROOT_DIRECTORY_NAMES):
|
for _ in list(GENERIC_DOC_ROOT_DIRECTORY_NAMES) + [conf.hostname]:
|
||||||
for _ in GENERIC_DOC_ROOT_DIRECTORY_NAMES:
|
|
||||||
_ = "/%s/" % _
|
_ = "/%s/" % _
|
||||||
|
|
||||||
if _ in absFilePath:
|
if _ in absFilePath:
|
||||||
directories = "%s%s" % (absFilePath.split(_)[0], _)
|
directories = "%s%s" % (absFilePath.split(_)[0], _)
|
||||||
break
|
break
|
||||||
|
|
||||||
if pagePath and pagePath in absFilePath:
|
if not directories and conf.path.strip('/') and conf.path in absFilePath:
|
||||||
directories = absFilePath.split(pagePath)[0]
|
directories = absFilePath.split(conf.path)[0]
|
||||||
if windowsDriveLetter:
|
|
||||||
|
if directories and windowsDriveLetter:
|
||||||
directories = "%s/%s" % (windowsDriveLetter, ntToPosixSlashes(directories))
|
directories = "%s/%s" % (windowsDriveLetter, ntToPosixSlashes(directories))
|
||||||
|
|
||||||
directories = normalizePath(directories)
|
directories = normalizePath(directories)
|
||||||
@@ -676,7 +731,7 @@ def getManualDirectories():
|
|||||||
infoMsg = "retrieved the web server document root: '%s'" % directories
|
infoMsg = "retrieved the web server document root: '%s'" % directories
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
else:
|
else:
|
||||||
warnMsg = "unable to retrieve automatically the web server "
|
warnMsg = "unable to automatically retrieve the web server "
|
||||||
warnMsg += "document root"
|
warnMsg += "document root"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
@@ -715,8 +770,13 @@ def getManualDirectories():
|
|||||||
|
|
||||||
for suffix in BRUTE_DOC_ROOT_SUFFIXES:
|
for suffix in BRUTE_DOC_ROOT_SUFFIXES:
|
||||||
for target in targets:
|
for target in targets:
|
||||||
|
if not prefix.endswith("/%s" % suffix):
|
||||||
item = "%s/%s" % (prefix, suffix)
|
item = "%s/%s" % (prefix, suffix)
|
||||||
|
else:
|
||||||
|
item = prefix
|
||||||
|
|
||||||
item = item.replace(BRUTE_DOC_ROOT_TARGET_MARK, target).replace("//", '/').rstrip('/')
|
item = item.replace(BRUTE_DOC_ROOT_TARGET_MARK, target).replace("//", '/').rstrip('/')
|
||||||
|
if item not in directories:
|
||||||
directories.append(item)
|
directories.append(item)
|
||||||
|
|
||||||
if BRUTE_DOC_ROOT_TARGET_MARK not in prefix:
|
if BRUTE_DOC_ROOT_TARGET_MARK not in prefix:
|
||||||
@@ -871,7 +931,6 @@ def dataToDumpFile(dumpFile, data):
|
|||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
def dataToOutFile(filename, data):
|
def dataToOutFile(filename, data):
|
||||||
retVal = None
|
retVal = None
|
||||||
|
|
||||||
@@ -879,8 +938,8 @@ def dataToOutFile(filename, data):
|
|||||||
retVal = os.path.join(conf.filePath, filePathToSafeString(filename))
|
retVal = os.path.join(conf.filePath, filePathToSafeString(filename))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(retVal, "w+b") as f:
|
with open(retVal, "w+b") as f: # has to stay as non-codecs because data is raw ASCII encoded data
|
||||||
f.write(data)
|
f.write(unicodeencode(data))
|
||||||
except IOError, ex:
|
except IOError, ex:
|
||||||
errMsg = "something went wrong while trying to write "
|
errMsg = "something went wrong while trying to write "
|
||||||
errMsg += "to the output file ('%s')" % getSafeExString(ex)
|
errMsg += "to the output file ('%s')" % getSafeExString(ex)
|
||||||
@@ -950,7 +1009,11 @@ def readInput(message, default=None, checkBatch=True):
|
|||||||
retVal = raw_input() or default
|
retVal = raw_input() or default
|
||||||
retVal = getUnicode(retVal, encoding=sys.stdin.encoding) if retVal else retVal
|
retVal = getUnicode(retVal, encoding=sys.stdin.encoding) if retVal else retVal
|
||||||
except:
|
except:
|
||||||
|
try:
|
||||||
time.sleep(0.05) # Reference: http://www.gossamer-threads.com/lists/python/python/781893
|
time.sleep(0.05) # Reference: http://www.gossamer-threads.com/lists/python/python/781893
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
kb.prependFlag = True
|
kb.prependFlag = True
|
||||||
raise SqlmapUserQuitException
|
raise SqlmapUserQuitException
|
||||||
|
|
||||||
@@ -968,7 +1031,12 @@ def randomRange(start=0, stop=1000, seed=None):
|
|||||||
423
|
423
|
||||||
"""
|
"""
|
||||||
|
|
||||||
randint = random.WichmannHill(seed).randint if seed is not None else random.randint
|
if seed is not None:
|
||||||
|
_ = getCurrentThreadData().random
|
||||||
|
_.seed(seed)
|
||||||
|
randint = _.randint
|
||||||
|
else:
|
||||||
|
randint = random.randint
|
||||||
|
|
||||||
return int(randint(start, stop))
|
return int(randint(start, stop))
|
||||||
|
|
||||||
@@ -981,7 +1049,12 @@ def randomInt(length=4, seed=None):
|
|||||||
874254
|
874254
|
||||||
"""
|
"""
|
||||||
|
|
||||||
choice = random.WichmannHill(seed).choice if seed is not None else random.choice
|
if seed is not None:
|
||||||
|
_ = getCurrentThreadData().random
|
||||||
|
_.seed(seed)
|
||||||
|
choice = _.choice
|
||||||
|
else:
|
||||||
|
choice = random.choice
|
||||||
|
|
||||||
return int("".join(choice(string.digits if _ != 0 else string.digits.replace('0', '')) for _ in xrange(0, length)))
|
return int("".join(choice(string.digits if _ != 0 else string.digits.replace('0', '')) for _ in xrange(0, length)))
|
||||||
|
|
||||||
@@ -994,7 +1067,12 @@ def randomStr(length=4, lowercase=False, alphabet=None, seed=None):
|
|||||||
'RNvnAv'
|
'RNvnAv'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
choice = random.WichmannHill(seed).choice if seed is not None else random.choice
|
if seed is not None:
|
||||||
|
_ = getCurrentThreadData().random
|
||||||
|
_.seed(seed)
|
||||||
|
choice = _.choice
|
||||||
|
else:
|
||||||
|
choice = random.choice
|
||||||
|
|
||||||
if alphabet:
|
if alphabet:
|
||||||
retVal = "".join(choice(alphabet) for _ in xrange(0, length))
|
retVal = "".join(choice(alphabet) for _ in xrange(0, length))
|
||||||
@@ -1053,9 +1131,14 @@ def banner():
|
|||||||
This function prints sqlmap banner with its version
|
This function prints sqlmap banner with its version
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if not any(_ in sys.argv for _ in ("--version", "--pickled-options")):
|
||||||
_ = BANNER
|
_ = BANNER
|
||||||
if not getattr(LOGGER_HANDLER, "is_tty", False):
|
|
||||||
|
if not getattr(LOGGER_HANDLER, "is_tty", False) or "--disable-coloring" in sys.argv:
|
||||||
_ = re.sub("\033.+?m", "", _)
|
_ = re.sub("\033.+?m", "", _)
|
||||||
|
elif IS_WIN:
|
||||||
|
coloramainit()
|
||||||
|
|
||||||
dataToStdout(_, forceOutput=True)
|
dataToStdout(_, forceOutput=True)
|
||||||
|
|
||||||
def parsePasswordHash(password):
|
def parsePasswordHash(password):
|
||||||
@@ -1097,11 +1180,13 @@ def cleanQuery(query):
|
|||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def setPaths():
|
def setPaths(rootPath):
|
||||||
"""
|
"""
|
||||||
Sets absolute paths for project directories and files
|
Sets absolute paths for project directories and files
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
paths.SQLMAP_ROOT_PATH = rootPath
|
||||||
|
|
||||||
# sqlmap paths
|
# sqlmap paths
|
||||||
paths.SQLMAP_EXTRAS_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "extra")
|
paths.SQLMAP_EXTRAS_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "extra")
|
||||||
paths.SQLMAP_PROCS_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "procs")
|
paths.SQLMAP_PROCS_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "procs")
|
||||||
@@ -1115,7 +1200,7 @@ def setPaths():
|
|||||||
paths.SQLMAP_XML_PAYLOADS_PATH = os.path.join(paths.SQLMAP_XML_PATH, "payloads")
|
paths.SQLMAP_XML_PAYLOADS_PATH = os.path.join(paths.SQLMAP_XML_PATH, "payloads")
|
||||||
|
|
||||||
_ = os.path.join(os.path.expandvars(os.path.expanduser("~")), ".sqlmap")
|
_ = os.path.join(os.path.expandvars(os.path.expanduser("~")), ".sqlmap")
|
||||||
paths.SQLMAP_OUTPUT_PATH = getUnicode(paths.get("SQLMAP_OUTPUT_PATH", os.path.join(_, "output")), encoding=sys.getfilesystemencoding())
|
paths.SQLMAP_OUTPUT_PATH = getUnicode(paths.get("SQLMAP_OUTPUT_PATH", os.path.join(_, "output")), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING)
|
||||||
paths.SQLMAP_DUMP_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "dump")
|
paths.SQLMAP_DUMP_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "dump")
|
||||||
paths.SQLMAP_FILES_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "files")
|
paths.SQLMAP_FILES_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "files")
|
||||||
|
|
||||||
@@ -1124,6 +1209,7 @@ def setPaths():
|
|||||||
paths.SQL_SHELL_HISTORY = os.path.join(_, "sql.hst")
|
paths.SQL_SHELL_HISTORY = os.path.join(_, "sql.hst")
|
||||||
paths.SQLMAP_SHELL_HISTORY = os.path.join(_, "sqlmap.hst")
|
paths.SQLMAP_SHELL_HISTORY = os.path.join(_, "sqlmap.hst")
|
||||||
paths.GITHUB_HISTORY = os.path.join(_, "github.hst")
|
paths.GITHUB_HISTORY = os.path.join(_, "github.hst")
|
||||||
|
paths.CHECKSUM_MD5 = os.path.join(paths.SQLMAP_TXT_PATH, "checksum.md5")
|
||||||
paths.COMMON_COLUMNS = os.path.join(paths.SQLMAP_TXT_PATH, "common-columns.txt")
|
paths.COMMON_COLUMNS = os.path.join(paths.SQLMAP_TXT_PATH, "common-columns.txt")
|
||||||
paths.COMMON_TABLES = os.path.join(paths.SQLMAP_TXT_PATH, "common-tables.txt")
|
paths.COMMON_TABLES = os.path.join(paths.SQLMAP_TXT_PATH, "common-tables.txt")
|
||||||
paths.COMMON_OUTPUTS = os.path.join(paths.SQLMAP_TXT_PATH, 'common-outputs.txt')
|
paths.COMMON_OUTPUTS = os.path.join(paths.SQLMAP_TXT_PATH, 'common-outputs.txt')
|
||||||
@@ -1302,8 +1388,8 @@ def parseTargetUrl():
|
|||||||
except UnicodeError:
|
except UnicodeError:
|
||||||
_ = None
|
_ = None
|
||||||
|
|
||||||
if any((_ is None, re.search(r'\s', conf.hostname), '..' in conf.hostname, conf.hostname.startswith('.'))):
|
if any((_ is None, re.search(r'\s', conf.hostname), '..' in conf.hostname, conf.hostname.startswith('.'), '\n' in originalUrl)):
|
||||||
errMsg = "invalid target URL"
|
errMsg = "invalid target URL ('%s')" % originalUrl
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
if len(hostnamePort) == 2:
|
if len(hostnamePort) == 2:
|
||||||
@@ -1317,12 +1403,19 @@ def parseTargetUrl():
|
|||||||
else:
|
else:
|
||||||
conf.port = 80
|
conf.port = 80
|
||||||
|
|
||||||
if urlSplit.query:
|
if conf.port < 0 or conf.port > 65535:
|
||||||
conf.parameters[PLACE.GET] = urldecode(urlSplit.query) if urlSplit.query and urlencode(DEFAULT_GET_POST_DELIMITER, None) not in urlSplit.query else urlSplit.query
|
errMsg = "invalid target URL's port (%d)" % conf.port
|
||||||
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
conf.url = getUnicode("%s://%s:%d%s" % (conf.scheme, ("[%s]" % conf.hostname) if conf.ipv6 else conf.hostname, conf.port, conf.path))
|
conf.url = getUnicode("%s://%s:%d%s" % (conf.scheme, ("[%s]" % conf.hostname) if conf.ipv6 else conf.hostname, conf.port, conf.path))
|
||||||
conf.url = conf.url.replace(URI_QUESTION_MARKER, '?')
|
conf.url = conf.url.replace(URI_QUESTION_MARKER, '?')
|
||||||
|
|
||||||
|
if urlSplit.query:
|
||||||
|
if '=' not in urlSplit.query:
|
||||||
|
conf.url = "%s?%s" % (conf.url, getUnicode(urlSplit.query))
|
||||||
|
else:
|
||||||
|
conf.parameters[PLACE.GET] = urldecode(urlSplit.query) if urlSplit.query and urlencode(DEFAULT_GET_POST_DELIMITER, None) not in urlSplit.query else urlSplit.query
|
||||||
|
|
||||||
if not conf.referer and (intersect(REFERER_ALIASES, conf.testParameter, True) or conf.level >= 3):
|
if not conf.referer and (intersect(REFERER_ALIASES, conf.testParameter, True) or conf.level >= 3):
|
||||||
debugMsg = "setting the HTTP Referer header to the target URL"
|
debugMsg = "setting the HTTP Referer header to the target URL"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
@@ -1452,7 +1545,7 @@ def parseFilePaths(page):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if page:
|
if page:
|
||||||
for regex in (r" in <b>(?P<result>.*?)</b> on line", r"(?:>|\s)(?P<result>[A-Za-z]:[\\/][\w.\\/]*)", r"(?:>|\s)(?P<result>/\w[/\w.]+)"):
|
for regex in FILE_PATH_REGEXES:
|
||||||
for match in re.finditer(regex, page):
|
for match in re.finditer(regex, page):
|
||||||
absFilePath = match.group("result").strip()
|
absFilePath = match.group("result").strip()
|
||||||
page = page.replace(absFilePath, "")
|
page = page.replace(absFilePath, "")
|
||||||
@@ -1828,7 +1921,7 @@ def parseXmlFile(xmlFile, handler):
|
|||||||
with contextlib.closing(StringIO(readCachedFileContent(xmlFile))) as stream:
|
with contextlib.closing(StringIO(readCachedFileContent(xmlFile))) as stream:
|
||||||
parse(stream, handler)
|
parse(stream, handler)
|
||||||
except (SAXParseException, UnicodeError), ex:
|
except (SAXParseException, UnicodeError), ex:
|
||||||
errMsg = "something seems to be wrong with "
|
errMsg = "something appears to be wrong with "
|
||||||
errMsg += "the file '%s' ('%s'). Please make " % (xmlFile, getSafeExString(ex))
|
errMsg += "the file '%s' ('%s'). Please make " % (xmlFile, getSafeExString(ex))
|
||||||
errMsg += "sure that you haven't made any changes to it"
|
errMsg += "sure that you haven't made any changes to it"
|
||||||
raise SqlmapInstallationException, errMsg
|
raise SqlmapInstallationException, errMsg
|
||||||
@@ -2783,7 +2876,7 @@ def setOptimize():
|
|||||||
conf.nullConnection = not any((conf.data, conf.textOnly, conf.titles, conf.string, conf.notString, conf.regexp, conf.tor))
|
conf.nullConnection = not any((conf.data, conf.textOnly, conf.titles, conf.string, conf.notString, conf.regexp, conf.tor))
|
||||||
|
|
||||||
if not conf.nullConnection:
|
if not conf.nullConnection:
|
||||||
debugMsg = "turning off --null-connection switch used indirectly by switch -o"
|
debugMsg = "turning off switch '--null-connection' used indirectly by switch '-o'"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
def initTechnique(technique=None):
|
def initTechnique(technique=None):
|
||||||
@@ -2971,7 +3064,10 @@ def decodeIntToUnicode(value):
|
|||||||
_ = "0%s" % _
|
_ = "0%s" % _
|
||||||
raw = hexdecode(_)
|
raw = hexdecode(_)
|
||||||
|
|
||||||
if Backend.isDbms(DBMS.MSSQL):
|
if Backend.isDbms(DBMS.MYSQL):
|
||||||
|
# https://github.com/sqlmapproject/sqlmap/issues/1531
|
||||||
|
retVal = getUnicode(raw, conf.charset or UNICODE_ENCODING)
|
||||||
|
elif Backend.isDbms(DBMS.MSSQL):
|
||||||
retVal = getUnicode(raw, "UTF-16-BE")
|
retVal = getUnicode(raw, "UTF-16-BE")
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE):
|
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE):
|
||||||
retVal = unichr(value)
|
retVal = unichr(value)
|
||||||
@@ -2984,6 +3080,24 @@ def decodeIntToUnicode(value):
|
|||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
|
def checkIntegrity():
|
||||||
|
"""
|
||||||
|
Checks integrity of code files during the unhandled exceptions
|
||||||
|
"""
|
||||||
|
|
||||||
|
logger.debug("running code integrity check")
|
||||||
|
|
||||||
|
retVal = True
|
||||||
|
for checksum, _ in (re.split(r'\s+', _) for _ in getFileItems(paths.CHECKSUM_MD5)):
|
||||||
|
path = os.path.normpath(os.path.join(paths.SQLMAP_ROOT_PATH, _))
|
||||||
|
if not os.path.isfile(path):
|
||||||
|
logger.error("missing file detected '%s'" % path)
|
||||||
|
retVal = False
|
||||||
|
elif hashlib.md5(open(path, 'rb').read()).hexdigest() != checksum:
|
||||||
|
logger.error("wrong checksum of file '%s' detected" % path)
|
||||||
|
retVal = False
|
||||||
|
return retVal
|
||||||
|
|
||||||
def unhandledExceptionMessage():
|
def unhandledExceptionMessage():
|
||||||
"""
|
"""
|
||||||
Returns detailed message about occurred unhandled exception
|
Returns detailed message about occurred unhandled exception
|
||||||
@@ -3147,14 +3261,6 @@ def intersect(valueA, valueB, lowerCase=False):
|
|||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def cpuThrottle(value):
|
|
||||||
"""
|
|
||||||
Does a CPU throttling for lesser CPU consumption
|
|
||||||
"""
|
|
||||||
|
|
||||||
delay = 0.00001 * (value ** 2)
|
|
||||||
time.sleep(delay)
|
|
||||||
|
|
||||||
def removeReflectiveValues(content, payload, suppressWarning=False):
|
def removeReflectiveValues(content, payload, suppressWarning=False):
|
||||||
"""
|
"""
|
||||||
Neutralizes reflective values in a given content based on a payload
|
Neutralizes reflective values in a given content based on a payload
|
||||||
@@ -3258,7 +3364,7 @@ def safeSQLIdentificatorNaming(name, isTable=False):
|
|||||||
retVal = "\"%s\"" % retVal.strip("\"")
|
retVal = "\"%s\"" % retVal.strip("\"")
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE,):
|
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE,):
|
||||||
retVal = "\"%s\"" % retVal.strip("\"").upper()
|
retVal = "\"%s\"" % retVal.strip("\"").upper()
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL,) and not re.match(r"\A\w+\Z", retVal, re.U):
|
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL,) and ((retVal or " ")[0].isdigit() or not re.match(r"\A\w+\Z", retVal, re.U)):
|
||||||
retVal = "[%s]" % retVal.strip("[]")
|
retVal = "[%s]" % retVal.strip("[]")
|
||||||
|
|
||||||
if _ and DEFAULT_MSSQL_SCHEMA not in retVal and '.' not in re.sub(r"\[[^]]+\]", "", retVal):
|
if _ and DEFAULT_MSSQL_SCHEMA not in retVal and '.' not in re.sub(r"\[[^]]+\]", "", retVal):
|
||||||
@@ -3897,7 +4003,7 @@ def resetCookieJar(cookieJar):
|
|||||||
|
|
||||||
content = readCachedFileContent(conf.loadCookies)
|
content = readCachedFileContent(conf.loadCookies)
|
||||||
lines = filter(None, (line.strip() for line in content.split("\n") if not line.startswith('#')))
|
lines = filter(None, (line.strip() for line in content.split("\n") if not line.startswith('#')))
|
||||||
handle, filename = tempfile.mkstemp(prefix="sqlmapcj-")
|
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.COOKIE_JAR)
|
||||||
os.close(handle)
|
os.close(handle)
|
||||||
|
|
||||||
# Reference: http://www.hashbangcode.com/blog/netscape-http-cooke-file-parser-php-584.html
|
# Reference: http://www.hashbangcode.com/blog/netscape-http-cooke-file-parser-php-584.html
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import pickle
|
|||||||
import re
|
import re
|
||||||
import StringIO
|
import StringIO
|
||||||
import sys
|
import sys
|
||||||
import types
|
|
||||||
|
|
||||||
from lib.core.settings import IS_WIN
|
from lib.core.settings import IS_WIN
|
||||||
from lib.core.settings import UNICODE_ENCODING
|
from lib.core.settings import UNICODE_ENCODING
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ See the file 'doc/COPYING' for copying permission
|
|||||||
import copy
|
import copy
|
||||||
import types
|
import types
|
||||||
|
|
||||||
from lib.core.exception import SqlmapDataException
|
|
||||||
|
|
||||||
class AttribDict(dict):
|
class AttribDict(dict):
|
||||||
"""
|
"""
|
||||||
This class defines the sqlmap object, inheriting from Python data
|
This class defines the sqlmap object, inheriting from Python data
|
||||||
@@ -43,7 +41,7 @@ class AttribDict(dict):
|
|||||||
try:
|
try:
|
||||||
return self.__getitem__(item)
|
return self.__getitem__(item)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise SqlmapDataException("unable to access item '%s'" % item)
|
raise AttributeError("unable to access item '%s'" % item)
|
||||||
|
|
||||||
def __setattr__(self, item, value):
|
def __setattr__(self, item, value):
|
||||||
"""
|
"""
|
||||||
@@ -93,6 +91,7 @@ class InjectionDict(AttribDict):
|
|||||||
self.prefix = None
|
self.prefix = None
|
||||||
self.suffix = None
|
self.suffix = None
|
||||||
self.clause = None
|
self.clause = None
|
||||||
|
self.notes = [] # Note: https://github.com/sqlmapproject/sqlmap/issues/1888
|
||||||
|
|
||||||
# data is a dict with various stype, each which is a dict with
|
# data is a dict with various stype, each which is a dict with
|
||||||
# all the information specific for that stype
|
# all the information specific for that stype
|
||||||
|
|||||||
@@ -15,10 +15,13 @@ def cachedmethod(f, cache={}):
|
|||||||
def _(*args, **kwargs):
|
def _(*args, **kwargs):
|
||||||
try:
|
try:
|
||||||
key = (f, tuple(args), frozenset(kwargs.items()))
|
key = (f, tuple(args), frozenset(kwargs.items()))
|
||||||
|
if key not in cache:
|
||||||
|
cache[key] = f(*args, **kwargs)
|
||||||
except:
|
except:
|
||||||
key = "".join(str(_) for _ in (f, args, kwargs))
|
key = "".join(str(_) for _ in (f, args, kwargs))
|
||||||
if key not in cache:
|
if key not in cache:
|
||||||
cache[key] = f(*args, **kwargs)
|
cache[key] = f(*args, **kwargs)
|
||||||
|
|
||||||
return cache[key]
|
return cache[key]
|
||||||
|
|
||||||
return _
|
return _
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ _defaults = {
|
|||||||
"csvDel": ",",
|
"csvDel": ",",
|
||||||
"timeSec": 5,
|
"timeSec": 5,
|
||||||
"googlePage": 1,
|
"googlePage": 1,
|
||||||
"cpuThrottle": 5,
|
|
||||||
"verbose": 1,
|
"verbose": 1,
|
||||||
"delay": 0,
|
"delay": 0,
|
||||||
"timeout": 30,
|
"timeout": 30,
|
||||||
@@ -22,7 +21,7 @@ _defaults = {
|
|||||||
"risk": 1,
|
"risk": 1,
|
||||||
"dumpFormat": "CSV",
|
"dumpFormat": "CSV",
|
||||||
"tech": "BEUSTQ",
|
"tech": "BEUSTQ",
|
||||||
"torType": "HTTP",
|
"torType": "SOCKS5",
|
||||||
}
|
}
|
||||||
|
|
||||||
defaults = AttribDict(_defaults)
|
defaults = AttribDict(_defaults)
|
||||||
|
|||||||
@@ -234,6 +234,6 @@ DUMP_DATA_PREPROCESS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEFAULT_DOC_ROOTS = {
|
DEFAULT_DOC_ROOTS = {
|
||||||
OS.WINDOWS: ("C:/xampp/htdocs/", "C:/Inetpub/wwwroot/"),
|
OS.WINDOWS: ("C:/xampp/htdocs/", "C:/wamp/www/", "C:/Inetpub/wwwroot/"),
|
||||||
OS.LINUX: ("/var/www/", "/var/www/html", "/usr/local/apache2/htdocs", "/var/www/nginx-default") # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout
|
OS.LINUX: ("/var/www/", "/var/www/html", "/usr/local/apache2/htdocs", "/var/www/nginx-default", "/srv/www") # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import cgi
|
|||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
@@ -118,9 +119,15 @@ class Dump(object):
|
|||||||
elif data is not None:
|
elif data is not None:
|
||||||
_ = getUnicode(data)
|
_ = getUnicode(data)
|
||||||
|
|
||||||
if _ and _[-1] == '\n':
|
if _.endswith("\r\n"):
|
||||||
|
_ = _[:-2]
|
||||||
|
|
||||||
|
elif _.endswith("\n"):
|
||||||
_ = _[:-1]
|
_ = _[:-1]
|
||||||
|
|
||||||
|
if _.strip(' '):
|
||||||
|
_ = _.strip(' ')
|
||||||
|
|
||||||
if "\n" in _:
|
if "\n" in _:
|
||||||
self._write("%s:\n---\n%s\n---" % (header, _))
|
self._write("%s:\n---\n%s\n---" % (header, _))
|
||||||
else:
|
else:
|
||||||
@@ -449,8 +456,23 @@ class Dump(object):
|
|||||||
dumpFileName = os.path.join(dumpDbPath, "%s-%s.%s" % (_, hashlib.md5(unicodeencode(table)).hexdigest()[:8], conf.dumpFormat.lower()))
|
dumpFileName = os.path.join(dumpDbPath, "%s-%s.%s" % (_, hashlib.md5(unicodeencode(table)).hexdigest()[:8], conf.dumpFormat.lower()))
|
||||||
else:
|
else:
|
||||||
dumpFileName = os.path.join(dumpDbPath, "%s.%s" % (_, conf.dumpFormat.lower()))
|
dumpFileName = os.path.join(dumpDbPath, "%s.%s" % (_, conf.dumpFormat.lower()))
|
||||||
|
else:
|
||||||
|
appendToFile = any((conf.limitStart, conf.limitStop))
|
||||||
|
|
||||||
|
if not appendToFile:
|
||||||
|
count = 1
|
||||||
|
while True:
|
||||||
|
candidate = "%s.%d" % (dumpFileName, count)
|
||||||
|
if not checkFile(candidate, False):
|
||||||
|
try:
|
||||||
|
shutil.copyfile(dumpFileName, candidate)
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
count += 1
|
||||||
|
|
||||||
appendToFile = any((conf.limitStart, conf.limitStop)) and checkFile(dumpFileName, False)
|
|
||||||
dumpFP = openFile(dumpFileName, "wb" if not appendToFile else "ab", buffering=DUMP_FILE_BUFFER_SIZE)
|
dumpFP = openFile(dumpFileName, "wb" if not appendToFile else "ab", buffering=DUMP_FILE_BUFFER_SIZE)
|
||||||
|
|
||||||
count = int(tableValues["__infos__"]["count"])
|
count = int(tableValues["__infos__"]["count"])
|
||||||
|
|||||||
@@ -194,6 +194,7 @@ class OPTION_TYPE:
|
|||||||
|
|
||||||
class HASHDB_KEYS:
|
class HASHDB_KEYS:
|
||||||
DBMS = "DBMS"
|
DBMS = "DBMS"
|
||||||
|
DBMS_FORK = "DBMS_FORK"
|
||||||
CHECK_WAF_RESULT = "CHECK_WAF_RESULT"
|
CHECK_WAF_RESULT = "CHECK_WAF_RESULT"
|
||||||
CONF_TMP_PATH = "CONF_TMP_PATH"
|
CONF_TMP_PATH = "CONF_TMP_PATH"
|
||||||
KB_ABS_FILE_PATHS = "KB_ABS_FILE_PATHS"
|
KB_ABS_FILE_PATHS = "KB_ABS_FILE_PATHS"
|
||||||
@@ -351,3 +352,15 @@ class AUTOCOMPLETE_TYPE:
|
|||||||
SQL = 0
|
SQL = 0
|
||||||
OS = 1
|
OS = 1
|
||||||
SQLMAP = 2
|
SQLMAP = 2
|
||||||
|
|
||||||
|
class NOTE:
|
||||||
|
FALSE_POSITIVE_OR_UNEXPLOITABLE = "false positive or unexploitable"
|
||||||
|
|
||||||
|
class MKSTEMP_PREFIX:
|
||||||
|
HASHES = "sqlmaphashes-"
|
||||||
|
CRAWLER = "sqlmapcrawler-"
|
||||||
|
IPC = "sqlmapipc-"
|
||||||
|
TESTING = "sqlmaptesting-"
|
||||||
|
RESULTS = "sqlmapresults-"
|
||||||
|
COOKIE_JAR = "sqlmapcookiejar-"
|
||||||
|
BIG_ARRAY = "sqlmapbigarray-"
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ from lib.core.settings import MAX_CONNECT_RETRIES
|
|||||||
from lib.core.settings import MAX_NUMBER_OF_THREADS
|
from lib.core.settings import MAX_NUMBER_OF_THREADS
|
||||||
from lib.core.settings import NULL
|
from lib.core.settings import NULL
|
||||||
from lib.core.settings import PARAMETER_SPLITTING_REGEX
|
from lib.core.settings import PARAMETER_SPLITTING_REGEX
|
||||||
|
from lib.core.settings import PRECONNECT_CANDIDATE_TIMEOUT
|
||||||
from lib.core.settings import PROBLEMATIC_CUSTOM_INJECTION_PATTERNS
|
from lib.core.settings import PROBLEMATIC_CUSTOM_INJECTION_PATTERNS
|
||||||
from lib.core.settings import SITE
|
from lib.core.settings import SITE
|
||||||
from lib.core.settings import SOCKET_PRE_CONNECT_QUEUE_SIZE
|
from lib.core.settings import SOCKET_PRE_CONNECT_QUEUE_SIZE
|
||||||
@@ -127,12 +128,14 @@ from lib.core.settings import SQLMAP_ENVIRONMENT_PREFIX
|
|||||||
from lib.core.settings import SUPPORTED_DBMS
|
from lib.core.settings import SUPPORTED_DBMS
|
||||||
from lib.core.settings import SUPPORTED_OS
|
from lib.core.settings import SUPPORTED_OS
|
||||||
from lib.core.settings import TIME_DELAY_CANDIDATES
|
from lib.core.settings import TIME_DELAY_CANDIDATES
|
||||||
|
from lib.core.settings import UNICODE_ENCODING
|
||||||
from lib.core.settings import UNION_CHAR_REGEX
|
from lib.core.settings import UNION_CHAR_REGEX
|
||||||
from lib.core.settings import UNKNOWN_DBMS_VERSION
|
from lib.core.settings import UNKNOWN_DBMS_VERSION
|
||||||
from lib.core.settings import URI_INJECTABLE_REGEX
|
from lib.core.settings import URI_INJECTABLE_REGEX
|
||||||
from lib.core.settings import VERSION_STRING
|
from lib.core.settings import VERSION_STRING
|
||||||
from lib.core.settings import WEBSCARAB_SPLITTER
|
from lib.core.settings import WEBSCARAB_SPLITTER
|
||||||
from lib.core.threads import getCurrentThreadData
|
from lib.core.threads import getCurrentThreadData
|
||||||
|
from lib.core.threads import setDaemon
|
||||||
from lib.core.update import update
|
from lib.core.update import update
|
||||||
from lib.parse.configfile import configFileParser
|
from lib.parse.configfile import configFileParser
|
||||||
from lib.parse.payloads import loadBoundaries
|
from lib.parse.payloads import loadBoundaries
|
||||||
@@ -151,7 +154,6 @@ from lib.utils.crawler import crawl
|
|||||||
from lib.utils.deps import checkDependencies
|
from lib.utils.deps import checkDependencies
|
||||||
from lib.utils.search import search
|
from lib.utils.search import search
|
||||||
from lib.utils.purge import purge
|
from lib.utils.purge import purge
|
||||||
from thirdparty.colorama.initialise import init as coloramainit
|
|
||||||
from thirdparty.keepalive import keepalive
|
from thirdparty.keepalive import keepalive
|
||||||
from thirdparty.oset.pyoset import oset
|
from thirdparty.oset.pyoset import oset
|
||||||
from thirdparty.socks import socks
|
from thirdparty.socks import socks
|
||||||
@@ -385,7 +387,7 @@ def _loadQueries():
|
|||||||
try:
|
try:
|
||||||
tree.parse(paths.QUERIES_XML)
|
tree.parse(paths.QUERIES_XML)
|
||||||
except Exception, ex:
|
except Exception, ex:
|
||||||
errMsg = "something seems to be wrong with "
|
errMsg = "something appears to be wrong with "
|
||||||
errMsg += "the file '%s' ('%s'). Please make " % (paths.QUERIES_XML, getSafeExString(ex))
|
errMsg += "the file '%s' ('%s'). Please make " % (paths.QUERIES_XML, getSafeExString(ex))
|
||||||
errMsg += "sure that you haven't made any changes to it"
|
errMsg += "sure that you haven't made any changes to it"
|
||||||
raise SqlmapInstallationException, errMsg
|
raise SqlmapInstallationException, errMsg
|
||||||
@@ -913,9 +915,9 @@ def _setTamperingFunctions():
|
|||||||
sys.path.insert(0, dirname)
|
sys.path.insert(0, dirname)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
module = __import__(filename[:-3].encode(sys.getfilesystemencoding()))
|
module = __import__(filename[:-3].encode(sys.getfilesystemencoding() or UNICODE_ENCODING))
|
||||||
except (ImportError, SyntaxError), msg:
|
except (ImportError, SyntaxError), ex:
|
||||||
raise SqlmapSyntaxException("cannot import tamper script '%s' (%s)" % (filename[:-3], msg))
|
raise SqlmapSyntaxException("cannot import tamper script '%s' (%s)" % (filename[:-3], getSafeExString(ex)))
|
||||||
|
|
||||||
priority = PRIORITY.NORMAL if not hasattr(module, '__priority__') else module.__priority__
|
priority = PRIORITY.NORMAL if not hasattr(module, '__priority__') else module.__priority__
|
||||||
|
|
||||||
@@ -926,7 +928,7 @@ def _setTamperingFunctions():
|
|||||||
function.func_name = module.__name__
|
function.func_name = module.__name__
|
||||||
|
|
||||||
if check_priority and priority > last_priority:
|
if check_priority and priority > last_priority:
|
||||||
message = "it seems that you might have mixed "
|
message = "it appears that you might have mixed "
|
||||||
message += "the order of tamper scripts. "
|
message += "the order of tamper scripts. "
|
||||||
message += "Do you want to auto resolve this? [Y/n/q] "
|
message += "Do you want to auto resolve this? [Y/n/q] "
|
||||||
test = readInput(message, default="Y")
|
test = readInput(message, default="Y")
|
||||||
@@ -998,6 +1000,8 @@ def _setWafFunctions():
|
|||||||
else:
|
else:
|
||||||
kb.wafFunctions.append((_["detect"], _.get("__product__", filename[:-3])))
|
kb.wafFunctions.append((_["detect"], _.get("__product__", filename[:-3])))
|
||||||
|
|
||||||
|
kb.wafFunctions = sorted(kb.wafFunctions, key=lambda _: "generic" in _[1].lower())
|
||||||
|
|
||||||
def _setThreads():
|
def _setThreads():
|
||||||
if not isinstance(conf.threads, int) or conf.threads <= 0:
|
if not isinstance(conf.threads, int) or conf.threads <= 0:
|
||||||
conf.threads = 1
|
conf.threads = 1
|
||||||
@@ -1036,7 +1040,7 @@ def _setSocketPreConnect():
|
|||||||
s = socket.socket(family, type, proto)
|
s = socket.socket(family, type, proto)
|
||||||
s._connect(address)
|
s._connect(address)
|
||||||
with kb.locks.socket:
|
with kb.locks.socket:
|
||||||
socket._ready[key].append(s._sock)
|
socket._ready[key].append((s._sock, time.time()))
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
break
|
break
|
||||||
except:
|
except:
|
||||||
@@ -1051,9 +1055,17 @@ def _setSocketPreConnect():
|
|||||||
with kb.locks.socket:
|
with kb.locks.socket:
|
||||||
if key not in socket._ready:
|
if key not in socket._ready:
|
||||||
socket._ready[key] = []
|
socket._ready[key] = []
|
||||||
if len(socket._ready[key]) > 0:
|
while len(socket._ready[key]) > 0:
|
||||||
self._sock = socket._ready[key].pop(0)
|
candidate, created = socket._ready[key].pop(0)
|
||||||
|
if (time.time() - created) < PRECONNECT_CANDIDATE_TIMEOUT:
|
||||||
|
self._sock = candidate
|
||||||
found = True
|
found = True
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
candidate.close()
|
||||||
|
except socket.error:
|
||||||
|
pass
|
||||||
|
|
||||||
if not found:
|
if not found:
|
||||||
self._connect(address)
|
self._connect(address)
|
||||||
@@ -1064,6 +1076,7 @@ def _setSocketPreConnect():
|
|||||||
socket.socket.connect = connect
|
socket.socket.connect = connect
|
||||||
|
|
||||||
thread = threading.Thread(target=_)
|
thread = threading.Thread(target=_)
|
||||||
|
setDaemon(thread)
|
||||||
thread.start()
|
thread.start()
|
||||||
|
|
||||||
def _setHTTPHandlers():
|
def _setHTTPHandlers():
|
||||||
@@ -1545,6 +1558,24 @@ def _createTemporaryDirectory():
|
|||||||
Creates temporary directory for this run.
|
Creates temporary directory for this run.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if conf.tmpDir:
|
||||||
|
try:
|
||||||
|
if not os.path.isdir(conf.tmpDir):
|
||||||
|
os.makedirs(conf.tmpDir)
|
||||||
|
|
||||||
|
_ = os.path.join(conf.tmpDir, randomStr())
|
||||||
|
open(_, "w+b").close()
|
||||||
|
os.remove(_)
|
||||||
|
|
||||||
|
tempfile.tempdir = conf.tmpDir
|
||||||
|
|
||||||
|
warnMsg = "using '%s' as the temporary directory" % conf.tmpDir
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
except (OSError, IOError), ex:
|
||||||
|
errMsg = "there has been a problem while accessing "
|
||||||
|
errMsg += "temporary directory location(s) ('%s')" % getSafeExString(ex)
|
||||||
|
raise SqlmapSystemException, errMsg
|
||||||
|
else:
|
||||||
try:
|
try:
|
||||||
if not os.path.isdir(tempfile.gettempdir()):
|
if not os.path.isdir(tempfile.gettempdir()):
|
||||||
os.makedirs(tempfile.gettempdir())
|
os.makedirs(tempfile.gettempdir())
|
||||||
@@ -1556,7 +1587,7 @@ def _createTemporaryDirectory():
|
|||||||
errMsg += "writeable by the current user"
|
errMsg += "writeable by the current user"
|
||||||
raise SqlmapSystemException, errMsg
|
raise SqlmapSystemException, errMsg
|
||||||
|
|
||||||
if "sqlmap" not in (tempfile.tempdir or ""):
|
if "sqlmap" not in (tempfile.tempdir or "") or conf.tmpDir and tempfile.tempdir == conf.tmpDir:
|
||||||
tempfile.tempdir = tempfile.mkdtemp(prefix="sqlmap", suffix=str(os.getpid()))
|
tempfile.tempdir = tempfile.mkdtemp(prefix="sqlmap", suffix=str(os.getpid()))
|
||||||
|
|
||||||
kb.tempDir = tempfile.tempdir
|
kb.tempDir = tempfile.tempdir
|
||||||
@@ -1590,6 +1621,9 @@ def _cleanupOptions():
|
|||||||
else:
|
else:
|
||||||
conf.testParameter = []
|
conf.testParameter = []
|
||||||
|
|
||||||
|
if conf.agent:
|
||||||
|
conf.agent = re.sub(r"[\r\n]", "", conf.agent)
|
||||||
|
|
||||||
if conf.user:
|
if conf.user:
|
||||||
conf.user = conf.user.replace(" ", "")
|
conf.user = conf.user.replace(" ", "")
|
||||||
|
|
||||||
@@ -1654,10 +1688,20 @@ def _cleanupOptions():
|
|||||||
conf.testFilter = conf.testFilter.strip('*+')
|
conf.testFilter = conf.testFilter.strip('*+')
|
||||||
conf.testFilter = re.sub(r"([^.])([*+])", "\g<1>.\g<2>", conf.testFilter)
|
conf.testFilter = re.sub(r"([^.])([*+])", "\g<1>.\g<2>", conf.testFilter)
|
||||||
|
|
||||||
|
try:
|
||||||
|
re.compile(conf.testFilter)
|
||||||
|
except re.error:
|
||||||
|
conf.testFilter = re.escape(conf.testFilter)
|
||||||
|
|
||||||
if conf.testSkip:
|
if conf.testSkip:
|
||||||
conf.testSkip = conf.testSkip.strip('*+')
|
conf.testSkip = conf.testSkip.strip('*+')
|
||||||
conf.testSkip = re.sub(r"([^.])([*+])", "\g<1>.\g<2>", conf.testSkip)
|
conf.testSkip = re.sub(r"([^.])([*+])", "\g<1>.\g<2>", conf.testSkip)
|
||||||
|
|
||||||
|
try:
|
||||||
|
re.compile(conf.testSkip)
|
||||||
|
except re.error:
|
||||||
|
conf.testSkip = re.escape(conf.testSkip)
|
||||||
|
|
||||||
if "timeSec" not in kb.explicitSettings:
|
if "timeSec" not in kb.explicitSettings:
|
||||||
if conf.tor:
|
if conf.tor:
|
||||||
conf.timeSec = 2 * conf.timeSec
|
conf.timeSec = 2 * conf.timeSec
|
||||||
@@ -1687,7 +1731,7 @@ def _cleanupOptions():
|
|||||||
|
|
||||||
if conf.outputDir:
|
if conf.outputDir:
|
||||||
paths.SQLMAP_OUTPUT_PATH = os.path.realpath(os.path.expanduser(conf.outputDir))
|
paths.SQLMAP_OUTPUT_PATH = os.path.realpath(os.path.expanduser(conf.outputDir))
|
||||||
setPaths()
|
setPaths(paths.SQLMAP_ROOT_PATH)
|
||||||
|
|
||||||
if conf.string:
|
if conf.string:
|
||||||
try:
|
try:
|
||||||
@@ -1799,6 +1843,8 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
|||||||
kb.cache.regex = {}
|
kb.cache.regex = {}
|
||||||
kb.cache.stdev = {}
|
kb.cache.stdev = {}
|
||||||
|
|
||||||
|
kb.captchaDetected = None
|
||||||
|
|
||||||
kb.chars = AttribDict()
|
kb.chars = AttribDict()
|
||||||
kb.chars.delimiter = randomStr(length=6, lowercase=True)
|
kb.chars.delimiter = randomStr(length=6, lowercase=True)
|
||||||
kb.chars.start = "%s%s%s" % (KB_CHARS_BOUNDARY_CHAR, randomStr(length=3, alphabet=KB_CHARS_LOW_FREQUENCY_ALPHABET), KB_CHARS_BOUNDARY_CHAR)
|
kb.chars.start = "%s%s%s" % (KB_CHARS_BOUNDARY_CHAR, randomStr(length=3, alphabet=KB_CHARS_LOW_FREQUENCY_ALPHABET), KB_CHARS_BOUNDARY_CHAR)
|
||||||
@@ -1807,6 +1853,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
|||||||
|
|
||||||
kb.columnExistsChoice = None
|
kb.columnExistsChoice = None
|
||||||
kb.commonOutputs = None
|
kb.commonOutputs = None
|
||||||
|
kb.cookieEncodeChoice = None
|
||||||
kb.counters = {}
|
kb.counters = {}
|
||||||
kb.data = AttribDict()
|
kb.data = AttribDict()
|
||||||
kb.dataOutputFlag = False
|
kb.dataOutputFlag = False
|
||||||
@@ -1820,6 +1867,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
|||||||
kb.dnsMode = False
|
kb.dnsMode = False
|
||||||
kb.dnsTest = None
|
kb.dnsTest = None
|
||||||
kb.docRoot = None
|
kb.docRoot = None
|
||||||
|
kb.dumpColumns = None
|
||||||
kb.dumpTable = None
|
kb.dumpTable = None
|
||||||
kb.dumpKeyboardInterrupt = False
|
kb.dumpKeyboardInterrupt = False
|
||||||
kb.dynamicMarkings = []
|
kb.dynamicMarkings = []
|
||||||
@@ -1829,6 +1877,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
|||||||
kb.extendTests = None
|
kb.extendTests = None
|
||||||
kb.errorChunkLength = None
|
kb.errorChunkLength = None
|
||||||
kb.errorIsNone = True
|
kb.errorIsNone = True
|
||||||
|
kb.falsePositives = []
|
||||||
kb.fileReadMode = False
|
kb.fileReadMode = False
|
||||||
kb.followSitemapRecursion = None
|
kb.followSitemapRecursion = None
|
||||||
kb.forcedDbms = None
|
kb.forcedDbms = None
|
||||||
@@ -1838,6 +1887,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
|||||||
kb.headersFp = {}
|
kb.headersFp = {}
|
||||||
kb.heuristicDbms = None
|
kb.heuristicDbms = None
|
||||||
kb.heuristicMode = False
|
kb.heuristicMode = False
|
||||||
|
kb.heuristicPage = False
|
||||||
kb.heuristicTest = None
|
kb.heuristicTest = None
|
||||||
kb.hintValue = None
|
kb.hintValue = None
|
||||||
kb.htmlFp = []
|
kb.htmlFp = []
|
||||||
@@ -1896,13 +1946,16 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
|||||||
kb.reflectiveCounters = {REFLECTIVE_COUNTER.MISS: 0, REFLECTIVE_COUNTER.HIT: 0}
|
kb.reflectiveCounters = {REFLECTIVE_COUNTER.MISS: 0, REFLECTIVE_COUNTER.HIT: 0}
|
||||||
kb.requestCounter = 0
|
kb.requestCounter = 0
|
||||||
kb.resendPostOnRedirect = None
|
kb.resendPostOnRedirect = None
|
||||||
|
kb.resolutionDbms = None
|
||||||
kb.responseTimes = {}
|
kb.responseTimes = {}
|
||||||
kb.responseTimeMode = None
|
kb.responseTimeMode = None
|
||||||
kb.responseTimePayload = None
|
kb.responseTimePayload = None
|
||||||
kb.resumeValues = True
|
kb.resumeValues = True
|
||||||
|
kb.rowXmlMode = False
|
||||||
kb.safeCharEncode = False
|
kb.safeCharEncode = False
|
||||||
kb.safeReq = AttribDict()
|
kb.safeReq = AttribDict()
|
||||||
kb.singleLogFlags = set()
|
kb.singleLogFlags = set()
|
||||||
|
kb.skipSeqMatcher = False
|
||||||
kb.reduceTests = None
|
kb.reduceTests = None
|
||||||
kb.tlsSNI = {}
|
kb.tlsSNI = {}
|
||||||
kb.stickyDBMS = False
|
kb.stickyDBMS = False
|
||||||
@@ -1910,6 +1963,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
|||||||
kb.storeCrawlingChoice = None
|
kb.storeCrawlingChoice = None
|
||||||
kb.storeHashesChoice = None
|
kb.storeHashesChoice = None
|
||||||
kb.suppressResumeInfo = False
|
kb.suppressResumeInfo = False
|
||||||
|
kb.tableFrom = None
|
||||||
kb.technique = None
|
kb.technique = None
|
||||||
kb.tempDir = None
|
kb.tempDir = None
|
||||||
kb.testMode = False
|
kb.testMode = False
|
||||||
@@ -2140,6 +2194,8 @@ def _mergeOptions(inputOptions, overrideOptions):
|
|||||||
if inputOptions.pickledOptions:
|
if inputOptions.pickledOptions:
|
||||||
try:
|
try:
|
||||||
inputOptions = base64unpickle(inputOptions.pickledOptions)
|
inputOptions = base64unpickle(inputOptions.pickledOptions)
|
||||||
|
if type(inputOptions) == dict:
|
||||||
|
inputOptions = AttribDict(inputOptions)
|
||||||
_normalizeOptions(inputOptions)
|
_normalizeOptions(inputOptions)
|
||||||
except Exception, ex:
|
except Exception, ex:
|
||||||
errMsg = "provided invalid value '%s' for option '--pickled-options'" % inputOptions.pickledOptions
|
errMsg = "provided invalid value '%s' for option '--pickled-options'" % inputOptions.pickledOptions
|
||||||
@@ -2237,6 +2293,7 @@ def _setTorHttpProxySettings():
|
|||||||
infoMsg = "setting Tor HTTP proxy settings"
|
infoMsg = "setting Tor HTTP proxy settings"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
s = None
|
||||||
found = None
|
found = None
|
||||||
|
|
||||||
for port in (DEFAULT_TOR_HTTP_PORTS if not conf.torPort else (conf.torPort,)):
|
for port in (DEFAULT_TOR_HTTP_PORTS if not conf.torPort else (conf.torPort,)):
|
||||||
@@ -2248,12 +2305,13 @@ def _setTorHttpProxySettings():
|
|||||||
except socket.error:
|
except socket.error:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
if s:
|
||||||
s.close()
|
s.close()
|
||||||
|
|
||||||
if found:
|
if found:
|
||||||
conf.proxy = "http://%s:%d" % (LOCALHOST, found)
|
conf.proxy = "http://%s:%d" % (LOCALHOST, found)
|
||||||
else:
|
else:
|
||||||
errMsg = "can't establish connection with the Tor proxy. "
|
errMsg = "can't establish connection with the Tor HTTP proxy. "
|
||||||
errMsg += "Please make sure that you have Vidalia, Privoxy or "
|
errMsg += "Please make sure that you have Vidalia, Privoxy or "
|
||||||
errMsg += "Polipo bundle installed for you to be able to "
|
errMsg += "Polipo bundle installed for you to be able to "
|
||||||
errMsg += "successfully use switch '--tor' "
|
errMsg += "successfully use switch '--tor' "
|
||||||
@@ -2298,7 +2356,7 @@ def _checkTor():
|
|||||||
page = None
|
page = None
|
||||||
|
|
||||||
if not page or 'Congratulations' not in page:
|
if not page or 'Congratulations' not in page:
|
||||||
errMsg = "it seems that Tor is not properly set. Please try using options '--tor-type' and/or '--tor-port'"
|
errMsg = "it appears that Tor is not properly set. Please try using options '--tor-type' and/or '--tor-port'"
|
||||||
raise SqlmapConnectionException(errMsg)
|
raise SqlmapConnectionException(errMsg)
|
||||||
else:
|
else:
|
||||||
infoMsg = "Tor is properly being used"
|
infoMsg = "Tor is properly being used"
|
||||||
@@ -2331,10 +2389,6 @@ def _basicOptionValidation():
|
|||||||
errMsg = "value for option '--first' (firstChar) must be smaller than or equal to value for --last (lastChar) option"
|
errMsg = "value for option '--first' (firstChar) must be smaller than or equal to value for --last (lastChar) option"
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
if isinstance(conf.cpuThrottle, int) and (conf.cpuThrottle > 100 or conf.cpuThrottle < 0):
|
|
||||||
errMsg = "value for option '--cpu-throttle' (cpuThrottle) must be in range [0,100]"
|
|
||||||
raise SqlmapSyntaxException(errMsg)
|
|
||||||
|
|
||||||
if conf.textOnly and conf.nullConnection:
|
if conf.textOnly and conf.nullConnection:
|
||||||
errMsg = "switch '--text-only' is incompatible with switch '--null-connection'"
|
errMsg = "switch '--text-only' is incompatible with switch '--null-connection'"
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
@@ -2534,11 +2588,9 @@ def _resolveCrossReferences():
|
|||||||
lib.request.connect.setHTTPHandlers = _setHTTPHandlers
|
lib.request.connect.setHTTPHandlers = _setHTTPHandlers
|
||||||
lib.utils.search.setHTTPHandlers = _setHTTPHandlers
|
lib.utils.search.setHTTPHandlers = _setHTTPHandlers
|
||||||
lib.controller.checks.setVerbosity = setVerbosity
|
lib.controller.checks.setVerbosity = setVerbosity
|
||||||
|
lib.controller.checks.setWafFunctions = _setWafFunctions
|
||||||
|
|
||||||
def initOptions(inputOptions=AttribDict(), overrideOptions=False):
|
def initOptions(inputOptions=AttribDict(), overrideOptions=False):
|
||||||
if IS_WIN:
|
|
||||||
coloramainit()
|
|
||||||
|
|
||||||
_setConfAttributes()
|
_setConfAttributes()
|
||||||
_setKnowledgeBaseAttributes()
|
_setKnowledgeBaseAttributes()
|
||||||
_mergeOptions(inputOptions, overrideOptions)
|
_mergeOptions(inputOptions, overrideOptions)
|
||||||
|
|||||||
@@ -136,6 +136,7 @@ optDict = {
|
|||||||
"tbl": "string",
|
"tbl": "string",
|
||||||
"col": "string",
|
"col": "string",
|
||||||
"excludeCol": "string",
|
"excludeCol": "string",
|
||||||
|
"pivotColumn": "string",
|
||||||
"dumpWhere": "string",
|
"dumpWhere": "string",
|
||||||
"user": "string",
|
"user": "string",
|
||||||
"excludeSysDbs": "boolean",
|
"excludeSysDbs": "boolean",
|
||||||
@@ -189,6 +190,7 @@ optDict = {
|
|||||||
#"xmlFile": "string",
|
#"xmlFile": "string",
|
||||||
"trafficFile": "string",
|
"trafficFile": "string",
|
||||||
"batch": "boolean",
|
"batch": "boolean",
|
||||||
|
"binaryFields": "string",
|
||||||
"charset": "string",
|
"charset": "string",
|
||||||
"crawlDepth": "integer",
|
"crawlDepth": "integer",
|
||||||
"crawlExclude": "string",
|
"crawlExclude": "string",
|
||||||
@@ -201,7 +203,6 @@ optDict = {
|
|||||||
"hexConvert": "boolean",
|
"hexConvert": "boolean",
|
||||||
"outputDir": "string",
|
"outputDir": "string",
|
||||||
"parseErrors": "boolean",
|
"parseErrors": "boolean",
|
||||||
"pivotColumn": "string",
|
|
||||||
"saveConfig": "string",
|
"saveConfig": "string",
|
||||||
"scope": "string",
|
"scope": "string",
|
||||||
"testFilter": "string",
|
"testFilter": "string",
|
||||||
@@ -217,23 +218,22 @@ optDict = {
|
|||||||
"dependencies": "boolean",
|
"dependencies": "boolean",
|
||||||
"disableColoring": "boolean",
|
"disableColoring": "boolean",
|
||||||
"googlePage": "integer",
|
"googlePage": "integer",
|
||||||
|
"identifyWaf": "boolean",
|
||||||
"mobile": "boolean",
|
"mobile": "boolean",
|
||||||
"offline": "boolean",
|
"offline": "boolean",
|
||||||
"pageRank": "boolean",
|
"pageRank": "boolean",
|
||||||
"purgeOutput": "boolean",
|
"purgeOutput": "boolean",
|
||||||
|
"skipWaf": "boolean",
|
||||||
"smart": "boolean",
|
"smart": "boolean",
|
||||||
|
"tmpDir": "string",
|
||||||
"wizard": "boolean",
|
"wizard": "boolean",
|
||||||
"verbose": "integer",
|
"verbose": "integer",
|
||||||
},
|
},
|
||||||
"Hidden": {
|
"Hidden": {
|
||||||
"dummy": "boolean",
|
"dummy": "boolean",
|
||||||
"disablePrecon": "boolean",
|
"disablePrecon": "boolean",
|
||||||
"binaryFields": "string",
|
|
||||||
"profile": "boolean",
|
"profile": "boolean",
|
||||||
"cpuThrottle": "integer",
|
|
||||||
"forceDns": "boolean",
|
"forceDns": "boolean",
|
||||||
"identifyWaf": "boolean",
|
|
||||||
"skipWaf": "boolean",
|
|
||||||
"ignore401": "boolean",
|
"ignore401": "boolean",
|
||||||
"smokeTest": "boolean",
|
"smokeTest": "boolean",
|
||||||
"liveTest": "boolean",
|
"liveTest": "boolean",
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ def setDbms(dbms):
|
|||||||
dbms = _.group(1)
|
dbms = _.group(1)
|
||||||
|
|
||||||
Backend.setDbms(dbms)
|
Backend.setDbms(dbms)
|
||||||
|
if kb.resolutionDbms:
|
||||||
|
hashDBWrite(HASHDB_KEYS.DBMS, kb.resolutionDbms)
|
||||||
|
|
||||||
logger.info("the back-end DBMS is %s" % Backend.getDbms())
|
logger.info("the back-end DBMS is %s" % Backend.getDbms())
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import re
|
|||||||
import subprocess
|
import subprocess
|
||||||
import string
|
import string
|
||||||
import sys
|
import sys
|
||||||
import time
|
|
||||||
import types
|
import types
|
||||||
|
|
||||||
from lib.core.datatype import AttribDict
|
from lib.core.datatype import AttribDict
|
||||||
@@ -20,7 +19,7 @@ from lib.core.enums import OS
|
|||||||
from lib.core.revision import getRevisionNumber
|
from lib.core.revision import getRevisionNumber
|
||||||
|
|
||||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||||
VERSION = "1.0.4.0"
|
VERSION = "1.0.8.2"
|
||||||
REVISION = getRevisionNumber()
|
REVISION = getRevisionNumber()
|
||||||
STABLE = VERSION.count('.') <= 2
|
STABLE = VERSION.count('.') <= 2
|
||||||
VERSION_STRING = "sqlmap/%s#%s" % (VERSION, "stable" if STABLE else "dev")
|
VERSION_STRING = "sqlmap/%s#%s" % (VERSION, "stable" if STABLE else "dev")
|
||||||
@@ -61,6 +60,7 @@ PARTIAL_HEX_VALUE_MARKER = "__PARTIAL_HEX_VALUE__"
|
|||||||
URI_QUESTION_MARKER = "__QUESTION_MARK__"
|
URI_QUESTION_MARKER = "__QUESTION_MARK__"
|
||||||
ASTERISK_MARKER = "__ASTERISK_MARK__"
|
ASTERISK_MARKER = "__ASTERISK_MARK__"
|
||||||
REPLACEMENT_MARKER = "__REPLACEMENT_MARK__"
|
REPLACEMENT_MARKER = "__REPLACEMENT_MARK__"
|
||||||
|
BOUNDED_INJECTION_MARKER = "__BOUNDED_INJECTION_MARK__"
|
||||||
|
|
||||||
RANDOM_INTEGER_MARKER = "[RANDINT]"
|
RANDOM_INTEGER_MARKER = "[RANDINT]"
|
||||||
RANDOM_STRING_MARKER = "[RANDSTR]"
|
RANDOM_STRING_MARKER = "[RANDSTR]"
|
||||||
@@ -69,6 +69,9 @@ PAYLOAD_DELIMITER = "__PAYLOAD_DELIMITER__"
|
|||||||
CHAR_INFERENCE_MARK = "%c"
|
CHAR_INFERENCE_MARK = "%c"
|
||||||
PRINTABLE_CHAR_REGEX = r"[^\x00-\x1f\x7f-\xff]"
|
PRINTABLE_CHAR_REGEX = r"[^\x00-\x1f\x7f-\xff]"
|
||||||
|
|
||||||
|
# Regular expression used for extraction of table names (useful for (e.g.) MsAccess)
|
||||||
|
SELECT_FROM_TABLE_REGEX = r"\bSELECT .+? FROM (?P<result>[\w.]+)\b"
|
||||||
|
|
||||||
# Regular expression used for recognition of textual content-type
|
# Regular expression used for recognition of textual content-type
|
||||||
TEXT_CONTENT_TYPE_REGEX = r"(?i)(text|form|message|xml|javascript|ecmascript|json)"
|
TEXT_CONTENT_TYPE_REGEX = r"(?i)(text|form|message|xml|javascript|ecmascript|json)"
|
||||||
|
|
||||||
@@ -78,6 +81,9 @@ PERMISSION_DENIED_REGEX = r"(command|permission|access)\s*(was|is)?\s*denied"
|
|||||||
# Regular expression used for recognition of generic maximum connection messages
|
# Regular expression used for recognition of generic maximum connection messages
|
||||||
MAX_CONNECTIONS_REGEX = r"max.+connections"
|
MAX_CONNECTIONS_REGEX = r"max.+connections"
|
||||||
|
|
||||||
|
# Timeout before the pre-connection candidate is being disposed (because of high probability that the web server will reset it)
|
||||||
|
PRECONNECT_CANDIDATE_TIMEOUT = 10
|
||||||
|
|
||||||
# Regular expression used for extracting results from Google search
|
# Regular expression used for extracting results from Google search
|
||||||
GOOGLE_REGEX = r"webcache\.googleusercontent\.com/search\?q=cache:[^:]+:([^+]+)\+&cd=|url\?\w+=((?![^>]+webcache\.googleusercontent\.com)http[^>]+)&(sa=U|rct=j)"
|
GOOGLE_REGEX = r"webcache\.googleusercontent\.com/search\?q=cache:[^:]+:([^+]+)\+&cd=|url\?\w+=((?![^>]+webcache\.googleusercontent\.com)http[^>]+)&(sa=U|rct=j)"
|
||||||
|
|
||||||
@@ -130,6 +136,9 @@ HTTP_ACCEPT_ENCODING_HEADER_VALUE = "gzip,deflate"
|
|||||||
# Default timeout for running commands over backdoor
|
# Default timeout for running commands over backdoor
|
||||||
BACKDOOR_RUN_CMD_TIMEOUT = 5
|
BACKDOOR_RUN_CMD_TIMEOUT = 5
|
||||||
|
|
||||||
|
# Number of seconds to wait for thread finalization at program end
|
||||||
|
THREAD_FINALIZATION_TIMEOUT = 1
|
||||||
|
|
||||||
# Maximum number of techniques used in inject.py/getValue() per one value
|
# Maximum number of techniques used in inject.py/getValue() per one value
|
||||||
MAX_TECHNIQUES_PER_VALUE = 2
|
MAX_TECHNIQUES_PER_VALUE = 2
|
||||||
|
|
||||||
@@ -281,12 +290,16 @@ BLANK = "<blank>"
|
|||||||
# String representation for current database
|
# String representation for current database
|
||||||
CURRENT_DB = "CD"
|
CURRENT_DB = "CD"
|
||||||
|
|
||||||
|
# Regular expressions used for finding file paths in error messages
|
||||||
|
FILE_PATH_REGEXES = (r" in (file )?<b>(?P<result>.*?)</b> on line \d+", r"in (?P<result>[^<>]+?) on line \d+", r"(?:[>(\[\s])(?P<result>[A-Za-z]:[\\/][\w. \\/-]*)", r"(?:[>(\[\s])(?P<result>/\w[/\w.-]+)", r"href=['\"]file://(?P<result>/[^'\"]+)")
|
||||||
|
|
||||||
# Regular expressions used for parsing error messages (--parse-errors)
|
# Regular expressions used for parsing error messages (--parse-errors)
|
||||||
ERROR_PARSING_REGEXES = (
|
ERROR_PARSING_REGEXES = (
|
||||||
r"<b>[^<]*(fatal|error|warning|exception)[^<]*</b>:?\s*(?P<result>.+?)<br\s*/?\s*>",
|
r"<b>[^<]*(fatal|error|warning|exception)[^<]*</b>:?\s*(?P<result>.+?)<br\s*/?\s*>",
|
||||||
r"(?m)^(fatal|error|warning|exception):?\s*(?P<result>.+?)$",
|
r"(?m)^(fatal|error|warning|exception):?\s*(?P<result>[^\n]+?)$",
|
||||||
r"<li>Error Type:<br>(?P<result>.+?)</li>",
|
r"<li>Error Type:<br>(?P<result>.+?)</li>",
|
||||||
r"error '[0-9a-f]{8}'((<[^>]+>)|\s)+(?P<result>[^<>]+)",
|
r"error '[0-9a-f]{8}'((<[^>]+>)|\s)+(?P<result>[^<>]+)",
|
||||||
|
r"(?m)^\s*\[[^\n]+(ODBC|JDBC)[^\n]+\](?P<result>[^\]]+in query expression[^\n]+)$"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Regular expression used for parsing charset info from meta html headers
|
# Regular expression used for parsing charset info from meta html headers
|
||||||
@@ -313,9 +326,6 @@ BURP_REQUEST_REGEX = r"={10,}\s+[^=]+={10,}\s(.+?)\s={10,}"
|
|||||||
# Regex used for parsing XML Burp saved history items
|
# Regex used for parsing XML Burp saved history items
|
||||||
BURP_XML_HISTORY_REGEX = r'<port>(\d+)</port>.+?<request base64="true"><!\[CDATA\[([^]]+)'
|
BURP_XML_HISTORY_REGEX = r'<port>(\d+)</port>.+?<request base64="true"><!\[CDATA\[([^]]+)'
|
||||||
|
|
||||||
# Server header in CloudFlare responses
|
|
||||||
CLOUDFLARE_SERVER_HEADER = "cloudflare-nginx"
|
|
||||||
|
|
||||||
# Encoding used for Unicode data
|
# Encoding used for Unicode data
|
||||||
UNICODE_ENCODING = "utf8"
|
UNICODE_ENCODING = "utf8"
|
||||||
|
|
||||||
@@ -448,7 +458,7 @@ DUMMY_SQL_INJECTION_CHARS = ";()'"
|
|||||||
DUMMY_USER_INJECTION = r"(?i)[^\w](AND|OR)\s+[^\s]+[=><]|\bUNION\b.+\bSELECT\b|\bSELECT\b.+\bFROM\b|\b(CONCAT|information_schema|SLEEP|DELAY)\b"
|
DUMMY_USER_INJECTION = r"(?i)[^\w](AND|OR)\s+[^\s]+[=><]|\bUNION\b.+\bSELECT\b|\bSELECT\b.+\bFROM\b|\b(CONCAT|information_schema|SLEEP|DELAY)\b"
|
||||||
|
|
||||||
# Extensions skipped by crawler
|
# Extensions skipped by crawler
|
||||||
CRAWL_EXCLUDE_EXTENSIONS = ("gif", "jpg", "jpeg", "image", "jar", "tif", "bmp", "war", "ear", "mpg", "mpeg", "wmv", "mpeg", "scm", "iso", "dmp", "dll", "cab", "so", "avi", "mkv", "bin", "iso", "tar", "png", "pdf", "ps", "wav", "mp3", "mp4", "au", "aiff", "aac", "zip", "rar", "7z", "gz", "flv", "mov", "doc", "docx", "xls", "dot", "dotx", "xlt", "xlsx", "ppt", "pps", "pptx")
|
CRAWL_EXCLUDE_EXTENSIONS = ('3ds', '3g2', '3gp', '7z', 'DS_Store', 'a', 'aac', 'adp', 'ai', 'aif', 'aiff', 'apk', 'ar', 'asf', 'au', 'avi', 'bak', 'bin', 'bk', 'bmp', 'btif', 'bz2', 'cab', 'caf', 'cgm', 'cmx', 'cpio', 'cr2', 'dat', 'deb', 'djvu', 'dll', 'dmg', 'dmp', 'dng', 'doc', 'docx', 'dot', 'dotx', 'dra', 'dsk', 'dts', 'dtshd', 'dvb', 'dwg', 'dxf', 'ear', 'ecelp4800', 'ecelp7470', 'ecelp9600', 'egg', 'eol', 'eot', 'epub', 'exe', 'f4v', 'fbs', 'fh', 'fla', 'flac', 'fli', 'flv', 'fpx', 'fst', 'fvt', 'g3', 'gif', 'gz', 'h261', 'h263', 'h264', 'ico', 'ief', 'image', 'img', 'ipa', 'iso', 'jar', 'jpeg', 'jpg', 'jpgv', 'jpm', 'jxr', 'ktx', 'lvp', 'lz', 'lzma', 'lzo', 'm3u', 'm4a', 'm4v', 'mar', 'mdi', 'mid', 'mj2', 'mka', 'mkv', 'mmr', 'mng', 'mov', 'movie', 'mp3', 'mp4', 'mp4a', 'mpeg', 'mpg', 'mpga', 'mxu', 'nef', 'npx', 'o', 'oga', 'ogg', 'ogv', 'otf', 'pbm', 'pcx', 'pdf', 'pea', 'pgm', 'pic', 'png', 'pnm', 'ppm', 'pps', 'ppt', 'pptx', 'ps', 'psd', 'pya', 'pyc', 'pyo', 'pyv', 'qt', 'rar', 'ras', 'raw', 'rgb', 'rip', 'rlc', 'rz', 's3m', 's7z', 'scm', 'scpt', 'sgi', 'shar', 'sil', 'smv', 'so', 'sub', 'swf', 'tar', 'tbz2', 'tga', 'tgz', 'tif', 'tiff', 'tlz', 'ts', 'ttf', 'uvh', 'uvi', 'uvm', 'uvp', 'uvs', 'uvu', 'viv', 'vob', 'war', 'wav', 'wax', 'wbmp', 'wdp', 'weba', 'webm', 'webp', 'whl', 'wm', 'wma', 'wmv', 'wmx', 'woff', 'woff2', 'wvx', 'xbm', 'xif', 'xls', 'xlsx', 'xlt', 'xm', 'xpi', 'xpm', 'xwd', 'xz', 'z', 'zip', 'zipx')
|
||||||
|
|
||||||
# Patterns often seen in HTTP headers containing custom injection marking character
|
# Patterns often seen in HTTP headers containing custom injection marking character
|
||||||
PROBLEMATIC_CUSTOM_INJECTION_PATTERNS = r"(;q=[^;']+)|(\*/\*)"
|
PROBLEMATIC_CUSTOM_INJECTION_PATTERNS = r"(;q=[^;']+)|(\*/\*)"
|
||||||
@@ -459,8 +469,8 @@ BRUTE_TABLE_EXISTS_TEMPLATE = "EXISTS(SELECT %d FROM %s)"
|
|||||||
# Template used for common column existence check
|
# Template used for common column existence check
|
||||||
BRUTE_COLUMN_EXISTS_TEMPLATE = "EXISTS(SELECT %s FROM %s)"
|
BRUTE_COLUMN_EXISTS_TEMPLATE = "EXISTS(SELECT %s FROM %s)"
|
||||||
|
|
||||||
# Payload used for checking of existence of IDS/WAF (dummier the better)
|
# Payload used for checking of existence of IDS/IPS/WAF (dummier the better)
|
||||||
IDS_WAF_CHECK_PAYLOAD = "AND 1=1 UNION ALL SELECT 1,2,3,table_name FROM information_schema.tables WHERE 2>1-- ../../../etc/passwd"
|
IDS_WAF_CHECK_PAYLOAD = "AND 1=1 UNION ALL SELECT 1,NULL,'<script>alert(\"XSS\")</script>',table_name FROM information_schema.tables WHERE 2>1--/**/; EXEC xp_cmdshell('cat ../../../etc/passwd')#"
|
||||||
|
|
||||||
# Data inside shellcodeexec to be filled with random string
|
# Data inside shellcodeexec to be filled with random string
|
||||||
SHELLCODEEXEC_RANDOM_STRING_MARKER = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
SHELLCODEEXEC_RANDOM_STRING_MARKER = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||||
@@ -533,7 +543,7 @@ HASHDB_FLUSH_RETRIES = 3
|
|||||||
HASHDB_END_TRANSACTION_RETRIES = 3
|
HASHDB_END_TRANSACTION_RETRIES = 3
|
||||||
|
|
||||||
# Unique milestone value used for forced deprecation of old HashDB values (e.g. when changing hash/pickle mechanism)
|
# Unique milestone value used for forced deprecation of old HashDB values (e.g. when changing hash/pickle mechanism)
|
||||||
HASHDB_MILESTONE_VALUE = "JHjrBugdDA" # "".join(random.sample(string.ascii_letters, 10))
|
HASHDB_MILESTONE_VALUE = "baFJusZrel" # python -c 'import random, string; print "".join(random.sample(string.ascii_letters, 10))'
|
||||||
|
|
||||||
# Warn user of possible delay due to large page dump in full UNION query injections
|
# Warn user of possible delay due to large page dump in full UNION query injections
|
||||||
LARGE_OUTPUT_THRESHOLD = 1024 ** 2
|
LARGE_OUTPUT_THRESHOLD = 1024 ** 2
|
||||||
@@ -562,6 +572,9 @@ HEURISTIC_CHECK_ALPHABET = ('"', '\'', ')', '(', ',', '.')
|
|||||||
# String used for dummy non-SQLi (e.g. XSS) heuristic checks of a tested parameter value
|
# String used for dummy non-SQLi (e.g. XSS) heuristic checks of a tested parameter value
|
||||||
DUMMY_NON_SQLI_CHECK_APPENDIX = "<'\">"
|
DUMMY_NON_SQLI_CHECK_APPENDIX = "<'\">"
|
||||||
|
|
||||||
|
# Regular expression used for recognition of file inclusion errors
|
||||||
|
FI_ERROR_REGEX = "(?i)[^\n]*(no such file|failed (to )?open)[^\n]*"
|
||||||
|
|
||||||
# Length of prefix and suffix used in non-SQLI heuristic checks
|
# Length of prefix and suffix used in non-SQLI heuristic checks
|
||||||
NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH = 6
|
NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH = 6
|
||||||
|
|
||||||
@@ -571,6 +584,9 @@ MAX_CONNECTION_CHUNK_SIZE = 10 * 1024 * 1024
|
|||||||
# Maximum response total page size (trimmed if larger)
|
# Maximum response total page size (trimmed if larger)
|
||||||
MAX_CONNECTION_TOTAL_SIZE = 100 * 1024 * 1024
|
MAX_CONNECTION_TOTAL_SIZE = 100 * 1024 * 1024
|
||||||
|
|
||||||
|
# For preventing MemoryError exceptions (caused when using large sequences in difflib.SequenceMatcher)
|
||||||
|
MAX_DIFFLIB_SEQUENCE_LENGTH = 10 * 1024 * 1024
|
||||||
|
|
||||||
# Maximum (multi-threaded) length of entry in bisection algorithm
|
# Maximum (multi-threaded) length of entry in bisection algorithm
|
||||||
MAX_BISECTION_LENGTH = 50 * 1024 * 1024
|
MAX_BISECTION_LENGTH = 50 * 1024 * 1024
|
||||||
|
|
||||||
@@ -578,7 +594,7 @@ MAX_BISECTION_LENGTH = 50 * 1024 * 1024
|
|||||||
LARGE_CHUNK_TRIM_MARKER = "__TRIMMED_CONTENT__"
|
LARGE_CHUNK_TRIM_MARKER = "__TRIMMED_CONTENT__"
|
||||||
|
|
||||||
# Generic SQL comment formation
|
# Generic SQL comment formation
|
||||||
GENERIC_SQL_COMMENT = "-- -"
|
GENERIC_SQL_COMMENT = "-- [RANDSTR]"
|
||||||
|
|
||||||
# Threshold value for turning back on time auto-adjustment mechanism
|
# Threshold value for turning back on time auto-adjustment mechanism
|
||||||
VALID_TIME_CHARS_RUN_THRESHOLD = 100
|
VALID_TIME_CHARS_RUN_THRESHOLD = 100
|
||||||
@@ -587,7 +603,7 @@ VALID_TIME_CHARS_RUN_THRESHOLD = 100
|
|||||||
CHECK_ZERO_COLUMNS_THRESHOLD = 10
|
CHECK_ZERO_COLUMNS_THRESHOLD = 10
|
||||||
|
|
||||||
# Boldify all logger messages containing these "patterns"
|
# Boldify all logger messages containing these "patterns"
|
||||||
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "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", "CloudFlare")
|
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "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")
|
||||||
|
|
||||||
# Generic www root directory names
|
# Generic www root directory names
|
||||||
GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "httpdocs", "public", "wwwroot", "www")
|
GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "httpdocs", "public", "wwwroot", "www")
|
||||||
@@ -599,7 +615,7 @@ MAX_HELP_OPTION_LENGTH = 18
|
|||||||
MAX_CONNECT_RETRIES = 100
|
MAX_CONNECT_RETRIES = 100
|
||||||
|
|
||||||
# Strings for detecting formatting errors
|
# Strings for detecting formatting errors
|
||||||
FORMAT_EXCEPTION_STRINGS = ("Type mismatch", "Error converting", "Failed to convert", "System.FormatException", "java.lang.NumberFormatException", "ValueError: invalid literal")
|
FORMAT_EXCEPTION_STRINGS = ("Type mismatch", "Error converting", "Conversion failed", "String or binary data would be truncated", "Failed to convert", "unable to interpret text value", "Input string was not in a correct format", "System.FormatException", "java.lang.NumberFormatException", "ValueError: invalid literal", "DataTypeMismatchException", "CF_SQL_INTEGER", " for CFSQLTYPE ", "cfqueryparam cfsqltype", "InvalidParamTypeException", "Invalid parameter type", "is not of type numeric", "<cfif Not IsNumeric(", "invalid input syntax for integer", "invalid input syntax for type", "invalid number", "character to number conversion error", "unable to interpret text value", "String was not recognized as a valid", "Convert.ToInt", "cannot be converted to a ", "InvalidDataException")
|
||||||
|
|
||||||
# Regular expression used for extracting ASP.NET view state values
|
# Regular expression used for extracting ASP.NET view state values
|
||||||
VIEWSTATE_REGEX = r'(?i)(?P<name>__VIEWSTATE[^"]*)[^>]+value="(?P<result>[^"]+)'
|
VIEWSTATE_REGEX = r'(?i)(?P<name>__VIEWSTATE[^"]*)[^>]+value="(?P<result>[^"]+)'
|
||||||
@@ -649,6 +665,9 @@ SUHOSIN_MAX_VALUE_LENGTH = 512
|
|||||||
# Minimum size of an (binary) entry before it can be considered for dumping to disk
|
# Minimum size of an (binary) entry before it can be considered for dumping to disk
|
||||||
MIN_BINARY_DISK_DUMP_SIZE = 100
|
MIN_BINARY_DISK_DUMP_SIZE = 100
|
||||||
|
|
||||||
|
# Filenames of payloads xml files (in order of loading)
|
||||||
|
PAYLOAD_XML_FILES = ("boolean_blind.xml", "error_based.xml", "inline_query.xml", "stacked_queries.xml", "time_blind.xml", "union_query.xml")
|
||||||
|
|
||||||
# Regular expression used for extracting form tags
|
# Regular expression used for extracting form tags
|
||||||
FORM_SEARCH_REGEX = r"(?si)<form(?!.+<form).+?</form>"
|
FORM_SEARCH_REGEX = r"(?si)<form(?!.+<form).+?</form>"
|
||||||
|
|
||||||
@@ -680,7 +699,7 @@ BRUTE_DOC_ROOT_PREFIXES = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Suffixes used in brute force search for web server document root
|
# Suffixes used in brute force search for web server document root
|
||||||
BRUTE_DOC_ROOT_SUFFIXES = ("", "html", "htdocs", "httpdocs", "php", "public", "src", "site", "build", "web", "data", "sites/all", "www/build")
|
BRUTE_DOC_ROOT_SUFFIXES = ("", "html", "htdocs", "httpdocs", "php", "public", "src", "site", "build", "web", "www", "data", "sites/all", "www/build")
|
||||||
|
|
||||||
# String used for marking target name inside used brute force web server document root
|
# String used for marking target name inside used brute force web server document root
|
||||||
BRUTE_DOC_ROOT_TARGET_MARK = "%TARGET%"
|
BRUTE_DOC_ROOT_TARGET_MARK = "%TARGET%"
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ from lib.core.common import intersect
|
|||||||
from lib.core.common import normalizeUnicode
|
from lib.core.common import normalizeUnicode
|
||||||
from lib.core.common import openFile
|
from lib.core.common import openFile
|
||||||
from lib.core.common import paramToDict
|
from lib.core.common import paramToDict
|
||||||
|
from lib.core.common import randomStr
|
||||||
from lib.core.common import readInput
|
from lib.core.common import readInput
|
||||||
from lib.core.common import resetCookieJar
|
from lib.core.common import resetCookieJar
|
||||||
from lib.core.common import urldecode
|
from lib.core.common import urldecode
|
||||||
@@ -35,6 +36,7 @@ from lib.core.dump import dumper
|
|||||||
from lib.core.enums import HASHDB_KEYS
|
from lib.core.enums import HASHDB_KEYS
|
||||||
from lib.core.enums import HTTP_HEADER
|
from lib.core.enums import HTTP_HEADER
|
||||||
from lib.core.enums import HTTPMETHOD
|
from lib.core.enums import HTTPMETHOD
|
||||||
|
from lib.core.enums import MKSTEMP_PREFIX
|
||||||
from lib.core.enums import PLACE
|
from lib.core.enums import PLACE
|
||||||
from lib.core.enums import POST_HINT
|
from lib.core.enums import POST_HINT
|
||||||
from lib.core.exception import SqlmapFilePathException
|
from lib.core.exception import SqlmapFilePathException
|
||||||
@@ -214,9 +216,9 @@ def _setRequestParams():
|
|||||||
|
|
||||||
if re.search(URI_INJECTABLE_REGEX, conf.url, re.I) and not any(place in conf.parameters for place in (PLACE.GET, PLACE.POST)) and not kb.postHint and not CUSTOM_INJECTION_MARK_CHAR in (conf.data or "") and conf.url.startswith("http"):
|
if re.search(URI_INJECTABLE_REGEX, conf.url, re.I) and not any(place in conf.parameters for place in (PLACE.GET, PLACE.POST)) and not kb.postHint and not CUSTOM_INJECTION_MARK_CHAR in (conf.data or "") and conf.url.startswith("http"):
|
||||||
warnMsg = "you've provided target URL without any GET "
|
warnMsg = "you've provided target URL without any GET "
|
||||||
warnMsg += "parameters (e.g. www.site.com/article.php?id=1) "
|
warnMsg += "parameters (e.g. 'http://www.site.com/article.php?id=1') "
|
||||||
warnMsg += "and without providing any POST parameters "
|
warnMsg += "and without providing any POST parameters "
|
||||||
warnMsg += "through --data option"
|
warnMsg += "through option '--data'"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
message = "do you want to try URI injections "
|
message = "do you want to try URI injections "
|
||||||
@@ -370,7 +372,7 @@ def _setRequestParams():
|
|||||||
raise SqlmapGenericException(errMsg)
|
raise SqlmapGenericException(errMsg)
|
||||||
|
|
||||||
if conf.csrfToken:
|
if conf.csrfToken:
|
||||||
if not any(conf.csrfToken in _ for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))) and not conf.csrfToken in set(_[0].lower() for _ in conf.httpHeaders) and not conf.csrfToken in conf.paramDict.get(PLACE.COOKIE, {}):
|
if not any(conf.csrfToken in _ for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))) and not re.search(r"\b%s\b" % re.escape(conf.csrfToken), conf.data or "") and not conf.csrfToken in set(_[0].lower() for _ in conf.httpHeaders) and not conf.csrfToken in conf.paramDict.get(PLACE.COOKIE, {}):
|
||||||
errMsg = "anti-CSRF token parameter '%s' not " % conf.csrfToken
|
errMsg = "anti-CSRF token parameter '%s' not " % conf.csrfToken
|
||||||
errMsg += "found in provided GET, POST, Cookie or header values"
|
errMsg += "found in provided GET, POST, Cookie or header values"
|
||||||
raise SqlmapGenericException(errMsg)
|
raise SqlmapGenericException(errMsg)
|
||||||
@@ -531,7 +533,7 @@ def _setResultsFile():
|
|||||||
except (OSError, IOError), ex:
|
except (OSError, IOError), ex:
|
||||||
try:
|
try:
|
||||||
warnMsg = "unable to create results file '%s' ('%s'). " % (conf.resultsFilename, getUnicode(ex))
|
warnMsg = "unable to create results file '%s' ('%s'). " % (conf.resultsFilename, getUnicode(ex))
|
||||||
conf.resultsFilename = tempfile.mkstemp(prefix="sqlmapresults-", suffix=".csv")[1]
|
conf.resultsFilename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.RESULTS, suffix=".csv")[1]
|
||||||
conf.resultsFP = openFile(conf.resultsFilename, "w+", UNICODE_ENCODING, buffering=0)
|
conf.resultsFP = openFile(conf.resultsFilename, "w+", UNICODE_ENCODING, buffering=0)
|
||||||
warnMsg += "Using temporary file '%s' instead" % conf.resultsFilename
|
warnMsg += "Using temporary file '%s' instead" % conf.resultsFilename
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
@@ -542,7 +544,7 @@ def _setResultsFile():
|
|||||||
errMsg += "create temporary files and/or directories"
|
errMsg += "create temporary files and/or directories"
|
||||||
raise SqlmapSystemException(errMsg)
|
raise SqlmapSystemException(errMsg)
|
||||||
|
|
||||||
conf.resultsFP.writelines("Target URL,Place,Parameter,Techniques%s" % os.linesep)
|
conf.resultsFP.writelines("Target URL,Place,Parameter,Technique(s),Note(s)%s" % os.linesep)
|
||||||
|
|
||||||
logger.info("using '%s' as the CSV results file in multiple targets mode" % conf.resultsFilename)
|
logger.info("using '%s' as the CSV results file in multiple targets mode" % conf.resultsFilename)
|
||||||
|
|
||||||
@@ -603,10 +605,15 @@ def _createTargetDirs():
|
|||||||
Create the output directory.
|
Create the output directory.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not os.path.isdir(paths.SQLMAP_OUTPUT_PATH):
|
|
||||||
try:
|
try:
|
||||||
if not os.path.isdir(paths.SQLMAP_OUTPUT_PATH):
|
if not os.path.isdir(paths.SQLMAP_OUTPUT_PATH):
|
||||||
os.makedirs(paths.SQLMAP_OUTPUT_PATH, 0755)
|
os.makedirs(paths.SQLMAP_OUTPUT_PATH, 0755)
|
||||||
|
|
||||||
|
_ = os.path.join(paths.SQLMAP_OUTPUT_PATH, randomStr())
|
||||||
|
open(_, "w+b").close()
|
||||||
|
os.remove(_)
|
||||||
|
|
||||||
|
if conf.outputDir:
|
||||||
warnMsg = "using '%s' as the output directory" % paths.SQLMAP_OUTPUT_PATH
|
warnMsg = "using '%s' as the output directory" % paths.SQLMAP_OUTPUT_PATH
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
except (OSError, IOError), ex:
|
except (OSError, IOError), ex:
|
||||||
@@ -619,7 +626,7 @@ def _createTargetDirs():
|
|||||||
errMsg += "create temporary files and/or directories"
|
errMsg += "create temporary files and/or directories"
|
||||||
raise SqlmapSystemException(errMsg)
|
raise SqlmapSystemException(errMsg)
|
||||||
|
|
||||||
warnMsg = "unable to create regular output directory "
|
warnMsg = "unable to %s output directory " % ("create" if not os.path.isdir(paths.SQLMAP_OUTPUT_PATH) else "write to the")
|
||||||
warnMsg += "'%s' (%s). " % (paths.SQLMAP_OUTPUT_PATH, getUnicode(ex))
|
warnMsg += "'%s' (%s). " % (paths.SQLMAP_OUTPUT_PATH, getUnicode(ex))
|
||||||
warnMsg += "Using temporary directory '%s' instead" % getUnicode(tempDir)
|
warnMsg += "Using temporary directory '%s' instead" % getUnicode(tempDir)
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ from lib.core.common import readXmlFile
|
|||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.core.data import paths
|
from lib.core.data import paths
|
||||||
|
from lib.core.enums import MKSTEMP_PREFIX
|
||||||
from lib.core.exception import SqlmapBaseException
|
from lib.core.exception import SqlmapBaseException
|
||||||
from lib.core.exception import SqlmapNotVulnerableException
|
from lib.core.exception import SqlmapNotVulnerableException
|
||||||
from lib.core.log import LOGGER_HANDLER
|
from lib.core.log import LOGGER_HANDLER
|
||||||
@@ -235,7 +236,7 @@ def initCase(switches, count):
|
|||||||
Failures.failedParseOn = None
|
Failures.failedParseOn = None
|
||||||
Failures.failedTraceBack = None
|
Failures.failedTraceBack = None
|
||||||
|
|
||||||
paths.SQLMAP_OUTPUT_PATH = tempfile.mkdtemp(prefix="sqlmaptest-%d-" % count)
|
paths.SQLMAP_OUTPUT_PATH = tempfile.mkdtemp(prefix="%s%d-" % (MKSTEMP_PREFIX.TESTING, count))
|
||||||
paths.SQLMAP_DUMP_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "dump")
|
paths.SQLMAP_DUMP_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "dump")
|
||||||
paths.SQLMAP_FILES_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "files")
|
paths.SQLMAP_FILES_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "files")
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ See the file 'doc/COPYING' for copying permission
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import difflib
|
import difflib
|
||||||
|
import random
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
@@ -43,6 +44,7 @@ class _ThreadData(threading.local):
|
|||||||
self.inTransaction = False
|
self.inTransaction = False
|
||||||
self.lastComparisonPage = None
|
self.lastComparisonPage = None
|
||||||
self.lastComparisonHeaders = None
|
self.lastComparisonHeaders = None
|
||||||
|
self.lastComparisonCode = None
|
||||||
self.lastErrorPage = None
|
self.lastErrorPage = None
|
||||||
self.lastHTTPError = None
|
self.lastHTTPError = None
|
||||||
self.lastRedirectMsg = None
|
self.lastRedirectMsg = None
|
||||||
@@ -51,6 +53,7 @@ class _ThreadData(threading.local):
|
|||||||
self.lastRequestMsg = None
|
self.lastRequestMsg = None
|
||||||
self.lastRequestUID = 0
|
self.lastRequestUID = 0
|
||||||
self.lastRedirectURL = None
|
self.lastRedirectURL = None
|
||||||
|
self.random = random.WichmannHill()
|
||||||
self.resumed = False
|
self.resumed = False
|
||||||
self.retriesCount = 0
|
self.retriesCount = 0
|
||||||
self.seqMatcher = difflib.SequenceMatcher(None)
|
self.seqMatcher = difflib.SequenceMatcher(None)
|
||||||
@@ -199,7 +202,7 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
|
|||||||
kb.threadException = False
|
kb.threadException = False
|
||||||
|
|
||||||
for lock in kb.locks.values():
|
for lock in kb.locks.values():
|
||||||
if lock.locked_lock():
|
if lock.locked():
|
||||||
try:
|
try:
|
||||||
lock.release()
|
lock.release()
|
||||||
except thread.error:
|
except thread.error:
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import zipfile
|
|||||||
from lib.core.common import getSafeExString
|
from lib.core.common import getSafeExString
|
||||||
from lib.core.exception import SqlmapDataException
|
from lib.core.exception import SqlmapDataException
|
||||||
from lib.core.exception import SqlmapInstallationException
|
from lib.core.exception import SqlmapInstallationException
|
||||||
from lib.core.settings import UNICODE_ENCODING
|
|
||||||
|
|
||||||
class Wordlist(object):
|
class Wordlist(object):
|
||||||
"""
|
"""
|
||||||
@@ -45,7 +44,7 @@ class Wordlist(object):
|
|||||||
try:
|
try:
|
||||||
_ = zipfile.ZipFile(self.current, 'r')
|
_ = zipfile.ZipFile(self.current, 'r')
|
||||||
except zipfile.error, ex:
|
except zipfile.error, ex:
|
||||||
errMsg = "something seems to be wrong with "
|
errMsg = "something appears to be wrong with "
|
||||||
errMsg += "the file '%s' ('%s'). Please make " % (self.current, getSafeExString(ex))
|
errMsg += "the file '%s' ('%s'). Please make " % (self.current, getSafeExString(ex))
|
||||||
errMsg += "sure that you haven't made any changes to it"
|
errMsg += "sure that you haven't made any changes to it"
|
||||||
raise SqlmapInstallationException, errMsg
|
raise SqlmapInstallationException, errMsg
|
||||||
@@ -71,7 +70,7 @@ class Wordlist(object):
|
|||||||
try:
|
try:
|
||||||
retVal = self.iter.next().rstrip()
|
retVal = self.iter.next().rstrip()
|
||||||
except zipfile.error, ex:
|
except zipfile.error, ex:
|
||||||
errMsg = "something seems to be wrong with "
|
errMsg = "something appears to be wrong with "
|
||||||
errMsg += "the file '%s' ('%s'). Please make " % (self.current, getSafeExString(ex))
|
errMsg += "the file '%s' ('%s'). Please make " % (self.current, getSafeExString(ex))
|
||||||
errMsg += "sure that you haven't made any changes to it"
|
errMsg += "sure that you haven't made any changes to it"
|
||||||
raise SqlmapInstallationException, errMsg
|
raise SqlmapInstallationException, errMsg
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ from optparse import SUPPRESS_HELP
|
|||||||
|
|
||||||
from lib.core.common import checkDeprecatedOptions
|
from lib.core.common import checkDeprecatedOptions
|
||||||
from lib.core.common import checkSystemEncoding
|
from lib.core.common import checkSystemEncoding
|
||||||
|
from lib.core.common import dataToStdout
|
||||||
from lib.core.common import expandMnemonics
|
from lib.core.common import expandMnemonics
|
||||||
from lib.core.common import getUnicode
|
from lib.core.common import getUnicode
|
||||||
from lib.core.data import cmdLineOptions
|
from lib.core.data import cmdLineOptions
|
||||||
@@ -30,6 +31,7 @@ from lib.core.settings import BASIC_HELP_ITEMS
|
|||||||
from lib.core.settings import DUMMY_URL
|
from lib.core.settings import DUMMY_URL
|
||||||
from lib.core.settings import IS_WIN
|
from lib.core.settings import IS_WIN
|
||||||
from lib.core.settings import MAX_HELP_OPTION_LENGTH
|
from lib.core.settings import MAX_HELP_OPTION_LENGTH
|
||||||
|
from lib.core.settings import UNICODE_ENCODING
|
||||||
from lib.core.settings import VERSION_STRING
|
from lib.core.settings import VERSION_STRING
|
||||||
from lib.core.shell import autoCompletion
|
from lib.core.shell import autoCompletion
|
||||||
from lib.core.shell import clearHistory
|
from lib.core.shell import clearHistory
|
||||||
@@ -46,7 +48,7 @@ def cmdLineParser(argv=None):
|
|||||||
|
|
||||||
checkSystemEncoding()
|
checkSystemEncoding()
|
||||||
|
|
||||||
_ = getUnicode(os.path.basename(argv[0]), encoding=sys.getfilesystemencoding())
|
_ = getUnicode(os.path.basename(argv[0]), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING)
|
||||||
|
|
||||||
usage = "%s%s [options]" % ("python " if not IS_WIN else "", \
|
usage = "%s%s [options]" % ("python " if not IS_WIN else "", \
|
||||||
"\"%s\"" % _ if " " in _ else _)
|
"\"%s\"" % _ if " " in _ else _)
|
||||||
@@ -171,7 +173,7 @@ def cmdLineParser(argv=None):
|
|||||||
help="Set Tor proxy port other than default")
|
help="Set Tor proxy port other than default")
|
||||||
|
|
||||||
request.add_option("--tor-type", dest="torType",
|
request.add_option("--tor-type", dest="torType",
|
||||||
help="Set Tor proxy type (HTTP (default), SOCKS4 or SOCKS5)")
|
help="Set Tor proxy type (HTTP, SOCKS4 or SOCKS5 (default))")
|
||||||
|
|
||||||
request.add_option("--check-tor", dest="checkTor",
|
request.add_option("--check-tor", dest="checkTor",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
@@ -464,6 +466,9 @@ def cmdLineParser(argv=None):
|
|||||||
help="Exclude DBMS system databases when "
|
help="Exclude DBMS system databases when "
|
||||||
"enumerating tables")
|
"enumerating tables")
|
||||||
|
|
||||||
|
enumeration.add_option("--pivot-column", dest="pivotColumn",
|
||||||
|
help="Pivot column name")
|
||||||
|
|
||||||
enumeration.add_option("--where", dest="dumpWhere",
|
enumeration.add_option("--where", dest="dumpWhere",
|
||||||
help="Use WHERE condition while table dumping")
|
help="Use WHERE condition while table dumping")
|
||||||
|
|
||||||
@@ -617,6 +622,9 @@ def cmdLineParser(argv=None):
|
|||||||
action="store_true",
|
action="store_true",
|
||||||
help="Never ask for user input, use the default behaviour")
|
help="Never ask for user input, use the default behaviour")
|
||||||
|
|
||||||
|
general.add_option("--binary-fields", dest="binaryFields",
|
||||||
|
help="Result fields having binary values (e.g. \"digest\")")
|
||||||
|
|
||||||
general.add_option("--charset", dest="charset",
|
general.add_option("--charset", dest="charset",
|
||||||
help="Force character encoding used for data retrieval")
|
help="Force character encoding used for data retrieval")
|
||||||
|
|
||||||
@@ -662,9 +670,6 @@ def cmdLineParser(argv=None):
|
|||||||
action="store_true",
|
action="store_true",
|
||||||
help="Parse and display DBMS error messages from responses")
|
help="Parse and display DBMS error messages from responses")
|
||||||
|
|
||||||
general.add_option("--pivot-column", dest="pivotColumn",
|
|
||||||
help="Pivot column name")
|
|
||||||
|
|
||||||
general.add_option("--save", dest="saveConfig",
|
general.add_option("--save", dest="saveConfig",
|
||||||
help="Save options to a configuration INI file")
|
help="Save options to a configuration INI file")
|
||||||
|
|
||||||
@@ -716,10 +721,6 @@ def cmdLineParser(argv=None):
|
|||||||
action="store_true",
|
action="store_true",
|
||||||
help="Make a thorough testing for a WAF/IPS/IDS protection")
|
help="Make a thorough testing for a WAF/IPS/IDS protection")
|
||||||
|
|
||||||
miscellaneous.add_option("--skip-waf", dest="skipWaf",
|
|
||||||
action="store_true",
|
|
||||||
help="Skip heuristic detection of WAF/IPS/IDS protection")
|
|
||||||
|
|
||||||
miscellaneous.add_option("--mobile", dest="mobile",
|
miscellaneous.add_option("--mobile", dest="mobile",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Imitate smartphone through HTTP User-Agent header")
|
help="Imitate smartphone through HTTP User-Agent header")
|
||||||
@@ -736,6 +737,10 @@ def cmdLineParser(argv=None):
|
|||||||
action="store_true",
|
action="store_true",
|
||||||
help="Safely remove all content from output directory")
|
help="Safely remove all content from output directory")
|
||||||
|
|
||||||
|
miscellaneous.add_option("--skip-waf", dest="skipWaf",
|
||||||
|
action="store_true",
|
||||||
|
help="Skip heuristic detection of WAF/IPS/IDS protection")
|
||||||
|
|
||||||
miscellaneous.add_option("--smart", dest="smart",
|
miscellaneous.add_option("--smart", dest="smart",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Conduct thorough tests only if positive heuristic(s)")
|
help="Conduct thorough tests only if positive heuristic(s)")
|
||||||
@@ -743,6 +748,9 @@ def cmdLineParser(argv=None):
|
|||||||
miscellaneous.add_option("--sqlmap-shell", dest="sqlmapShell", action="store_true",
|
miscellaneous.add_option("--sqlmap-shell", dest="sqlmapShell", action="store_true",
|
||||||
help="Prompt for an interactive sqlmap shell")
|
help="Prompt for an interactive sqlmap shell")
|
||||||
|
|
||||||
|
miscellaneous.add_option("--tmp-dir", dest="tmpDir",
|
||||||
|
help="Local directory for storing temporary files")
|
||||||
|
|
||||||
miscellaneous.add_option("--wizard", dest="wizard",
|
miscellaneous.add_option("--wizard", dest="wizard",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Simple wizard interface for beginner users")
|
help="Simple wizard interface for beginner users")
|
||||||
@@ -760,12 +768,6 @@ def cmdLineParser(argv=None):
|
|||||||
parser.add_option("--profile", dest="profile", action="store_true",
|
parser.add_option("--profile", dest="profile", action="store_true",
|
||||||
help=SUPPRESS_HELP)
|
help=SUPPRESS_HELP)
|
||||||
|
|
||||||
parser.add_option("--binary-fields", dest="binaryFields",
|
|
||||||
help=SUPPRESS_HELP)
|
|
||||||
|
|
||||||
parser.add_option("--cpu-throttle", dest="cpuThrottle", type="int",
|
|
||||||
help=SUPPRESS_HELP)
|
|
||||||
|
|
||||||
parser.add_option("--force-dns", dest="forceDns", action="store_true",
|
parser.add_option("--force-dns", dest="forceDns", action="store_true",
|
||||||
help=SUPPRESS_HELP)
|
help=SUPPRESS_HELP)
|
||||||
|
|
||||||
@@ -809,12 +811,12 @@ def cmdLineParser(argv=None):
|
|||||||
parser.formatter._format_option_strings = parser.formatter.format_option_strings
|
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, type(parser))
|
||||||
|
|
||||||
# Dirty hack for making a short option -hh
|
# Dirty hack for making a short option '-hh'
|
||||||
option = parser.get_option("--hh")
|
option = parser.get_option("--hh")
|
||||||
option._short_opts = ["-hh"]
|
option._short_opts = ["-hh"]
|
||||||
option._long_opts = []
|
option._long_opts = []
|
||||||
|
|
||||||
# Dirty hack for inherent help message of switch -h
|
# Dirty hack for inherent help message of switch '-h'
|
||||||
option = parser.get_option("-h")
|
option = parser.get_option("-h")
|
||||||
option.help = option.help.capitalize().replace("this help", "basic help")
|
option.help = option.help.capitalize().replace("this help", "basic help")
|
||||||
|
|
||||||
@@ -824,7 +826,7 @@ def cmdLineParser(argv=None):
|
|||||||
extraHeaders = []
|
extraHeaders = []
|
||||||
|
|
||||||
for arg in argv:
|
for arg in argv:
|
||||||
_.append(getUnicode(arg, encoding=sys.getfilesystemencoding()))
|
_.append(getUnicode(arg, encoding=sys.getfilesystemencoding() or UNICODE_ENCODING))
|
||||||
|
|
||||||
argv = _
|
argv = _
|
||||||
checkDeprecatedOptions(argv)
|
checkDeprecatedOptions(argv)
|
||||||
@@ -862,13 +864,13 @@ def cmdLineParser(argv=None):
|
|||||||
continue
|
continue
|
||||||
elif command.lower() == "clear":
|
elif command.lower() == "clear":
|
||||||
clearHistory()
|
clearHistory()
|
||||||
print "[i] history cleared"
|
dataToStdout("[i] history cleared\n")
|
||||||
saveHistory(AUTOCOMPLETE_TYPE.SQLMAP)
|
saveHistory(AUTOCOMPLETE_TYPE.SQLMAP)
|
||||||
elif command.lower() in ("x", "q", "exit", "quit"):
|
elif command.lower() in ("x", "q", "exit", "quit"):
|
||||||
raise SqlmapShellQuitException
|
raise SqlmapShellQuitException
|
||||||
elif command[0] != '-':
|
elif command[0] != '-':
|
||||||
print "[!] invalid option(s) provided"
|
dataToStdout("[!] invalid option(s) provided\n")
|
||||||
print "[i] proper example: '-u http://www.site.com/vuln.php?id=1 --banner'"
|
dataToStdout("[i] proper example: '-u http://www.site.com/vuln.php?id=1 --banner'\n")
|
||||||
else:
|
else:
|
||||||
saveHistory(AUTOCOMPLETE_TYPE.SQLMAP)
|
saveHistory(AUTOCOMPLETE_TYPE.SQLMAP)
|
||||||
loadHistory(AUTOCOMPLETE_TYPE.SQLMAP)
|
loadHistory(AUTOCOMPLETE_TYPE.SQLMAP)
|
||||||
@@ -885,7 +887,8 @@ def cmdLineParser(argv=None):
|
|||||||
if argv[i] == "-hh":
|
if argv[i] == "-hh":
|
||||||
argv[i] = "-h"
|
argv[i] = "-h"
|
||||||
elif re.search(r"\A-\w=.+", argv[i]):
|
elif re.search(r"\A-\w=.+", argv[i]):
|
||||||
print "[!] potentially miswritten (illegal '=') short option detected ('%s')" % argv[i]
|
dataToStdout("[!] potentially miswritten (illegal '=') short option detected ('%s')\n" % argv[i])
|
||||||
|
raise SystemExit
|
||||||
elif argv[i] == "-H":
|
elif argv[i] == "-H":
|
||||||
if i + 1 < len(argv):
|
if i + 1 < len(argv):
|
||||||
extraHeaders.append(argv[i + 1])
|
extraHeaders.append(argv[i + 1])
|
||||||
@@ -910,11 +913,11 @@ def cmdLineParser(argv=None):
|
|||||||
try:
|
try:
|
||||||
(args, _) = parser.parse_args(argv)
|
(args, _) = parser.parse_args(argv)
|
||||||
except UnicodeEncodeError, ex:
|
except UnicodeEncodeError, ex:
|
||||||
print "\n[!] %s" % ex.object.encode("unicode-escape")
|
dataToStdout("\n[!] %s\n" % ex.object.encode("unicode-escape"))
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
if "-h" in argv and not advancedHelp:
|
if "-h" in argv and not advancedHelp:
|
||||||
print "\n[!] to see full list of options run with '-hh'"
|
dataToStdout("\n[!] to see full list of options run with '-hh'\n")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
if extraHeaders:
|
if extraHeaders:
|
||||||
@@ -946,7 +949,7 @@ def cmdLineParser(argv=None):
|
|||||||
except SystemExit:
|
except SystemExit:
|
||||||
# Protection against Windows dummy double clicking
|
# Protection against Windows dummy double clicking
|
||||||
if IS_WIN:
|
if IS_WIN:
|
||||||
print "\nPress Enter to continue...",
|
dataToStdout("\nPress Enter to continue...")
|
||||||
raw_input()
|
raw_input()
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ class HTMLHandler(ContentHandler):
|
|||||||
ContentHandler.__init__(self)
|
ContentHandler.__init__(self)
|
||||||
|
|
||||||
self._dbms = None
|
self._dbms = None
|
||||||
self._page = page
|
self._page = (page or "")
|
||||||
|
self._lower_page = self._page.lower()
|
||||||
|
|
||||||
self.dbms = None
|
self.dbms = None
|
||||||
|
|
||||||
@@ -33,11 +34,20 @@ class HTMLHandler(ContentHandler):
|
|||||||
threadData.lastErrorPage = (threadData.lastRequestUID, self._page)
|
threadData.lastErrorPage = (threadData.lastRequestUID, self._page)
|
||||||
|
|
||||||
def startElement(self, name, attrs):
|
def startElement(self, name, attrs):
|
||||||
|
if self.dbms:
|
||||||
|
return
|
||||||
|
|
||||||
if name == "dbms":
|
if name == "dbms":
|
||||||
self._dbms = attrs.get("value")
|
self._dbms = attrs.get("value")
|
||||||
|
|
||||||
elif name == "error":
|
elif name == "error":
|
||||||
if re.search(attrs.get("regexp"), self._page, re.I):
|
regexp = attrs.get("regexp")
|
||||||
|
if regexp not in kb.cache.regex:
|
||||||
|
keywords = re.findall("\w+", re.sub(r"\\.", " ", regexp))
|
||||||
|
keywords = sorted(keywords, key=len)
|
||||||
|
kb.cache.regex[regexp] = keywords[-1].lower()
|
||||||
|
|
||||||
|
if kb.cache.regex[regexp] in self._lower_page and re.search(regexp, self._page, re.I):
|
||||||
self.dbms = self._dbms
|
self.dbms = self._dbms
|
||||||
self._markAsErrorPage()
|
self._markAsErrorPage()
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ from lib.core.data import conf
|
|||||||
from lib.core.data import paths
|
from lib.core.data import paths
|
||||||
from lib.core.datatype import AttribDict
|
from lib.core.datatype import AttribDict
|
||||||
from lib.core.exception import SqlmapInstallationException
|
from lib.core.exception import SqlmapInstallationException
|
||||||
|
from lib.core.settings import PAYLOAD_XML_FILES
|
||||||
|
|
||||||
def cleanupVals(text, tag):
|
def cleanupVals(text, tag):
|
||||||
if tag in ("clause", "where"):
|
if tag in ("clause", "where"):
|
||||||
@@ -74,7 +75,7 @@ def loadBoundaries():
|
|||||||
try:
|
try:
|
||||||
doc = et.parse(paths.BOUNDARIES_XML)
|
doc = et.parse(paths.BOUNDARIES_XML)
|
||||||
except Exception, ex:
|
except Exception, ex:
|
||||||
errMsg = "something seems to be wrong with "
|
errMsg = "something appears to be wrong with "
|
||||||
errMsg += "the file '%s' ('%s'). Please make " % (paths.BOUNDARIES_XML, getSafeExString(ex))
|
errMsg += "the file '%s' ('%s'). Please make " % (paths.BOUNDARIES_XML, getSafeExString(ex))
|
||||||
errMsg += "sure that you haven't made any changes to it"
|
errMsg += "sure that you haven't made any changes to it"
|
||||||
raise SqlmapInstallationException, errMsg
|
raise SqlmapInstallationException, errMsg
|
||||||
@@ -83,16 +84,13 @@ def loadBoundaries():
|
|||||||
parseXmlNode(root)
|
parseXmlNode(root)
|
||||||
|
|
||||||
def loadPayloads():
|
def loadPayloads():
|
||||||
payloadFiles = os.listdir(paths.SQLMAP_XML_PAYLOADS_PATH)
|
for payloadFile in PAYLOAD_XML_FILES:
|
||||||
payloadFiles.sort()
|
|
||||||
|
|
||||||
for payloadFile in payloadFiles:
|
|
||||||
payloadFilePath = os.path.join(paths.SQLMAP_XML_PAYLOADS_PATH, payloadFile)
|
payloadFilePath = os.path.join(paths.SQLMAP_XML_PAYLOADS_PATH, payloadFile)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
doc = et.parse(payloadFilePath)
|
doc = et.parse(payloadFilePath)
|
||||||
except Exception, ex:
|
except Exception, ex:
|
||||||
errMsg = "something seems to be wrong with "
|
errMsg = "something appears to be wrong with "
|
||||||
errMsg += "the file '%s' ('%s'). Please make " % (payloadFilePath, getSafeExString(ex))
|
errMsg += "the file '%s' ('%s'). Please make " % (payloadFilePath, getSafeExString(ex))
|
||||||
errMsg += "sure that you haven't made any changes to it"
|
errMsg += "sure that you haven't made any changes to it"
|
||||||
raise SqlmapInstallationException, errMsg
|
raise SqlmapInstallationException, errMsg
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import StringIO
|
|||||||
import struct
|
import struct
|
||||||
import zlib
|
import zlib
|
||||||
|
|
||||||
|
from lib.core.common import Backend
|
||||||
from lib.core.common import extractErrorMessage
|
from lib.core.common import extractErrorMessage
|
||||||
from lib.core.common import extractRegexResult
|
from lib.core.common import extractRegexResult
|
||||||
from lib.core.common import getPublicTypeMembers
|
from lib.core.common import getPublicTypeMembers
|
||||||
@@ -25,6 +26,7 @@ from lib.core.common import singleTimeWarnMessage
|
|||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
|
from lib.core.enums import DBMS
|
||||||
from lib.core.enums import HTTP_HEADER
|
from lib.core.enums import HTTP_HEADER
|
||||||
from lib.core.enums import PLACE
|
from lib.core.enums import PLACE
|
||||||
from lib.core.exception import SqlmapCompressionException
|
from lib.core.exception import SqlmapCompressionException
|
||||||
@@ -34,6 +36,7 @@ from lib.core.settings import EVENTVALIDATION_REGEX
|
|||||||
from lib.core.settings import MAX_CONNECTION_TOTAL_SIZE
|
from lib.core.settings import MAX_CONNECTION_TOTAL_SIZE
|
||||||
from lib.core.settings import META_CHARSET_REGEX
|
from lib.core.settings import META_CHARSET_REGEX
|
||||||
from lib.core.settings import PARSE_HEADERS_LIMIT
|
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 UNICODE_ENCODING
|
||||||
from lib.core.settings import VIEWSTATE_REGEX
|
from lib.core.settings import VIEWSTATE_REGEX
|
||||||
from lib.parse.headers import headersParser
|
from lib.parse.headers import headersParser
|
||||||
@@ -91,7 +94,7 @@ def forgeHeaders(items=None):
|
|||||||
if cookie.domain_specified and not conf.hostname.endswith(cookie.domain):
|
if cookie.domain_specified and not conf.hostname.endswith(cookie.domain):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if ("%s=" % cookie.name) in headers[HTTP_HEADER.COOKIE]:
|
if ("%s=" % getUnicode(cookie.name)) in headers[HTTP_HEADER.COOKIE]:
|
||||||
if conf.loadCookies:
|
if conf.loadCookies:
|
||||||
conf.httpHeaders = filter(None, ((item if item[0] != HTTP_HEADER.COOKIE else None) for item in conf.httpHeaders))
|
conf.httpHeaders = filter(None, ((item if item[0] != HTTP_HEADER.COOKIE else None) for item in conf.httpHeaders))
|
||||||
elif kb.mergeCookies is None:
|
elif kb.mergeCookies is None:
|
||||||
@@ -103,7 +106,7 @@ def forgeHeaders(items=None):
|
|||||||
kb.mergeCookies = not _ or _[0] in ("y", "Y")
|
kb.mergeCookies = not _ or _[0] in ("y", "Y")
|
||||||
|
|
||||||
if kb.mergeCookies and kb.injection.place != PLACE.COOKIE:
|
if kb.mergeCookies and kb.injection.place != PLACE.COOKIE:
|
||||||
_ = lambda x: re.sub(r"(?i)\b%s=[^%s]+" % (re.escape(cookie.name), conf.cookieDel or DEFAULT_COOKIE_DELIMITER), ("%s=%s" % (cookie.name, getUnicode(cookie.value))).replace('\\', r'\\'), x)
|
_ = lambda x: re.sub(r"(?i)\b%s=[^%s]+" % (re.escape(getUnicode(cookie.name)), conf.cookieDel or DEFAULT_COOKIE_DELIMITER), ("%s=%s" % (getUnicode(cookie.name), getUnicode(cookie.value))).replace('\\', r'\\'), x)
|
||||||
headers[HTTP_HEADER.COOKIE] = _(headers[HTTP_HEADER.COOKIE])
|
headers[HTTP_HEADER.COOKIE] = _(headers[HTTP_HEADER.COOKIE])
|
||||||
|
|
||||||
if PLACE.COOKIE in conf.parameters:
|
if PLACE.COOKIE in conf.parameters:
|
||||||
@@ -112,7 +115,7 @@ def forgeHeaders(items=None):
|
|||||||
conf.httpHeaders = [(item[0], item[1] if item[0] != HTTP_HEADER.COOKIE else _(item[1])) for item in conf.httpHeaders]
|
conf.httpHeaders = [(item[0], item[1] if item[0] != HTTP_HEADER.COOKIE else _(item[1])) for item in conf.httpHeaders]
|
||||||
|
|
||||||
elif not kb.testMode:
|
elif not kb.testMode:
|
||||||
headers[HTTP_HEADER.COOKIE] += "%s %s=%s" % (conf.cookieDel or DEFAULT_COOKIE_DELIMITER, cookie.name, getUnicode(cookie.value))
|
headers[HTTP_HEADER.COOKIE] += "%s %s=%s" % (conf.cookieDel or DEFAULT_COOKIE_DELIMITER, getUnicode(cookie.name), getUnicode(cookie.value))
|
||||||
|
|
||||||
if kb.testMode and not any((conf.csrfToken, conf.safeUrl)):
|
if kb.testMode and not any((conf.csrfToken, conf.safeUrl)):
|
||||||
resetCookieJar(conf.cj)
|
resetCookieJar(conf.cj)
|
||||||
@@ -150,7 +153,7 @@ def checkCharEncoding(encoding, warn=True):
|
|||||||
return encoding
|
return encoding
|
||||||
|
|
||||||
# Reference: http://www.destructor.de/charsets/index.htm
|
# Reference: http://www.destructor.de/charsets/index.htm
|
||||||
translate = {"windows-874": "iso-8859-11", "utf-8859-1": "utf8", "en_us": "utf8", "macintosh": "iso-8859-1", "euc_tw": "big5_tw", "th": "tis-620", "unicode": "utf8", "utc8": "utf8", "ebcdic": "ebcdic-cp-be", "iso-8859": "iso8859-1", "ansi": "ascii", "gbk2312": "gbk", "windows-31j": "cp932"}
|
translate = {"windows-874": "iso-8859-11", "utf-8859-1": "utf8", "en_us": "utf8", "macintosh": "iso-8859-1", "euc_tw": "big5_tw", "th": "tis-620", "unicode": "utf8", "utc8": "utf8", "ebcdic": "ebcdic-cp-be", "iso-8859": "iso8859-1", "ansi": "ascii", "gbk2312": "gbk", "windows-31j": "cp932", "en": "us"}
|
||||||
|
|
||||||
for delimiter in (';', ',', '('):
|
for delimiter in (';', ',', '('):
|
||||||
if delimiter in encoding:
|
if delimiter in encoding:
|
||||||
@@ -258,6 +261,7 @@ def decodePage(page, contentEncoding, contentType):
|
|||||||
|
|
||||||
page = data.read()
|
page = data.read()
|
||||||
except Exception, msg:
|
except Exception, msg:
|
||||||
|
if "<html" not in page: # in some cases, invalid "Content-Encoding" appears for plain HTML (should be ignored)
|
||||||
errMsg = "detected invalid data for declared content "
|
errMsg = "detected invalid data for declared content "
|
||||||
errMsg += "encoding '%s' ('%s')" % (contentEncoding, msg)
|
errMsg += "encoding '%s' ('%s')" % (contentEncoding, msg)
|
||||||
singleTimeLogMessage(errMsg, logging.ERROR)
|
singleTimeLogMessage(errMsg, logging.ERROR)
|
||||||
@@ -330,11 +334,14 @@ def processResponse(page, responseHeaders):
|
|||||||
|
|
||||||
parseResponse(page, responseHeaders if kb.processResponseCounter < PARSE_HEADERS_LIMIT else None)
|
parseResponse(page, responseHeaders if kb.processResponseCounter < PARSE_HEADERS_LIMIT else None)
|
||||||
|
|
||||||
|
if not kb.tableFrom and Backend.getIdentifiedDbms() in (DBMS.ACCESS,):
|
||||||
|
kb.tableFrom = extractRegexResult(SELECT_FROM_TABLE_REGEX, page)
|
||||||
|
|
||||||
if conf.parseErrors:
|
if conf.parseErrors:
|
||||||
msg = extractErrorMessage(page)
|
msg = extractErrorMessage(page)
|
||||||
|
|
||||||
if msg:
|
if msg:
|
||||||
logger.warning("parsed DBMS error message: '%s'" % msg)
|
logger.warning("parsed DBMS error message: '%s'" % msg.rstrip('.'))
|
||||||
|
|
||||||
if kb.originalPage is None:
|
if kb.originalPage is None:
|
||||||
for regex in (EVENTVALIDATION_REGEX, VIEWSTATE_REGEX):
|
for regex in (EVENTVALIDATION_REGEX, VIEWSTATE_REGEX):
|
||||||
@@ -347,6 +354,16 @@ def processResponse(page, responseHeaders):
|
|||||||
conf.paramDict[PLACE.POST][name] = value
|
conf.paramDict[PLACE.POST][name] = value
|
||||||
conf.parameters[PLACE.POST] = re.sub("(?i)(%s=)[^&]+" % name, r"\g<1>%s" % value, conf.parameters[PLACE.POST])
|
conf.parameters[PLACE.POST] = re.sub("(?i)(%s=)[^&]+" % name, r"\g<1>%s" % value, conf.parameters[PLACE.POST])
|
||||||
|
|
||||||
|
if not kb.captchaDetected and re.search(r"(?i)captcha", page or ""):
|
||||||
|
for match in re.finditer(r"(?si)<form.+?</form>", page):
|
||||||
|
if re.search(r"(?i)captcha", match.group(0)):
|
||||||
|
kb.captchaDetected = True
|
||||||
|
warnMsg = "potential CAPTCHA protection mechanism detected"
|
||||||
|
if re.search(r"(?i)<title>[^<]*CloudFlare", page):
|
||||||
|
warnMsg += " (CloudFlare)"
|
||||||
|
singleTimeWarnMessage(warnMsg)
|
||||||
|
break
|
||||||
|
|
||||||
if re.search(BLOCKED_IP_REGEX, page):
|
if re.search(BLOCKED_IP_REGEX, page):
|
||||||
errMsg = "it appears that you have been blocked by the target server"
|
warnMsg = "it appears that you have been blocked by the target server"
|
||||||
singleTimeLogMessage(errMsg, logging.ERROR)
|
singleTimeWarnMessage(warnMsg)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ from lib.core.settings import DEFAULT_PAGE_ENCODING
|
|||||||
from lib.core.settings import DIFF_TOLERANCE
|
from lib.core.settings import DIFF_TOLERANCE
|
||||||
from lib.core.settings import HTML_TITLE_REGEX
|
from lib.core.settings import HTML_TITLE_REGEX
|
||||||
from lib.core.settings import MIN_RATIO
|
from lib.core.settings import MIN_RATIO
|
||||||
|
from lib.core.settings import MAX_DIFFLIB_SEQUENCE_LENGTH
|
||||||
from lib.core.settings import MAX_RATIO
|
from lib.core.settings import MAX_RATIO
|
||||||
from lib.core.settings import REFLECTED_VALUE_MARKER
|
from lib.core.settings import REFLECTED_VALUE_MARKER
|
||||||
from lib.core.settings import LOWER_RATIO_BOUND
|
from lib.core.settings import LOWER_RATIO_BOUND
|
||||||
@@ -49,12 +50,11 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
|
|||||||
if kb.testMode:
|
if kb.testMode:
|
||||||
threadData.lastComparisonHeaders = listToStrValue(headers.headers) if headers else ""
|
threadData.lastComparisonHeaders = listToStrValue(headers.headers) if headers else ""
|
||||||
threadData.lastComparisonPage = page
|
threadData.lastComparisonPage = page
|
||||||
|
threadData.lastComparisonCode = code
|
||||||
|
|
||||||
if page is None and pageLength is None:
|
if page is None and pageLength is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
count = 0
|
|
||||||
|
|
||||||
seqMatcher = threadData.seqMatcher
|
seqMatcher = threadData.seqMatcher
|
||||||
seqMatcher.set_seq1(kb.pageTemplate)
|
seqMatcher.set_seq1(kb.pageTemplate)
|
||||||
|
|
||||||
@@ -109,6 +109,13 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
|
|||||||
elif isinstance(seqMatcher.a, unicode) and isinstance(page, str):
|
elif isinstance(seqMatcher.a, unicode) and isinstance(page, str):
|
||||||
seqMatcher.a = seqMatcher.a.encode(kb.pageEncoding or DEFAULT_PAGE_ENCODING, 'ignore')
|
seqMatcher.a = seqMatcher.a.encode(kb.pageEncoding or DEFAULT_PAGE_ENCODING, 'ignore')
|
||||||
|
|
||||||
|
if seqMatcher.a and page and seqMatcher.a == page:
|
||||||
|
ratio = 1
|
||||||
|
elif kb.skipSeqMatcher or seqMatcher.a and page and any(len(_) > MAX_DIFFLIB_SEQUENCE_LENGTH for _ in (seqMatcher.a, page)):
|
||||||
|
ratio = 1.0 * len(seqMatcher.a) / len(page)
|
||||||
|
if ratio > 1:
|
||||||
|
ratio = 1. / ratio
|
||||||
|
else:
|
||||||
seq1, seq2 = None, None
|
seq1, seq2 = None, None
|
||||||
|
|
||||||
if conf.titles:
|
if conf.titles:
|
||||||
@@ -124,44 +131,15 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
|
|||||||
seq1 = seq1.replace(REFLECTED_VALUE_MARKER, "")
|
seq1 = seq1.replace(REFLECTED_VALUE_MARKER, "")
|
||||||
seq2 = seq2.replace(REFLECTED_VALUE_MARKER, "")
|
seq2 = seq2.replace(REFLECTED_VALUE_MARKER, "")
|
||||||
|
|
||||||
while count < min(len(seq1), len(seq2)):
|
|
||||||
if seq1[count] == seq2[count]:
|
|
||||||
count += 1
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
if count:
|
|
||||||
try:
|
|
||||||
_seq1 = seq1[count:]
|
|
||||||
_seq2 = seq2[count:]
|
|
||||||
except MemoryError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
seq1 = _seq1
|
|
||||||
seq2 = _seq2
|
|
||||||
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
seqMatcher.set_seq1(seq1)
|
seqMatcher.set_seq1(seq1)
|
||||||
except MemoryError:
|
|
||||||
seq1 = seq1[:len(seq1) / 1024]
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
seqMatcher.set_seq2(seq2)
|
seqMatcher.set_seq2(seq2)
|
||||||
except MemoryError:
|
|
||||||
seq2 = seq2[:len(seq2) / 1024]
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
ratio = round(seqMatcher.quick_ratio(), 3)
|
ratio = round(seqMatcher.quick_ratio(), 3)
|
||||||
|
|
||||||
# If the url is stable and we did not set yet the match ratio and the
|
# If the url is stable and we did not set yet the match ratio and the
|
||||||
# current injected value changes the url page content
|
# current injected value changes the url page content
|
||||||
if kb.matchRatio is None:
|
if kb.matchRatio is None:
|
||||||
if (count or ratio >= LOWER_RATIO_BOUND) and ratio <= UPPER_RATIO_BOUND:
|
if ratio >= LOWER_RATIO_BOUND and ratio <= UPPER_RATIO_BOUND:
|
||||||
kb.matchRatio = ratio
|
kb.matchRatio = ratio
|
||||||
logger.debug("setting match ratio for current parameter to %.3f" % kb.matchRatio)
|
logger.debug("setting match ratio for current parameter to %.3f" % kb.matchRatio)
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ from lib.core.agent import agent
|
|||||||
from lib.core.common import asciifyUrl
|
from lib.core.common import asciifyUrl
|
||||||
from lib.core.common import calculateDeltaSeconds
|
from lib.core.common import calculateDeltaSeconds
|
||||||
from lib.core.common import clearConsoleLine
|
from lib.core.common import clearConsoleLine
|
||||||
from lib.core.common import cpuThrottle
|
|
||||||
from lib.core.common import dataToStdout
|
from lib.core.common import dataToStdout
|
||||||
from lib.core.common import evaluateCode
|
from lib.core.common import evaluateCode
|
||||||
from lib.core.common import extractRegexResult
|
from lib.core.common import extractRegexResult
|
||||||
@@ -123,7 +122,10 @@ class Connect(object):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _getPageProxy(**kwargs):
|
def _getPageProxy(**kwargs):
|
||||||
|
try:
|
||||||
return Connect.getPage(**kwargs)
|
return Connect.getPage(**kwargs)
|
||||||
|
except RuntimeError:
|
||||||
|
return None, None, None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _retryProxy(**kwargs):
|
def _retryProxy(**kwargs):
|
||||||
@@ -145,7 +147,7 @@ class Connect(object):
|
|||||||
warnMsg = "most probably web server instance hasn't recovered yet "
|
warnMsg = "most probably web server instance hasn't recovered yet "
|
||||||
warnMsg += "from previous timed based payload. If the problem "
|
warnMsg += "from previous timed based payload. If the problem "
|
||||||
warnMsg += "persists please wait for few minutes and rerun "
|
warnMsg += "persists please wait for few minutes and rerun "
|
||||||
warnMsg += "without flag T in option '--technique' "
|
warnMsg += "without flag 'T' in option '--technique' "
|
||||||
warnMsg += "(e.g. '--flush-session --technique=BEUS') or try to "
|
warnMsg += "(e.g. '--flush-session --technique=BEUS') or try to "
|
||||||
warnMsg += "lower the value of option '--time-sec' (e.g. '--time-sec=2')"
|
warnMsg += "lower the value of option '--time-sec' (e.g. '--time-sec=2')"
|
||||||
singleTimeWarnMessage(warnMsg)
|
singleTimeWarnMessage(warnMsg)
|
||||||
@@ -220,8 +222,6 @@ class Connect(object):
|
|||||||
|
|
||||||
if isinstance(conf.delay, (int, float)) and conf.delay > 0:
|
if isinstance(conf.delay, (int, float)) and conf.delay > 0:
|
||||||
time.sleep(conf.delay)
|
time.sleep(conf.delay)
|
||||||
elif conf.cpuThrottle:
|
|
||||||
cpuThrottle(conf.cpuThrottle)
|
|
||||||
|
|
||||||
if conf.offline:
|
if conf.offline:
|
||||||
return None, None, None
|
return None, None, None
|
||||||
@@ -376,6 +376,9 @@ class Connect(object):
|
|||||||
if boundary:
|
if boundary:
|
||||||
headers[HTTP_HEADER.CONTENT_TYPE] = "%s; boundary=%s" % (headers[HTTP_HEADER.CONTENT_TYPE], boundary)
|
headers[HTTP_HEADER.CONTENT_TYPE] = "%s; boundary=%s" % (headers[HTTP_HEADER.CONTENT_TYPE], boundary)
|
||||||
|
|
||||||
|
if conf.keepAlive:
|
||||||
|
headers[HTTP_HEADER.CONNECTION] = "keep-alive"
|
||||||
|
|
||||||
# Reset header values to original in case of provided request file
|
# Reset header values to original in case of provided request file
|
||||||
if target and conf.requestFile:
|
if target and conf.requestFile:
|
||||||
headers = OrderedDict(conf.httpHeaders)
|
headers = OrderedDict(conf.httpHeaders)
|
||||||
@@ -443,7 +446,7 @@ class Connect(object):
|
|||||||
requestHeaders += "\n%s: %d" % (string.capwords(HTTP_HEADER.CONTENT_LENGTH), len(post))
|
requestHeaders += "\n%s: %d" % (string.capwords(HTTP_HEADER.CONTENT_LENGTH), len(post))
|
||||||
|
|
||||||
if not getRequestHeader(req, HTTP_HEADER.CONNECTION):
|
if not getRequestHeader(req, HTTP_HEADER.CONNECTION):
|
||||||
requestHeaders += "\n%s: close" % HTTP_HEADER.CONNECTION
|
requestHeaders += "\n%s: %s" % (HTTP_HEADER.CONNECTION, "close" if not conf.keepAlive else "keep-alive")
|
||||||
|
|
||||||
requestMsg += "\n%s" % requestHeaders
|
requestMsg += "\n%s" % requestHeaders
|
||||||
|
|
||||||
@@ -616,14 +619,21 @@ class Connect(object):
|
|||||||
elif "forcibly closed" in tbMsg or "Connection is already closed" in tbMsg:
|
elif "forcibly closed" in tbMsg or "Connection is already closed" in tbMsg:
|
||||||
warnMsg = "connection was forcibly closed by the target URL"
|
warnMsg = "connection was forcibly closed by the target URL"
|
||||||
elif "timed out" in tbMsg:
|
elif "timed out" in tbMsg:
|
||||||
|
if not conf.disablePrecon:
|
||||||
singleTimeWarnMessage("turning off pre-connect mechanism because of connection time out(s)")
|
singleTimeWarnMessage("turning off pre-connect mechanism because of connection time out(s)")
|
||||||
conf.disablePrecon = True
|
conf.disablePrecon = True
|
||||||
|
|
||||||
|
if kb.testMode and kb.testType not in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED):
|
||||||
|
kb.responseTimes.clear()
|
||||||
|
|
||||||
if kb.testMode and kb.testType not in (None, PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED):
|
if kb.testMode and kb.testType not in (None, PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED):
|
||||||
singleTimeWarnMessage("there is a possibility that the target (or WAF) is dropping 'suspicious' requests")
|
singleTimeWarnMessage("there is a possibility that the target (or WAF) is dropping 'suspicious' requests")
|
||||||
warnMsg = "connection timed out to the target URL"
|
warnMsg = "connection timed out to the target URL"
|
||||||
elif "URLError" in tbMsg or "error" in tbMsg:
|
elif "URLError" in tbMsg or "error" in tbMsg:
|
||||||
warnMsg = "unable to connect to the target URL"
|
warnMsg = "unable to connect to the target URL"
|
||||||
|
match = re.search(r"Errno \d+\] ([^>]+)", tbMsg)
|
||||||
|
if match:
|
||||||
|
warnMsg += " ('%s')" % match.group(1).strip()
|
||||||
elif "NTLM" in tbMsg:
|
elif "NTLM" in tbMsg:
|
||||||
warnMsg = "there has been a problem with NTLM authentication"
|
warnMsg = "there has been a problem with NTLM authentication"
|
||||||
elif "BadStatusLine" in tbMsg:
|
elif "BadStatusLine" in tbMsg:
|
||||||
@@ -642,7 +652,7 @@ class Connect(object):
|
|||||||
else:
|
else:
|
||||||
warnMsg = "unable to connect to the target URL"
|
warnMsg = "unable to connect to the target URL"
|
||||||
|
|
||||||
if "BadStatusLine" not in tbMsg:
|
if "BadStatusLine" not in tbMsg and any((conf.proxy, conf.tor)):
|
||||||
warnMsg += " or proxy"
|
warnMsg += " or proxy"
|
||||||
|
|
||||||
if silent:
|
if silent:
|
||||||
@@ -789,7 +799,18 @@ class Connect(object):
|
|||||||
value = agent.replacePayload(value, payload)
|
value = agent.replacePayload(value, payload)
|
||||||
else:
|
else:
|
||||||
# GET, POST, URI and Cookie payload needs to be thoroughly URL encoded
|
# GET, POST, URI and Cookie payload needs to be thoroughly URL encoded
|
||||||
if place in (PLACE.GET, PLACE.URI, PLACE.COOKIE) and not conf.skipUrlEncode or place in (PLACE.POST, PLACE.CUSTOM_POST) and kb.postUrlEncode:
|
if (place in (PLACE.GET, PLACE.URI, PLACE.COOKIE) or place == PLACE.CUSTOM_HEADER and value.split(',')[0] == HTTP_HEADER.COOKIE) and not conf.skipUrlEncode or place in (PLACE.POST, PLACE.CUSTOM_POST) and kb.postUrlEncode:
|
||||||
|
skip = False
|
||||||
|
|
||||||
|
if place == PLACE.COOKIE or place == PLACE.CUSTOM_HEADER and value.split(',')[0] == HTTP_HEADER.COOKIE:
|
||||||
|
if kb.cookieEncodeChoice is None:
|
||||||
|
msg = "do you want to URL encode cookie values (implementation specific)? %s" % ("[Y/n]" if not conf.url.endswith(".aspx") else "[y/N]") # Reference: https://support.microsoft.com/en-us/kb/313282
|
||||||
|
choice = readInput(msg, default='Y' if not conf.url.endswith(".aspx") else 'N')
|
||||||
|
kb.cookieEncodeChoice = choice.upper().strip() == "Y"
|
||||||
|
if not kb.cookieEncodeChoice:
|
||||||
|
skip = True
|
||||||
|
|
||||||
|
if not skip:
|
||||||
payload = urlencode(payload, '%', False, place != PLACE.URI) # spaceplus is handled down below
|
payload = urlencode(payload, '%', False, place != PLACE.URI) # spaceplus is handled down below
|
||||||
value = agent.replacePayload(value, payload)
|
value = agent.replacePayload(value, payload)
|
||||||
|
|
||||||
@@ -828,9 +849,13 @@ class Connect(object):
|
|||||||
|
|
||||||
if PLACE.GET in conf.parameters:
|
if PLACE.GET in conf.parameters:
|
||||||
get = conf.parameters[PLACE.GET] if place != PLACE.GET or not value else value
|
get = conf.parameters[PLACE.GET] if place != PLACE.GET or not value else value
|
||||||
|
elif place == PLACE.GET: # Note: for (e.g.) checkWaf() when there are no GET parameters
|
||||||
|
get = value
|
||||||
|
|
||||||
if PLACE.POST in conf.parameters:
|
if PLACE.POST in conf.parameters:
|
||||||
post = conf.parameters[PLACE.POST] if place != PLACE.POST or not value else value
|
post = conf.parameters[PLACE.POST] if place != PLACE.POST or not value else value
|
||||||
|
elif place == PLACE.POST:
|
||||||
|
post = value
|
||||||
|
|
||||||
if PLACE.CUSTOM_POST in conf.parameters:
|
if PLACE.CUSTOM_POST in conf.parameters:
|
||||||
post = conf.parameters[PLACE.CUSTOM_POST].replace(CUSTOM_INJECTION_MARK_CHAR, "") if place != PLACE.CUSTOM_POST or not value else value
|
post = conf.parameters[PLACE.CUSTOM_POST].replace(CUSTOM_INJECTION_MARK_CHAR, "") if place != PLACE.CUSTOM_POST or not value else value
|
||||||
@@ -859,15 +884,23 @@ class Connect(object):
|
|||||||
if conf.csrfToken:
|
if conf.csrfToken:
|
||||||
def _adjustParameter(paramString, parameter, newValue):
|
def _adjustParameter(paramString, parameter, newValue):
|
||||||
retVal = paramString
|
retVal = paramString
|
||||||
match = re.search("%s=(?P<value>[^&]*)" % re.escape(parameter), paramString)
|
match = re.search("%s=[^&]*" % re.escape(parameter), paramString)
|
||||||
if match:
|
if match:
|
||||||
retVal = re.sub("%s=[^&]*" % re.escape(parameter), "%s=%s" % (parameter, newValue), paramString)
|
retVal = re.sub(match.group(0), "%s=%s" % (parameter, newValue), paramString)
|
||||||
|
else:
|
||||||
|
match = re.search("(%s[\"']:[\"'])([^\"']+)" % re.escape(parameter), paramString)
|
||||||
|
if match:
|
||||||
|
retVal = re.sub(match.group(0), "%s%s" % (match.group(1), newValue), paramString)
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.data if conf.csrfUrl == conf.url else None, method=conf.method if conf.csrfUrl == conf.url else None, cookie=conf.parameters.get(PLACE.COOKIE), direct=True, silent=True, ua=conf.parameters.get(PLACE.USER_AGENT), referer=conf.parameters.get(PLACE.REFERER), host=conf.parameters.get(PLACE.HOST))
|
page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.data if conf.csrfUrl == conf.url else None, method=conf.method if conf.csrfUrl == conf.url else None, cookie=conf.parameters.get(PLACE.COOKIE), direct=True, silent=True, ua=conf.parameters.get(PLACE.USER_AGENT), referer=conf.parameters.get(PLACE.REFERER), host=conf.parameters.get(PLACE.HOST))
|
||||||
match = re.search(r"<input[^>]+name=[\"']?%s[\"']?\s[^>]*value=(\"([^\"]+)|'([^']+)|([^ >]+))" % re.escape(conf.csrfToken), page or "")
|
match = re.search(r"<input[^>]+name=[\"']?%s[\"']?\s[^>]*value=(\"([^\"]+)|'([^']+)|([^ >]+))" % re.escape(conf.csrfToken), page or "")
|
||||||
token = (match.group(2) or match.group(3) or match.group(4)) if match else None
|
token = (match.group(2) or match.group(3) or match.group(4)) if match else None
|
||||||
|
|
||||||
|
if not token:
|
||||||
|
match = re.search(r"%s[\"']:[\"']([^\"']+)" % re.escape(conf.csrfToken), page or "")
|
||||||
|
token = match.group(1) if match else None
|
||||||
|
|
||||||
if not token:
|
if not token:
|
||||||
if conf.csrfUrl != conf.url and code == httplib.OK:
|
if conf.csrfUrl != conf.url and code == httplib.OK:
|
||||||
if headers and "text/plain" in headers.get(HTTP_HEADER.CONTENT_TYPE, ""):
|
if headers and "text/plain" in headers.get(HTTP_HEADER.CONTENT_TYPE, ""):
|
||||||
@@ -959,7 +992,7 @@ class Connect(object):
|
|||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
compiler.parse(conf.evalCode.replace(';', '\n'))
|
compiler.parse(unicodeencode(conf.evalCode.replace(';', '\n')))
|
||||||
except SyntaxError, ex:
|
except SyntaxError, ex:
|
||||||
original = replacement = ex.text.strip()
|
original = replacement = ex.text.strip()
|
||||||
for _ in re.findall(r"[A-Za-z_]+", original)[::-1]:
|
for _ in re.findall(r"[A-Za-z_]+", original)[::-1]:
|
||||||
|
|||||||
@@ -284,7 +284,7 @@ def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, char
|
|||||||
|
|
||||||
outputs = _goInferenceFields(expression, expressionFields, expressionFieldsList, payload, charsetType=charsetType, firstChar=firstChar, lastChar=lastChar, dump=dump)
|
outputs = _goInferenceFields(expression, expressionFields, expressionFieldsList, payload, charsetType=charsetType, firstChar=firstChar, lastChar=lastChar, dump=dump)
|
||||||
|
|
||||||
return ", ".join(output for output in outputs) if not isNoneValue(outputs) else None
|
return ", ".join(output or "" for output in outputs) if not isNoneValue(outputs) else None
|
||||||
|
|
||||||
def _goBooleanProxy(expression):
|
def _goBooleanProxy(expression):
|
||||||
"""
|
"""
|
||||||
@@ -432,7 +432,7 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
|
|||||||
found = (value is not None) or (value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE
|
found = (value is not None) or (value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE
|
||||||
|
|
||||||
if time and (isTechniqueAvailable(PAYLOAD.TECHNIQUE.TIME) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED)) and not found:
|
if time and (isTechniqueAvailable(PAYLOAD.TECHNIQUE.TIME) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED)) and not found:
|
||||||
kb.responseTimeMode = re.sub(r"(?i)[^a-z]", "", re.sub(r"'[^']+'", "", expression)) if re.search(r"(?i)SELECT.+FROM", expression) else None
|
kb.responseTimeMode = re.sub(r"(?i)[^a-z]", "", re.sub(r"'[^']+'", "", re.sub(r"(?i)(\w+)\(.+\)", r"\g<1>", expression))) if re.search(r"(?i)SELECT.+FROM", expression) else None
|
||||||
|
|
||||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.TIME):
|
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.TIME):
|
||||||
kb.technique = PAYLOAD.TECHNIQUE.TIME
|
kb.technique = PAYLOAD.TECHNIQUE.TIME
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ See the file 'doc/COPYING' for copying permission
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
|
import socket
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from extra.icmpsh.icmpsh_m import main as icmpshmaster
|
from extra.icmpsh.icmpsh_m import main as icmpshmaster
|
||||||
@@ -54,15 +56,29 @@ class ICMPsh:
|
|||||||
if self.localIP:
|
if self.localIP:
|
||||||
message += "[Enter for '%s' (detected)] " % self.localIP
|
message += "[Enter for '%s' (detected)] " % self.localIP
|
||||||
|
|
||||||
while not address:
|
valid = None
|
||||||
address = readInput(message, default=self.localIP)
|
while not valid:
|
||||||
|
valid = True
|
||||||
|
address = readInput(message, default=self.localIP or "")
|
||||||
|
|
||||||
|
try:
|
||||||
|
socket.inet_aton(address)
|
||||||
|
except socket.error:
|
||||||
|
valid = False
|
||||||
|
finally:
|
||||||
|
valid = valid and re.search(r"\d+\.\d+\.\d+\.\d+", address) is not None
|
||||||
|
|
||||||
if conf.batch and not address:
|
if conf.batch and not address:
|
||||||
raise SqlmapDataException("local host address is missing")
|
raise SqlmapDataException("local host address is missing")
|
||||||
|
elif address and not valid:
|
||||||
|
warnMsg = "invalid local host address"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
return address
|
return address
|
||||||
|
|
||||||
def _prepareIngredients(self, encode=True):
|
def _prepareIngredients(self, encode=True):
|
||||||
|
self.localIP = getattr(self, "localIP", None)
|
||||||
|
self.remoteIP = getattr(self, "remoteIP", None)
|
||||||
self.lhostStr = ICMPsh._selectLhost(self)
|
self.lhostStr = ICMPsh._selectLhost(self)
|
||||||
self.rhostStr = ICMPsh._selectRhost(self)
|
self.rhostStr = ICMPsh._selectRhost(self)
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ See the file 'doc/COPYING' for copying permission
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import select
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
@@ -47,8 +48,6 @@ from lib.core.subprocessng import recv_some
|
|||||||
|
|
||||||
if IS_WIN:
|
if IS_WIN:
|
||||||
import msvcrt
|
import msvcrt
|
||||||
else:
|
|
||||||
from select import select
|
|
||||||
|
|
||||||
class Metasploit:
|
class Metasploit:
|
||||||
"""
|
"""
|
||||||
@@ -550,7 +549,7 @@ class Metasploit:
|
|||||||
# Probably the child has exited
|
# Probably the child has exited
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
ready_fds = select([stdin_fd], [], [], 1)
|
ready_fds = select.select([stdin_fd], [], [], 1)
|
||||||
|
|
||||||
if stdin_fd in ready_fds[0]:
|
if stdin_fd in ready_fds[0]:
|
||||||
try:
|
try:
|
||||||
@@ -598,7 +597,7 @@ class Metasploit:
|
|||||||
else:
|
else:
|
||||||
proc.kill()
|
proc.kill()
|
||||||
|
|
||||||
except (EOFError, IOError):
|
except (EOFError, IOError, select.error):
|
||||||
return proc.returncode
|
return proc.returncode
|
||||||
|
|
||||||
def createMsfShellcode(self, exitfunc, format, extra, encode):
|
def createMsfShellcode(self, exitfunc, format, extra, encode):
|
||||||
|
|||||||
@@ -217,8 +217,6 @@ class Web:
|
|||||||
|
|
||||||
if not isWindowsDriveLetterPath(directory) and not directory.startswith('/'):
|
if not isWindowsDriveLetterPath(directory) and not directory.startswith('/'):
|
||||||
directory = "/%s" % directory
|
directory = "/%s" % directory
|
||||||
else:
|
|
||||||
directory = directory[2:] if isWindowsDriveLetterPath(directory) else directory
|
|
||||||
|
|
||||||
if not directory.endswith('/'):
|
if not directory.endswith('/'):
|
||||||
directory += '/'
|
directory += '/'
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class Xp_cmdshell:
|
|||||||
def _xpCmdshellCreate(self):
|
def _xpCmdshellCreate(self):
|
||||||
cmd = ""
|
cmd = ""
|
||||||
|
|
||||||
if Backend.isVersionWithin(("2005", "2008", "2012")):
|
if not Backend.isVersionWithin(("2000",)):
|
||||||
logger.debug("activating sp_OACreate")
|
logger.debug("activating sp_OACreate")
|
||||||
|
|
||||||
cmd = getSQLSnippet(DBMS.MSSQL, "activate_sp_oacreate")
|
cmd = getSQLSnippet(DBMS.MSSQL, "activate_sp_oacreate")
|
||||||
@@ -56,7 +56,7 @@ class Xp_cmdshell:
|
|||||||
|
|
||||||
cmd = getSQLSnippet(DBMS.MSSQL, "create_new_xp_cmdshell", RANDSTR=self._randStr)
|
cmd = getSQLSnippet(DBMS.MSSQL, "create_new_xp_cmdshell", RANDSTR=self._randStr)
|
||||||
|
|
||||||
if Backend.isVersionWithin(("2005", "2008")):
|
if not Backend.isVersionWithin(("2000",)):
|
||||||
cmd += ";RECONFIGURE WITH OVERRIDE"
|
cmd += ";RECONFIGURE WITH OVERRIDE"
|
||||||
|
|
||||||
inject.goStacked(agent.runAsDBMSUser(cmd))
|
inject.goStacked(agent.runAsDBMSUser(cmd))
|
||||||
@@ -83,10 +83,10 @@ class Xp_cmdshell:
|
|||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
def _xpCmdshellConfigure(self, mode):
|
def _xpCmdshellConfigure(self, mode):
|
||||||
if Backend.isVersionWithin(("2005", "2008")):
|
if Backend.isVersionWithin(("2000",)):
|
||||||
cmd = self._xpCmdshellConfigure2005(mode)
|
|
||||||
else:
|
|
||||||
cmd = self._xpCmdshellConfigure2000(mode)
|
cmd = self._xpCmdshellConfigure2000(mode)
|
||||||
|
else:
|
||||||
|
cmd = self._xpCmdshellConfigure2005(mode)
|
||||||
|
|
||||||
inject.goStacked(agent.runAsDBMSUser(cmd))
|
inject.goStacked(agent.runAsDBMSUser(cmd))
|
||||||
|
|
||||||
@@ -111,8 +111,8 @@ class Xp_cmdshell:
|
|||||||
errMsg += "storing console output within the back-end file system "
|
errMsg += "storing console output within the back-end file system "
|
||||||
errMsg += "does not have writing permissions for the DBMS process. "
|
errMsg += "does not have writing permissions for the DBMS process. "
|
||||||
errMsg += "You are advised to manually adjust it with option "
|
errMsg += "You are advised to manually adjust it with option "
|
||||||
errMsg += "--tmp-path switch or you will not be able to retrieve "
|
errMsg += "'--tmp-path' or you won't be able to retrieve "
|
||||||
errMsg += "the commands output"
|
errMsg += "the command(s) output"
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
elif isNoneValue(output):
|
elif isNoneValue(output):
|
||||||
logger.error("unable to retrieve xp_cmdshell output")
|
logger.error("unable to retrieve xp_cmdshell output")
|
||||||
|
|||||||
@@ -5,11 +5,9 @@ Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
|||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from extra.safe2bin.safe2bin import safechardecode
|
|
||||||
from extra.safe2bin.safe2bin import safecharencode
|
from extra.safe2bin.safe2bin import safecharencode
|
||||||
from lib.core.agent import agent
|
from lib.core.agent import agent
|
||||||
from lib.core.common import Backend
|
from lib.core.common import Backend
|
||||||
@@ -20,13 +18,11 @@ from lib.core.common import decodeIntToUnicode
|
|||||||
from lib.core.common import filterControlChars
|
from lib.core.common import filterControlChars
|
||||||
from lib.core.common import getCharset
|
from lib.core.common import getCharset
|
||||||
from lib.core.common import getCounter
|
from lib.core.common import getCounter
|
||||||
from lib.core.common import getUnicode
|
|
||||||
from lib.core.common import goGoodSamaritan
|
from lib.core.common import goGoodSamaritan
|
||||||
from lib.core.common import getPartRun
|
from lib.core.common import getPartRun
|
||||||
from lib.core.common import hashDBRetrieve
|
from lib.core.common import hashDBRetrieve
|
||||||
from lib.core.common import hashDBWrite
|
from lib.core.common import hashDBWrite
|
||||||
from lib.core.common import incrementCounter
|
from lib.core.common import incrementCounter
|
||||||
from lib.core.common import randomInt
|
|
||||||
from lib.core.common import safeStringFormat
|
from lib.core.common import safeStringFormat
|
||||||
from lib.core.common import singleTimeWarnMessage
|
from lib.core.common import singleTimeWarnMessage
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
@@ -44,7 +40,6 @@ from lib.core.settings import INFERENCE_UNKNOWN_CHAR
|
|||||||
from lib.core.settings import INFERENCE_GREATER_CHAR
|
from lib.core.settings import INFERENCE_GREATER_CHAR
|
||||||
from lib.core.settings import INFERENCE_EQUALS_CHAR
|
from lib.core.settings import INFERENCE_EQUALS_CHAR
|
||||||
from lib.core.settings import INFERENCE_NOT_EQUALS_CHAR
|
from lib.core.settings import INFERENCE_NOT_EQUALS_CHAR
|
||||||
from lib.core.settings import MIN_TIME_RESPONSES
|
|
||||||
from lib.core.settings import MAX_BISECTION_LENGTH
|
from lib.core.settings import MAX_BISECTION_LENGTH
|
||||||
from lib.core.settings import MAX_TIME_REVALIDATION_STEPS
|
from lib.core.settings import MAX_TIME_REVALIDATION_STEPS
|
||||||
from lib.core.settings import NULL
|
from lib.core.settings import NULL
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ from lib.core.common import calculateDeltaSeconds
|
|||||||
from lib.core.common import dataToStdout
|
from lib.core.common import dataToStdout
|
||||||
from lib.core.common import decodeHexValue
|
from lib.core.common import decodeHexValue
|
||||||
from lib.core.common import extractRegexResult
|
from lib.core.common import extractRegexResult
|
||||||
|
from lib.core.common import getConsoleWidth
|
||||||
from lib.core.common import getPartRun
|
from lib.core.common import getPartRun
|
||||||
from lib.core.common import getUnicode
|
from lib.core.common import getUnicode
|
||||||
from lib.core.common import hashDBRetrieve
|
from lib.core.common import hashDBRetrieve
|
||||||
@@ -43,6 +44,7 @@ from lib.core.settings import MIN_ERROR_CHUNK_LENGTH
|
|||||||
from lib.core.settings import MAX_ERROR_CHUNK_LENGTH
|
from lib.core.settings import MAX_ERROR_CHUNK_LENGTH
|
||||||
from lib.core.settings import NULL
|
from lib.core.settings import NULL
|
||||||
from lib.core.settings import PARTIAL_VALUE_MARKER
|
from lib.core.settings import PARTIAL_VALUE_MARKER
|
||||||
|
from lib.core.settings import ROTATING_CHARS
|
||||||
from lib.core.settings import SLOW_ORDER_COUNT_THRESHOLD
|
from lib.core.settings import SLOW_ORDER_COUNT_THRESHOLD
|
||||||
from lib.core.settings import SQL_SCALAR_REGEX
|
from lib.core.settings import SQL_SCALAR_REGEX
|
||||||
from lib.core.settings import TURN_OFF_RESUME_INFO_LIMIT
|
from lib.core.settings import TURN_OFF_RESUME_INFO_LIMIT
|
||||||
@@ -54,6 +56,7 @@ from lib.utils.progress import ProgressBar
|
|||||||
|
|
||||||
def _oneShotErrorUse(expression, field=None, chunkTest=False):
|
def _oneShotErrorUse(expression, field=None, chunkTest=False):
|
||||||
offset = 1
|
offset = 1
|
||||||
|
rotator = 0
|
||||||
partialValue = None
|
partialValue = None
|
||||||
threadData = getCurrentThreadData()
|
threadData = getCurrentThreadData()
|
||||||
retVal = hashDBRetrieve(expression, checkConf=True)
|
retVal = hashDBRetrieve(expression, checkConf=True)
|
||||||
@@ -173,8 +176,16 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False):
|
|||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
if kb.fileReadMode and output:
|
if output:
|
||||||
|
if kb.fileReadMode:
|
||||||
dataToStdout(_formatPartialContent(output).replace(r"\n", "\n").replace(r"\t", "\t"))
|
dataToStdout(_formatPartialContent(output).replace(r"\n", "\n").replace(r"\t", "\t"))
|
||||||
|
elif offset > 1:
|
||||||
|
rotator += 1
|
||||||
|
|
||||||
|
if rotator >= len(ROTATING_CHARS):
|
||||||
|
rotator = 0
|
||||||
|
|
||||||
|
dataToStdout("\r%s\r" % ROTATING_CHARS[rotator])
|
||||||
else:
|
else:
|
||||||
retVal = output
|
retVal = output
|
||||||
break
|
break
|
||||||
@@ -203,6 +214,7 @@ def _errorFields(expression, expressionFields, expressionFieldsList, num=None, e
|
|||||||
values = []
|
values = []
|
||||||
origExpr = None
|
origExpr = None
|
||||||
|
|
||||||
|
width = getConsoleWidth()
|
||||||
threadData = getCurrentThreadData()
|
threadData = getCurrentThreadData()
|
||||||
|
|
||||||
for field in expressionFieldsList:
|
for field in expressionFieldsList:
|
||||||
@@ -229,7 +241,12 @@ def _errorFields(expression, expressionFields, expressionFieldsList, num=None, e
|
|||||||
if kb.fileReadMode and output and output.strip():
|
if kb.fileReadMode and output and output.strip():
|
||||||
print
|
print
|
||||||
elif output is not None and not (threadData.resumed and kb.suppressResumeInfo) and not (emptyFields and field in emptyFields):
|
elif output is not None and not (threadData.resumed and kb.suppressResumeInfo) and not (emptyFields and field in emptyFields):
|
||||||
dataToStdout("[%s] [INFO] %s: %s\n" % (time.strftime("%X"), "resumed" if threadData.resumed else "retrieved", safecharencode(output)))
|
status = "[%s] [INFO] %s: %s" % (time.strftime("%X"), "resumed" if threadData.resumed else "retrieved", output if kb.safeCharEncode else safecharencode(output))
|
||||||
|
|
||||||
|
if len(status) > width:
|
||||||
|
status = "%s..." % status[:width - 3]
|
||||||
|
|
||||||
|
dataToStdout("%s\n" % status)
|
||||||
|
|
||||||
if isinstance(num, int):
|
if isinstance(num, int):
|
||||||
expression = origExpr
|
expression = origExpr
|
||||||
|
|||||||
@@ -53,10 +53,10 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
|
|||||||
query = agent.suffixQuery(query, suffix=suffix, comment=comment)
|
query = agent.suffixQuery(query, suffix=suffix, comment=comment)
|
||||||
payload = agent.payload(newValue=query, place=place, parameter=parameter, where=where)
|
payload = agent.payload(newValue=query, place=place, parameter=parameter, where=where)
|
||||||
page, headers = Request.queryPage(payload, place=place, content=True, raise404=False)
|
page, headers = Request.queryPage(payload, place=place, content=True, raise404=False)
|
||||||
return not re.search(r"(warning|error|order by|failed)", page or "", re.I) and comparison(page, headers) or re.search(r"data types cannot be compared or sorted", page or "", re.I)
|
return not any(re.search(_, page or "", re.I) and not re.search(_, kb.pageTemplate or "", re.I) for _ in ("(warning|error):", "order by", "unknown column", "failed")) and comparison(page, headers) or re.search(r"data types cannot be compared or sorted", page or "", re.I)
|
||||||
|
|
||||||
if _orderByTest(1) and not _orderByTest(randomInt()):
|
if _orderByTest(1) and not _orderByTest(randomInt()):
|
||||||
infoMsg = "ORDER BY technique seems to be usable. "
|
infoMsg = "'ORDER BY' technique appears to be usable. "
|
||||||
infoMsg += "This should reduce the time needed "
|
infoMsg += "This should reduce the time needed "
|
||||||
infoMsg += "to find the right number "
|
infoMsg += "to find the right number "
|
||||||
infoMsg += "of query columns. Automatically extending the "
|
infoMsg += "of query columns. Automatically extending the "
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
|||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import binascii
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
|
import xml.etree.ElementTree
|
||||||
|
|
||||||
from extra.safe2bin.safe2bin import safecharencode
|
from extra.safe2bin.safe2bin import safecharencode
|
||||||
from lib.core.agent import agent
|
from lib.core.agent import agent
|
||||||
@@ -46,8 +48,10 @@ from lib.core.enums import PAYLOAD
|
|||||||
from lib.core.exception import SqlmapDataException
|
from lib.core.exception import SqlmapDataException
|
||||||
from lib.core.exception import SqlmapSyntaxException
|
from lib.core.exception import SqlmapSyntaxException
|
||||||
from lib.core.settings import MAX_BUFFERED_PARTIAL_UNION_LENGTH
|
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 SQL_SCALAR_REGEX
|
||||||
from lib.core.settings import TURN_OFF_RESUME_INFO_LIMIT
|
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 getCurrentThreadData
|
||||||
from lib.core.threads import runThreads
|
from lib.core.threads import runThreads
|
||||||
from lib.core.unescaper import unescaper
|
from lib.core.unescaper import unescaper
|
||||||
@@ -62,15 +66,18 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
|
|||||||
threadData.resumed = retVal is not None
|
threadData.resumed = retVal is not None
|
||||||
|
|
||||||
if retVal is None:
|
if retVal is None:
|
||||||
# Prepare expression with delimiters
|
|
||||||
injExpression = unescaper.escape(agent.concatQuery(expression, unpack))
|
|
||||||
|
|
||||||
# Forge the UNION SQL injection request
|
|
||||||
vector = kb.injection.data[PAYLOAD.TECHNIQUE.UNION].vector
|
vector = kb.injection.data[PAYLOAD.TECHNIQUE.UNION].vector
|
||||||
|
|
||||||
|
if not kb.rowXmlMode:
|
||||||
|
injExpression = unescaper.escape(agent.concatQuery(expression, unpack))
|
||||||
kb.unionDuplicates = vector[7]
|
kb.unionDuplicates = vector[7]
|
||||||
kb.forcePartialUnion = vector[8]
|
kb.forcePartialUnion = vector[8]
|
||||||
query = agent.forgeUnionQuery(injExpression, vector[0], vector[1], vector[2], vector[3], vector[4], vector[5], vector[6], None, limited)
|
query = agent.forgeUnionQuery(injExpression, vector[0], vector[1], vector[2], vector[3], vector[4], vector[5], vector[6], None, limited)
|
||||||
where = PAYLOAD.WHERE.NEGATIVE if conf.limitStart or conf.limitStop else vector[6]
|
where = PAYLOAD.WHERE.NEGATIVE if conf.limitStart or conf.limitStop else vector[6]
|
||||||
|
else:
|
||||||
|
where = vector[6]
|
||||||
|
query = agent.forgeUnionQuery(expression, vector[0], vector[1], vector[2], vector[3], vector[4], vector[5], vector[6], None, False)
|
||||||
|
|
||||||
payload = agent.payload(newValue=query, where=where)
|
payload = agent.payload(newValue=query, where=where)
|
||||||
|
|
||||||
# Perform the request
|
# Perform the request
|
||||||
@@ -78,6 +85,7 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
|
|||||||
|
|
||||||
incrementCounter(PAYLOAD.TECHNIQUE.UNION)
|
incrementCounter(PAYLOAD.TECHNIQUE.UNION)
|
||||||
|
|
||||||
|
if not kb.rowXmlMode:
|
||||||
# Parse the returned page to get the exact UNION-based
|
# Parse the returned page to get the exact UNION-based
|
||||||
# SQL injection output
|
# SQL injection output
|
||||||
def _(regex):
|
def _(regex):
|
||||||
@@ -94,6 +102,40 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
|
|||||||
page = page.replace(kb.chars.stop[:-1], kb.chars.stop)
|
page = page.replace(kb.chars.stop[:-1], kb.chars.stop)
|
||||||
|
|
||||||
retVal = _("(?P<result>%s.*%s)" % (kb.chars.start, kb.chars.stop))
|
retVal = _("(?P<result>%s.*%s)" % (kb.chars.start, kb.chars.stop))
|
||||||
|
else:
|
||||||
|
output = extractRegexResult(r"(?P<result>(<row.+?/>)+)", page)
|
||||||
|
if output:
|
||||||
|
try:
|
||||||
|
root = xml.etree.ElementTree.fromstring("<root>%s</root>" % output.encode(UNICODE_ENCODING))
|
||||||
|
retVal = ""
|
||||||
|
for column in kb.dumpColumns:
|
||||||
|
base64 = True
|
||||||
|
for child in root:
|
||||||
|
value = child.attrib.get(column, "").strip()
|
||||||
|
if value and not re.match(r"\A[a-zA-Z0-9+/]+={0,2}\Z", value):
|
||||||
|
base64 = False
|
||||||
|
break
|
||||||
|
|
||||||
|
try:
|
||||||
|
value.decode("base64")
|
||||||
|
except binascii.Error:
|
||||||
|
base64 = False
|
||||||
|
break
|
||||||
|
|
||||||
|
if base64:
|
||||||
|
for child in root:
|
||||||
|
child.attrib[column] = child.attrib.get(column, "").decode("base64") or NULL
|
||||||
|
|
||||||
|
for child in root:
|
||||||
|
row = []
|
||||||
|
for column in kb.dumpColumns:
|
||||||
|
row.append(child.attrib.get(column, NULL))
|
||||||
|
retVal += "%s%s%s" % (kb.chars.start, kb.chars.delimiter.join(row), kb.chars.stop)
|
||||||
|
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
retVal = getUnicode(retVal)
|
||||||
|
|
||||||
if retVal is not None:
|
if retVal is not None:
|
||||||
retVal = getUnicode(retVal, kb.pageEncoding)
|
retVal = getUnicode(retVal, kb.pageEncoding)
|
||||||
@@ -103,7 +145,8 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
|
|||||||
retVal = htmlunescape(retVal).replace("<br>", "\n")
|
retVal = htmlunescape(retVal).replace("<br>", "\n")
|
||||||
|
|
||||||
hashDBWrite("%s%s" % (conf.hexConvert or False, expression), retVal)
|
hashDBWrite("%s%s" % (conf.hexConvert or False, expression), retVal)
|
||||||
else:
|
|
||||||
|
elif not kb.rowXmlMode:
|
||||||
trimmed = _("%s(?P<result>.*?)<" % (kb.chars.start))
|
trimmed = _("%s(?P<result>.*?)<" % (kb.chars.start))
|
||||||
|
|
||||||
if trimmed:
|
if trimmed:
|
||||||
@@ -174,6 +217,13 @@ def unionUse(expression, unpack=True, dump=False):
|
|||||||
# Set kb.partRun in case the engine is called from the API
|
# Set kb.partRun in case the engine is called from the API
|
||||||
kb.partRun = getPartRun(alias=False) if hasattr(conf, "api") else None
|
kb.partRun = getPartRun(alias=False) if hasattr(conf, "api") else None
|
||||||
|
|
||||||
|
if Backend.isDbms(DBMS.MSSQL) and kb.dumpColumns:
|
||||||
|
kb.rowXmlMode = True
|
||||||
|
_ = "(%s FOR XML RAW, BINARY BASE64)" % expression
|
||||||
|
output = _oneShotUnionUse(_, False)
|
||||||
|
value = parseUnionPage(output)
|
||||||
|
kb.rowXmlMode = False
|
||||||
|
|
||||||
if expressionFieldsList and len(expressionFieldsList) > 1 and "ORDER BY" in expression.upper():
|
if expressionFieldsList and len(expressionFieldsList) > 1 and "ORDER BY" in expression.upper():
|
||||||
# Removed ORDER BY clause because UNION does not play well with it
|
# Removed ORDER BY clause because UNION does not play well with it
|
||||||
expression = re.sub("\s*ORDER BY\s+[\w,]+", "", expression, re.I)
|
expression = re.sub("\s*ORDER BY\s+[\w,]+", "", expression, re.I)
|
||||||
@@ -186,7 +236,7 @@ def unionUse(expression, unpack=True, dump=False):
|
|||||||
# SQL limiting the query output one entry at a time
|
# SQL limiting the query output one entry at a time
|
||||||
# NOTE: we assume that only queries that get data from a table can
|
# NOTE: we assume that only queries that get data from a table can
|
||||||
# return multiple entries
|
# return multiple entries
|
||||||
if (kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.NEGATIVE or \
|
if value is None and (kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.NEGATIVE or \
|
||||||
kb.forcePartialUnion or \
|
kb.forcePartialUnion or \
|
||||||
(dump and (conf.limitStart or conf.limitStop)) or "LIMIT " in expression.upper()) and \
|
(dump and (conf.limitStart or conf.limitStop)) or "LIMIT " in expression.upper()) and \
|
||||||
" FROM " in expression.upper() and ((Backend.getIdentifiedDbms() \
|
" FROM " in expression.upper() and ((Backend.getIdentifiedDbms() \
|
||||||
@@ -328,12 +378,13 @@ def unionUse(expression, unpack=True, dump=False):
|
|||||||
del threadData.shared.buffered[0]
|
del threadData.shared.buffered[0]
|
||||||
|
|
||||||
if conf.verbose == 1 and not (threadData.resumed and kb.suppressResumeInfo) and not threadData.shared.showEta:
|
if conf.verbose == 1 and not (threadData.resumed and kb.suppressResumeInfo) and not threadData.shared.showEta:
|
||||||
status = "[%s] [INFO] %s: %s" % (time.strftime("%X"), "resumed" if threadData.resumed else "retrieved", safecharencode(",".join("\"%s\"" % _ for _ in flattenValue(arrayizeValue(items))) if not isinstance(items, basestring) else items))
|
_ = ",".join("\"%s\"" % _ for _ in flattenValue(arrayizeValue(items))) if not isinstance(items, basestring) else items
|
||||||
|
status = "[%s] [INFO] %s: %s" % (time.strftime("%X"), "resumed" if threadData.resumed else "retrieved", _ if kb.safeCharEncode else safecharencode(_))
|
||||||
|
|
||||||
if len(status) > width:
|
if len(status) > width:
|
||||||
status = "%s..." % status[:width - 3]
|
status = "%s..." % status[:width - 3]
|
||||||
|
|
||||||
dataToStdout("%s\n" % status, True)
|
dataToStdout("%s\n" % status)
|
||||||
|
|
||||||
runThreads(numThreads, unionThread)
|
runThreads(numThreads, unionThread)
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ from lib.core.data import logger
|
|||||||
from lib.core.datatype import AttribDict
|
from lib.core.datatype import AttribDict
|
||||||
from lib.core.defaults import _defaults
|
from lib.core.defaults import _defaults
|
||||||
from lib.core.enums import CONTENT_STATUS
|
from lib.core.enums import CONTENT_STATUS
|
||||||
|
from lib.core.enums import MKSTEMP_PREFIX
|
||||||
from lib.core.enums import PART_RUN_CONTENT_TYPES
|
from lib.core.enums import PART_RUN_CONTENT_TYPES
|
||||||
from lib.core.exception import SqlmapConnectionException
|
from lib.core.exception import SqlmapConnectionException
|
||||||
from lib.core.log import LOGGER_HANDLER
|
from lib.core.log import LOGGER_HANDLER
|
||||||
@@ -643,7 +644,7 @@ def server(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, adapter=REST
|
|||||||
REST-JSON API server
|
REST-JSON API server
|
||||||
"""
|
"""
|
||||||
DataStore.admin_id = hexencode(os.urandom(16))
|
DataStore.admin_id = hexencode(os.urandom(16))
|
||||||
Database.filepath = tempfile.mkstemp(prefix="sqlmapipc-", text=False)[1]
|
Database.filepath = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.IPC, text=False)[1]
|
||||||
|
|
||||||
logger.info("Running REST-JSON API server at '%s:%d'.." % (host, port))
|
logger.info("Running REST-JSON API server at '%s:%d'.." % (host, port))
|
||||||
logger.info("Admin ID: %s" % DataStore.admin_id)
|
logger.info("Admin ID: %s" % DataStore.admin_id)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ from lib.core.common import safeCSValue
|
|||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
|
from lib.core.enums import MKSTEMP_PREFIX
|
||||||
from lib.core.exception import SqlmapConnectionException
|
from lib.core.exception import SqlmapConnectionException
|
||||||
from lib.core.exception import SqlmapSyntaxException
|
from lib.core.exception import SqlmapSyntaxException
|
||||||
from lib.core.settings import CRAWL_EXCLUDE_EXTENSIONS
|
from lib.core.settings import CRAWL_EXCLUDE_EXTENSIONS
|
||||||
@@ -198,7 +199,7 @@ def storeResultsToFile(results):
|
|||||||
kb.storeCrawlingChoice = test[0] in ("y", "Y")
|
kb.storeCrawlingChoice = test[0] in ("y", "Y")
|
||||||
|
|
||||||
if kb.storeCrawlingChoice:
|
if kb.storeCrawlingChoice:
|
||||||
handle, filename = tempfile.mkstemp(prefix="sqlmapcrawling-", suffix=".csv" if conf.forms else ".txt")
|
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.CRAWLER, suffix=".csv" if conf.forms else ".txt")
|
||||||
os.close(handle)
|
os.close(handle)
|
||||||
|
|
||||||
infoMsg = "writing crawling results to a temporary file '%s' " % filename
|
infoMsg = "writing crawling results to a temporary file '%s' " % filename
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import os
|
|||||||
import re
|
import re
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
|
import zipfile
|
||||||
|
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
from hashlib import sha1
|
from hashlib import sha1
|
||||||
@@ -45,6 +46,7 @@ from lib.core.common import dataToStdout
|
|||||||
from lib.core.common import getFileItems
|
from lib.core.common import getFileItems
|
||||||
from lib.core.common import getPublicTypeMembers
|
from lib.core.common import getPublicTypeMembers
|
||||||
from lib.core.common import getSafeExString
|
from lib.core.common import getSafeExString
|
||||||
|
from lib.core.common import getUnicode
|
||||||
from lib.core.common import hashDBRetrieve
|
from lib.core.common import hashDBRetrieve
|
||||||
from lib.core.common import hashDBWrite
|
from lib.core.common import hashDBWrite
|
||||||
from lib.core.common import normalizeUnicode
|
from lib.core.common import normalizeUnicode
|
||||||
@@ -60,6 +62,8 @@ from lib.core.data import kb
|
|||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.core.enums import DBMS
|
from lib.core.enums import DBMS
|
||||||
from lib.core.enums import HASH
|
from lib.core.enums import HASH
|
||||||
|
from lib.core.enums import MKSTEMP_PREFIX
|
||||||
|
from lib.core.exception import SqlmapDataException
|
||||||
from lib.core.exception import SqlmapUserQuitException
|
from lib.core.exception import SqlmapUserQuitException
|
||||||
from lib.core.settings import COMMON_PASSWORD_SUFFIXES
|
from lib.core.settings import COMMON_PASSWORD_SUFFIXES
|
||||||
from lib.core.settings import COMMON_USER_COLUMNS
|
from lib.core.settings import COMMON_USER_COLUMNS
|
||||||
@@ -384,7 +388,7 @@ def storeHashesToFile(attack_dict):
|
|||||||
if not kb.storeHashesChoice:
|
if not kb.storeHashesChoice:
|
||||||
return
|
return
|
||||||
|
|
||||||
handle, filename = tempfile.mkstemp(prefix="sqlmaphashes-", suffix=".txt")
|
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.HASHES, suffix=".txt")
|
||||||
os.close(handle)
|
os.close(handle)
|
||||||
|
|
||||||
infoMsg = "writing hashes to a temporary file '%s' " % filename
|
infoMsg = "writing hashes to a temporary file '%s' " % filename
|
||||||
@@ -501,7 +505,7 @@ def attackDumpedTable():
|
|||||||
value = table[column]['values'][i]
|
value = table[column]['values'][i]
|
||||||
|
|
||||||
if value and value.lower() in lut:
|
if value and value.lower() in lut:
|
||||||
table[column]['values'][i] += " (%s)" % lut[value.lower()]
|
table[column]['values'][i] = "%s (%s)" % (getUnicode(table[column]['values'][i]), getUnicode(lut[value.lower()]))
|
||||||
table[column]['length'] = max(table[column]['length'], len(table[column]['values'][i]))
|
table[column]['length'] = max(table[column]['length'], len(table[column]['values'][i]))
|
||||||
|
|
||||||
def hashRecognition(value):
|
def hashRecognition(value):
|
||||||
@@ -785,6 +789,14 @@ def dictionaryAttack(attack_dict):
|
|||||||
for dictPath in dictPaths:
|
for dictPath in dictPaths:
|
||||||
checkFile(dictPath)
|
checkFile(dictPath)
|
||||||
|
|
||||||
|
if os.path.splitext(dictPath)[1].lower() == ".zip":
|
||||||
|
_ = zipfile.ZipFile(dictPath, 'r')
|
||||||
|
if len(_.namelist()) == 0:
|
||||||
|
errMsg = "no file(s) inside '%s'" % dictPath
|
||||||
|
raise SqlmapDataException(errMsg)
|
||||||
|
else:
|
||||||
|
_.open(_.namelist()[0])
|
||||||
|
|
||||||
kb.wordlists = dictPaths
|
kb.wordlists = dictPaths
|
||||||
|
|
||||||
except Exception, ex:
|
except Exception, ex:
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class HashDB(object):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def hashKey(key):
|
def hashKey(key):
|
||||||
key = key.encode(UNICODE_ENCODING) if isinstance(key, unicode) else repr(key)
|
key = key.encode(UNICODE_ENCODING) if isinstance(key, unicode) else repr(key)
|
||||||
retVal = int(hashlib.md5(key).hexdigest()[:12], 16)
|
retVal = int(hashlib.md5(key).hexdigest(), 16) & 0x7fffffffffffffff # Reference: http://stackoverflow.com/a/4448400
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def retrieve(self, key, unserialize=False):
|
def retrieve(self, key, unserialize=False):
|
||||||
|
|||||||
@@ -11,14 +11,17 @@ from extra.safe2bin.safe2bin import safechardecode
|
|||||||
from lib.core.agent import agent
|
from lib.core.agent import agent
|
||||||
from lib.core.bigarray import BigArray
|
from lib.core.bigarray import BigArray
|
||||||
from lib.core.common import Backend
|
from lib.core.common import Backend
|
||||||
|
from lib.core.common import getUnicode
|
||||||
from lib.core.common import isNoneValue
|
from lib.core.common import isNoneValue
|
||||||
from lib.core.common import isNumPosStrValue
|
from lib.core.common import isNumPosStrValue
|
||||||
from lib.core.common import singleTimeWarnMessage
|
from lib.core.common import singleTimeWarnMessage
|
||||||
from lib.core.common import unArrayizeValue
|
from lib.core.common import unArrayizeValue
|
||||||
from lib.core.common import unsafeSQLIdentificatorNaming
|
from lib.core.common import unsafeSQLIdentificatorNaming
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.core.data import queries
|
from lib.core.data import queries
|
||||||
|
from lib.core.dicts import DUMP_REPLACEMENTS
|
||||||
from lib.core.enums import CHARSET_TYPE
|
from lib.core.enums import CHARSET_TYPE
|
||||||
from lib.core.enums import EXPECTED
|
from lib.core.enums import EXPECTED
|
||||||
from lib.core.exception import SqlmapConnectionException
|
from lib.core.exception import SqlmapConnectionException
|
||||||
@@ -134,10 +137,13 @@ def pivotDumpTable(table, colList, count=None, blind=True):
|
|||||||
value = _(column, pivotValue)
|
value = _(column, pivotValue)
|
||||||
if column == colList[0]:
|
if column == colList[0]:
|
||||||
if isNoneValue(value):
|
if isNoneValue(value):
|
||||||
|
try:
|
||||||
for pivotValue in filter(None, (" " if pivotValue == " " else None, "%s%s" % (pivotValue[0], unichr(ord(pivotValue[1]) + 1)) if len(pivotValue) > 1 else None, unichr(ord(pivotValue[0]) + 1))):
|
for pivotValue in filter(None, (" " if pivotValue == " " else None, "%s%s" % (pivotValue[0], unichr(ord(pivotValue[1]) + 1)) if len(pivotValue) > 1 else None, unichr(ord(pivotValue[0]) + 1))):
|
||||||
value = _(column, pivotValue)
|
value = _(column, pivotValue)
|
||||||
if not isNoneValue(value):
|
if not isNoneValue(value):
|
||||||
break
|
break
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
if isNoneValue(value):
|
if isNoneValue(value):
|
||||||
breakRetrieval = True
|
breakRetrieval = True
|
||||||
@@ -156,10 +162,12 @@ def pivotDumpTable(table, colList, count=None, blind=True):
|
|||||||
|
|
||||||
value = "" if isNoneValue(value) else unArrayizeValue(value)
|
value = "" if isNoneValue(value) else unArrayizeValue(value)
|
||||||
|
|
||||||
lengths[column] = max(lengths[column], len(value) if value else 0)
|
lengths[column] = max(lengths[column], len(DUMP_REPLACEMENTS.get(getUnicode(value), getUnicode(value))))
|
||||||
entries[column].append(value)
|
entries[column].append(value)
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
kb.dumpKeyboardInterrupt = True
|
||||||
|
|
||||||
warnMsg = "user aborted during enumeration. sqlmap "
|
warnMsg = "user aborted during enumeration. sqlmap "
|
||||||
warnMsg += "will display partial output"
|
warnMsg += "will display partial output"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
|||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import cookielib
|
|
||||||
import httplib
|
import httplib
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
@@ -26,7 +25,6 @@ from lib.core.enums import HTTP_HEADER
|
|||||||
from lib.core.enums import REDIRECTION
|
from lib.core.enums import REDIRECTION
|
||||||
from lib.core.exception import SqlmapBaseException
|
from lib.core.exception import SqlmapBaseException
|
||||||
from lib.core.exception import SqlmapConnectionException
|
from lib.core.exception import SqlmapConnectionException
|
||||||
from lib.core.exception import SqlmapGenericException
|
|
||||||
from lib.core.exception import SqlmapUserQuitException
|
from lib.core.exception import SqlmapUserQuitException
|
||||||
from lib.core.settings import DUMMY_SEARCH_USER_AGENT
|
from lib.core.settings import DUMMY_SEARCH_USER_AGENT
|
||||||
from lib.core.settings import DUCKDUCKGO_REGEX
|
from lib.core.settings import DUCKDUCKGO_REGEX
|
||||||
@@ -35,7 +33,6 @@ from lib.core.settings import GOOGLE_REGEX
|
|||||||
from lib.core.settings import HTTP_ACCEPT_ENCODING_HEADER_VALUE
|
from lib.core.settings import HTTP_ACCEPT_ENCODING_HEADER_VALUE
|
||||||
from lib.core.settings import UNICODE_ENCODING
|
from lib.core.settings import UNICODE_ENCODING
|
||||||
from lib.request.basic import decodePage
|
from lib.request.basic import decodePage
|
||||||
from lib.request.httpshandler import HTTPSHandler
|
|
||||||
from thirdparty.socks import socks
|
from thirdparty.socks import socks
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -106,12 +106,6 @@ class Fingerprint(GenericFingerprint):
|
|||||||
if not conf.extensiveFp and (Backend.isDbmsWithin(FIREBIRD_ALIASES) \
|
if not conf.extensiveFp and (Backend.isDbmsWithin(FIREBIRD_ALIASES) \
|
||||||
or (conf.dbms or "").lower() in FIREBIRD_ALIASES) and Backend.getVersion() and \
|
or (conf.dbms or "").lower() in FIREBIRD_ALIASES) and Backend.getVersion() and \
|
||||||
Backend.getVersion() != UNKNOWN_DBMS_VERSION:
|
Backend.getVersion() != UNKNOWN_DBMS_VERSION:
|
||||||
v = Backend.getVersion().replace(">", "")
|
|
||||||
v = v.replace("=", "")
|
|
||||||
v = v.replace(" ", "")
|
|
||||||
|
|
||||||
Backend.setVersion(v)
|
|
||||||
|
|
||||||
setDbms("%s %s" % (DBMS.FIREBIRD, Backend.getVersion()))
|
setDbms("%s %s" % (DBMS.FIREBIRD, Backend.getVersion()))
|
||||||
|
|
||||||
self.getBanner()
|
self.getBanner()
|
||||||
|
|||||||
@@ -83,12 +83,6 @@ class Fingerprint(GenericFingerprint):
|
|||||||
if not conf.extensiveFp and (Backend.isDbmsWithin(HSQLDB_ALIASES) \
|
if not conf.extensiveFp and (Backend.isDbmsWithin(HSQLDB_ALIASES) \
|
||||||
or (conf.dbms or "").lower() in HSQLDB_ALIASES) and Backend.getVersion() and \
|
or (conf.dbms or "").lower() in HSQLDB_ALIASES) and Backend.getVersion() and \
|
||||||
Backend.getVersion() != UNKNOWN_DBMS_VERSION:
|
Backend.getVersion() != UNKNOWN_DBMS_VERSION:
|
||||||
v = Backend.getVersion().replace(">", "")
|
|
||||||
v = v.replace("=", "")
|
|
||||||
v = v.replace(" ", "")
|
|
||||||
|
|
||||||
Backend.setVersion(v)
|
|
||||||
|
|
||||||
setDbms("%s %s" % (DBMS.HSQLDB, Backend.getVersion()))
|
setDbms("%s %s" % (DBMS.HSQLDB, Backend.getVersion()))
|
||||||
|
|
||||||
if Backend.isVersionGreaterOrEqualThan("1.7.2"):
|
if Backend.isVersionGreaterOrEqualThan("1.7.2"):
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class Connector(GenericConnector):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
self.connector = pymssql.connect(host="%s:%d" % (self.hostname, self.port), user=self.user, password=self.password, database=self.db, login_timeout=conf.timeout, timeout=conf.timeout)
|
self.connector = pymssql.connect(host="%s:%d" % (self.hostname, self.port), user=self.user, password=self.password, database=self.db, login_timeout=conf.timeout, timeout=conf.timeout)
|
||||||
except (pymssql.ProgrammingError, pymssql.OperationalError, _mssql.MssqlDatabaseException), msg:
|
except (pymssql.Error, _mssql.MssqlDatabaseException), msg:
|
||||||
raise SqlmapConnectionException(msg)
|
raise SqlmapConnectionException(msg)
|
||||||
|
|
||||||
self.initCursor()
|
self.initCursor()
|
||||||
@@ -50,7 +50,7 @@ class Connector(GenericConnector):
|
|||||||
def fetchall(self):
|
def fetchall(self):
|
||||||
try:
|
try:
|
||||||
return self.cursor.fetchall()
|
return self.cursor.fetchall()
|
||||||
except (pymssql.ProgrammingError, pymssql.OperationalError, _mssql.MssqlDatabaseException), msg:
|
except (pymssql.Error, _mssql.MssqlDatabaseException), msg:
|
||||||
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % str(msg).replace("\n", " "))
|
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % str(msg).replace("\n", " "))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,9 @@ class Fingerprint(GenericFingerprint):
|
|||||||
for version, check in (("2000", "HOST_NAME()=HOST_NAME()"), \
|
for version, check in (("2000", "HOST_NAME()=HOST_NAME()"), \
|
||||||
("2005", "XACT_STATE()=XACT_STATE()"), \
|
("2005", "XACT_STATE()=XACT_STATE()"), \
|
||||||
("2008", "SYSDATETIME()=SYSDATETIME()"), \
|
("2008", "SYSDATETIME()=SYSDATETIME()"), \
|
||||||
("2012", "CONCAT(NULL,NULL)=CONCAT(NULL,NULL)")):
|
("2012", "CONCAT(NULL,NULL)=CONCAT(NULL,NULL)"), \
|
||||||
|
("2014", "CHARINDEX('12.0.2000',@@version)>0"), \
|
||||||
|
("2016", "ISJSON(NULL) IS NULL")):
|
||||||
result = inject.checkBooleanExpression(check)
|
result = inject.checkBooleanExpression(check)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
|
|||||||
@@ -10,10 +10,13 @@ import re
|
|||||||
from lib.core.common import Backend
|
from lib.core.common import Backend
|
||||||
from lib.core.common import Format
|
from lib.core.common import Format
|
||||||
from lib.core.common import getUnicode
|
from lib.core.common import getUnicode
|
||||||
|
from lib.core.common import hashDBRetrieve
|
||||||
|
from lib.core.common import hashDBWrite
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.core.enums import DBMS
|
from lib.core.enums import DBMS
|
||||||
|
from lib.core.enums import HASHDB_KEYS
|
||||||
from lib.core.enums import OS
|
from lib.core.enums import OS
|
||||||
from lib.core.session import setDbms
|
from lib.core.session import setDbms
|
||||||
from lib.core.settings import MYSQL_ALIASES
|
from lib.core.settings import MYSQL_ALIASES
|
||||||
@@ -37,17 +40,18 @@ class Fingerprint(GenericFingerprint):
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# MySQL valid versions updated on 04/2011
|
# Reference: https://downloads.mysql.com/archives/community/
|
||||||
versions = (
|
versions = (
|
||||||
(32200, 32235), # MySQL 3.22
|
(32200, 32235), # MySQL 3.22
|
||||||
(32300, 32359), # MySQL 3.23
|
(32300, 32359), # MySQL 3.23
|
||||||
(40000, 40032), # MySQL 4.0
|
(40000, 40032), # MySQL 4.0
|
||||||
(40100, 40131), # MySQL 4.1
|
(40100, 40131), # MySQL 4.1
|
||||||
(50000, 50092), # MySQL 5.0
|
(50000, 50092), # MySQL 5.0
|
||||||
(50100, 50156), # MySQL 5.1
|
(50100, 50172), # MySQL 5.1
|
||||||
(50400, 50404), # MySQL 5.4
|
(50400, 50404), # MySQL 5.4
|
||||||
(50500, 50521), # MySQL 5.5
|
(50500, 50549), # MySQL 5.5
|
||||||
(50600, 50604), # MySQL 5.6
|
(50600, 50630), # MySQL 5.6
|
||||||
|
(50700, 50712), # MySQL 5.7
|
||||||
(60000, 60014), # MySQL 6.0
|
(60000, 60014), # MySQL 6.0
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -103,6 +107,10 @@ class Fingerprint(GenericFingerprint):
|
|||||||
value += "back-end DBMS: "
|
value += "back-end DBMS: "
|
||||||
actVer = Format.getDbms()
|
actVer = Format.getDbms()
|
||||||
|
|
||||||
|
_ = hashDBRetrieve(HASHDB_KEYS.DBMS_FORK)
|
||||||
|
if _:
|
||||||
|
actVer += " (%s fork)" % _
|
||||||
|
|
||||||
if not conf.extensiveFp:
|
if not conf.extensiveFp:
|
||||||
value += actVer
|
value += actVer
|
||||||
return value
|
return value
|
||||||
@@ -145,12 +153,6 @@ class Fingerprint(GenericFingerprint):
|
|||||||
if not conf.extensiveFp and (Backend.isDbmsWithin(MYSQL_ALIASES) \
|
if not conf.extensiveFp and (Backend.isDbmsWithin(MYSQL_ALIASES) \
|
||||||
or (conf.dbms or "").lower() in MYSQL_ALIASES) and Backend.getVersion() and \
|
or (conf.dbms or "").lower() in MYSQL_ALIASES) and Backend.getVersion() and \
|
||||||
Backend.getVersion() != UNKNOWN_DBMS_VERSION:
|
Backend.getVersion() != UNKNOWN_DBMS_VERSION:
|
||||||
v = Backend.getVersion().replace(">", "")
|
|
||||||
v = v.replace("=", "")
|
|
||||||
v = v.replace(" ", "")
|
|
||||||
|
|
||||||
Backend.setVersion(v)
|
|
||||||
|
|
||||||
setDbms("%s %s" % (DBMS.MYSQL, Backend.getVersion()))
|
setDbms("%s %s" % (DBMS.MYSQL, Backend.getVersion()))
|
||||||
|
|
||||||
if Backend.isVersionGreaterOrEqualThan("5"):
|
if Backend.isVersionGreaterOrEqualThan("5"):
|
||||||
@@ -177,6 +179,9 @@ class Fingerprint(GenericFingerprint):
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if hashDBRetrieve(HASHDB_KEYS.DBMS_FORK) is None:
|
||||||
|
hashDBWrite(HASHDB_KEYS.DBMS_FORK, inject.checkBooleanExpression("VERSION() LIKE '%MariaDB%'") and "MariaDB" or "")
|
||||||
|
|
||||||
# reading information_schema on some platforms is causing annoying timeout exits
|
# reading information_schema on some platforms is causing annoying timeout exits
|
||||||
# Reference: http://bugs.mysql.com/bug.php?id=15855
|
# Reference: http://bugs.mysql.com/bug.php?id=15855
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,8 @@ class Fingerprint(GenericFingerprint):
|
|||||||
infoMsg = "actively fingerprinting %s" % DBMS.ORACLE
|
infoMsg = "actively fingerprinting %s" % DBMS.ORACLE
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
for version in ("11i", "10g", "9i", "8i"):
|
# Reference: https://en.wikipedia.org/wiki/Oracle_Database
|
||||||
|
for version in ("12c", "11g", "10g", "9i", "8i"):
|
||||||
number = int(re.search("([\d]+)", version).group(1))
|
number = int(re.search("([\d]+)", version).group(1))
|
||||||
output = inject.checkBooleanExpression("%d=(SELECT SUBSTR((VERSION),1,%d) FROM SYS.PRODUCT_COMPONENT_VERSION WHERE ROWNUM=1)" % (number, 1 if number < 10 else 2))
|
output = inject.checkBooleanExpression("%d=(SELECT SUBSTR((VERSION),1,%d) FROM SYS.PRODUCT_COMPONENT_VERSION WHERE ROWNUM=1)" % (number, 1 if number < 10 else 2))
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class Connector(GenericConnector):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
self.connector = pymssql.connect(host="%s:%d" % (self.hostname, self.port), user=self.user, password=self.password, database=self.db, login_timeout=conf.timeout, timeout=conf.timeout)
|
self.connector = pymssql.connect(host="%s:%d" % (self.hostname, self.port), user=self.user, password=self.password, database=self.db, login_timeout=conf.timeout, timeout=conf.timeout)
|
||||||
except (pymssql.ProgrammingError, pymssql.OperationalError, _mssql.MssqlDatabaseException), msg:
|
except (pymssql.Error, _mssql.MssqlDatabaseException), msg:
|
||||||
raise SqlmapConnectionException(msg)
|
raise SqlmapConnectionException(msg)
|
||||||
|
|
||||||
self.initCursor()
|
self.initCursor()
|
||||||
@@ -50,7 +50,7 @@ class Connector(GenericConnector):
|
|||||||
def fetchall(self):
|
def fetchall(self):
|
||||||
try:
|
try:
|
||||||
return self.cursor.fetchall()
|
return self.cursor.fetchall()
|
||||||
except (pymssql.ProgrammingError, pymssql.OperationalError, _mssql.MssqlDatabaseException), msg:
|
except (pymssql.Error, _mssql.MssqlDatabaseException), msg:
|
||||||
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % str(msg).replace("\n", " "))
|
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % str(msg).replace("\n", " "))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ See the file 'doc/COPYING' for copying permission
|
|||||||
from lib.core.agent import agent
|
from lib.core.agent import agent
|
||||||
from lib.core.common import arrayizeValue
|
from lib.core.common import arrayizeValue
|
||||||
from lib.core.common import Backend
|
from lib.core.common import Backend
|
||||||
|
from lib.core.common import extractRegexResult
|
||||||
from lib.core.common import filterPairValues
|
from lib.core.common import filterPairValues
|
||||||
from lib.core.common import flattenValue
|
from lib.core.common import flattenValue
|
||||||
from lib.core.common import getLimitRange
|
from lib.core.common import getLimitRange
|
||||||
@@ -19,6 +20,7 @@ from lib.core.common import isTechniqueAvailable
|
|||||||
from lib.core.common import parseSqliteTableSchema
|
from lib.core.common import parseSqliteTableSchema
|
||||||
from lib.core.common import popValue
|
from lib.core.common import popValue
|
||||||
from lib.core.common import pushValue
|
from lib.core.common import pushValue
|
||||||
|
from lib.core.common import randomStr
|
||||||
from lib.core.common import readInput
|
from lib.core.common import readInput
|
||||||
from lib.core.common import safeSQLIdentificatorNaming
|
from lib.core.common import safeSQLIdentificatorNaming
|
||||||
from lib.core.common import singleTimeWarnMessage
|
from lib.core.common import singleTimeWarnMessage
|
||||||
@@ -41,6 +43,7 @@ from lib.core.settings import CURRENT_DB
|
|||||||
from lib.request import inject
|
from lib.request import inject
|
||||||
from lib.techniques.brute.use import columnExists
|
from lib.techniques.brute.use import columnExists
|
||||||
from lib.techniques.brute.use import tableExists
|
from lib.techniques.brute.use import tableExists
|
||||||
|
from lib.techniques.union.use import unionUse
|
||||||
|
|
||||||
class Databases:
|
class Databases:
|
||||||
"""
|
"""
|
||||||
@@ -450,7 +453,7 @@ class Databases:
|
|||||||
|
|
||||||
elif Backend.isDbms(DBMS.ACCESS):
|
elif Backend.isDbms(DBMS.ACCESS):
|
||||||
errMsg = "cannot retrieve column names, "
|
errMsg = "cannot retrieve column names, "
|
||||||
errMsg += "back-end DBMS is Access"
|
errMsg += "back-end DBMS is %s" % DBMS.ACCESS
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
bruteForce = True
|
bruteForce = True
|
||||||
|
|
||||||
@@ -539,6 +542,21 @@ class Databases:
|
|||||||
infoMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
infoMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
values = None
|
||||||
|
if Backend.isDbms(DBMS.MSSQL) and isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION):
|
||||||
|
expression = query
|
||||||
|
kb.dumpColumns = []
|
||||||
|
kb.rowXmlMode = True
|
||||||
|
|
||||||
|
for column in extractRegexResult(r"SELECT (?P<result>.+?) FROM", query).split(','):
|
||||||
|
kb.dumpColumns.append(randomStr().lower())
|
||||||
|
expression = expression.replace(column, "%s AS %s" % (column, kb.dumpColumns[-1]), 1)
|
||||||
|
|
||||||
|
values = unionUse(expression)
|
||||||
|
kb.rowXmlMode = False
|
||||||
|
kb.dumpColumns = None
|
||||||
|
|
||||||
|
if values is None:
|
||||||
values = inject.getValue(query, blind=False, time=False)
|
values = inject.getValue(query, blind=False, time=False)
|
||||||
|
|
||||||
if Backend.isDbms(DBMS.MSSQL) and isNoneValue(values):
|
if Backend.isDbms(DBMS.MSSQL) and isNoneValue(values):
|
||||||
@@ -572,7 +590,11 @@ class Databases:
|
|||||||
query = _.query % (unsafeSQLIdentificatorNaming(conf.db.upper()), unsafeSQLIdentificatorNaming(tbl.upper()), unsafeSQLIdentificatorNaming(name.upper()))
|
query = _.query % (unsafeSQLIdentificatorNaming(conf.db.upper()), unsafeSQLIdentificatorNaming(tbl.upper()), unsafeSQLIdentificatorNaming(name.upper()))
|
||||||
else:
|
else:
|
||||||
query = _.query % (unsafeSQLIdentificatorNaming(conf.db), unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(name))
|
query = _.query % (unsafeSQLIdentificatorNaming(conf.db), unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(name))
|
||||||
|
|
||||||
comment = unArrayizeValue(inject.getValue(query, blind=False, time=False))
|
comment = unArrayizeValue(inject.getValue(query, blind=False, time=False))
|
||||||
|
if not isNoneValue(comment):
|
||||||
|
infoMsg = "retrieved comment '%s' for column '%s'" % (comment, name)
|
||||||
|
logger.info(infoMsg)
|
||||||
else:
|
else:
|
||||||
warnMsg = "on %s it is not " % Backend.getIdentifiedDbms()
|
warnMsg = "on %s it is not " % Backend.getIdentifiedDbms()
|
||||||
warnMsg += "possible to get column comments"
|
warnMsg += "possible to get column comments"
|
||||||
@@ -702,7 +724,11 @@ class Databases:
|
|||||||
query = _.query % (unsafeSQLIdentificatorNaming(conf.db.upper()), unsafeSQLIdentificatorNaming(tbl.upper()), unsafeSQLIdentificatorNaming(column.upper()))
|
query = _.query % (unsafeSQLIdentificatorNaming(conf.db.upper()), unsafeSQLIdentificatorNaming(tbl.upper()), unsafeSQLIdentificatorNaming(column.upper()))
|
||||||
else:
|
else:
|
||||||
query = _.query % (unsafeSQLIdentificatorNaming(conf.db), unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(column))
|
query = _.query % (unsafeSQLIdentificatorNaming(conf.db), unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(column))
|
||||||
|
|
||||||
comment = unArrayizeValue(inject.getValue(query, union=False, error=False))
|
comment = unArrayizeValue(inject.getValue(query, union=False, error=False))
|
||||||
|
if not isNoneValue(comment):
|
||||||
|
infoMsg = "retrieved comment '%s' for column '%s'" % (comment, column)
|
||||||
|
logger.info(infoMsg)
|
||||||
else:
|
else:
|
||||||
warnMsg = "on %s it is not " % Backend.getIdentifiedDbms()
|
warnMsg = "on %s it is not " % Backend.getIdentifiedDbms()
|
||||||
warnMsg += "possible to get column comments"
|
warnMsg += "possible to get column comments"
|
||||||
|
|||||||
@@ -19,9 +19,7 @@ from lib.core.common import isListLike
|
|||||||
from lib.core.common import isNoneValue
|
from lib.core.common import isNoneValue
|
||||||
from lib.core.common import isNumPosStrValue
|
from lib.core.common import isNumPosStrValue
|
||||||
from lib.core.common import isTechniqueAvailable
|
from lib.core.common import isTechniqueAvailable
|
||||||
from lib.core.common import popValue
|
|
||||||
from lib.core.common import prioritySortColumns
|
from lib.core.common import prioritySortColumns
|
||||||
from lib.core.common import pushValue
|
|
||||||
from lib.core.common import readInput
|
from lib.core.common import readInput
|
||||||
from lib.core.common import safeSQLIdentificatorNaming
|
from lib.core.common import safeSQLIdentificatorNaming
|
||||||
from lib.core.common import unArrayizeValue
|
from lib.core.common import unArrayizeValue
|
||||||
@@ -139,6 +137,7 @@ class Entries:
|
|||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
kb.dumpColumns = colList
|
||||||
colNames = colString = ", ".join(column for column in colList)
|
colNames = colString = ", ".join(column for column in colList)
|
||||||
rootQuery = queries[Backend.getIdentifiedDbms()].dump_table
|
rootQuery = queries[Backend.getIdentifiedDbms()].dump_table
|
||||||
|
|
||||||
@@ -214,8 +213,7 @@ class Entries:
|
|||||||
else:
|
else:
|
||||||
colEntry = unArrayizeValue(entry[index]) if index < len(entry) else u''
|
colEntry = unArrayizeValue(entry[index]) if index < len(entry) else u''
|
||||||
|
|
||||||
_ = len(DUMP_REPLACEMENTS.get(getUnicode(colEntry), getUnicode(colEntry)))
|
maxLen = max(len(column), len(DUMP_REPLACEMENTS.get(getUnicode(colEntry), getUnicode(colEntry))))
|
||||||
maxLen = max(len(column), _)
|
|
||||||
|
|
||||||
if maxLen > kb.data.dumpedTable[column]["length"]:
|
if maxLen > kb.data.dumpedTable[column]["length"]:
|
||||||
kb.data.dumpedTable[column]["length"] = maxLen
|
kb.data.dumpedTable[column]["length"] = maxLen
|
||||||
@@ -294,8 +292,11 @@ class Entries:
|
|||||||
indexRange = getLimitRange(count, plusOne=plusOne)
|
indexRange = getLimitRange(count, plusOne=plusOne)
|
||||||
|
|
||||||
if len(colList) < len(indexRange) > CHECK_ZERO_COLUMNS_THRESHOLD:
|
if len(colList) < len(indexRange) > CHECK_ZERO_COLUMNS_THRESHOLD:
|
||||||
|
debugMsg = "checking for empty columns"
|
||||||
|
logger.debug(infoMsg)
|
||||||
|
|
||||||
for column in colList:
|
for column in colList:
|
||||||
if inject.getValue("SELECT COUNT(%s) FROM %s" % (column, kb.dumpTable), union=False, error=False) == '0':
|
if not inject.checkBooleanExpression("(SELECT COUNT(%s) FROM %s)>0" % (column, kb.dumpTable)):
|
||||||
emptyColumns.append(column)
|
emptyColumns.append(column)
|
||||||
debugMsg = "column '%s' of table '%s' will not be " % (column, kb.dumpTable)
|
debugMsg = "column '%s' of table '%s' will not be " % (column, kb.dumpTable)
|
||||||
debugMsg += "dumped as it appears to be empty"
|
debugMsg += "dumped as it appears to be empty"
|
||||||
@@ -329,8 +330,7 @@ class Entries:
|
|||||||
value = NULL if column in emptyColumns else inject.getValue(query, union=False, error=False, dump=True)
|
value = NULL if column in emptyColumns else inject.getValue(query, union=False, error=False, dump=True)
|
||||||
value = '' if value is None else value
|
value = '' if value is None else value
|
||||||
|
|
||||||
_ = DUMP_REPLACEMENTS.get(getUnicode(value), getUnicode(value))
|
lengths[column] = max(lengths[column], len(DUMP_REPLACEMENTS.get(getUnicode(value), getUnicode(value))))
|
||||||
lengths[column] = max(lengths[column], len(_))
|
|
||||||
entries[column].append(value)
|
entries[column].append(value)
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
@@ -371,6 +371,7 @@ class Entries:
|
|||||||
logger.critical(errMsg)
|
logger.critical(errMsg)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
kb.dumpColumns = None
|
||||||
kb.dumpTable = None
|
kb.dumpTable = None
|
||||||
|
|
||||||
def dumpAll(self):
|
def dumpAll(self):
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ from lib.core.enums import CHARSET_TYPE
|
|||||||
from lib.core.enums import EXPECTED
|
from lib.core.enums import EXPECTED
|
||||||
from lib.core.enums import PAYLOAD
|
from lib.core.enums import PAYLOAD
|
||||||
from lib.core.exception import SqlmapUndefinedMethod
|
from lib.core.exception import SqlmapUndefinedMethod
|
||||||
|
from lib.core.settings import UNICODE_ENCODING
|
||||||
from lib.request import inject
|
from lib.request import inject
|
||||||
|
|
||||||
class Filesystem:
|
class Filesystem:
|
||||||
@@ -69,7 +70,7 @@ class Filesystem:
|
|||||||
|
|
||||||
if isNumPosStrValue(remoteFileSize):
|
if isNumPosStrValue(remoteFileSize):
|
||||||
remoteFileSize = long(remoteFileSize)
|
remoteFileSize = long(remoteFileSize)
|
||||||
localFile = getUnicode(localFile, encoding=sys.getfilesystemencoding())
|
localFile = getUnicode(localFile, encoding=sys.getfilesystemencoding() or UNICODE_ENCODING)
|
||||||
sameFile = False
|
sameFile = False
|
||||||
|
|
||||||
if localFileSize == remoteFileSize:
|
if localFileSize == remoteFileSize:
|
||||||
@@ -87,7 +88,7 @@ class Filesystem:
|
|||||||
else:
|
else:
|
||||||
sameFile = False
|
sameFile = False
|
||||||
warnMsg = "it looks like the file has not been written (usually "
|
warnMsg = "it looks like the file has not been written (usually "
|
||||||
warnMsg += "occurs if the DBMS process' user has no write "
|
warnMsg += "occurs if the DBMS process user has no write "
|
||||||
warnMsg += "privileges in the destination path)"
|
warnMsg += "privileges in the destination path)"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ EXEC master..sp_configure 'show advanced options',1;
|
|||||||
RECONFIGURE WITH OVERRIDE;
|
RECONFIGURE WITH OVERRIDE;
|
||||||
EXEC master..sp_configure 'xp_cmdshell',%ENABLE%;
|
EXEC master..sp_configure 'xp_cmdshell',%ENABLE%;
|
||||||
RECONFIGURE WITH OVERRIDE;
|
RECONFIGURE WITH OVERRIDE;
|
||||||
EXEC sp_configure 'show advanced options',0;
|
EXEC master..sp_configure 'show advanced options',0;
|
||||||
RECONFIGURE WITH OVERRIDE
|
RECONFIGURE WITH OVERRIDE
|
||||||
|
|||||||
22
sqlmap.conf
22
sqlmap.conf
@@ -124,7 +124,7 @@ tor = False
|
|||||||
|
|
||||||
# Set Tor proxy type.
|
# Set Tor proxy type.
|
||||||
# Valid: HTTP, SOCKS4, SOCKS5
|
# Valid: HTTP, SOCKS4, SOCKS5
|
||||||
torType = HTTP
|
torType = SOCKS5
|
||||||
|
|
||||||
# Check to see if Tor is used properly.
|
# Check to see if Tor is used properly.
|
||||||
# Valid: True or False
|
# Valid: True or False
|
||||||
@@ -482,6 +482,9 @@ col =
|
|||||||
# Back-end database management system database table column(s) to not enumerate.
|
# Back-end database management system database table column(s) to not enumerate.
|
||||||
excludeCol =
|
excludeCol =
|
||||||
|
|
||||||
|
# Pivot column name.
|
||||||
|
pivotColumn =
|
||||||
|
|
||||||
# Use WHERE condition while table dumping (e.g. "id=1").
|
# Use WHERE condition while table dumping (e.g. "id=1").
|
||||||
dumpWhere =
|
dumpWhere =
|
||||||
|
|
||||||
@@ -650,6 +653,9 @@ trafficFile =
|
|||||||
# Valid: True or False
|
# Valid: True or False
|
||||||
batch = False
|
batch = False
|
||||||
|
|
||||||
|
# Result fields having binary values (e.g. "digest").
|
||||||
|
binaryFields =
|
||||||
|
|
||||||
# Force character encoding used for data retrieval.
|
# Force character encoding used for data retrieval.
|
||||||
charset =
|
charset =
|
||||||
|
|
||||||
@@ -697,9 +703,6 @@ outputDir =
|
|||||||
# Valid: True or False
|
# Valid: True or False
|
||||||
parseErrors = False
|
parseErrors = False
|
||||||
|
|
||||||
# Pivot column name.
|
|
||||||
pivotColumn =
|
|
||||||
|
|
||||||
# Regular expression for filtering targets from provided Burp.
|
# Regular expression for filtering targets from provided Burp.
|
||||||
# or WebScarab proxy log.
|
# or WebScarab proxy log.
|
||||||
# Example: (google|yahoo)
|
# Example: (google|yahoo)
|
||||||
@@ -753,10 +756,6 @@ googlePage = 1
|
|||||||
# Valid: True or False
|
# Valid: True or False
|
||||||
identifyWaf = False
|
identifyWaf = False
|
||||||
|
|
||||||
# Skip heuristic detection of WAF/IPS/IDS protection.
|
|
||||||
# Valid: True or False
|
|
||||||
skipWaf = False
|
|
||||||
|
|
||||||
# Imitate smartphone through HTTP User-Agent header.
|
# Imitate smartphone through HTTP User-Agent header.
|
||||||
# Valid: True or False
|
# Valid: True or False
|
||||||
mobile = False
|
mobile = False
|
||||||
@@ -769,10 +768,17 @@ offline = False
|
|||||||
# Valid: True or False
|
# Valid: True or False
|
||||||
pageRank = False
|
pageRank = False
|
||||||
|
|
||||||
|
# Skip heuristic detection of WAF/IPS/IDS protection.
|
||||||
|
# Valid: True or False
|
||||||
|
skipWaf = False
|
||||||
|
|
||||||
# Conduct thorough tests only if positive heuristic(s).
|
# Conduct thorough tests only if positive heuristic(s).
|
||||||
# Valid: True or False
|
# Valid: True or False
|
||||||
smart = False
|
smart = False
|
||||||
|
|
||||||
|
# Local directory for storing temporary files.
|
||||||
|
tmpDir =
|
||||||
|
|
||||||
# Simple wizard interface for beginner users.
|
# Simple wizard interface for beginner users.
|
||||||
# Valid: True or False
|
# Valid: True or False
|
||||||
wizard = False
|
wizard = False
|
||||||
|
|||||||
104
sqlmap.py
104
sqlmap.py
@@ -12,6 +12,8 @@ sys.dont_write_bytecode = True
|
|||||||
from lib.utils import versioncheck # this has to be the first non-standard import
|
from lib.utils import versioncheck # this has to be the first non-standard import
|
||||||
|
|
||||||
import bdb
|
import bdb
|
||||||
|
import distutils
|
||||||
|
import glob
|
||||||
import inspect
|
import inspect
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
@@ -19,6 +21,7 @@ import re
|
|||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import thread
|
import thread
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
import warnings
|
import warnings
|
||||||
@@ -26,8 +29,12 @@ import warnings
|
|||||||
warnings.filterwarnings(action="ignore", message=".*was already imported", category=UserWarning)
|
warnings.filterwarnings(action="ignore", message=".*was already imported", category=UserWarning)
|
||||||
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
|
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
|
||||||
|
|
||||||
|
from lib.core.data import logger
|
||||||
|
|
||||||
|
try:
|
||||||
from lib.controller.controller import start
|
from lib.controller.controller import start
|
||||||
from lib.core.common import banner
|
from lib.core.common import banner
|
||||||
|
from lib.core.common import checkIntegrity
|
||||||
from lib.core.common import createGithubIssue
|
from lib.core.common import createGithubIssue
|
||||||
from lib.core.common import dataToStdout
|
from lib.core.common import dataToStdout
|
||||||
from lib.core.common import getSafeExString
|
from lib.core.common import getSafeExString
|
||||||
@@ -38,9 +45,8 @@ from lib.core.common import weAreFrozen
|
|||||||
from lib.core.data import cmdLineOptions
|
from lib.core.data import cmdLineOptions
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
|
||||||
from lib.core.data import paths
|
|
||||||
from lib.core.common import unhandledExceptionMessage
|
from lib.core.common import unhandledExceptionMessage
|
||||||
|
from lib.core.common import MKSTEMP_PREFIX
|
||||||
from lib.core.exception import SqlmapBaseException
|
from lib.core.exception import SqlmapBaseException
|
||||||
from lib.core.exception import SqlmapShellQuitException
|
from lib.core.exception import SqlmapShellQuitException
|
||||||
from lib.core.exception import SqlmapSilentQuitException
|
from lib.core.exception import SqlmapSilentQuitException
|
||||||
@@ -48,12 +54,22 @@ from lib.core.exception import SqlmapUserQuitException
|
|||||||
from lib.core.option import initOptions
|
from lib.core.option import initOptions
|
||||||
from lib.core.option import init
|
from lib.core.option import init
|
||||||
from lib.core.profiling import profile
|
from lib.core.profiling import profile
|
||||||
|
from lib.core.settings import GIT_PAGE
|
||||||
|
from lib.core.settings import IS_WIN
|
||||||
from lib.core.settings import LEGAL_DISCLAIMER
|
from lib.core.settings import LEGAL_DISCLAIMER
|
||||||
|
from lib.core.settings import THREAD_FINALIZATION_TIMEOUT
|
||||||
|
from lib.core.settings import UNICODE_ENCODING
|
||||||
|
from lib.core.settings import VERSION
|
||||||
from lib.core.testing import smokeTest
|
from lib.core.testing import smokeTest
|
||||||
from lib.core.testing import liveTest
|
from lib.core.testing import liveTest
|
||||||
from lib.parse.cmdline import cmdLineParser
|
from lib.parse.cmdline import cmdLineParser
|
||||||
from lib.utils.api import setRestAPILog
|
from lib.utils.api import setRestAPILog
|
||||||
from lib.utils.api import StdDbOut
|
from lib.utils.api import StdDbOut
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
errMsg = "user aborted"
|
||||||
|
logger.error(errMsg)
|
||||||
|
|
||||||
|
raise SystemExit
|
||||||
|
|
||||||
def modulePath():
|
def modulePath():
|
||||||
"""
|
"""
|
||||||
@@ -66,7 +82,24 @@ def modulePath():
|
|||||||
except NameError:
|
except NameError:
|
||||||
_ = inspect.getsourcefile(modulePath)
|
_ = inspect.getsourcefile(modulePath)
|
||||||
|
|
||||||
return getUnicode(os.path.dirname(os.path.realpath(_)), encoding=sys.getfilesystemencoding())
|
return getUnicode(os.path.dirname(os.path.realpath(_)), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING)
|
||||||
|
|
||||||
|
def checkEnvironment():
|
||||||
|
try:
|
||||||
|
os.path.isdir(modulePath())
|
||||||
|
except UnicodeEncodeError:
|
||||||
|
errMsg = "your system does not properly handle non-ASCII paths. "
|
||||||
|
errMsg += "Please move the sqlmap's directory to the other location"
|
||||||
|
logger.critical(errMsg)
|
||||||
|
raise SystemExit
|
||||||
|
|
||||||
|
if distutils.version.LooseVersion(VERSION) < distutils.version.LooseVersion("1.0"):
|
||||||
|
errMsg = "your runtime environment (e.g. PYTHONPATH) is "
|
||||||
|
errMsg += "broken. Please make sure that you are not running "
|
||||||
|
errMsg += "newer versions of sqlmap with runtime scripts for older "
|
||||||
|
errMsg += "versions"
|
||||||
|
logger.critical(errMsg)
|
||||||
|
raise SystemExit
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""
|
"""
|
||||||
@@ -74,17 +107,10 @@ def main():
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
paths.SQLMAP_ROOT_PATH = modulePath()
|
checkEnvironment()
|
||||||
|
|
||||||
try:
|
setPaths(modulePath())
|
||||||
os.path.isdir(paths.SQLMAP_ROOT_PATH)
|
banner()
|
||||||
except UnicodeEncodeError:
|
|
||||||
errMsg = "your system does not properly handle non-ASCII paths. "
|
|
||||||
errMsg += "Please move the sqlmap's directory to the other location"
|
|
||||||
logger.error(errMsg)
|
|
||||||
raise SystemExit
|
|
||||||
|
|
||||||
setPaths()
|
|
||||||
|
|
||||||
# Store original command line options for possible later restoration
|
# Store original command line options for possible later restoration
|
||||||
cmdLineOptions.update(cmdLineParser().__dict__)
|
cmdLineOptions.update(cmdLineParser().__dict__)
|
||||||
@@ -97,8 +123,6 @@ def main():
|
|||||||
sys.stderr = StdDbOut(conf.taskid, messagetype="stderr")
|
sys.stderr = StdDbOut(conf.taskid, messagetype="stderr")
|
||||||
setRestAPILog()
|
setRestAPILog()
|
||||||
|
|
||||||
banner()
|
|
||||||
|
|
||||||
conf.showTime = True
|
conf.showTime = True
|
||||||
dataToStdout("[!] legal disclaimer: %s\n\n" % LEGAL_DISCLAIMER, forceOutput=True)
|
dataToStdout("[!] legal disclaimer: %s\n\n" % LEGAL_DISCLAIMER, forceOutput=True)
|
||||||
dataToStdout("[*] starting at %s\n\n" % time.strftime("%X"), forceOutput=True)
|
dataToStdout("[*] starting at %s\n\n" % time.strftime("%X"), forceOutput=True)
|
||||||
@@ -170,16 +194,44 @@ def main():
|
|||||||
excMsg = traceback.format_exc()
|
excMsg = traceback.format_exc()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if any(_ in excMsg for _ in ("No space left", "Disk quota exceeded")):
|
if not checkIntegrity():
|
||||||
|
errMsg = "code integrity check failed. "
|
||||||
|
errMsg += "You should retrieve the latest development version from official GitHub "
|
||||||
|
errMsg += "repository at '%s'" % GIT_PAGE
|
||||||
|
logger.critical(errMsg)
|
||||||
|
print
|
||||||
|
dataToStdout(excMsg)
|
||||||
|
raise SystemExit
|
||||||
|
elif any(_ in excMsg for _ in ("No space left", "Disk quota exceeded")):
|
||||||
errMsg = "no space left on output device"
|
errMsg = "no space left on output device"
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
|
|
||||||
|
elif all(_ in excMsg for _ in ("No such file", "_'", "self.get_prog_name()")):
|
||||||
|
errMsg = "corrupted installation detected ('%s'). " % excMsg.strip().split('\n')[-1]
|
||||||
|
errMsg += "You should retrieve the latest development version from official GitHub "
|
||||||
|
errMsg += "repository at '%s'" % GIT_PAGE
|
||||||
|
logger.error(errMsg)
|
||||||
|
raise SystemExit
|
||||||
|
|
||||||
|
elif "Read-only file system" in excMsg:
|
||||||
|
errMsg = "output device is mounted as read-only"
|
||||||
|
logger.error(errMsg)
|
||||||
|
raise SystemExit
|
||||||
|
|
||||||
elif "_mkstemp_inner" in excMsg:
|
elif "_mkstemp_inner" in excMsg:
|
||||||
errMsg = "there has been a problem while accessing temporary files"
|
errMsg = "there has been a problem while accessing temporary files"
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
|
|
||||||
|
elif "can't start new thread" in excMsg:
|
||||||
|
errMsg = "there has been a problem while creating new thread instance. "
|
||||||
|
errMsg += "Please make sure that you are not running too many processes"
|
||||||
|
if not IS_WIN:
|
||||||
|
errMsg += " (or increase the 'ulimit -u' value)"
|
||||||
|
logger.error(errMsg)
|
||||||
|
raise SystemExit
|
||||||
|
|
||||||
elif all(_ in excMsg for _ in ("pymysql", "configparser")):
|
elif all(_ in excMsg for _ in ("pymysql", "configparser")):
|
||||||
errMsg = "wrong initialization of pymsql detected (using Python3 dependencies)"
|
errMsg = "wrong initialization of pymsql detected (using Python3 dependencies)"
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
@@ -218,12 +270,20 @@ def main():
|
|||||||
|
|
||||||
finally:
|
finally:
|
||||||
kb.threadContinue = False
|
kb.threadContinue = False
|
||||||
kb.threadException = True
|
|
||||||
|
|
||||||
if conf.get("showTime"):
|
if conf.get("showTime"):
|
||||||
dataToStdout("\n[*] shutting down at %s\n\n" % time.strftime("%X"), forceOutput=True)
|
dataToStdout("\n[*] shutting down at %s\n\n" % time.strftime("%X"), forceOutput=True)
|
||||||
|
|
||||||
|
kb.threadException = True
|
||||||
|
|
||||||
if kb.get("tempDir"):
|
if kb.get("tempDir"):
|
||||||
|
for prefix in (MKSTEMP_PREFIX.IPC, MKSTEMP_PREFIX.TESTING, MKSTEMP_PREFIX.COOKIE_JAR, MKSTEMP_PREFIX.BIG_ARRAY):
|
||||||
|
for filepath in glob.glob(os.path.join(kb.tempDir, "%s*" % prefix)):
|
||||||
|
try:
|
||||||
|
os.remove(filepath)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
if not filter(None, (filepath for filepath in glob.glob(os.path.join(kb.tempDir, '*')) if not any(filepath.endswith(_) for _ in ('.lock', '.exe', '_')))):
|
||||||
shutil.rmtree(kb.tempDir, ignore_errors=True)
|
shutil.rmtree(kb.tempDir, ignore_errors=True)
|
||||||
|
|
||||||
if conf.get("hashDB"):
|
if conf.get("hashDB"):
|
||||||
@@ -247,8 +307,16 @@ def main():
|
|||||||
if conf.get("dumper"):
|
if conf.get("dumper"):
|
||||||
conf.dumper.flush()
|
conf.dumper.flush()
|
||||||
|
|
||||||
|
# short delay for thread finalization
|
||||||
|
try:
|
||||||
|
_ = time.time()
|
||||||
|
while threading.activeCount() > 1 and (time.time() - _) > THREAD_FINALIZATION_TIMEOUT:
|
||||||
|
time.sleep(0.01)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
|
||||||
# Reference: http://stackoverflow.com/questions/1635080/terminate-a-multi-thread-python-program
|
# Reference: http://stackoverflow.com/questions/1635080/terminate-a-multi-thread-python-program
|
||||||
if conf.get("threads", 0) > 1 or conf.get("dnsServer"):
|
if threading.activeCount() > 1:
|
||||||
os._exit(0)
|
os._exit(0)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ from lib.utils import versioncheck # this has to be the first non-standard impo
|
|||||||
|
|
||||||
from sqlmap import modulePath
|
from sqlmap import modulePath
|
||||||
from lib.core.common import setPaths
|
from lib.core.common import setPaths
|
||||||
from lib.core.data import paths
|
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.core.settings import RESTAPI_DEFAULT_ADAPTER
|
from lib.core.settings import RESTAPI_DEFAULT_ADAPTER
|
||||||
from lib.core.settings import RESTAPI_DEFAULT_ADDRESS
|
from lib.core.settings import RESTAPI_DEFAULT_ADDRESS
|
||||||
@@ -31,9 +30,8 @@ def main():
|
|||||||
# Set default logging level to debug
|
# Set default logging level to debug
|
||||||
logger.setLevel(logging.DEBUG)
|
logger.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
# Initialize path variable
|
# Initialize paths
|
||||||
paths.SQLMAP_ROOT_PATH = modulePath()
|
setPaths(modulePath())
|
||||||
setPaths()
|
|
||||||
|
|
||||||
# Parse command line options
|
# Parse command line options
|
||||||
apiparser = optparse.OptionParser()
|
apiparser = optparse.OptionParser()
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
|||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from lib.core.common import singleTimeWarnMessage
|
|
||||||
from lib.core.enums import PRIORITY
|
from lib.core.enums import PRIORITY
|
||||||
|
|
||||||
__priority__ = PRIORITY.HIGH
|
__priority__ = PRIORITY.HIGH
|
||||||
|
|||||||
@@ -5,10 +5,7 @@ Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
|||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import base64
|
|
||||||
|
|
||||||
from lib.core.enums import PRIORITY
|
from lib.core.enums import PRIORITY
|
||||||
from lib.core.settings import UNICODE_ENCODING
|
|
||||||
|
|
||||||
__priority__ = PRIORITY.LOWEST
|
__priority__ = PRIORITY.LOWEST
|
||||||
|
|
||||||
|
|||||||
2
thirdparty/clientform/clientform.py
vendored
2
thirdparty/clientform/clientform.py
vendored
@@ -1142,7 +1142,7 @@ def _ParseFileEx(file, base_uri,
|
|||||||
try:
|
try:
|
||||||
form.fixup()
|
form.fixup()
|
||||||
except AttributeError, ex:
|
except AttributeError, ex:
|
||||||
if "item is disabled" not in str(ex):
|
if not any(_ in str(ex) for _ in ("item is disabled", "is readonly")):
|
||||||
raise
|
raise
|
||||||
return forms
|
return forms
|
||||||
|
|
||||||
|
|||||||
13
thirdparty/colorama/initialise.py
vendored
13
thirdparty/colorama/initialise.py
vendored
@@ -21,13 +21,15 @@ def reset_all():
|
|||||||
|
|
||||||
|
|
||||||
def init(autoreset=False, convert=None, strip=None, wrap=True):
|
def init(autoreset=False, convert=None, strip=None, wrap=True):
|
||||||
|
global wrapped_stdout, wrapped_stderr
|
||||||
|
global orig_stdout, orig_stderr
|
||||||
|
|
||||||
|
if orig_stdout is not None:
|
||||||
|
return
|
||||||
|
|
||||||
if not wrap and any([autoreset, convert, strip]):
|
if not wrap and any([autoreset, convert, strip]):
|
||||||
raise ValueError('wrap=False conflicts with any other arg=True')
|
raise ValueError('wrap=False conflicts with any other arg=True')
|
||||||
|
|
||||||
global wrapped_stdout, wrapped_stderr
|
|
||||||
global orig_stdout, orig_stderr
|
|
||||||
|
|
||||||
orig_stdout = sys.stdout
|
orig_stdout = sys.stdout
|
||||||
orig_stderr = sys.stderr
|
orig_stderr = sys.stderr
|
||||||
|
|
||||||
@@ -49,10 +51,15 @@ def init(autoreset=False, convert=None, strip=None, wrap=True):
|
|||||||
|
|
||||||
|
|
||||||
def deinit():
|
def deinit():
|
||||||
|
global orig_stdout
|
||||||
|
global orig_stderr
|
||||||
|
|
||||||
if orig_stdout is not None:
|
if orig_stdout is not None:
|
||||||
sys.stdout = orig_stdout
|
sys.stdout = orig_stdout
|
||||||
|
orig_stdout = None
|
||||||
if orig_stderr is not None:
|
if orig_stderr is not None:
|
||||||
sys.stderr = orig_stderr
|
sys.stderr = orig_stderr
|
||||||
|
orig_stderr = None
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
|
|||||||
523
thirdparty/keepalive/keepalive.py
vendored
523
thirdparty/keepalive/keepalive.py
vendored
@@ -1,30 +1,40 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This library is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
|
# License as published by the Free Software Foundation; either
|
||||||
|
# version 2.1 of the License, or (at your option) any later version.
|
||||||
#
|
#
|
||||||
# Copyright 2002-2003 Michael D. Stenner
|
# This library is distributed in the hope that it will be useful,
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify it
|
|
||||||
# under the terms of the GNU Lesser General Public License as published
|
|
||||||
# by the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
# GNU Lesser General Public License for more details.
|
# Lesser General Public License for more details.
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public
|
||||||
|
# License along with this library; if not, write to the
|
||||||
|
# Free Software Foundation, Inc.,
|
||||||
|
# 59 Temple Place, Suite 330,
|
||||||
|
# Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
# This file was part of urlgrabber, a high-level cross-protocol url-grabber
|
||||||
|
# Copyright 2002-2004 Michael D. Stenner, Ryan Tomayko
|
||||||
|
# Copyright 2015 Sergio Fernández
|
||||||
|
|
||||||
"""An HTTP handler for urllib2 that supports HTTP 1.1 and keepalive.
|
"""An HTTP handler for urllib2 that supports HTTP 1.1 and keepalive.
|
||||||
|
|
||||||
import urllib2
|
>>> import urllib2
|
||||||
from keepalive import HTTPHandler
|
>>> from keepalive import HTTPHandler
|
||||||
keepalive_handler = HTTPHandler()
|
>>> keepalive_handler = HTTPHandler()
|
||||||
opener = urllib2.build_opener(keepalive_handler)
|
>>> opener = urllib2.build_opener(keepalive_handler)
|
||||||
urllib2.install_opener(opener)
|
>>> urllib2.install_opener(opener)
|
||||||
|
>>>
|
||||||
|
>>> fo = urllib2.urlopen('http://www.python.org')
|
||||||
|
|
||||||
fo = urllib2.urlopen('http://www.python.org')
|
If a connection to a given host is requested, and all of the existing
|
||||||
|
connections are still in use, another connection will be opened. If
|
||||||
|
the handler tries to use an existing connection but it fails in some
|
||||||
|
way, it will be closed and removed from the pool.
|
||||||
|
|
||||||
To remove the handler, simply re-run build_opener with no arguments, and
|
To remove the handler, simply re-run build_opener with no arguments, and
|
||||||
install that opener.
|
install that opener.
|
||||||
@@ -37,9 +47,13 @@ use the handler methods:
|
|||||||
close_all()
|
close_all()
|
||||||
open_connections()
|
open_connections()
|
||||||
|
|
||||||
Example:
|
NOTE: using the close_connection and close_all methods of the handler
|
||||||
|
should be done with care when using multiple threads.
|
||||||
|
* there is nothing that prevents another thread from creating new
|
||||||
|
connections immediately after connections are closed
|
||||||
|
* no checks are done to prevent in-use connections from being closed
|
||||||
|
|
||||||
keepalive_handler.close_all()
|
>>> keepalive_handler.close_all()
|
||||||
|
|
||||||
EXTRA ATTRIBUTES AND METHODS
|
EXTRA ATTRIBUTES AND METHODS
|
||||||
|
|
||||||
@@ -55,162 +69,307 @@ EXTRA ATTRIBUTES AND METHODS
|
|||||||
If you want the best of both worlds, use this inside an
|
If you want the best of both worlds, use this inside an
|
||||||
AttributeError-catching try:
|
AttributeError-catching try:
|
||||||
|
|
||||||
try: status = fo.status
|
>>> try: status = fo.status
|
||||||
except AttributeError: status = None
|
>>> except AttributeError: status = None
|
||||||
|
|
||||||
Unfortunately, these are ONLY there if status == 200, so it's not
|
Unfortunately, these are ONLY there if status == 200, so it's not
|
||||||
easy to distinguish between non-200 responses. The reason is that
|
easy to distinguish between non-200 responses. The reason is that
|
||||||
urllib2 tries to do clever things with error codes 301, 302, 401,
|
urllib2 tries to do clever things with error codes 301, 302, 401,
|
||||||
and 407, and it wraps the object upon return.
|
and 407, and it wraps the object upon return.
|
||||||
|
|
||||||
You can optionally set the module-level global HANDLE_ERRORS to 0,
|
For python versions earlier than 2.4, you can avoid this fancy error
|
||||||
in which case the handler will always return the object directly.
|
handling by setting the module-level global HANDLE_ERRORS to zero.
|
||||||
If you like the fancy handling of errors, don't do this. If you
|
You see, prior to 2.4, it's the HTTP Handler's job to determine what
|
||||||
prefer to see your error codes, then do.
|
to handle specially, and what to just pass up. HANDLE_ERRORS == 0
|
||||||
|
means "pass everything up". In python 2.4, however, this job no
|
||||||
|
longer belongs to the HTTP Handler and is now done by a NEW handler,
|
||||||
|
HTTPErrorProcessor. Here's the bottom line:
|
||||||
|
|
||||||
|
python version < 2.4
|
||||||
|
HANDLE_ERRORS == 1 (default) pass up 200, treat the rest as
|
||||||
|
errors
|
||||||
|
HANDLE_ERRORS == 0 pass everything up, error processing is
|
||||||
|
left to the calling code
|
||||||
|
python version >= 2.4
|
||||||
|
HANDLE_ERRORS == 1 pass up 200, treat the rest as errors
|
||||||
|
HANDLE_ERRORS == 0 (default) pass everything up, let the
|
||||||
|
other handlers (specifically,
|
||||||
|
HTTPErrorProcessor) decide what to do
|
||||||
|
|
||||||
|
In practice, setting the variable either way makes little difference
|
||||||
|
in python 2.4, so for the most consistent behavior across versions,
|
||||||
|
you probably just want to use the defaults, which will give you
|
||||||
|
exceptions on errors.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from httplib import _CS_REQ_STARTED, _CS_REQ_SENT, _CS_IDLE, CannotSendHeader
|
|
||||||
|
|
||||||
from lib.core.convert import unicodeencode
|
# $Id: keepalive.py,v 1.17 2006/12/08 00:14:16 mstenner Exp $
|
||||||
from lib.core.data import kb
|
|
||||||
|
|
||||||
import threading
|
|
||||||
import urllib2
|
import urllib2
|
||||||
import httplib
|
import httplib
|
||||||
import socket
|
import socket
|
||||||
|
import thread
|
||||||
|
|
||||||
VERSION = (0, 1)
|
DEBUG = None
|
||||||
#STRING_VERSION = '.'.join(map(str, VERSION))
|
|
||||||
DEBUG = 0
|
|
||||||
HANDLE_ERRORS = 1
|
|
||||||
|
|
||||||
class HTTPHandler(urllib2.HTTPHandler):
|
import sys
|
||||||
|
if sys.version_info < (2, 4): HANDLE_ERRORS = 1
|
||||||
|
else: HANDLE_ERRORS = 0
|
||||||
|
|
||||||
|
class ConnectionManager:
|
||||||
|
"""
|
||||||
|
The connection manager must be able to:
|
||||||
|
* keep track of all existing
|
||||||
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._connections = {}
|
self._lock = thread.allocate_lock()
|
||||||
|
self._hostmap = {} # map hosts to a list of connections
|
||||||
|
self._connmap = {} # map connections to host
|
||||||
|
self._readymap = {} # map connection to ready state
|
||||||
|
|
||||||
|
def add(self, host, connection, ready):
|
||||||
|
self._lock.acquire()
|
||||||
|
try:
|
||||||
|
if not self._hostmap.has_key(host): self._hostmap[host] = []
|
||||||
|
self._hostmap[host].append(connection)
|
||||||
|
self._connmap[connection] = host
|
||||||
|
self._readymap[connection] = ready
|
||||||
|
finally:
|
||||||
|
self._lock.release()
|
||||||
|
|
||||||
|
def remove(self, connection):
|
||||||
|
self._lock.acquire()
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
host = self._connmap[connection]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
del self._connmap[connection]
|
||||||
|
del self._readymap[connection]
|
||||||
|
self._hostmap[host].remove(connection)
|
||||||
|
if not self._hostmap[host]: del self._hostmap[host]
|
||||||
|
finally:
|
||||||
|
self._lock.release()
|
||||||
|
|
||||||
|
def set_ready(self, connection, ready):
|
||||||
|
try: self._readymap[connection] = ready
|
||||||
|
except KeyError: pass
|
||||||
|
|
||||||
|
def get_ready_conn(self, host):
|
||||||
|
conn = None
|
||||||
|
self._lock.acquire()
|
||||||
|
try:
|
||||||
|
if self._hostmap.has_key(host):
|
||||||
|
for c in self._hostmap[host]:
|
||||||
|
if self._readymap[c]:
|
||||||
|
self._readymap[c] = 0
|
||||||
|
conn = c
|
||||||
|
break
|
||||||
|
finally:
|
||||||
|
self._lock.release()
|
||||||
|
return conn
|
||||||
|
|
||||||
|
def get_all(self, host=None):
|
||||||
|
if host:
|
||||||
|
return list(self._hostmap.get(host, []))
|
||||||
|
else:
|
||||||
|
return dict(self._hostmap)
|
||||||
|
|
||||||
|
class KeepAliveHandler:
|
||||||
|
def __init__(self):
|
||||||
|
self._cm = ConnectionManager()
|
||||||
|
|
||||||
|
#### Connection Management
|
||||||
|
def open_connections(self):
|
||||||
|
"""return a list of connected hosts and the number of connections
|
||||||
|
to each. [('foo.com:80', 2), ('bar.org', 1)]"""
|
||||||
|
return [(host, len(li)) for (host, li) in self._cm.get_all().items()]
|
||||||
|
|
||||||
def close_connection(self, host):
|
def close_connection(self, host):
|
||||||
"""close connection to <host>
|
"""close connection(s) to <host>
|
||||||
host is the host:port spec, as in 'www.cnn.com:8080' as passed in.
|
host is the host:port spec, as in 'www.cnn.com:8080' as passed in.
|
||||||
no error occurs if there is no connection to that host."""
|
no error occurs if there is no connection to that host."""
|
||||||
self._remove_connection(host, close=1)
|
for h in self._cm.get_all(host):
|
||||||
|
self._cm.remove(h)
|
||||||
def open_connections(self):
|
h.close()
|
||||||
"""return a list of connected hosts"""
|
|
||||||
retVal = []
|
|
||||||
currentThread = threading.currentThread()
|
|
||||||
for name, host in self._connections.keys():
|
|
||||||
if name == currentThread.getName():
|
|
||||||
retVal.append(host)
|
|
||||||
return retVal
|
|
||||||
|
|
||||||
def close_all(self):
|
def close_all(self):
|
||||||
"""close all open connections"""
|
"""close all open connections"""
|
||||||
for _, conn in self._connections.items():
|
for host, conns in self._cm.get_all().items():
|
||||||
conn.close()
|
for h in conns:
|
||||||
self._connections = {}
|
self._cm.remove(h)
|
||||||
|
|
||||||
def _remove_connection(self, host, close=0):
|
|
||||||
key = self._get_connection_key(host)
|
|
||||||
if self._connections.has_key(key):
|
|
||||||
if close: self._connections[key].close()
|
|
||||||
del self._connections[key]
|
|
||||||
|
|
||||||
def _get_connection_key(self, host):
|
|
||||||
return (threading.currentThread().getName(), host)
|
|
||||||
|
|
||||||
def _start_connection(self, h, req):
|
|
||||||
h.clearheaders()
|
|
||||||
try:
|
|
||||||
if req.has_data():
|
|
||||||
data = req.get_data()
|
|
||||||
h.putrequest('POST', req.get_selector())
|
|
||||||
if not req.headers.has_key('Content-type'):
|
|
||||||
req.headers['Content-type'] = 'application/x-www-form-urlencoded'
|
|
||||||
if not req.headers.has_key('Content-length'):
|
|
||||||
req.headers['Content-length'] = '%d' % len(data)
|
|
||||||
else:
|
|
||||||
h.putrequest(req.get_method() or 'GET', req.get_selector())
|
|
||||||
|
|
||||||
if not req.headers.has_key('Connection'):
|
|
||||||
req.headers['Connection'] = 'keep-alive'
|
|
||||||
|
|
||||||
for args in self.parent.addheaders:
|
|
||||||
h.putheader(*args)
|
|
||||||
for k, v in req.headers.items():
|
|
||||||
h.putheader(k, v)
|
|
||||||
h.endheaders()
|
|
||||||
if req.has_data():
|
|
||||||
h.send(data)
|
|
||||||
except socket.error, err:
|
|
||||||
h.close()
|
h.close()
|
||||||
raise urllib2.URLError(err)
|
|
||||||
|
|
||||||
def do_open(self, http_class, req):
|
def _request_closed(self, request, host, connection):
|
||||||
h = None
|
"""tells us that this request is now closed and the the
|
||||||
host = req.get_host()
|
connection is ready for another request"""
|
||||||
|
self._cm.set_ready(connection, 1)
|
||||||
|
|
||||||
|
def _remove_connection(self, host, connection, close=0):
|
||||||
|
if close: connection.close()
|
||||||
|
self._cm.remove(connection)
|
||||||
|
|
||||||
|
#### Transaction Execution
|
||||||
|
def do_open(self, req):
|
||||||
|
host = req.host
|
||||||
if not host:
|
if not host:
|
||||||
raise urllib2.URLError('no host given')
|
raise urllib2.URLError('no host given')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
need_new_connection = 1
|
h = self._cm.get_ready_conn(host)
|
||||||
key = self._get_connection_key(host)
|
while h:
|
||||||
h = self._connections.get(key)
|
r = self._reuse_connection(h, req, host)
|
||||||
if not h is None:
|
|
||||||
try:
|
# if this response is non-None, then it worked and we're
|
||||||
self._start_connection(h, req)
|
# done. Break out, skipping the else block.
|
||||||
except:
|
if r: break
|
||||||
r = None
|
|
||||||
|
# connection is bad - possibly closed by server
|
||||||
|
# discard it and ask for the next free connection
|
||||||
|
h.close()
|
||||||
|
self._cm.remove(h)
|
||||||
|
h = self._cm.get_ready_conn(host)
|
||||||
else:
|
else:
|
||||||
try: r = h.getresponse()
|
# no (working) free connections were found. Create a new one.
|
||||||
except httplib.ResponseNotReady, e: r = None
|
h = self._get_connection(host)
|
||||||
except httplib.BadStatusLine, e: r = None
|
if DEBUG: DEBUG.info("creating new connection to %s (%d)",
|
||||||
|
host, id(h))
|
||||||
|
self._cm.add(host, h, 0)
|
||||||
|
self._start_transaction(h, req)
|
||||||
|
r = h.getresponse()
|
||||||
|
except (socket.error, httplib.HTTPException), err:
|
||||||
|
raise urllib2.URLError(err)
|
||||||
|
|
||||||
|
if DEBUG: DEBUG.info("STATUS: %s, %s", r.status, r.reason)
|
||||||
|
|
||||||
|
# if not a persistent connection, don't try to reuse it
|
||||||
|
if r.will_close:
|
||||||
|
if DEBUG: DEBUG.info('server will close connection, discarding')
|
||||||
|
self._cm.remove(h)
|
||||||
|
|
||||||
|
r._handler = self
|
||||||
|
r._host = host
|
||||||
|
r._url = req.get_full_url()
|
||||||
|
r._connection = h
|
||||||
|
r.code = r.status
|
||||||
|
r.headers = r.msg
|
||||||
|
r.msg = r.reason
|
||||||
|
|
||||||
|
if r.status == 200 or not HANDLE_ERRORS:
|
||||||
|
return r
|
||||||
|
else:
|
||||||
|
return self.parent.error('http', req, r,
|
||||||
|
r.status, r.msg, r.headers)
|
||||||
|
|
||||||
|
def _reuse_connection(self, h, req, host):
|
||||||
|
"""start the transaction with a re-used connection
|
||||||
|
return a response object (r) upon success or None on failure.
|
||||||
|
This DOES not close or remove bad connections in cases where
|
||||||
|
it returns. However, if an unexpected exception occurs, it
|
||||||
|
will close and remove the connection before re-raising.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
self._start_transaction(h, req)
|
||||||
|
r = h.getresponse()
|
||||||
|
# note: just because we got something back doesn't mean it
|
||||||
|
# worked. We'll check the version below, too.
|
||||||
|
except (socket.error, httplib.HTTPException):
|
||||||
|
r = None
|
||||||
|
except:
|
||||||
|
# adding this block just in case we've missed
|
||||||
|
# something we will still raise the exception, but
|
||||||
|
# lets try and close the connection and remove it
|
||||||
|
# first. We previously got into a nasty loop
|
||||||
|
# where an exception was uncaught, and so the
|
||||||
|
# connection stayed open. On the next try, the
|
||||||
|
# same exception was raised, etc. The tradeoff is
|
||||||
|
# that it's now possible this call will raise
|
||||||
|
# a DIFFERENT exception
|
||||||
|
if DEBUG: DEBUG.error("unexpected exception - closing " + \
|
||||||
|
"connection to %s (%d)", host, id(h))
|
||||||
|
self._cm.remove(h)
|
||||||
|
h.close()
|
||||||
|
raise
|
||||||
|
|
||||||
if r is None or r.version == 9:
|
if r is None or r.version == 9:
|
||||||
# httplib falls back to assuming HTTP 0.9 if it gets a
|
# httplib falls back to assuming HTTP 0.9 if it gets a
|
||||||
# bad header back. This is most likely to happen if
|
# bad header back. This is most likely to happen if
|
||||||
# the socket has been closed by the server since we
|
# the socket has been closed by the server since we
|
||||||
# last used the connection.
|
# last used the connection.
|
||||||
if DEBUG: print "failed to re-use connection to %s" % host
|
if DEBUG: DEBUG.info("failed to re-use connection to %s (%d)",
|
||||||
h.close()
|
host, id(h))
|
||||||
|
r = None
|
||||||
else:
|
else:
|
||||||
if DEBUG: print "re-using connection to %s" % host
|
if DEBUG: DEBUG.info("re-using connection to %s (%d)", host, id(h))
|
||||||
need_new_connection = 0
|
|
||||||
if need_new_connection:
|
return r
|
||||||
if DEBUG: print "creating new connection to %s" % host
|
|
||||||
h = http_class(host)
|
def _start_transaction(self, h, req):
|
||||||
self._connections[key] = h
|
try:
|
||||||
self._start_connection(h, req)
|
if req.has_data():
|
||||||
r = h.getresponse()
|
data = req.data
|
||||||
except socket.error, err:
|
if hasattr(req, 'selector'):
|
||||||
if h: h.close()
|
h.putrequest(req.get_method() or 'POST', req.selector, skip_host=req.has_header("Host"), skip_accept_encoding=req.has_header("Accept-encoding"))
|
||||||
|
else:
|
||||||
|
h.putrequest(req.get_method() or 'POST', req.get_selector(), skip_host=req.has_header("Host"), skip_accept_encoding=req.has_header("Accept-encoding"))
|
||||||
|
if not req.headers.has_key('Content-type'):
|
||||||
|
h.putheader('Content-type',
|
||||||
|
'application/x-www-form-urlencoded')
|
||||||
|
if not req.headers.has_key('Content-length'):
|
||||||
|
h.putheader('Content-length', '%d' % len(data))
|
||||||
|
else:
|
||||||
|
if hasattr(req, 'selector'):
|
||||||
|
h.putrequest(req.get_method() or 'GET', req.selector, skip_host=req.has_header("Host"), skip_accept_encoding=req.has_header("Accept-encoding"))
|
||||||
|
else:
|
||||||
|
h.putrequest(req.get_method() or 'GET', req.get_selector(), skip_host=req.has_header("Host"), skip_accept_encoding=req.has_header("Accept-encoding"))
|
||||||
|
except (socket.error, httplib.HTTPException), err:
|
||||||
raise urllib2.URLError(err)
|
raise urllib2.URLError(err)
|
||||||
|
|
||||||
# if not a persistent connection, don't try to reuse it
|
if not req.headers.has_key('Connection'):
|
||||||
if r.will_close: self._remove_connection(host)
|
req.headers['Connection'] = 'keep-alive'
|
||||||
|
|
||||||
if DEBUG:
|
for args in self.parent.addheaders:
|
||||||
print "STATUS: %s, %s" % (r.status, r.reason)
|
if not req.headers.has_key(args[0]):
|
||||||
r._handler = self
|
h.putheader(*args)
|
||||||
r._host = host
|
for k, v in req.headers.items():
|
||||||
r._url = req.get_full_url()
|
h.putheader(k, v)
|
||||||
|
h.endheaders()
|
||||||
|
if req.has_data():
|
||||||
|
h.send(data)
|
||||||
|
|
||||||
#if r.status == 200 or not HANDLE_ERRORS:
|
def _get_connection(self, host):
|
||||||
#return r
|
return NotImplementedError
|
||||||
if r.status == 200 or not HANDLE_ERRORS:
|
|
||||||
# [speedplane] Must return an adinfourl object
|
class HTTPHandler(KeepAliveHandler, urllib2.HTTPHandler):
|
||||||
resp = urllib2.addinfourl(r, r.msg, req.get_full_url())
|
def __init__(self):
|
||||||
resp.code = r.status
|
KeepAliveHandler.__init__(self)
|
||||||
resp.msg = r.reason
|
|
||||||
return resp;
|
|
||||||
else:
|
|
||||||
r.code = r.status
|
|
||||||
return self.parent.error('http', req, r, r.status, r.reason, r.msg)
|
|
||||||
|
|
||||||
def http_open(self, req):
|
def http_open(self, req):
|
||||||
return self.do_open(HTTPConnection, req)
|
return self.do_open(req)
|
||||||
|
|
||||||
|
def _get_connection(self, host):
|
||||||
|
return HTTPConnection(host)
|
||||||
|
|
||||||
|
class HTTPSHandler(KeepAliveHandler, urllib2.HTTPSHandler):
|
||||||
|
def __init__(self, ssl_factory=None):
|
||||||
|
KeepAliveHandler.__init__(self)
|
||||||
|
if not ssl_factory:
|
||||||
|
try:
|
||||||
|
import sslfactory
|
||||||
|
ssl_factory = sslfactory.get_factory()
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
self._ssl_factory = ssl_factory
|
||||||
|
|
||||||
|
def https_open(self, req):
|
||||||
|
return self.do_open(req)
|
||||||
|
|
||||||
|
def _get_connection(self, host):
|
||||||
|
try: return self._ssl_factory.get_https_connection(host)
|
||||||
|
except AttributeError: return HTTPSConnection(host)
|
||||||
|
|
||||||
class HTTPResponse(httplib.HTTPResponse):
|
class HTTPResponse(httplib.HTTPResponse):
|
||||||
|
|
||||||
# we need to subclass HTTPResponse in order to
|
# we need to subclass HTTPResponse in order to
|
||||||
# 1) add readline() and readlines() methods
|
# 1) add readline() and readlines() methods
|
||||||
# 2) add close_connection() methods
|
# 2) add close_connection() methods
|
||||||
@@ -236,21 +395,31 @@ class HTTPResponse(httplib.HTTPResponse):
|
|||||||
else: # 2.2 doesn't
|
else: # 2.2 doesn't
|
||||||
httplib.HTTPResponse.__init__(self, sock, debuglevel)
|
httplib.HTTPResponse.__init__(self, sock, debuglevel)
|
||||||
self.fileno = sock.fileno
|
self.fileno = sock.fileno
|
||||||
|
self.code = None
|
||||||
self._method = method
|
self._method = method
|
||||||
self._rbuf = ''
|
self._rbuf = b""
|
||||||
self._rbufsize = 8096
|
self._rbufsize = 8096
|
||||||
self._handler = None # inserted by the handler later
|
self._handler = None # inserted by the handler later
|
||||||
self._host = None # (same)
|
self._host = None # (same)
|
||||||
self._url = None # (same)
|
self._url = None # (same)
|
||||||
|
self._connection = None # (same)
|
||||||
|
|
||||||
_raw_read = httplib.HTTPResponse.read
|
_raw_read = httplib.HTTPResponse.read
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
if self.fp:
|
||||||
|
self.fp.close()
|
||||||
|
self.fp = None
|
||||||
|
if self._handler:
|
||||||
|
self._handler._request_closed(self, self._host,
|
||||||
|
self._connection)
|
||||||
|
|
||||||
def close_connection(self):
|
def close_connection(self):
|
||||||
|
self._handler._remove_connection(self._host, self._connection, close=1)
|
||||||
self.close()
|
self.close()
|
||||||
self._handler._remove_connection(self._host, close=1)
|
|
||||||
|
|
||||||
def info(self):
|
def info(self):
|
||||||
return self.msg
|
return self.headers
|
||||||
|
|
||||||
def geturl(self):
|
def geturl(self):
|
||||||
return self._url
|
return self._url
|
||||||
@@ -268,11 +437,11 @@ class HTTPResponse(httplib.HTTPResponse):
|
|||||||
return s
|
return s
|
||||||
|
|
||||||
s = self._rbuf + self._raw_read(amt)
|
s = self._rbuf + self._raw_read(amt)
|
||||||
self._rbuf = ''
|
self._rbuf = b""
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def readline(self, limit=-1):
|
def readline(self, limit=-1):
|
||||||
data = ""
|
data = b""
|
||||||
i = self._rbuf.find('\n')
|
i = self._rbuf.find('\n')
|
||||||
while i < 0 and not (0 < limit <= len(self._rbuf)):
|
while i < 0 and not (0 < limit <= len(self._rbuf)):
|
||||||
new = self._raw_read(self._rbufsize)
|
new = self._raw_read(self._rbufsize)
|
||||||
@@ -302,43 +471,9 @@ class HTTPResponse(httplib.HTTPResponse):
|
|||||||
class HTTPConnection(httplib.HTTPConnection):
|
class HTTPConnection(httplib.HTTPConnection):
|
||||||
# use the modified response class
|
# use the modified response class
|
||||||
response_class = HTTPResponse
|
response_class = HTTPResponse
|
||||||
_headers = None
|
|
||||||
|
|
||||||
def clearheaders(self):
|
class HTTPSConnection(httplib.HTTPSConnection):
|
||||||
self._headers = {}
|
response_class = HTTPResponse
|
||||||
|
|
||||||
def putheader(self, header, value):
|
|
||||||
"""Send a request header line to the server.
|
|
||||||
|
|
||||||
For example: h.putheader('Accept', 'text/html')
|
|
||||||
"""
|
|
||||||
if self.__state != _CS_REQ_STARTED:
|
|
||||||
raise CannotSendHeader()
|
|
||||||
|
|
||||||
self._headers[header] = value
|
|
||||||
|
|
||||||
def endheaders(self):
|
|
||||||
"""Indicate that the last header line has been sent to the server."""
|
|
||||||
|
|
||||||
if self.__state == _CS_REQ_STARTED:
|
|
||||||
self.__state = _CS_REQ_SENT
|
|
||||||
else:
|
|
||||||
raise CannotSendHeader()
|
|
||||||
|
|
||||||
for header in ('Host', 'Accept-Encoding'):
|
|
||||||
if header in self._headers:
|
|
||||||
str = '%s: %s' % (header, self._headers[header])
|
|
||||||
self._output(str)
|
|
||||||
del self._headers[header]
|
|
||||||
|
|
||||||
for header, value in self._headers.items():
|
|
||||||
str = '%s: %s' % (header, value)
|
|
||||||
self._output(str)
|
|
||||||
|
|
||||||
self._send_output()
|
|
||||||
|
|
||||||
def send(self, str):
|
|
||||||
httplib.HTTPConnection.send(self, unicodeencode(str, kb.pageEncoding))
|
|
||||||
|
|
||||||
#########################################################################
|
#########################################################################
|
||||||
##### TEST FUNCTIONS
|
##### TEST FUNCTIONS
|
||||||
@@ -367,7 +502,7 @@ def error_handler(url):
|
|||||||
print " status = %s, reason = %s" % (status, reason)
|
print " status = %s, reason = %s" % (status, reason)
|
||||||
HANDLE_ERRORS = orig
|
HANDLE_ERRORS = orig
|
||||||
hosts = keepalive_handler.open_connections()
|
hosts = keepalive_handler.open_connections()
|
||||||
print "open connections:", ' '.join(hosts)
|
print "open connections:", hosts
|
||||||
keepalive_handler.close_all()
|
keepalive_handler.close_all()
|
||||||
|
|
||||||
def continuity(url):
|
def continuity(url):
|
||||||
@@ -422,9 +557,10 @@ def comp(N, url):
|
|||||||
print ' improvement factor: %.2f' % (t1/t2, )
|
print ' improvement factor: %.2f' % (t1/t2, )
|
||||||
|
|
||||||
def fetch(N, url, delay=0):
|
def fetch(N, url, delay=0):
|
||||||
|
import time
|
||||||
lens = []
|
lens = []
|
||||||
starttime = time.time()
|
starttime = time.time()
|
||||||
for i in xrange(N):
|
for i in range(N):
|
||||||
if delay and i > 0: time.sleep(delay)
|
if delay and i > 0: time.sleep(delay)
|
||||||
fo = urllib2.urlopen(url)
|
fo = urllib2.urlopen(url)
|
||||||
foo = fo.read()
|
foo = fo.read()
|
||||||
@@ -440,6 +576,40 @@ def fetch(N, url, delay=0):
|
|||||||
|
|
||||||
return diff
|
return diff
|
||||||
|
|
||||||
|
def test_timeout(url):
|
||||||
|
global DEBUG
|
||||||
|
dbbackup = DEBUG
|
||||||
|
class FakeLogger:
|
||||||
|
def debug(self, msg, *args): print msg % args
|
||||||
|
info = warning = error = debug
|
||||||
|
DEBUG = FakeLogger()
|
||||||
|
print " fetching the file to establish a connection"
|
||||||
|
fo = urllib2.urlopen(url)
|
||||||
|
data1 = fo.read()
|
||||||
|
fo.close()
|
||||||
|
|
||||||
|
i = 20
|
||||||
|
print " waiting %i seconds for the server to close the connection" % i
|
||||||
|
while i > 0:
|
||||||
|
sys.stdout.write('\r %2i' % i)
|
||||||
|
sys.stdout.flush()
|
||||||
|
time.sleep(1)
|
||||||
|
i -= 1
|
||||||
|
sys.stderr.write('\r')
|
||||||
|
|
||||||
|
print " fetching the file a second time"
|
||||||
|
fo = urllib2.urlopen(url)
|
||||||
|
data2 = fo.read()
|
||||||
|
fo.close()
|
||||||
|
|
||||||
|
if data1 == data2:
|
||||||
|
print ' data are identical'
|
||||||
|
else:
|
||||||
|
print ' ERROR: DATA DIFFER'
|
||||||
|
|
||||||
|
DEBUG = dbbackup
|
||||||
|
|
||||||
|
|
||||||
def test(url, N=10):
|
def test(url, N=10):
|
||||||
print "checking error hander (do this on a non-200)"
|
print "checking error hander (do this on a non-200)"
|
||||||
try: error_handler(url)
|
try: error_handler(url)
|
||||||
@@ -452,6 +622,9 @@ def test(url, N=10):
|
|||||||
print
|
print
|
||||||
print "performing speed comparison"
|
print "performing speed comparison"
|
||||||
comp(N, url)
|
comp(N, url)
|
||||||
|
print
|
||||||
|
print "performing dropped-connection check"
|
||||||
|
test_timeout(url)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import time
|
import time
|
||||||
|
|||||||
449
txt/checksum.md5
Normal file
449
txt/checksum.md5
Normal file
@@ -0,0 +1,449 @@
|
|||||||
|
c981335b0035fe8d5667d1c952e641e4 extra/beep/beep.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e extra/beep/__init__.py
|
||||||
|
002e2688fe38d03dd6d64a4c2acbee9f extra/cloak/cloak.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e extra/cloak/__init__.py
|
||||||
|
4d986b77ce6f616eb904e0920ae60890 extra/dbgtool/dbgtool.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e extra/dbgtool/__init__.py
|
||||||
|
acba8b5dc93db0fe6b2b04ff0138c33c extra/icmpsh/icmpsh.exe_
|
||||||
|
2176d964f2d5ba2d871383d6a1868b8f extra/icmpsh/icmpsh_m.py
|
||||||
|
2d020d2bdcee1170805f48839fdb89df extra/icmpsh/__init__.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e extra/__init__.py
|
||||||
|
2237d0568236c354b0436d2cd9434f97 extra/mssqlsig/update.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e extra/safe2bin/__init__.py
|
||||||
|
cc5b67714d8a0b6b81d29a4f15634c16 extra/safe2bin/safe2bin.py
|
||||||
|
d229479d02d21b29f209143cb0547780 extra/shellcodeexec/linux/shellcodeexec.x32_
|
||||||
|
2fe2f94eebc62f7614f0391a8a90104f extra/shellcodeexec/linux/shellcodeexec.x64_
|
||||||
|
c55b400b72acc43e0e59c87dd8bb8d75 extra/shellcodeexec/windows/shellcodeexec.x32.exe_
|
||||||
|
b46521e29ea3d813bab5aeb16cac6498 extra/shutils/duplicates.py
|
||||||
|
4bf52b3fd5e906b9bbe104dda769f5c5 extra/shutils/pylint.py
|
||||||
|
05615626222060120450518136b14ba9 extra/shutils/regressiontest.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e extra/sqlharvest/__init__.py
|
||||||
|
4f2f817596540d82f9fcc0c5b2228beb extra/sqlharvest/sqlharvest.py
|
||||||
|
b704c0f943c015f6247cfae20048ae8e lib/controller/action.py
|
||||||
|
d1451b43f3ac80bfbea8657e288865f8 lib/controller/checks.py
|
||||||
|
7c5ba631796f12d6de9b667e4cc7812b lib/controller/controller.py
|
||||||
|
5ae8f657fd4e8026fcc9624f5b5533fe lib/controller/handler.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e lib/controller/__init__.py
|
||||||
|
2689f320908964b2c88a3eb8265fd2dd lib/core/agent.py
|
||||||
|
eb0bd28b0bd9fbf67dcc3119116df377 lib/core/bigarray.py
|
||||||
|
1dd298ac06c961037bb76a675bb4b322 lib/core/common.py
|
||||||
|
5680d0c446a3bed5c0f2a0402d031557 lib/core/convert.py
|
||||||
|
e77cca1cb063016f71f6e6bdebf4ec73 lib/core/data.py
|
||||||
|
1d042f0bc0557d3fd564ea5a46deb77e lib/core/datatype.py
|
||||||
|
e4ca0fd47f20cf7ba6a5f5cbf980073c lib/core/decorators.py
|
||||||
|
67f206cf2658145992cc1d7020138325 lib/core/defaults.py
|
||||||
|
4a16002c5d9cd047c2e89ddc5db63737 lib/core/dicts.py
|
||||||
|
1f98d3f57ce21d625fd67adb26cfd13c lib/core/dump.py
|
||||||
|
34a45b9bc68a6381247a620ddf30de1c lib/core/enums.py
|
||||||
|
e4aec2b11c1ad6039d0c3dbbfbc5eb1a lib/core/exception.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e lib/core/__init__.py
|
||||||
|
91c514013daa796e2cdd940389354eac lib/core/log.py
|
||||||
|
b9779615206791e6ebbaa84947842b49 lib/core/optiondict.py
|
||||||
|
85b144015724e1961e6c9ea1a42b329a lib/core/option.py
|
||||||
|
1e8948dddbd12def5c2af52530738059 lib/core/profiling.py
|
||||||
|
e60456db5380840a586654344003d4e6 lib/core/readlineng.py
|
||||||
|
5ef56abb8671c2ca6ceecb208258e360 lib/core/replication.py
|
||||||
|
99a2b496b9d5b546b335653ca801153f lib/core/revision.py
|
||||||
|
7c15dd2777af4dac2c89cab6df17462e lib/core/session.py
|
||||||
|
1a0fab09e6840a52bdfec892fbd9ee53 lib/core/settings.py
|
||||||
|
7af83e4f18cab6dff5e67840eb65be80 lib/core/shell.py
|
||||||
|
23657cd7d924e3c6d225719865855827 lib/core/subprocessng.py
|
||||||
|
0bc2fae1dec18cdd11954b22358293f2 lib/core/target.py
|
||||||
|
21b9aa385c851a4e8faaff9b985e29b8 lib/core/testing.py
|
||||||
|
424a6cf9bdfaf7182657ed7929d7df5a lib/core/threads.py
|
||||||
|
53c15b78e0288274f52410db25406432 lib/core/unescaper.py
|
||||||
|
6bdc53e2ca152ff8cd35ad671e48a96b lib/core/update.py
|
||||||
|
8485a3cd94c0a5af2718bad60c5f1ae5 lib/core/wordlist.py
|
||||||
|
354ecc0c6d3e0ac9c06ed897c4d52edf lib/core/xmldump.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e lib/__init__.py
|
||||||
|
c1288bc4ce5651dbdd82d4a9435fdc03 lib/parse/banner.py
|
||||||
|
bf7fbfb04d6150d19ecfd9b25ee5618a lib/parse/cmdline.py
|
||||||
|
8ec4d4f02634834701f8258726f2e511 lib/parse/configfile.py
|
||||||
|
fe4e2152292587928edb94c9a4d311ff lib/parse/handler.py
|
||||||
|
8e6bfb13e5a34b2610f3ff23467a34cf lib/parse/headers.py
|
||||||
|
c8e14fbfc6616d8149b2603c97abec84 lib/parse/html.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e lib/parse/__init__.py
|
||||||
|
af6b8e1c6eb074b56bbd9cd80aebcd97 lib/parse/payloads.py
|
||||||
|
b40a4c5d91770d347df36d3065b63798 lib/parse/sitemap.py
|
||||||
|
9299f21804033f099681525bb9bf51c0 lib/request/basicauthhandler.py
|
||||||
|
a3e83cfe7e6825fb1b70951ad290d2ae lib/request/basic.py
|
||||||
|
9d757c63413a15222af90d3648de9de3 lib/request/comparison.py
|
||||||
|
72a0e7bb1010bb39c6538dbc77eae180 lib/request/connect.py
|
||||||
|
49b4c583af68689de5f9acb162de2939 lib/request/direct.py
|
||||||
|
1a46f7bb26b23ec0c0d9d9c95828241b lib/request/dns.py
|
||||||
|
567656470d23a42ab57ec55a03989dbb lib/request/httpshandler.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e lib/request/__init__.py
|
||||||
|
aa155f8b27d56485d3ff15efa5e1b07a lib/request/inject.py
|
||||||
|
3fc323d525beddd14cd4d4dca4934fa8 lib/request/methodrequest.py
|
||||||
|
585a6705cfac79f795b835affb80c901 lib/request/pkihandler.py
|
||||||
|
b2ffd261947994f4a4af555d468b4970 lib/request/rangehandler.py
|
||||||
|
53eede2efbfabc7315ea99756a03f49d lib/request/redirecthandler.py
|
||||||
|
4d838b086f128a94a91aa293ca1e0719 lib/request/templates.py
|
||||||
|
937b7e276f25ccac5a2ac0bf9b1ef434 lib/takeover/abstraction.py
|
||||||
|
3ecf028d8d93025d2a12c6f6fc13adb2 lib/takeover/icmpsh.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e lib/takeover/__init__.py
|
||||||
|
1d064463302b85b2241263ea48a83837 lib/takeover/metasploit.py
|
||||||
|
7083825564c051a7265cfdd1a5e6629c lib/takeover/registry.py
|
||||||
|
7d6cd7bdfc8f4bc4e8aed60c84cdf87f lib/takeover/udf.py
|
||||||
|
f6e3084abd506925a8be3d1c0a6d058c lib/takeover/web.py
|
||||||
|
9af83a62de360184f1c14e69b8a95cfe lib/takeover/xp_cmdshell.py
|
||||||
|
927092550c89f8c3c5caad2b14af0830 lib/techniques/blind/inference.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e lib/techniques/blind/__init__.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e lib/techniques/brute/__init__.py
|
||||||
|
d36effffe64e63ef9b3be490f850e2cc lib/techniques/brute/use.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e lib/techniques/dns/__init__.py
|
||||||
|
b658a1df33fd967c0b6d82911383abda lib/techniques/dns/test.py
|
||||||
|
4033bdb9e6973ee814fb68d3cf9e710c lib/techniques/dns/use.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e lib/techniques/error/__init__.py
|
||||||
|
4a1fb475f4a193e2cac48c8c038f5677 lib/techniques/error/use.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e lib/techniques/__init__.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e lib/techniques/union/__init__.py
|
||||||
|
f5d6884cdeed28281187c111d3e49e3b lib/techniques/union/test.py
|
||||||
|
12ce1bb7ee5f1f23f58be12fe9fa8472 lib/techniques/union/use.py
|
||||||
|
2dfc03a7322c46deb2e5353a7fd4be5e lib/utils/api.py
|
||||||
|
8cdc8c1e663c3b92a756fb7b02cc3c02 lib/utils/crawler.py
|
||||||
|
393f8fd1684308213e1d2e6a9d4258c2 lib/utils/deps.py
|
||||||
|
4dfd3a95e73e806f62372d63bc82511f lib/utils/getch.py
|
||||||
|
b1e83fc549334fae8f60552dcdad28cb lib/utils/hashdb.py
|
||||||
|
0330607242d4f704ae6d7bba5f52ccae lib/utils/hash.py
|
||||||
|
a3e885f7d4c6ff05db1156244bb84158 lib/utils/htmlentities.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e lib/utils/__init__.py
|
||||||
|
f0bd8f810332027a5c2c60bd17455f90 lib/utils/pivotdumptable.py
|
||||||
|
da08a0b58c08ff452c7d1da4857d6680 lib/utils/progress.py
|
||||||
|
4c8895fb543aa5ae81f2d066422613f0 lib/utils/purge.py
|
||||||
|
cc9b0f68dd58a2576a5a454b7f5f6b9c lib/utils/search.py
|
||||||
|
4a0374ac0bc9d726446f04c77fbb5697 lib/utils/sqlalchemy.py
|
||||||
|
8013e4a4c62ad916452434ea3c352a7a lib/utils/timeout.py
|
||||||
|
e6fa0e76367a77015da113811dfd9712 lib/utils/versioncheck.py
|
||||||
|
4759e0bb8931d461dfcad410ca05fc5d lib/utils/xrange.py
|
||||||
|
988100b4a1cd3b07acfd8b6ec692aed5 plugins/dbms/access/connector.py
|
||||||
|
27a5ae5611836b073dd53b21435f0979 plugins/dbms/access/enumeration.py
|
||||||
|
438090ab8ca63d9c23831a5ffbef74d9 plugins/dbms/access/filesystem.py
|
||||||
|
ec6e8a706c3e281677de4a21f0b68d6e plugins/dbms/access/fingerprint.py
|
||||||
|
7e54993a1a8340425eb9e6d1396596de plugins/dbms/access/__init__.py
|
||||||
|
994fc6a93632219d76831aad415742de plugins/dbms/access/syntax.py
|
||||||
|
495e835bea7703ae343179e3df838b86 plugins/dbms/access/takeover.py
|
||||||
|
393da1c45d0b1ecf67bfa5ae9a490f3f plugins/dbms/db2/connector.py
|
||||||
|
90271f2422c4374edfb7936151a440a4 plugins/dbms/db2/enumeration.py
|
||||||
|
e8f0f28da98020dce27970a50e10a23b plugins/dbms/db2/filesystem.py
|
||||||
|
b95216204096179fd50004c489ba5c6e plugins/dbms/db2/fingerprint.py
|
||||||
|
49b62689e8f0d2da9e10d782b53a3d13 plugins/dbms/db2/__init__.py
|
||||||
|
8300ca02ecf00d3b00d78ecde8a86c09 plugins/dbms/db2/syntax.py
|
||||||
|
5f130772d2295ae61140acba894eaceb plugins/dbms/db2/takeover.py
|
||||||
|
42fc25e6a5363d2447ed1e2a81d77159 plugins/dbms/firebird/connector.py
|
||||||
|
22cadcf4f20aeea2f2abead6553ed460 plugins/dbms/firebird/enumeration.py
|
||||||
|
9e12a966e280951deb996a8a634eb9e2 plugins/dbms/firebird/filesystem.py
|
||||||
|
74f0a234bcb11cac697751ef9488579b plugins/dbms/firebird/fingerprint.py
|
||||||
|
0f9bf6cf9dad52336ad1c528bdb4d142 plugins/dbms/firebird/__init__.py
|
||||||
|
d16de4d9516f95956d4518e9412de77a plugins/dbms/firebird/syntax.py
|
||||||
|
80496d64b22c10ed4893b4149a162365 plugins/dbms/firebird/takeover.py
|
||||||
|
e125fb5d8d75861532a01828d829d85e plugins/dbms/hsqldb/connector.py
|
||||||
|
8fbc4653d0c880ca78278c8ae6823136 plugins/dbms/hsqldb/enumeration.py
|
||||||
|
b763ce42f66f7b81d05130bbd3e383a9 plugins/dbms/hsqldb/filesystem.py
|
||||||
|
c9d59b7c60aa0f0b23f920f932547e40 plugins/dbms/hsqldb/fingerprint.py
|
||||||
|
d278ad5f1c13fea871ed1120942244d5 plugins/dbms/hsqldb/__init__.py
|
||||||
|
d781720e15c23b662bae3098ed470756 plugins/dbms/hsqldb/syntax.py
|
||||||
|
2f957281cfe80396f73a3dccc0cb6d45 plugins/dbms/hsqldb/takeover.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e plugins/dbms/__init__.py
|
||||||
|
4c8667e8af763ddf82ee314c6681d4e1 plugins/dbms/maxdb/connector.py
|
||||||
|
075fd66b8bbabed18aeb304c6c0ef2a2 plugins/dbms/maxdb/enumeration.py
|
||||||
|
aa46f115a06c66b1e011aba98ec284bd plugins/dbms/maxdb/filesystem.py
|
||||||
|
535b389c7bac381c06ca34b0fe48c8ae plugins/dbms/maxdb/fingerprint.py
|
||||||
|
c24f2512f13dbaff9543fe6d96cbe53b plugins/dbms/maxdb/__init__.py
|
||||||
|
df0766e0f322505dcbfca2fc792fe62f plugins/dbms/maxdb/syntax.py
|
||||||
|
aeec4f12950e20c46da405d23ea08dbb plugins/dbms/maxdb/takeover.py
|
||||||
|
579d582f3716c310689b4aa7317b57df plugins/dbms/mssqlserver/connector.py
|
||||||
|
8318300d92865330f5b0db5c3df29835 plugins/dbms/mssqlserver/enumeration.py
|
||||||
|
6c249bcdef486803686a8b2f11566637 plugins/dbms/mssqlserver/filesystem.py
|
||||||
|
d01229e7161a5071934fc26b48a11e8c plugins/dbms/mssqlserver/fingerprint.py
|
||||||
|
2fbe5e485bcd05511cd1d7cb8cbdbde4 plugins/dbms/mssqlserver/__init__.py
|
||||||
|
a727b3cac910622d22b2ed92815716ef plugins/dbms/mssqlserver/syntax.py
|
||||||
|
f3da9f5298dac5d1f468828c07c81f70 plugins/dbms/mssqlserver/takeover.py
|
||||||
|
d8cd212ba7be09483af3f32256b71f05 plugins/dbms/mysql/connector.py
|
||||||
|
d251aecff7544f79f78385386bb7fa35 plugins/dbms/mysql/enumeration.py
|
||||||
|
a970f90c91ebd3a7e22955424fe5414e plugins/dbms/mysql/filesystem.py
|
||||||
|
eed5093257e65adfae7bb56c5a6d3eb0 plugins/dbms/mysql/fingerprint.py
|
||||||
|
a4535cb3873ada344e6e61dbe1a546d3 plugins/dbms/mysql/__init__.py
|
||||||
|
4ad721acc40a964fc67154dd4683870e plugins/dbms/mysql/syntax.py
|
||||||
|
aa88b5d6198cd31d9ab2be664da9a265 plugins/dbms/mysql/takeover.py
|
||||||
|
2f2b7b1f08a8e6bfbe2fd0467d477667 plugins/dbms/oracle/connector.py
|
||||||
|
061b5f0a2cf2e61c8a03ef73ee43a869 plugins/dbms/oracle/enumeration.py
|
||||||
|
97579ede42f5fa64397792a65d6c0781 plugins/dbms/oracle/filesystem.py
|
||||||
|
82b3e501ebae93c5dc0ef2abccb10177 plugins/dbms/oracle/fingerprint.py
|
||||||
|
ecfc3b8b1e97e41cad6681fc68f93998 plugins/dbms/oracle/__init__.py
|
||||||
|
1814ceabb19b6fcf908d4638cf0436ef plugins/dbms/oracle/syntax.py
|
||||||
|
cac6bd84d44ac929da6800719279875b plugins/dbms/oracle/takeover.py
|
||||||
|
6c54ca5c9efad3e437467f9fe44435d6 plugins/dbms/postgresql/connector.py
|
||||||
|
419dd50e6688fef760fec4f71430fb29 plugins/dbms/postgresql/enumeration.py
|
||||||
|
9756fc02fc84719c3e330fcc7914bf17 plugins/dbms/postgresql/filesystem.py
|
||||||
|
28bce42dac3ee8efccc78c7a58b170b6 plugins/dbms/postgresql/fingerprint.py
|
||||||
|
0e7d17abf68f1dd770e969c84878d246 plugins/dbms/postgresql/__init__.py
|
||||||
|
8711e7c1265a5e651c9aadca7db40cd5 plugins/dbms/postgresql/syntax.py
|
||||||
|
50d8070e687e5806058a121311a36385 plugins/dbms/postgresql/takeover.py
|
||||||
|
316c39c5c866c5e6b0afaf51fc773ca3 plugins/dbms/sqlite/connector.py
|
||||||
|
1cbe2b28041e52b421f256b813e0ec9d plugins/dbms/sqlite/enumeration.py
|
||||||
|
f3318e79b1130e052242db8299eb1968 plugins/dbms/sqlite/filesystem.py
|
||||||
|
17752c107b24f5a83926f8c62a50f15a plugins/dbms/sqlite/fingerprint.py
|
||||||
|
098c50a83ceca04e3acc67a7c66fb0d2 plugins/dbms/sqlite/__init__.py
|
||||||
|
a27325e2c88a0d38fe871509329cc9d5 plugins/dbms/sqlite/syntax.py
|
||||||
|
53b0be0cb6599d042bf6772e62b25ca5 plugins/dbms/sqlite/takeover.py
|
||||||
|
579d582f3716c310689b4aa7317b57df plugins/dbms/sybase/connector.py
|
||||||
|
7d58cbb4527d7a48ca05037f0b2ffe0a plugins/dbms/sybase/enumeration.py
|
||||||
|
ca107f3d1b4854ce84386109d476d494 plugins/dbms/sybase/filesystem.py
|
||||||
|
e095022426f2b986d069748ee2289af1 plugins/dbms/sybase/fingerprint.py
|
||||||
|
d0c7cc8ec2aa716b2e5cd3b5ab805c3a plugins/dbms/sybase/__init__.py
|
||||||
|
4763a90266c1633054ad7f3f0926a71d plugins/dbms/sybase/syntax.py
|
||||||
|
7a1c6cb238b5b464e1e9641469e6e503 plugins/dbms/sybase/takeover.py
|
||||||
|
62faa58e5aace4b6a6d562788685186f plugins/generic/connector.py
|
||||||
|
cdbf6eec4a94f830deb7dbab1c1a2935 plugins/generic/custom.py
|
||||||
|
977bbd1bced67c2c4aa74d12c77ac165 plugins/generic/databases.py
|
||||||
|
f2394baa3746188184be2144025eeffc plugins/generic/entries.py
|
||||||
|
e335b868f5fb1154c9f72143d602915d plugins/generic/enumeration.py
|
||||||
|
3e673ef4e6592f52a11d88e61fe4dc2b plugins/generic/filesystem.py
|
||||||
|
5637c508ca6348f29c2b100a3e80dddc plugins/generic/fingerprint.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e plugins/generic/__init__.py
|
||||||
|
7ffeee6d232ff6b342f362a2a4d226c0 plugins/generic/misc.py
|
||||||
|
7b3e044a7fca497278d79883697089b7 plugins/generic/search.py
|
||||||
|
73f8d047dbbcff307d62357836e382e6 plugins/generic/syntax.py
|
||||||
|
da3ebc20998af02e3d952d0417a67792 plugins/generic/takeover.py
|
||||||
|
4b5a6e2aec8e240fc43916d9dde27b14 plugins/generic/users.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e plugins/__init__.py
|
||||||
|
b04db3e861edde1f9dd0a3850d5b96c8 shell/backdoor.asp_
|
||||||
|
158bfa168128393dde8d6ed11fe9a1b8 shell/backdoor.aspx_
|
||||||
|
1add5a9a67539e7fd1999c8c20a69d15 shell/backdoor.jsp_
|
||||||
|
09fc3ed6543f4d1885e338b271e5e97a shell/backdoor.php_
|
||||||
|
ff90cb0366f7cefbdd6e573e27e6238c shell/runcmd.exe_
|
||||||
|
0e7aba05423c272f051f31165b0e416d shell/stager.asp_
|
||||||
|
c3cc8b7727161e64ab59f312c33b541a shell/stager.aspx_
|
||||||
|
1f7f125f30e0e800beb21e2ebbab18e1 shell/stager.jsp_
|
||||||
|
01e3505e796edf19aad6a996101c81c9 shell/stager.php_
|
||||||
|
56702e95555adee718b6a11ee7098fd4 sqlmapapi.py
|
||||||
|
7e80fcefc56426ed780c48556b70a1f0 sqlmap.py
|
||||||
|
1316deb997418507e76221c84ec99946 tamper/apostrophemask.py
|
||||||
|
a6efe8f914c769c52afec703bd73609f tamper/apostrophenullencode.py
|
||||||
|
b1c56983919b69f4f6f0e7929c881e7a tamper/appendnullbyte.py
|
||||||
|
1233f8bad4d9a33d7961073c449874a2 tamper/base64encode.py
|
||||||
|
6aa5ba5689d9689825338260194670e0 tamper/between.py
|
||||||
|
21f4ce75916531641cfe405ce91663fc tamper/bluecoat.py
|
||||||
|
43cfacec17de26ff2a61c519e2e86dc9 tamper/chardoubleencode.py
|
||||||
|
344751c277ca62fa42dac95deedb0cdf tamper/charencode.py
|
||||||
|
c6c90b5c175770ff98859653115dc478 tamper/charunicodeencode.py
|
||||||
|
b7f5de532d2b87a477840c7d2a3cf386 tamper/commalesslimit.py
|
||||||
|
e2aca0ea57afc24dd154472034dc9c8c tamper/commalessmid.py
|
||||||
|
7dec60fa5a1f27513cfba131e07b4d2f tamper/concat2concatws.py
|
||||||
|
906f38bffac305d341e69721631c9b1e tamper/equaltolike.py
|
||||||
|
11bb0652668bb6624494567fd92933b3 tamper/escapequotes.py
|
||||||
|
731c25dd33fca28514930d4409daaaa3 tamper/greatest.py
|
||||||
|
1becabc90d81c70fd24b54cae03a3702 tamper/halfversionedmorekeywords.py
|
||||||
|
17313c5a68aa44325616e0e38869b98e tamper/ifnull2ifisnull.py
|
||||||
|
dd71bbc7f76ef55a2c9c16645347ead8 tamper/informationschemacomment.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e tamper/__init__.py
|
||||||
|
4f022b7dbe12957003ee06e2610baa85 tamper/lowercase.py
|
||||||
|
38543c4fc77acbd346cdbdbdfebee799 tamper/modsecurityversioned.py
|
||||||
|
c16c3ed0ce302034d99ee0b8f34fbd0b tamper/modsecurityzeroversioned.py
|
||||||
|
658742d52fe9fcd357c87198650982b8 tamper/multiplespaces.py
|
||||||
|
e65ff0680df2fc89444ec5953bb2f161 tamper/nonrecursivereplacement.py
|
||||||
|
6780d738236ac200d230c4cb497bd1a2 tamper/overlongutf8.py
|
||||||
|
3f05d5218b22280adcd91fe53830bcb4 tamper/percentage.py
|
||||||
|
7a93f510f231278897650da1c7d13b23 tamper/randomcase.py
|
||||||
|
34c255f3bca6d5fee2dfb18ed86d406f tamper/randomcomments.py
|
||||||
|
f5e9eb84d4c5e9a19fe7154a8aebe13d tamper/securesphere.py
|
||||||
|
b4fc315dd6956dbe62a14c3efbe734b8 tamper/space2comment.py
|
||||||
|
c58858bebc9128a2685e93c985c8c23e tamper/space2dash.py
|
||||||
|
7cb376474d8d2dfa524be8f09d5bbf87 tamper/space2hash.py
|
||||||
|
ac2674939af0d1e82802d9343856db08 tamper/space2morehash.py
|
||||||
|
7f26c6fca4ef394c8d84c1ffe0162834 tamper/space2mssqlblank.py
|
||||||
|
df92b78d4ebe3de3e922eae1520020bf tamper/space2mssqlhash.py
|
||||||
|
63dcc179881387c6a2ca4b84b4723efe tamper/space2mysqlblank.py
|
||||||
|
6c9a0f9f98b938b0dc814644eeeb4d69 tamper/space2mysqldash.py
|
||||||
|
898361e5bc84fee788005a31494c1b8d tamper/space2plus.py
|
||||||
|
ea567cf81dafcb961eb1e88396534fd5 tamper/space2randomblank.py
|
||||||
|
da09cdc03e7d306e68a0c45322cc14c2 tamper/sp_password.py
|
||||||
|
84d536cd1296affcf4d294846508ef1a tamper/symboliclogical.py
|
||||||
|
50ead20b50db1051f8f3790c910b7b36 tamper/unionalltounion.py
|
||||||
|
f248289f5bc6ff9df8d82f8a3649d7a2 tamper/unmagicquotes.py
|
||||||
|
05824e0a1eb695bfc61d83ca8578de8f tamper/uppercase.py
|
||||||
|
ccdcf7afb18efd83d8b7a59d744fe51f tamper/varnish.py
|
||||||
|
a5f02f75856551499c0bf33672869a7f tamper/versionedkeywords.py
|
||||||
|
61aec82c2fb383bf9db95b74f5f0e67a tamper/versionedmorekeywords.py
|
||||||
|
99a90d668f367f5660698c00e84ec671 tamper/xforwardedfor.py
|
||||||
|
368165b45dadcdff4422bc010700832a thirdparty/ansistrm/ansistrm.py
|
||||||
|
d41d8cd98f00b204e9800998ecf8427e thirdparty/ansistrm/__init__.py
|
||||||
|
a53a7a876b401aaaa3535376676692ae thirdparty/beautifulsoup/beautifulsoup.py
|
||||||
|
cb2e1fe7c404dff41a2ae9132828f532 thirdparty/beautifulsoup/__init__.py
|
||||||
|
ff54a1d98f0ab01ba7b58b068d2ebd26 thirdparty/bottle/bottle.py
|
||||||
|
4528e6a7bb9341c36c425faf40ef32c3 thirdparty/bottle/__init__.py
|
||||||
|
b20f539dc45fa9e514c1eb4f5aa8b5c6 thirdparty/chardet/big5freq.py
|
||||||
|
44159687c2bae35f165b44f07f5f167a thirdparty/chardet/big5prober.py
|
||||||
|
c80b09e2a63b375c02c8c1e825a953c5 thirdparty/chardet/chardetect.py
|
||||||
|
d2c4ad8cc905d95f148ead169d249eb8 thirdparty/chardet/chardistribution.py
|
||||||
|
24c57085435b8ad1a7bf9ff4ffe6cce0 thirdparty/chardet/charsetgroupprober.py
|
||||||
|
0cb6549c5cf979c8023f8aaf3392a117 thirdparty/chardet/charsetprober.py
|
||||||
|
241dd3b7d3eb97ae384320fc8346c6ff thirdparty/chardet/codingstatemachine.py
|
||||||
|
73f2b9ae331ab011571a3b3a2c62acc1 thirdparty/chardet/compat.py
|
||||||
|
6cccf2eada7dfa841a5c39aaecb037e7 thirdparty/chardet/constants.py
|
||||||
|
dd0087e46f835b791a5c9904fcda2de3 thirdparty/chardet/cp949prober.py
|
||||||
|
ecf56c6473c5a9bc0540a1ca11ec998a thirdparty/chardet/escprober.py
|
||||||
|
00590b3c94c4db8f25639ab261e4c725 thirdparty/chardet/escsm.py
|
||||||
|
99bc93e45136ecd15d8dfb489059f118 thirdparty/chardet/eucjpprober.py
|
||||||
|
65b6b3e75845e033ce34c11ccdd85450 thirdparty/chardet/euckrfreq.py
|
||||||
|
cc2282aef66a161b3451f9cf455fdd7d thirdparty/chardet/euckrprober.py
|
||||||
|
f13fee8c7bd6db0e8c40030ccacdfbde thirdparty/chardet/euctwfreq.py
|
||||||
|
ca66f5277872165faa5140068794604a thirdparty/chardet/euctwprober.py
|
||||||
|
0fb5414fcc0bdb8b04af324015505c06 thirdparty/chardet/gb2312freq.py
|
||||||
|
84284584b8e29f50f40781205a9d4e76 thirdparty/chardet/gb2312prober.py
|
||||||
|
354a83d1bb3c20b4626b6c4ad54d163a thirdparty/chardet/hebrewprober.py
|
||||||
|
d91ddc14e31824faacd96fa88e42a6b8 thirdparty/chardet/__init__.py
|
||||||
|
03be91b7ead4725af61234d4852bb7ab thirdparty/chardet/jisfreq.py
|
||||||
|
b59a7b8b0debe197444bf831ba42bbe9 thirdparty/chardet/jpcntx.py
|
||||||
|
e4e05437410aa80cf9a13afac19997fe thirdparty/chardet/langbulgarianmodel.py
|
||||||
|
74ce958cbef2eee08a7a04fb4db41260 thirdparty/chardet/langcyrillicmodel.py
|
||||||
|
7090da7635347b767b4eb194f697207d thirdparty/chardet/langgreekmodel.py
|
||||||
|
22df1e2996355e4c082cc0b2f8dbe261 thirdparty/chardet/langhebrewmodel.py
|
||||||
|
3b86d62fe73022a609b2e8095edecf87 thirdparty/chardet/langhungarianmodel.py
|
||||||
|
4f941425be84ee4e1b7ccb7c4b31e8d8 thirdparty/chardet/langthaimodel.py
|
||||||
|
9e7400a368b70c1acccab78d2cc489cd thirdparty/chardet/latin1prober.py
|
||||||
|
c27857a02a65a1100f3195f95c50aff9 thirdparty/chardet/mbcharsetprober.py
|
||||||
|
719ecf479d507a3e6450aefbaa42fcc8 thirdparty/chardet/mbcsgroupprober.py
|
||||||
|
2fd9f3c93568c552779bd46990027c36 thirdparty/chardet/mbcssm.py
|
||||||
|
93349a5fa5cb824d1485cd5f3a53928a thirdparty/chardet/sbcharsetprober.py
|
||||||
|
ee25f2a03587e2c283eab0b36c9e5783 thirdparty/chardet/sbcsgroupprober.py
|
||||||
|
c9349824f2647962175d321cc0c52134 thirdparty/chardet/sjisprober.py
|
||||||
|
bcae4c645a737d3f0e7c96a66528ca4a thirdparty/chardet/universaldetector.py
|
||||||
|
6f8b3e25472c02fb45a75215a175991f thirdparty/chardet/utf8prober.py
|
||||||
|
b678dcd25ecb1533ffe2493b6e711bb1 thirdparty/clientform/clientform.py
|
||||||
|
722281d87fb13ec22555480f8f4c715b thirdparty/clientform/__init__.py
|
||||||
|
0b625ccefa6b066f79d3cbb3639267e6 thirdparty/colorama/ansi.py
|
||||||
|
e52252bb81ce1a14b7245b53af33e75f thirdparty/colorama/ansitowin32.py
|
||||||
|
ed4d76c08741d34ac79f6488663345f7 thirdparty/colorama/initialise.py
|
||||||
|
c0707ca77ccb4a2c0f12b4085057193c thirdparty/colorama/__init__.py
|
||||||
|
ad3d022d4591aee80f7391248d722413 thirdparty/colorama/win32.py
|
||||||
|
c690e140157d0caac5824c73688231b3 thirdparty/colorama/winterm.py
|
||||||
|
be7eac2e6cfb45c5e297ec5eee66e747 thirdparty/fcrypt/fcrypt.py
|
||||||
|
e00542d22ffa8d8ac894c210f38454be thirdparty/fcrypt/__init__.py
|
||||||
|
2f94ddd6ada38e4091e819568e7c4b7c thirdparty/gprof2dot/gprof2dot.py
|
||||||
|
855372c870a23d46683f8aa39d75f6a1 thirdparty/gprof2dot/__init__.py
|
||||||
|
d41d8cd98f00b204e9800998ecf8427e thirdparty/__init__.py
|
||||||
|
e3b18f925d125bd17c7e7a7ec0b4b85f thirdparty/keepalive/__init__.py
|
||||||
|
e0c6a936506bffeed53ce106ec15942d thirdparty/keepalive/keepalive.py
|
||||||
|
d41d8cd98f00b204e9800998ecf8427e thirdparty/magic/__init__.py
|
||||||
|
49f0d123e044dd32a452e2fe51f1a9c3 thirdparty/magic/magic.py
|
||||||
|
d41d8cd98f00b204e9800998ecf8427e thirdparty/multipart/__init__.py
|
||||||
|
fd52df5770ee286a7c186fdd2ccc4e0c thirdparty/multipart/multipartpost.py
|
||||||
|
3e502b04f3849afbb7f0e13b5fd2b5c1 thirdparty/odict/__init__.py
|
||||||
|
127fe54fdb9b13fdac93c8fc9c9cad5e thirdparty/odict/odict.py
|
||||||
|
08801ea0ba9ae22885275ef65d3ee9dc thirdparty/oset/_abc.py
|
||||||
|
54a861de0f08bb80c2e8846579ec83bd thirdparty/oset/__init__.py
|
||||||
|
179f0c584ef3fb39437bdb6e15d9c867 thirdparty/oset/pyoset.py
|
||||||
|
d24924d878e24946e83cfc1459f806af thirdparty/pagerank/__init__.py
|
||||||
|
7616693115d08f9b815a567515a0db56 thirdparty/pagerank/pagerank.py
|
||||||
|
94a4abc0fdac64ef0661b82aff68d791 thirdparty/prettyprint/__init__.py
|
||||||
|
ff80a22ee858f5331b0c088efa98b3ff thirdparty/prettyprint/prettyprint.py
|
||||||
|
5c70f8e5f7353aedc6d8d21d4fb72b37 thirdparty/pydes/__init__.py
|
||||||
|
a7f735641c5b695f3d6220fe7c91b030 thirdparty/pydes/pyDes.py
|
||||||
|
d41d8cd98f00b204e9800998ecf8427e thirdparty/socks/__init__.py
|
||||||
|
ec6bab337d529037fb7db0b126bce7cd thirdparty/socks/socks.py
|
||||||
|
d41d8cd98f00b204e9800998ecf8427e thirdparty/termcolor/__init__.py
|
||||||
|
ea649aae139d8551af513769dd913dbf thirdparty/termcolor/termcolor.py
|
||||||
|
855372c870a23d46683f8aa39d75f6a1 thirdparty/xdot/__init__.py
|
||||||
|
593473084228b63a12318d812e50f1e2 thirdparty/xdot/xdot.py
|
||||||
|
08c706478fad0acba049d0e32cbb6411 udf/mysql/linux/32/lib_mysqludf_sys.so_
|
||||||
|
1501fa7150239b18acc0f4a9db2ebc0d udf/mysql/linux/64/lib_mysqludf_sys.so_
|
||||||
|
7824059e8fc87c4a565e774676e2f1eb udf/mysql/windows/32/lib_mysqludf_sys.dll_
|
||||||
|
7fed5b8e99e36ce255c64527ec61a995 udf/mysql/windows/64/lib_mysqludf_sys.dll_
|
||||||
|
6b4dc184e545d7bd5e7c31590647471d udf/postgresql/linux/32/8.2/lib_postgresqludf_sys.so_
|
||||||
|
8c5573d1da59024c47d00cc8492a92df udf/postgresql/linux/32/8.3/lib_postgresqludf_sys.so_
|
||||||
|
b9930f6bf43780fff469bc40e20599c3 udf/postgresql/linux/32/8.4/lib_postgresqludf_sys.so_
|
||||||
|
6930b6d67f4d52b5c1663ac2d8460576 udf/postgresql/linux/32/9.0/lib_postgresqludf_sys.so_
|
||||||
|
5c177ee2cffad6133e99a24d1f913660 udf/postgresql/linux/32/9.1/lib_postgresqludf_sys.so_
|
||||||
|
4d0c06a51c5b03b41ad4df33a304d282 udf/postgresql/linux/32/9.2/lib_postgresqludf_sys.so_
|
||||||
|
db0b1fe75fd9db96c1fc6ab42ae76d70 udf/postgresql/linux/32/9.3/lib_postgresqludf_sys.so_
|
||||||
|
df8524a627568864e1de516bbe5718ef udf/postgresql/linux/32/9.4/lib_postgresqludf_sys.so_
|
||||||
|
3c3e3b72fa5b5860108a0350a0604ba2 udf/postgresql/linux/64/8.2/lib_postgresqludf_sys.so_
|
||||||
|
b10e351f5d8c07fdf08dc3f44b00c01c udf/postgresql/linux/64/8.3/lib_postgresqludf_sys.so_
|
||||||
|
7714b28ee7669f60a2321f1b4ce6bba8 udf/postgresql/linux/64/8.4/lib_postgresqludf_sys.so_
|
||||||
|
9911482642131fd3be6a03a28294d24a udf/postgresql/linux/64/9.0/lib_postgresqludf_sys.so_
|
||||||
|
fed2ed6df3f809b1019e9a0ee102799d udf/postgresql/linux/64/9.1/lib_postgresqludf_sys.so_
|
||||||
|
d5d004b396ca5b14afe03a294d42c475 udf/postgresql/linux/64/9.2/lib_postgresqludf_sys.so_
|
||||||
|
5b79d7f667a0e1e4a70a5ceb70107cbe udf/postgresql/linux/64/9.3/lib_postgresqludf_sys.so_
|
||||||
|
b396f050d36e82baf2724f140165fbd5 udf/postgresql/linux/64/9.4/lib_postgresqludf_sys.so_
|
||||||
|
a6b9c964f7c7d7012f8f434bbd84a041 udf/postgresql/windows/32/8.2/lib_postgresqludf_sys.dll_
|
||||||
|
d9006810684baf01ea33281d21522519 udf/postgresql/windows/32/8.3/lib_postgresqludf_sys.dll_
|
||||||
|
ca3ab78d6ed53b7f2c07ed2530d47efd udf/postgresql/windows/32/8.4/lib_postgresqludf_sys.dll_
|
||||||
|
0d3fe0293573a4453463a0fa5a081de1 udf/postgresql/windows/32/9.0/lib_postgresqludf_sys.dll_
|
||||||
|
9bb247767c4ba118f2c5f0416e3e6151 waf/360.py
|
||||||
|
deb8dd4543177479b185af8b383a8bdf waf/airlock.py
|
||||||
|
0da662422cde266dd47cea3f5be6a309 waf/anquanbao.py
|
||||||
|
012b4acd41f0c12df88cf0276c2afd1a waf/armor.py
|
||||||
|
757fe0f66a24719fa596cb974ee6ae71 waf/baidu.py
|
||||||
|
8a26fe9e0ae48e8f28272769aa7dc16e waf/barracuda.py
|
||||||
|
826b64868a10caf1229d3bfcbbb4d594 waf/bigip.py
|
||||||
|
3105f71b03c428f8b58cbf7a91eebff0 waf/binarysec.py
|
||||||
|
e75422b8487f9937e050a60bc5c35896 waf/blockdos.py
|
||||||
|
f60078f702612da43dd2a8ed07e26694 waf/ciscoacexml.py
|
||||||
|
ac2edfa1d49b00b4bf730a9317090566 waf/cloudflare.py
|
||||||
|
c69e1091521671452eaedf4787817ede waf/cloudfront.py
|
||||||
|
765d0663658257ef0ab1060519c6e175 waf/comodo.py
|
||||||
|
33633c9a2b9d53c325ba1110607d566f waf/datapower.py
|
||||||
|
e0ad6e34b6082558e9f8f652d938c785 waf/denyall.py
|
||||||
|
1ab6764976b3e2e28bab68cc73b5d8d9 waf/dotdefender.py
|
||||||
|
037b715e1274fe2b4d2f31f6d24c9e77 waf/edgecast.py
|
||||||
|
29d0c8331a4d7013d784e5dc91db49aa waf/expressionengine.py
|
||||||
|
d50415b49d9df72cb9d193d05630ab8a waf/fortiweb.py
|
||||||
|
c5d83d63647baa46dadf5cf992156edc waf/generic.py
|
||||||
|
b302a688932296357fe10658a81eee0c waf/hyperguard.py
|
||||||
|
f62b484e9083fcbf271a2b0c8f6d3528 waf/incapsula.py
|
||||||
|
cc9c82cfffd8ee9b25ba3af6284f057e waf/__init__.py
|
||||||
|
5a898cfc081236d176274c5b513d0401 waf/isaserver.py
|
||||||
|
9689ff3faaeb2ea1837b3e04520b0e42 waf/jiasule.py
|
||||||
|
07eb9ee33a3e31bfc74763bea8026a2b waf/knownsec.py
|
||||||
|
32516985d3cb0aeeb1bf28062820b045 waf/kona.py
|
||||||
|
c3de612a7960b08e1e7f97aa05b58df1 waf/modsecurity.py
|
||||||
|
dc79a2e675d17df4cba1f8b839cbc11b waf/netcontinuum.py
|
||||||
|
c218fd16246dfbbd0485cb3456182c71 waf/netscaler.py
|
||||||
|
4e05b8169e53edd36a6269e937958744 waf/newdefend.py
|
||||||
|
80eb59b4dcb62de8c97bd1bebbfb3f80 waf/nsfocus.py
|
||||||
|
477c3b6b31e8eb1fe836bd5a24c9fab2 waf/paloalto.py
|
||||||
|
e667efa27b53191315df547e95e04fa7 waf/profense.py
|
||||||
|
8d5609a37127782fb35af4f67b5787ee waf/proventia.py
|
||||||
|
40125df9f8184eab1926add588762294 waf/radware.py
|
||||||
|
fffbd039ec907274cdb6ee8e07e3cac4 waf/requestvalidationmode.py
|
||||||
|
44bef80f1a34663c3e0a963d969d9b1f waf/safe3.py
|
||||||
|
65a519516a597232fd902082dbcbc796 waf/safedog.py
|
||||||
|
e8cbddfffab8b400ea03f28ebfe14536 waf/secureiis.py
|
||||||
|
32de8507c956422926aaf13085dbcf42 waf/senginx.py
|
||||||
|
33db1ac9a11667199c7886bbb74f6b02 waf/sitelock.py
|
||||||
|
ff2b052672f4753be1508f2a22118631 waf/sonicwall.py
|
||||||
|
310b6081c65fb81917b8695b013559b6 waf/sophos.py
|
||||||
|
ade8698c8096d373034bac72069873f6 waf/stingray.py
|
||||||
|
b372c4fcc949767c38f2bead62d07418 waf/sucuri.py
|
||||||
|
4c02fbf63989df9ab58b04229f00f6df waf/teros.py
|
||||||
|
b5ea5375df444e0240f1ee0e2a8e52fb waf/trafficshield.py
|
||||||
|
89a11a755a4ea3cb71feb3f5f2b5809e waf/urlscan.py
|
||||||
|
0569c783e3487551affe5c91aec3c6d3 waf/uspses.py
|
||||||
|
960a8db9d3807fcd87f7f66dbfaa4628 waf/varnish.py
|
||||||
|
98c909c8b6e50d715e5b88c639ff1836 waf/wallarm.py
|
||||||
|
7a723ce2f1b82d7297a2ab025d5ca0be waf/webappsecure.py
|
||||||
|
75e51fea7f206e8faa2f743e44e58383 waf/webknight.py
|
||||||
|
3bcac085dcd9ed26b50a2320e418e9f3 waf/yundun.py
|
||||||
|
2d53fdaca0d7b42edad5192661248d76 xml/banner/cookie.xml
|
||||||
|
37603bc0905af0c65480a2ca959990ec xml/banner/generic.xml
|
||||||
|
d8925c034263bf1b83e7d8e1c78eec57 xml/banner/mssql.xml
|
||||||
|
c97c383b560cd578f74c5e4d88c88ed2 xml/banner/mysql.xml
|
||||||
|
9b262a617b06af56b1267987d694bf6f xml/banner/oracle.xml
|
||||||
|
0d1c881156b760492d8004bd0d926c63 xml/banner/postgresql.xml
|
||||||
|
b07b5c47c751787e136650ded060197f xml/banner/server.xml
|
||||||
|
e5d141fb2ba31e4eae3495554b538908 xml/banner/servlet.xml
|
||||||
|
d989813ee377252bca2103cea524c06b xml/banner/sharepoint.xml
|
||||||
|
350605448f049cd982554123a75f11e1 xml/banner/x-aspnet-version.xml
|
||||||
|
2394458d582a636c52342cff33ae3035 xml/banner/x-powered-by.xml
|
||||||
|
fb93505ef0ab3b4a20900f3e5625260d xml/boundaries.xml
|
||||||
|
535d625cff8418bdc086ab4e1bbf5135 xml/errors.xml
|
||||||
|
2e13b9e0a51768969d4ccc02cf62ea70 xml/livetests.xml
|
||||||
|
18b2c7e5738a3be72d759af96a9aaddf xml/payloads/boolean_blind.xml
|
||||||
|
103a4c9b12c582b24a3fac8147a9c8d4 xml/payloads/error_based.xml
|
||||||
|
06b1a210b190d52477a9d492443725b5 xml/payloads/inline_query.xml
|
||||||
|
96adb9bfbab867d221974d3ddb303cb6 xml/payloads/stacked_queries.xml
|
||||||
|
c8b152ecebf04ec997e52c6c78cbd488 xml/payloads/time_blind.xml
|
||||||
|
033b39025e8ee0f302935f6db3a39e77 xml/payloads/union_query.xml
|
||||||
|
313c0e1cc42de27a29c0e0ac67fee71d xml/queries.xml
|
||||||
@@ -15,8 +15,9 @@ def detect(get_page):
|
|||||||
retval = False
|
retval = False
|
||||||
|
|
||||||
for vector in WAF_ATTACK_VECTORS:
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
_, headers, _ = get_page(get=vector)
|
page, headers, code = get_page(get=vector)
|
||||||
retval = re.search(r"wangzhan\.360\.cn", headers.get("X-Powered-By-360wzb", ""), re.I) is not None
|
retval = re.search(r"wangzhan\.360\.cn", headers.get("X-Powered-By-360wzb", ""), re.I) is not None
|
||||||
|
retval |= code == 493 and "/wzws-waf-cgi/" in (page or "")
|
||||||
if retval:
|
if retval:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,9 @@ def detect(get_page):
|
|||||||
retval = False
|
retval = False
|
||||||
|
|
||||||
for vector in WAF_ATTACK_VECTORS:
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
_, headers, _ = get_page(get=vector)
|
page, headers, code = get_page(get=vector)
|
||||||
retval = re.search(r"MISS", headers.get("X-Powered-By-Anquanbao", ""), re.I) is not None
|
retval = re.search(r"MISS", headers.get("X-Powered-By-Anquanbao", ""), re.I) is not None
|
||||||
|
retval |= code == 405 and "/aqb_cc/error/" in (page or "")
|
||||||
if retval:
|
if retval:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
21
waf/armor.py
Normal file
21
waf/armor.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'doc/COPYING' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.settings import WAF_ATTACK_VECTORS
|
||||||
|
|
||||||
|
__product__ = "Armor Protection (Armor Defense)"
|
||||||
|
|
||||||
|
def detect(get_page):
|
||||||
|
retval = False
|
||||||
|
|
||||||
|
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 "")
|
||||||
|
if retval:
|
||||||
|
break
|
||||||
|
|
||||||
|
return retval
|
||||||
@@ -18,7 +18,7 @@ def detect(get_page):
|
|||||||
for vector in WAF_ATTACK_VECTORS:
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
_, headers, _ = get_page(get=vector)
|
_, headers, _ = get_page(get=vector)
|
||||||
retval = re.search(r"fhl", headers.get("X-Server", ""), re.I) is not None
|
retval = re.search(r"fhl", headers.get("X-Server", ""), re.I) is not None
|
||||||
retval |= re.search(r"yunjiasu-nginx", headers.get(HTTP_HEADER.SERVER), re.I) is not None
|
retval |= re.search(r"yunjiasu-nginx", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
|
||||||
if retval:
|
if retval:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ def detect(get_page):
|
|||||||
for vector in WAF_ATTACK_VECTORS:
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
_, headers, _ = get_page(get=vector)
|
_, headers, _ = get_page(get=vector)
|
||||||
retval = headers.get("X-Cnection", "").lower() == "close"
|
retval = headers.get("X-Cnection", "").lower() == "close"
|
||||||
retval |= re.search(r"\ATS[a-zA-Z0-9]{3,6}=", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
|
retval |= re.search(r"\ATS[a-zA-Z0-9]{4,}=", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
|
||||||
|
retval |= re.search(r"BigIP|BIGipServer", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
|
||||||
retval |= re.search(r"BigIP|BIGipServer", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
|
retval |= re.search(r"BigIP|BIGipServer", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
|
||||||
|
retval |= re.search(r"\AF5\Z", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
|
||||||
if retval:
|
if retval:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,14 @@ def detect(get_page):
|
|||||||
retval = False
|
retval = False
|
||||||
|
|
||||||
for vector in WAF_ATTACK_VECTORS:
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
_, headers, _ = get_page(get=vector)
|
page, headers, code = get_page(get=vector)
|
||||||
retval = re.search(r"cloudflare-nginx", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
|
retval = re.search(r"cloudflare-nginx", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
|
||||||
|
|
||||||
|
if code >= 400:
|
||||||
retval |= re.search(r"\A__cfduid=", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
|
retval |= re.search(r"\A__cfduid=", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
|
||||||
|
retval |= headers.get("cf-ray") is not None
|
||||||
|
retval |= re.search(r"CloudFlare Ray ID:|var CloudFlare=", page or "") is not None
|
||||||
|
|
||||||
if retval:
|
if retval:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
26
waf/cloudfront.py
Normal file
26
waf/cloudfront.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'doc/COPYING' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
from lib.core.settings import WAF_ATTACK_VECTORS
|
||||||
|
|
||||||
|
__product__ = "CloudFront (Amazon)"
|
||||||
|
|
||||||
|
def detect(get_page):
|
||||||
|
retval = False
|
||||||
|
|
||||||
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
|
_, headers, _ = get_page(get=vector)
|
||||||
|
|
||||||
|
retval |= re.search(r"cloudfront", headers.get("X-Cache", ""), re.I) is not None
|
||||||
|
retval |= headers.get("X-Amz-Cf-Id") is not None
|
||||||
|
|
||||||
|
if retval:
|
||||||
|
break
|
||||||
|
|
||||||
|
return retval
|
||||||
24
waf/comodo.py
Normal file
24
waf/comodo.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'doc/COPYING' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
from lib.core.enums import HTTP_HEADER
|
||||||
|
from lib.core.settings import WAF_ATTACK_VECTORS
|
||||||
|
|
||||||
|
__product__ = "Comodo Web Application Firewall (Comodo)"
|
||||||
|
|
||||||
|
def detect(get_page):
|
||||||
|
retval = False
|
||||||
|
|
||||||
|
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
|
||||||
|
if retval:
|
||||||
|
break
|
||||||
|
|
||||||
|
return retval
|
||||||
@@ -18,7 +18,7 @@ def detect(get_page):
|
|||||||
for vector in WAF_ATTACK_VECTORS:
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
page, headers, code = get_page(get=vector)
|
page, headers, code = get_page(get=vector)
|
||||||
retval = re.search(r"\Asessioncookie=", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
|
retval = re.search(r"\Asessioncookie=", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
|
||||||
retval |= code == 200 and re.search(r"\ACondition Intercepted", page, re.I) is not None
|
retval |= code == 200 and re.search(r"\ACondition Intercepted", page or "", re.I) is not None
|
||||||
if retval:
|
if retval:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@@ -13,9 +13,10 @@ def detect(get_page):
|
|||||||
retval = False
|
retval = False
|
||||||
|
|
||||||
for vector in WAF_ATTACK_VECTORS:
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
_, headers, _ = get_page(get=vector)
|
page, headers, _ = get_page(get=vector)
|
||||||
retVal = headers.get("X-dotDefender-denied", "") == "1"
|
retval = headers.get("X-dotDefender-denied", "") == "1"
|
||||||
if retVal:
|
retval |= "dotDefender Blocked Your Request" in (page or "")
|
||||||
|
if retval:
|
||||||
break
|
break
|
||||||
|
|
||||||
return retval
|
return retval
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ from lib.core.settings import WAF_ATTACK_VECTORS
|
|||||||
__product__ = "EdgeCast WAF (Verizon)"
|
__product__ = "EdgeCast WAF (Verizon)"
|
||||||
|
|
||||||
def detect(get_page):
|
def detect(get_page):
|
||||||
retVal = False
|
retval = False
|
||||||
|
|
||||||
for vector in WAF_ATTACK_VECTORS:
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
_, headers, code = get_page(get=vector)
|
_, 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:
|
if retval:
|
||||||
break
|
break
|
||||||
|
|
||||||
return retVal
|
return retval
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ def detect(get_page):
|
|||||||
|
|
||||||
for vector in WAF_ATTACK_VECTORS:
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
page, _, _ = get_page(get=vector)
|
page, _, _ = get_page(get=vector)
|
||||||
retval = "Invalid GET Data" in page
|
retval = "Invalid GET Data" in (page or "")
|
||||||
if retval:
|
if retval:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
27
waf/generic.py
Normal file
27
waf/generic.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'doc/COPYING' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.settings import IDS_WAF_CHECK_PAYLOAD
|
||||||
|
from lib.core.settings import WAF_ATTACK_VECTORS
|
||||||
|
|
||||||
|
__product__ = "Generic (Unknown)"
|
||||||
|
|
||||||
|
def detect(get_page):
|
||||||
|
retval = False
|
||||||
|
|
||||||
|
page, _, code = get_page()
|
||||||
|
if page is None or code >= 400:
|
||||||
|
return False
|
||||||
|
|
||||||
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
|
page, _, code = get_page(get=vector)
|
||||||
|
|
||||||
|
if code >= 400 or IDS_WAF_CHECK_PAYLOAD in vector and code is None:
|
||||||
|
retval = True
|
||||||
|
break
|
||||||
|
|
||||||
|
return retval
|
||||||
@@ -16,9 +16,10 @@ def detect(get_page):
|
|||||||
retval = False
|
retval = False
|
||||||
|
|
||||||
for vector in WAF_ATTACK_VECTORS:
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
_, headers, _ = get_page(get=vector)
|
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 |= re.search(r"Incapsula", headers.get("X-CDN", ""), re.I) is not None
|
||||||
|
retval |= "Incapsula incident ID" in (page or "")
|
||||||
if retval:
|
if retval:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@@ -16,10 +16,12 @@ def detect(get_page):
|
|||||||
retval = False
|
retval = False
|
||||||
|
|
||||||
for vector in WAF_ATTACK_VECTORS:
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
page, headers, _ = get_page(get=vector)
|
page, headers, code = get_page(get=vector)
|
||||||
retval = re.search(r"jiasule-WAF", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
|
retval = re.search(r"jiasule-WAF", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
|
||||||
retval |= re.search(r"__jsluid=", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
|
retval |= re.search(r"__jsluid=", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
|
||||||
retval |= re.search(r"static\.jiasule\.com/static/js/http_error\.js", page, re.I) is not None
|
retval |= re.search(r"jsl_tracking", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
|
||||||
|
retval |= re.search(r"static\.jiasule\.com/static/js/http_error\.js", page or "", re.I) is not None
|
||||||
|
retval |= code == 403 and "notice-jiasule" in (page or "")
|
||||||
if retval:
|
if retval:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ def detect(get_page):
|
|||||||
|
|
||||||
for vector in WAF_ATTACK_VECTORS:
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
page, _, _ = get_page(get=vector)
|
page, _, _ = get_page(get=vector)
|
||||||
retval = re.search(r"url\('/ks-waf-error\.png'\)", page, re.I) is not None
|
retval = re.search(r"url\('/ks-waf-error\.png'\)", page or "", re.I) is not None
|
||||||
if retval:
|
if retval:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ See the file 'doc/COPYING' for copying permission
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from lib.core.enums import HTTP_HEADER
|
||||||
from lib.core.settings import WAF_ATTACK_VECTORS
|
from lib.core.settings import WAF_ATTACK_VECTORS
|
||||||
|
|
||||||
__product__ = "KONA Security Solutions (Akamai Technologies)"
|
__product__ = "KONA Security Solutions (Akamai Technologies)"
|
||||||
@@ -15,8 +16,9 @@ def detect(get_page):
|
|||||||
retval = False
|
retval = False
|
||||||
|
|
||||||
for vector in WAF_ATTACK_VECTORS:
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
page, _, code = get_page(get=vector)
|
page, headers, code = get_page(get=vector)
|
||||||
retval = code in (400, 501) and re.search(r"Reference #[0-9A-Fa-f.]+", page, re.I) is not None
|
retval = code in (400, 403, 501) and re.search(r"Reference #[0-9A-Fa-f.]+", page or "", re.I) is not None
|
||||||
|
retval |= re.search(r"AkamaiGHost", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
|
||||||
if retval:
|
if retval:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@@ -17,9 +17,8 @@ def detect(get_page):
|
|||||||
|
|
||||||
for vector in WAF_ATTACK_VECTORS:
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
page, headers, code = get_page(get=vector)
|
page, headers, code = get_page(get=vector)
|
||||||
retval = code == 501 and re.search(r"Reference #[0-9A-Fa-f.]+", page, re.I) is None
|
retval = re.search(r"Mod_Security|NOYB", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
|
||||||
retval |= re.search(r"Mod_Security|NOYB", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
|
retval |= "This error was generated by Mod_Security" in (page or "")
|
||||||
retval |= "This error was generated by Mod_Security" in page
|
|
||||||
if retval:
|
if retval:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
24
waf/nsfocus.py
Normal file
24
waf/nsfocus.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'doc/COPYING' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
from lib.core.enums import HTTP_HEADER
|
||||||
|
from lib.core.settings import WAF_ATTACK_VECTORS
|
||||||
|
|
||||||
|
__product__ = "NSFOCUS Web Application Firewall (NSFOCUS)"
|
||||||
|
|
||||||
|
def detect(get_page):
|
||||||
|
retval = False
|
||||||
|
|
||||||
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
|
_, headers, _ = get_page(get=vector)
|
||||||
|
retval = re.search(r"NSFocus", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
|
||||||
|
if retval:
|
||||||
|
break
|
||||||
|
|
||||||
|
return retval
|
||||||
@@ -16,7 +16,7 @@ def detect(get_page):
|
|||||||
|
|
||||||
for vector in WAF_ATTACK_VECTORS:
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
page, _, _ = get_page(get=vector)
|
page, _, _ = get_page(get=vector)
|
||||||
retval = re.search(r"Access[^<]+has been blocked in accordance with company policy", page, re.I) is not None
|
retval = re.search(r"Access[^<]+has been blocked in accordance with company policy", page or "", re.I) is not None
|
||||||
if retval:
|
if retval:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ def detect(get_page):
|
|||||||
|
|
||||||
for vector in WAF_ATTACK_VECTORS:
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
page, headers, _ = get_page(get=vector)
|
page, headers, _ = get_page(get=vector)
|
||||||
retval = re.search(r"Unauthorized Activity Has Been Detected.+Case Number:", page, re.I | re.S) is not None
|
retval = re.search(r"Unauthorized Activity Has Been Detected.+Case Number:", page or "", re.I | re.S) is not None
|
||||||
retval |= headers.get("X-SL-CompState") is not None
|
retval |= headers.get("X-SL-CompState") is not None
|
||||||
if retval:
|
if retval:
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -13,9 +13,10 @@ def detect(get_page):
|
|||||||
retval = False
|
retval = False
|
||||||
|
|
||||||
for vector in WAF_ATTACK_VECTORS:
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
page, _, _ = get_page(get=vector)
|
page, _, code = get_page(get=vector)
|
||||||
retval = "ASP.NET has detected data in the request that is potentially dangerous" in page
|
retval = "ASP.NET has detected data in the request that is potentially dangerous" in (page or "")
|
||||||
retval |= "Request Validation has detected a potentially dangerous client input value" in page
|
retval |= "Request Validation has detected a potentially dangerous client input value" in (page or "")
|
||||||
|
retval |= code == 500 and "HttpRequestValidationException" in page
|
||||||
if retval:
|
if retval:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@@ -5,13 +5,21 @@ Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
|||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from lib.core.enums import HTTP_HEADER
|
import re
|
||||||
|
|
||||||
|
from lib.core.settings import WAF_ATTACK_VECTORS
|
||||||
|
|
||||||
__product__ = "SecureIIS Web Server Security (BeyondTrust)"
|
__product__ = "SecureIIS Web Server Security (BeyondTrust)"
|
||||||
|
|
||||||
def detect(get_page):
|
def detect(get_page):
|
||||||
_, _, code = get_page()
|
retval = False
|
||||||
retval = code != 404
|
|
||||||
_, _, code = get_page(auxHeaders={HTTP_HEADER.TRANSFER_ENCODING: 'a' * 1025, HTTP_HEADER.ACCEPT_ENCODING: "identity"})
|
for vector in WAF_ATTACK_VECTORS:
|
||||||
retval = retval and code == 404
|
page, _, _ = get_page(get=vector)
|
||||||
|
retval = re.search(r"SecureIIS[^<]+Web Server Protection", page or "") is not None
|
||||||
|
retval |= "http://www.eeye.com/SecureIIS/" in (page or "")
|
||||||
|
retval |= re.search(r"\?subject=[^>]*SecureIIS Error", page or "") is not None
|
||||||
|
if retval:
|
||||||
|
break
|
||||||
|
|
||||||
return retval
|
return retval
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user