Compare commits

...
86 Commits
Author SHA1 Message Date
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
351 changed files with 1247 additions and 1024 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
COPYING -- Describes the terms under which sqlmap is distributed. A copy COPYING -- Describes the terms under which sqlmap is distributed. A copy
of the GNU General Public License (GPL) is appended to this file. of the GNU General Public License (GPL) is appended to this file.
sqlmap is (C) 2006-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 This program is free software; you may redistribute and/or modify it under
the terms of the GNU General Public License as published by the Free the terms of the GNU General Public License as published by the Free
+4 -4
View File
@@ -13,7 +13,7 @@ Les captures d'écran disponible [ici](https://github.com/sqlmapproject/sqlmap/w
Installation 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): 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/) 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: 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 python sqlmap.py -hh
Vous pouvez regarder un vidéo [ici](https://asciinema.org/a/46601) pour plus d'exemples. 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 Liens
---- ----
@@ -41,7 +41,7 @@ Liens
* Page d'acceuil: http://sqlmap.org * 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) * 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 * 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 * Manuel de l'utilisateur: https://github.com/sqlmapproject/sqlmap/wiki
* Foire aux questions (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * Foire aux questions (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
* Twitter: [@sqlmap](https://twitter.com/sqlmap) * Twitter: [@sqlmap](https://twitter.com/sqlmap)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -3,7 +3,7 @@
""" """
beep.py - Make a beep sound 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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -3,7 +3,7 @@
""" """
cloak.py - Simple file encryption/compression utility 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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -3,7 +3,7 @@
""" """
dbgtool.py - Portable executable to ASCII debug script converter 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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -3,7 +3,7 @@
""" """
safe2bin.py - Simple safe(hex) to binary format converter 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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python #!/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 # See the file 'LICENSE' for copying permission
# Removes duplicate entries in wordlist like files # Removes duplicate entries in wordlist like files
+15 -15
View File
@@ -12,21 +12,21 @@ CHECKSUM_FULLPATH=${SCRIPTPATH%/*}/$CHECKSUM
git diff $SETTINGS_FULLPATH | grep "VERSION =" > /dev/null && exit 0 git diff $SETTINGS_FULLPATH | grep "VERSION =" > /dev/null && exit 0
if [ -f $SETTINGS_FULLPATH ] # if [ -f $SETTINGS_FULLPATH ]
then # then
LINE=$(grep -o ${SETTINGS_FULLPATH} -e 'VERSION = "[0-9.]*"') # LINE=$(grep -o ${SETTINGS_FULLPATH} -e 'VERSION = "[0-9.]*"')
declare -a LINE # declare -a LINE
INCREMENTED=$(python -c "import re, sys, time; version = re.search('\"([0-9.]*)\"', sys.argv[1]).group(1); _ = version.split('.'); _.append(0) if len(_) < 3 else _; _[-1] = str(int(_[-1]) + 1); month = str(time.gmtime().tm_mon); _[-1] = '0' if _[-2] != month else _[-1]; _[-2] = month; print sys.argv[1].replace(version, '.'.join(_))" "$LINE") # INCREMENTED=$(python -c "import re, sys, time; version = re.search('\"([0-9.]*)\"', sys.argv[1]).group(1); _ = version.split('.'); _.append(0) if len(_) < 3 else _; _[-1] = str(int(_[-1]) + 1); month = str(time.gmtime().tm_mon); _[-1] = '0' if _[-2] != month else _[-1]; _[-2] = month; print sys.argv[1].replace(version, '.'.join(_))" "$LINE")
if [ -n "$INCREMENTED" ] # if [ -n "$INCREMENTED" ]
then # then
sed -i "s/${LINE}/${INCREMENTED}/" $SETTINGS_FULLPATH # sed -i "s/${LINE}/${INCREMENTED}/" $SETTINGS_FULLPATH
echo "Updated ${INCREMENTED} in ${SETTINGS_FULLPATH}" # echo "Updated ${INCREMENTED} in ${SETTINGS_FULLPATH}"
else # else
echo "Something went wrong in VERSION increment" # echo "Something went wrong in VERSION increment"
exit 1 # exit 1
fi # fi
git add "$SETTINGS_FULLPATH" # git add "$SETTINGS_FULLPATH"
fi # fi
truncate -s 0 "$CHECKSUM_FULLPATH" truncate -s 0 "$CHECKSUM_FULLPATH"
cd $PROJECT_FULLPATH && for i in $(find . -name "*.py" -o -name "*.xml" -o -iname "*_" | sort); do git ls-files $i --error-unmatch &>/dev/null && md5sum $i | stdbuf -i0 -o0 -e0 sed 's/\.\///' >> "$CHECKSUM_FULLPATH"; git add "$CHECKSUM_FULLPATH"; done cd $PROJECT_FULLPATH && for i in $(find . -name "*.py" -o -name "*.xml" -o -iname "*_" | sort); do git ls-files $i --error-unmatch &>/dev/null && md5sum $i | stdbuf -i0 -o0 -e0 sed 's/\.\///' >> "$CHECKSUM_FULLPATH"; git add "$CHECKSUM_FULLPATH"; done
+2 -2
View File
@@ -16,7 +16,7 @@ cat > $TMP_DIR/setup.py << EOF
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -60,7 +60,7 @@ cat > sqlmap/__init__.py << EOF
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python #!/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 # See the file 'LICENSE' for copying permission
import codecs import codecs
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+44 -29
View File
@@ -1,12 +1,13 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
import copy import copy
import httplib import httplib
import logging
import os import os
import random import random
import re import re
@@ -42,6 +43,7 @@ from lib.core.common import readInput
from lib.core.common import showStaticWords from lib.core.common import showStaticWords
from lib.core.common import singleTimeLogMessage from lib.core.common import singleTimeLogMessage
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage
from lib.core.common import unArrayizeValue
from lib.core.common import urlencode from lib.core.common import urlencode
from lib.core.common import wasLastResponseDBMSError from lib.core.common import wasLastResponseDBMSError
from lib.core.common import wasLastResponseHTTPError from lib.core.common import wasLastResponseHTTPError
@@ -108,6 +110,9 @@ def checkSqlInjection(place, parameter, value):
if value.isdigit(): 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 ('"', '\''))) 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 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: else:
boundaries = conf.boundaries boundaries = conf.boundaries
@@ -281,9 +286,9 @@ def checkSqlInjection(place, parameter, value):
# Skip DBMS-specific test if it does not match the # Skip DBMS-specific test if it does not match the
# previously identified DBMS (via DBMS-specific error message) # previously identified DBMS (via DBMS-specific error message)
if kb.reduceTests and not intersect(payloadDbms, kb.reduceTests, True): if kb.reduceTests and not intersect(payloadDbms, kb.reduceTests, True):
debugMsg = "skipping test '%s' because the parsed " % title debugMsg = "skipping test '%s' because the heuristic " % title
debugMsg += "error message(s) showed that the back-end DBMS " debugMsg += "tests showed that the back-end DBMS "
debugMsg += "could be %s" % Format.getErrorParsedDBMSes() debugMsg += "could be '%s'" % unArrayizeValue(kb.reduceTests)
logger.debug(debugMsg) logger.debug(debugMsg)
continue continue
@@ -506,8 +511,13 @@ def checkSqlInjection(place, parameter, value):
trueSet = set(getFilteredPageContent(truePage, True, "\n").split("\n")) trueSet = set(getFilteredPageContent(truePage, True, "\n").split("\n"))
falseSet = set(getFilteredPageContent(falsePage, 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: if originalSet == trueSet != falseSet:
candidates = trueSet - falseSet candidates = trueSet - falseSet - errorSet
if candidates: if candidates:
candidates = sorted(candidates, key=lambda _: len(_)) candidates = sorted(candidates, key=lambda _: len(_))
@@ -535,7 +545,13 @@ def checkSqlInjection(place, parameter, value):
falseSet = set(extractTextTagContent(falseRawResponse)) falseSet = set(extractTextTagContent(falseRawResponse))
falseSet = falseSet.union(__ for _ in falseSet for __ in _.split()) 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: if candidates:
candidates = sorted(candidates, key=lambda _: len(_)) 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) page, headers, _ = Request.queryPage(reqPayload, place, content=True, raise404=False)
output = extractRegexResult(check, page, re.DOTALL | re.IGNORECASE) \ output = extractRegexResult(check, page, re.DOTALL | re.IGNORECASE) \
or extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None, 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) or extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None, re.DOTALL | re.IGNORECASE)
if output: if output:
@@ -629,11 +645,12 @@ def checkSqlInjection(place, parameter, value):
Backend.forceDbms(kb.dbmsFilter[0]) Backend.forceDbms(kb.dbmsFilter[0])
elif not Backend.getIdentifiedDbms(): elif not Backend.getIdentifiedDbms():
if kb.heuristicDbms is None: if kb.heuristicDbms is None:
warnMsg = "using unescaped version of the test " if kb.heuristicTest == HEURISTIC_TEST.POSITIVE or injection.data:
warnMsg += "because of zero knowledge of the " warnMsg = "using unescaped version of the test "
warnMsg += "back-end DBMS. You can try to " warnMsg += "because of zero knowledge of the "
warnMsg += "explicitly set it with option '--dbms'" warnMsg += "back-end DBMS. You can try to "
singleTimeWarnMessage(warnMsg) warnMsg += "explicitly set it with option '--dbms'"
singleTimeWarnMessage(warnMsg)
else: else:
Backend.forceDbms(kb.heuristicDbms) Backend.forceDbms(kb.heuristicDbms)
@@ -918,7 +935,7 @@ def checkSuhosinPatch(injection):
if injection.place == PLACE.GET: if injection.place == PLACE.GET:
debugMsg = "checking for parameter length " debugMsg = "checking for parameter length "
debugMsg += "constrainting mechanisms" debugMsg += "constraining mechanisms"
logger.debug(debugMsg) logger.debug(debugMsg)
pushValue(kb.injection) pushValue(kb.injection)
@@ -927,7 +944,7 @@ def checkSuhosinPatch(injection):
randInt = randomInt() randInt = randomInt()
if not checkBooleanExpression("%d=%s%d" % (randInt, ' ' * SUHOSIN_MAX_VALUE_LENGTH, randInt)): 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 += "mechanism detected (e.g. Suhosin patch). "
warnMsg += "Potential problems in enumeration phase can be expected" warnMsg += "Potential problems in enumeration phase can be expected"
logger.warn(warnMsg) logger.warn(warnMsg)
@@ -1051,13 +1068,13 @@ def heuristicCheckSqlInjection(place, parameter):
if value.lower() in (page or "").lower(): if value.lower() in (page or "").lower():
infoMsg = "heuristic (XSS) test shows that %s parameter " % paramType 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) logger.info(infoMsg)
for match in re.finditer(FI_ERROR_REGEX, page or ""): for match in re.finditer(FI_ERROR_REGEX, page or ""):
if randStr1.lower() in match.group(0).lower(): if randStr1.lower() in match.group(0).lower():
infoMsg = "heuristic (FI) test shows that %s parameter " % paramType infoMsg = "heuristic (FI) test shows that %s parameter " % paramType
infoMsg += "'%s' might be vulnerable to file inclusion attacks" % parameter infoMsg += "'%s' might be vulnerable to file inclusion (FI) attacks" % parameter
logger.info(infoMsg) logger.info(infoMsg)
break break
@@ -1143,16 +1160,16 @@ def checkDynamicContent(firstPage, secondPage):
count += 1 count += 1
if count > conf.retries: if count > conf.retries:
warnMsg = "target URL is too dynamic. " warnMsg = "target URL content appears to be too dynamic. "
warnMsg += "Switching to '--text-only' " warnMsg += "Switching to '--text-only' "
logger.warn(warnMsg) logger.warn(warnMsg)
conf.textOnly = True conf.textOnly = True
return return
warnMsg = "target URL is heavily dynamic" warnMsg = "target URL content appears to be heavily dynamic. "
warnMsg += ". sqlmap is going to retry the request" warnMsg += "sqlmap is going to retry the request(s)"
logger.critical(warnMsg) singleTimeLogMessage(warnMsg, logging.CRITICAL)
secondPage, _, _ = Request.queryPage(content=True) secondPage, _, _ = Request.queryPage(content=True)
findDynamicContent(firstPage, secondPage) findDynamicContent(firstPage, secondPage)
@@ -1168,7 +1185,7 @@ def checkStability():
like for instance string matching (--string). 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) logger.info(infoMsg)
firstPage = kb.originalPage # set inside checkConnection() firstPage = kb.originalPage # set inside checkConnection()
@@ -1186,7 +1203,7 @@ def checkStability():
if kb.pageStable: if kb.pageStable:
if firstPage: if firstPage:
infoMsg = "target URL is stable" infoMsg = "target URL content is stable"
logger.info(infoMsg) logger.info(infoMsg)
else: else:
errMsg = "there was an error checking the stability of page " errMsg = "there was an error checking the stability of page "
@@ -1196,12 +1213,11 @@ def checkStability():
logger.error(errMsg) logger.error(errMsg)
else: 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 += "comparison on a sequence matcher. If no dynamic nor "
warnMsg += "injectable parameters are detected, or in case of " warnMsg += "injectable parameters are detected, or in case of "
warnMsg += "junk results, refer to user's manual paragraph " warnMsg += "junk results, refer to user's manual paragraph "
warnMsg += "'Page comparison' and provide a string or regular " warnMsg += "'Page comparison'"
warnMsg += "expression to match on"
logger.warn(warnMsg) logger.warn(warnMsg)
message = "how do you want to proceed? [(C)ontinue/(s)tring/(r)egex/(q)uit] " message = "how do you want to proceed? [(C)ontinue/(s)tring/(r)egex/(q)uit] "
@@ -1454,7 +1470,7 @@ def checkNullConnection():
if not page and HTTP_HEADER.CONTENT_LENGTH in (headers or {}): if not page and HTTP_HEADER.CONTENT_LENGTH in (headers or {}):
kb.nullConnection = NULLCONNECTION.HEAD 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) logger.info(infoMsg)
else: else:
page, headers, _ = Request.getPage(auxHeaders={HTTP_HEADER.RANGE: "bytes=-1"}) 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 {}): if page and len(page) == 1 and HTTP_HEADER.CONTENT_RANGE in (headers or {}):
kb.nullConnection = NULLCONNECTION.RANGE kb.nullConnection = NULLCONNECTION.RANGE
infoMsg = "NULL connection is supported with GET method (Range)" infoMsg = "NULL connection is supported with GET method ('Range')"
infoMsg += "'%s'" % kb.nullConnection
logger.info(infoMsg) logger.info(infoMsg)
else: else:
_, headers, _ = Request.getPage(skipRead = True) _, headers, _ = Request.getPage(skipRead=True)
if HTTP_HEADER.CONTENT_LENGTH in (headers or {}): if HTTP_HEADER.CONTENT_LENGTH in (headers or {}):
kb.nullConnection = NULLCONNECTION.SKIP_READ kb.nullConnection = NULLCONNECTION.SKIP_READ
+12 -16
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -242,11 +242,13 @@ def _saveToResultsFile():
for key, value in results.items(): for key, value in results.items():
place, parameter, notes = key place, parameter, notes = key
line = "%s,%s,%s,%s,%s%s" % (safeCSValue(kb.originalUrls.get(conf.url) or conf.url), place, parameter, "".join(techniques[_][0].upper() for _ in sorted(value)), notes, os.linesep) line = "%s,%s,%s,%s,%s%s" % (safeCSValue(kb.originalUrls.get(conf.url) or conf.url), place, parameter, "".join(techniques[_][0].upper() for _ in sorted(value)), notes, os.linesep)
conf.resultsFP.writelines(line) conf.resultsFP.write(line)
if not results: if not results:
line = "%s,,,,%s" % (conf.url, os.linesep) line = "%s,,,,%s" % (conf.url, os.linesep)
conf.resultsFP.writelines(line) conf.resultsFP.write(line)
conf.resultsFP.flush()
def start(): def start():
""" """
@@ -581,11 +583,11 @@ def start():
errMsg += "(e.g. GET parameter 'id' in 'www.site.com/index.php?id=1')" errMsg += "(e.g. GET parameter 'id' in 'www.site.com/index.php?id=1')"
raise SqlmapNoneDataException(errMsg) raise SqlmapNoneDataException(errMsg)
else: 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: if conf.level < 5 or conf.risk < 3:
errMsg += " Try to increase '--level'/'--risk' values " errMsg += " Try to increase values for '--level'/'--risk' options "
errMsg += "to perform more tests." errMsg += "if you wish to perform more tests."
if isinstance(conf.tech, list) and len(conf.tech) < 5: if isinstance(conf.tech, list) and len(conf.tech) < 5:
errMsg += " Rerun without providing the option '--technique'." errMsg += " Rerun without providing the option '--technique'."
@@ -608,15 +610,9 @@ def start():
if kb.heuristicTest == HEURISTIC_TEST.POSITIVE: if kb.heuristicTest == HEURISTIC_TEST.POSITIVE:
errMsg += " As heuristic test turned out positive you are " errMsg += " As heuristic test turned out positive you are "
errMsg += "strongly advised to continue on with the tests. " errMsg += "strongly advised to continue on with the tests."
errMsg += "Please, consider usage of tampering scripts as "
errMsg += "your target might filter the queries."
if not conf.string and not conf.notString and not conf.regexp: if conf.string:
errMsg += " Also, you can try to rerun by providing "
errMsg += "either a valid value for option '--string' "
errMsg += "(or '--regexp')."
elif conf.string:
errMsg += " Also, you can try to rerun by providing a " errMsg += " Also, you can try to rerun by providing a "
errMsg += "valid value for option '--string' as perhaps the string you " errMsg += "valid value for option '--string' as perhaps the string you "
errMsg += "have chosen does not match " errMsg += "have chosen does not match "
@@ -629,8 +625,8 @@ def start():
if not conf.tamper: if not conf.tamper:
errMsg += " If you suspect that there is some kind of protection mechanism " errMsg += " If you suspect that there is some kind of protection mechanism "
errMsg += "involved (e.g. WAF) maybe you could retry " errMsg += "involved (e.g. WAF) maybe you could try to use "
errMsg += "with an option '--tamper' (e.g. '--tamper=space2comment')" errMsg += "option '--tamper' (e.g. '--tamper=space2comment')"
raise SqlmapNotVulnerableException(errMsg.rstrip('.')) raise SqlmapNotVulnerableException(errMsg.rstrip('.'))
else: else:
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+4 -13
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -97,6 +97,7 @@ class Agent(object):
paramString = conf.parameters[place] paramString = conf.parameters[place]
paramDict = conf.paramDict[place] paramDict = conf.paramDict[place]
origValue = getUnicode(paramDict[parameter]) origValue = getUnicode(paramDict[parameter])
newValue = getUnicode(newValue) if newValue else newValue
if place == PLACE.URI or BOUNDED_INJECTION_MARKER in origValue: if place == PLACE.URI or BOUNDED_INJECTION_MARKER in origValue:
paramString = origValue paramString = origValue
@@ -105,7 +106,7 @@ class Agent(object):
else: 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 = filter(None, (re.search(_, origValue.split(BOUNDED_INJECTION_MARKER)[0]) for _ in (r"\w+\Z", r"[^\"'><]+\Z", r"[^ ]+\Z")))[0].group(0)
origValue = origValue[origValue.rfind('/') + 1:] origValue = origValue[origValue.rfind('/') + 1:]
for char in ('?', '=', ':'): for char in ('?', '=', ':', ','):
if char in origValue: if char in origValue:
origValue = origValue[origValue.rfind(char) + 1:] origValue = origValue[origValue.rfind(char) + 1:]
elif place == PLACE.CUSTOM_POST: elif place == PLACE.CUSTOM_POST:
@@ -207,16 +208,6 @@ class Agent(object):
return retVal 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): def prefixQuery(self, expression, prefix=None, where=None, clause=None):
""" """
This method defines how the input expression has to be escaped This method defines how the input expression has to be escaped
@@ -371,7 +362,7 @@ class Agent(object):
rootQuery = queries[Backend.getIdentifiedDbms()] rootQuery = queries[Backend.getIdentifiedDbms()]
hexField = field hexField = field
if 'hex' in rootQuery: if "hex" in rootQuery:
hexField = rootQuery.hex.query % field hexField = rootQuery.hex.query % field
else: else:
warnMsg = "switch '--hex' is currently not supported on DBMS %s" % Backend.getIdentifiedDbms() warnMsg = "switch '--hex' is currently not supported on DBMS %s" % Backend.getIdentifiedDbms()
+14 -14
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -14,10 +14,12 @@ import itertools
import os import os
import sys import sys
import tempfile import tempfile
import zlib
from lib.core.enums import MKSTEMP_PREFIX from lib.core.enums import MKSTEMP_PREFIX
from lib.core.exception import SqlmapSystemException from lib.core.exception import SqlmapSystemException
from lib.core.settings import BIGARRAY_CHUNK_SIZE from lib.core.settings import BIGARRAY_CHUNK_SIZE
from lib.core.settings import BIGARRAY_COMPRESS_LEVEL
DEFAULT_SIZE_OF = sys.getsizeof(object()) 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) List-like class used for storing large amounts of data (disk cached)
""" """
def __init__(self): def __init__(self, items=[]):
self.chunks = [[]] self.chunks = [[]]
self.chunk_length = sys.maxint self.chunk_length = sys.maxint
self.cache = None self.cache = None
@@ -58,6 +60,9 @@ class BigArray(list):
self._os_remove = os.remove self._os_remove = os.remove
self._size_counter = 0 self._size_counter = 0
for item in items:
self.append(item)
def append(self, value): def append(self, value):
self.chunks[-1].append(value) self.chunks[-1].append(value)
@@ -80,8 +85,8 @@ class BigArray(list):
if len(self.chunks[-1]) < 1: if len(self.chunks[-1]) < 1:
self.chunks.pop() self.chunks.pop()
try: try:
with open(self.chunks[-1], "rb") as fp: with open(self.chunks[-1], "rb") as f:
self.chunks[-1] = pickle.load(fp) self.chunks[-1] = pickle.loads(zlib.decompress(f.read()))
except IOError, ex: except IOError, ex:
errMsg = "exception occurred while retrieving data " errMsg = "exception occurred while retrieving data "
errMsg += "from a temporary file ('%s')" % ex.message errMsg += "from a temporary file ('%s')" % ex.message
@@ -101,8 +106,8 @@ class BigArray(list):
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.BIG_ARRAY) handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.BIG_ARRAY)
self.filenames.add(filename) self.filenames.add(filename)
os.close(handle) os.close(handle)
with open(filename, "w+b") as fp: with open(filename, "w+b") as f:
pickle.dump(chunk, fp, pickle.HIGHEST_PROTOCOL) f.write(zlib.compress(pickle.dumps(chunk, pickle.HIGHEST_PROTOCOL), BIGARRAY_COMPRESS_LEVEL))
return filename return filename
except (OSError, IOError), ex: except (OSError, IOError), ex:
errMsg = "exception occurred while storing data " errMsg = "exception occurred while storing data "
@@ -119,8 +124,8 @@ class BigArray(list):
if not (self.cache and self.cache.index == index): if not (self.cache and self.cache.index == index):
try: try:
with open(self.chunks[index], "rb") as fp: with open(self.chunks[index], "rb") as f:
self.cache = Cache(index, pickle.load(fp), False) self.cache = Cache(index, pickle.loads(zlib.decompress(f.read())), False)
except IOError, ex: except IOError, ex:
errMsg = "exception occurred while retrieving data " errMsg = "exception occurred while retrieving data "
errMsg += "from a temporary file ('%s')" % ex.message errMsg += "from a temporary file ('%s')" % ex.message
@@ -134,15 +139,10 @@ class BigArray(list):
self.chunks, self.filenames = state self.chunks, self.filenames = state
def __getslice__(self, i, j): def __getslice__(self, i, j):
retval = BigArray()
i = max(0, len(self) + i if i < 0 else i) i = max(0, len(self) + i if i < 0 else i)
j = min(len(self), len(self) + j if j < 0 else j) j = min(len(self), len(self) + j if j < 0 else j)
for _ in xrange(i, j): return BigArray(self[_] for _ in xrange(i, j))
retval.append(self[_])
return retval
def __getitem__(self, y): def __getitem__(self, y):
if y < 0: if y < 0:
+87 -86
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -9,6 +9,7 @@ import codecs
import contextlib import contextlib
import cookielib import cookielib
import copy import copy
import distutils
import getpass import getpass
import hashlib import hashlib
import httplib import httplib
@@ -28,6 +29,7 @@ import sys
import tempfile import tempfile
import threading import threading
import time import time
import types
import urllib import urllib
import urllib2 import urllib2
import urlparse import urlparse
@@ -104,7 +106,7 @@ from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import DEFAULT_MSSQL_SCHEMA from lib.core.settings import DEFAULT_MSSQL_SCHEMA
from lib.core.settings import DEV_EMAIL_ADDRESS from lib.core.settings import DEV_EMAIL_ADDRESS
from lib.core.settings import DUMMY_USER_INJECTION from lib.core.settings import DUMMY_USER_INJECTION
from lib.core.settings import DYNAMICITY_MARK_LENGTH from lib.core.settings import DYNAMICITY_BOUNDARY_LENGTH
from lib.core.settings import ERROR_PARSING_REGEXES from lib.core.settings import ERROR_PARSING_REGEXES
from lib.core.settings import FILE_PATH_REGEXES from lib.core.settings import FILE_PATH_REGEXES
from lib.core.settings import FORCE_COOKIE_EXPIRATION_TIME from lib.core.settings import FORCE_COOKIE_EXPIRATION_TIME
@@ -634,7 +636,7 @@ def paramToDict(place, parameters=None):
elif isinstance(value, (bool, int, float, basestring)): elif isinstance(value, (bool, int, float, basestring)):
original = current[key] original = current[key]
if isinstance(value, bool): 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: else:
current[key] = "%s%s" % (value, BOUNDED_INJECTION_MARKER) 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) 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)
@@ -1012,21 +1014,21 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
dataToStdout("\r%s%s\n" % (message, options), forceOutput=True, bold=True) dataToStdout("\r%s%s\n" % (message, options), forceOutput=True, bold=True)
debugMsg = "used the default behaviour, running in batch mode" debugMsg = "used the default behavior, running in batch mode"
logger.debug(debugMsg) logger.debug(debugMsg)
retVal = default retVal = default
else: else:
logging._acquireLock()
if conf.get("beep"):
beep()
dataToStdout("\r%s" % message, forceOutput=True, bold=True)
kb.prependFlag = False
try: try:
retVal = raw_input() or default logging._acquireLock()
if conf.get("beep"):
beep()
dataToStdout("\r%s" % message, forceOutput=True, bold=True)
kb.prependFlag = False
retVal = raw_input().strip() or default
retVal = getUnicode(retVal, encoding=sys.stdin.encoding) if retVal else retVal retVal = getUnicode(retVal, encoding=sys.stdin.encoding) if retVal else retVal
except: except:
try: try:
@@ -1046,7 +1048,7 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
if boolean: if boolean:
retVal = retVal.strip().upper() == 'Y' retVal = retVal.strip().upper() == 'Y'
return retVal return retVal or ""
def randomRange(start=0, stop=1000, seed=None): def randomRange(start=0, stop=1000, seed=None):
""" """
@@ -1675,32 +1677,32 @@ def getCharset(charsetType=None):
# Binary # Binary
elif charsetType == CHARSET_TYPE.BINARY: elif charsetType == CHARSET_TYPE.BINARY:
asciiTbl.extend([0, 1]) asciiTbl.extend((0, 1))
asciiTbl.extend(xrange(47, 50)) asciiTbl.extend(xrange(47, 50))
# Digits # Digits
elif charsetType == CHARSET_TYPE.DIGITS: elif charsetType == CHARSET_TYPE.DIGITS:
asciiTbl.extend([0, 9]) asciiTbl.extend((0, 9))
asciiTbl.extend(xrange(47, 58)) asciiTbl.extend(xrange(47, 58))
# Hexadecimal # Hexadecimal
elif charsetType == CHARSET_TYPE.HEXADECIMAL: elif charsetType == CHARSET_TYPE.HEXADECIMAL:
asciiTbl.extend([0, 1]) asciiTbl.extend((0, 1))
asciiTbl.extend(xrange(47, 58)) asciiTbl.extend(xrange(47, 58))
asciiTbl.extend(xrange(64, 71)) asciiTbl.extend(xrange(64, 71))
asciiTbl.extend([87, 88]) # X asciiTbl.extend((87, 88)) # X
asciiTbl.extend(xrange(96, 103)) asciiTbl.extend(xrange(96, 103))
asciiTbl.extend([119, 120]) # x asciiTbl.extend((119, 120)) # x
# Characters # Characters
elif charsetType == CHARSET_TYPE.ALPHA: elif charsetType == CHARSET_TYPE.ALPHA:
asciiTbl.extend([0, 1]) asciiTbl.extend((0, 1))
asciiTbl.extend(xrange(64, 91)) asciiTbl.extend(xrange(64, 91))
asciiTbl.extend(xrange(96, 123)) asciiTbl.extend(xrange(96, 123))
# Characters and digits # Characters and digits
elif charsetType == CHARSET_TYPE.ALPHANUM: elif charsetType == CHARSET_TYPE.ALPHANUM:
asciiTbl.extend([0, 1]) asciiTbl.extend((0, 1))
asciiTbl.extend(xrange(47, 58)) asciiTbl.extend(xrange(47, 58))
asciiTbl.extend(xrange(64, 91)) asciiTbl.extend(xrange(64, 91))
asciiTbl.extend(xrange(96, 123)) asciiTbl.extend(xrange(96, 123))
@@ -1839,8 +1841,7 @@ def getPageWordSet(page):
# only if the page's charset has been successfully identified # only if the page's charset has been successfully identified
if isinstance(page, unicode): if isinstance(page, unicode):
_ = getFilteredPageContent(page) retVal = set(_.group(0) for _ in re.finditer(r"\w+", getFilteredPageContent(page)))
retVal = set(re.findall(r"\w+", _))
return retVal return retVal
@@ -1892,7 +1893,7 @@ def isWindowsDriveLetterPath(filepath):
def posixToNtSlashes(filepath): def posixToNtSlashes(filepath):
""" """
Replaces all occurances of Posix slashes (/) in provided Replaces all occurrences of Posix slashes (/) in provided
filepath with NT ones (\) filepath with NT ones (\)
>>> posixToNtSlashes('C:/Windows') >>> posixToNtSlashes('C:/Windows')
@@ -1903,7 +1904,7 @@ def posixToNtSlashes(filepath):
def ntToPosixSlashes(filepath): def ntToPosixSlashes(filepath):
""" """
Replaces all occurances of NT slashes (\) in provided Replaces all occurrences of NT slashes (\) in provided
filepath with Posix ones (/) filepath with Posix ones (/)
>>> ntToPosixSlashes('C:\\Windows') >>> ntToPosixSlashes('C:\\Windows')
@@ -2057,6 +2058,7 @@ def readXmlFile(xmlFile):
return retVal return retVal
@cachedmethod
def stdev(values): def stdev(values):
""" """
Computes standard deviation of a list of numbers. Computes standard deviation of a list of numbers.
@@ -2068,19 +2070,10 @@ def stdev(values):
if not values or len(values) < 2: if not values or len(values) < 2:
return None 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: else:
avg = average(values) avg = average(values)
_ = reduce(lambda x, y: x + pow((y or 0) - avg, 2), values, 0.0) _ = reduce(lambda x, y: x + pow((y or 0) - avg, 2), values, 0.0)
retVal = sqrt(_ / (len(values) - 1)) return sqrt(_ / (len(values) - 1))
if kb.get("cache"):
kb.cache.stdev[key] = retVal
return retVal
def average(values): def average(values):
""" """
@@ -2240,7 +2233,7 @@ def goGoodSamaritan(prevValue, originalCharset):
def getPartRun(alias=True): def getPartRun(alias=True):
""" """
Goes through call stack and finds constructs matching conf.dbmsHandler.*. 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 retVal = None
@@ -2498,6 +2491,9 @@ def findLocalPort(ports):
def findMultipartPostBoundary(post): def findMultipartPostBoundary(post):
""" """
Finds value for a boundary parameter in given multipart POST body Finds value for a boundary parameter in given multipart POST body
>>> findMultipartPostBoundary("-----------------------------9051914041544843365972754266\\nContent-Disposition: form-data; name=text\\n\\ndefault")
'9051914041544843365972754266'
""" """
retVal = None retVal = None
@@ -2687,6 +2683,7 @@ def enumValueToNameLookup(type_, value_):
return retVal return retVal
@cachedmethod
def extractRegexResult(regex, content, flags=0): def extractRegexResult(regex, content, flags=0):
""" """
Returns 'result' group value from a possible match with regex on a given Returns 'result' group value from a possible match with regex on a given
@@ -2779,13 +2776,17 @@ def findDynamicContent(firstPage, secondPage):
""" """
This function checks if the provided pages have dynamic content. If they This function checks if the provided pages have dynamic content. If they
are dynamic, proper markings will be made 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: if not firstPage or not secondPage:
return return
infoMsg = "searching for dynamic content" infoMsg = "searching for dynamic content"
logger.info(infoMsg) singleTimeLogMessage(infoMsg)
blocks = SequenceMatcher(None, firstPage, secondPage).get_matching_blocks() blocks = SequenceMatcher(None, firstPage, secondPage).get_matching_blocks()
kb.dynamicMarkings = [] kb.dynamicMarkings = []
@@ -2794,7 +2795,7 @@ def findDynamicContent(firstPage, secondPage):
for block in blocks[:]: for block in blocks[:]:
(_, _, length) = block (_, _, length) = block
if length <= DYNAMICITY_MARK_LENGTH: if length <= 2 * DYNAMICITY_BOUNDARY_LENGTH:
blocks.remove(block) blocks.remove(block)
# Making of dynamic markings based on prefix/suffix principle # Making of dynamic markings based on prefix/suffix principle
@@ -2812,14 +2813,23 @@ def findDynamicContent(firstPage, secondPage):
if suffix is None and (blocks[i][0] + blocks[i][2] >= len(firstPage)): if suffix is None and (blocks[i][0] + blocks[i][2] >= len(firstPage)):
continue continue
prefix = trimAlphaNum(prefix) if prefix and suffix:
suffix = trimAlphaNum(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: if len(kb.dynamicMarkings) > 0:
infoMsg = "dynamic content marked for removal (%d region%s)" % (len(kb.dynamicMarkings), 's' if len(kb.dynamicMarkings) > 1 else '') 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): def removeDynamicContent(page):
""" """
@@ -2889,7 +2899,7 @@ def isDBMSVersionAtLeast(version):
value = filterStringValue(value, '[0-9.><=]') value = filterStringValue(value, '[0-9.><=]')
if isinstance(value, basestring): if value and isinstance(value, basestring):
if value.startswith(">="): if value.startswith(">="):
value = float(value.replace(">=", "")) value = float(value.replace(">=", ""))
elif value.startswith(">"): elif value.startswith(">"):
@@ -2899,7 +2909,7 @@ def isDBMSVersionAtLeast(version):
elif value.startswith(">"): elif value.startswith(">"):
value = float(value.replace("<", "")) - 0.01 value = float(value.replace("<", "")) - 0.01
retVal = getUnicode(value) >= getUnicode(version) retVal = distutils.version.LooseVersion(getUnicode(value)) >= distutils.version.LooseVersion(getUnicode(version))
return retVal return retVal
@@ -3374,6 +3384,9 @@ def createGithubIssue(errMsg, excMsg):
def maskSensitiveData(msg): def maskSensitiveData(msg):
""" """
Masks sensitive data in the supplied message 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) retVal = getUnicode(msg)
@@ -3402,7 +3415,7 @@ def listToStrValue(value):
'1, 2, 3' '1, 2, 3'
""" """
if isinstance(value, (set, tuple)): if isinstance(value, (set, tuple, types.GeneratorType)):
value = list(value) value = list(value)
if isinstance(value, list): if isinstance(value, list):
@@ -3412,22 +3425,6 @@ def listToStrValue(value):
return retVal 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): def intersect(valueA, valueB, lowerCase=False):
""" """
Returns intersection of the array-ized values Returns intersection of the array-ized values
@@ -3459,7 +3456,7 @@ def removeReflectiveValues(content, payload, suppressWarning=False):
retVal = content retVal = content
try: 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): def _(value):
while 2 * REFLECTED_REPLACEMENT_REGEX in value: while 2 * REFLECTED_REPLACEMENT_REGEX in value:
value = value.replace(2 * REFLECTED_REPLACEMENT_REGEX, REFLECTED_REPLACEMENT_REGEX) value = value.replace(2 * REFLECTED_REPLACEMENT_REGEX, REFLECTED_REPLACEMENT_REGEX)
@@ -3565,17 +3562,19 @@ def safeSQLIdentificatorNaming(name, isTable=False):
_ = isTable and Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) _ = isTable and Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE)
if _: if _:
retVal = re.sub(r"(?i)\A%s\." % DEFAULT_MSSQL_SCHEMA, "", retVal) retVal = re.sub(r"(?i)\A\[?%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): 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): 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,): elif Backend.getIdentifiedDbms() in (DBMS.ORACLE,):
retVal = "\"%s\"" % retVal.strip("\"").upper() retVal = "\"%s\"" % retVal.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)): 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
if _ and DEFAULT_MSSQL_SCHEMA not in retVal and '.' not in re.sub(r"\[[^]]+\]", "", retVal): if _ and DEFAULT_MSSQL_SCHEMA not in retVal and '.' not in re.sub(r"\[[^]]+\]", "", retVal):
retVal = "%s.%s" % (DEFAULT_MSSQL_SCHEMA, retVal) retVal = "%s.%s" % (DEFAULT_MSSQL_SCHEMA, retVal)
@@ -3600,9 +3599,7 @@ def unsafeSQLIdentificatorNaming(name):
retVal = name.replace("[", "").replace("]", "") retVal = name.replace("[", "").replace("]", "")
if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE): if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
prefix = "%s." % DEFAULT_MSSQL_SCHEMA retVal = re.sub(r"(?i)\A\[?%s\]?\." % DEFAULT_MSSQL_SCHEMA, "", retVal)
if retVal.startswith(prefix):
retVal = retVal[len(prefix):]
return retVal return retVal
@@ -3767,7 +3764,7 @@ def filterPairValues(values):
def randomizeParameterValue(value): 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) >>> random.seed(0)
>>> randomizeParameterValue('foobar') >>> randomizeParameterValue('foobar')
@@ -3812,7 +3809,7 @@ def randomizeParameterValue(value):
@cachedmethod @cachedmethod
def asciifyUrl(url, forceQuote=False): 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``, More specifically, it attempts to convert the unicode object ``url``,
which is meant to represent a IRI, to an unicode object that, which is meant to represent a IRI, to an unicode object that,
@@ -3852,7 +3849,7 @@ def asciifyUrl(url, forceQuote=False):
# Triggers on non-ascii characters - another option would be: # Triggers on non-ascii characters - another option would be:
# urllib.quote(s.replace('%', '')) != s.replace('%', '') # urllib.quote(s.replace('%', '')) != s.replace('%', '')
# which would trigger on all %-characters, e.g. "&". # 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 urllib.quote(s.encode(UNICODE_ENCODING), safe=safe)
return s return s
@@ -3877,13 +3874,15 @@ def asciifyUrl(url, forceQuote=False):
if port: if port:
netloc += ':' + str(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): def isAdminFromPrivileges(privileges):
""" """
Inspects privileges to see if those are coming from an admin user Inspects privileges to see if those are coming from an admin user
""" """
privileges = privileges or []
# In PostgreSQL the usesuper privilege means that the # In PostgreSQL the usesuper privilege means that the
# user is DBA # user is DBA
retVal = (Backend.isDbms(DBMS.PGSQL) and "super" in privileges) retVal = (Backend.isDbms(DBMS.PGSQL) and "super" in privileges)
@@ -3934,18 +3933,20 @@ def findPageForms(content, url, raise_=False, addToTargets=False):
except (UnicodeError, ValueError): except (UnicodeError, ValueError):
pass pass
except ParseError: 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 warnMsg = "badly formed HTML at the given URL ('%s'). Going to filter it" % url
logger.warning(warnMsg) logger.warning(warnMsg)
filtered = _("".join(re.findall(FORM_SEARCH_REGEX, content)), url) filtered = _("".join(re.findall(FORM_SEARCH_REGEX, content)), url)
try:
forms = ParseResponse(filtered, backwards_compat=False) if filtered and filtered != content:
except ParseError: try:
errMsg = "no success" forms = ParseResponse(filtered, backwards_compat=False)
if raise_: except ParseError:
raise SqlmapGenericException(errMsg) errMsg = "no success"
else: if raise_:
logger.debug(errMsg) raise SqlmapGenericException(errMsg)
else:
logger.debug(errMsg)
if forms: if forms:
for form in forms: for form in forms:
@@ -4022,7 +4023,7 @@ def checkSameHost(*urls):
elif len(urls) == 1: elif len(urls) == 1:
return True return True
else: 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): def getHostHeader(url):
""" """
@@ -4341,7 +4342,7 @@ def getRequestHeader(request, name):
if request and name: if request and name:
_ = name.upper() _ = 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 return retVal
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -193,7 +193,7 @@ def stdoutencode(data):
warnMsg = "cannot properly display Unicode characters " warnMsg = "cannot properly display Unicode characters "
warnMsg += "inside Windows OS command prompt " warnMsg += "inside Windows OS command prompt "
warnMsg += "(http://bugs.python.org/issue1602). All " warnMsg += "(http://bugs.python.org/issue1602). All "
warnMsg += "unhandled occurances will result in " warnMsg += "unhandled occurrences will result in "
warnMsg += "replacement with '?' character. Please, find " warnMsg += "replacement with '?' character. Please, find "
warnMsg += "proper character representation inside " warnMsg += "proper character representation inside "
warnMsg += "corresponding output files. " warnMsg += "corresponding output files. "
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+6 -9
View File
@@ -1,10 +1,12 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
import hashlib
def cachedmethod(f, cache={}): def cachedmethod(f, cache={}):
""" """
Method with a cached content Method with a cached content
@@ -13,14 +15,9 @@ def cachedmethod(f, cache={}):
""" """
def _(*args, **kwargs): def _(*args, **kwargs):
try: key = int(hashlib.md5("".join(str(_) for _ in (f, args, kwargs))).hexdigest()[:8], 16)
key = (f, tuple(args), frozenset(kwargs.items())) if key not in cache:
if key not in cache: cache[key] = f(*args, **kwargs)
cache[key] = f(*args, **kwargs)
except:
key = "".join(str(_) for _ in (f, args, kwargs))
if key not in cache:
cache[key] = f(*args, **kwargs)
return cache[key] return cache[key]
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+4 -4
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -184,10 +184,10 @@ DUMP_REPLACEMENTS = {" ": NULL, "": BLANK}
DBMS_DICT = { DBMS_DICT = {
DBMS.MSSQL: (MSSQL_ALIASES, "python-pymssql", "https://github.com/pymssql/pymssql", "mssql+pymssql"), 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.PGSQL: (PGSQL_ALIASES, "python-psycopg2", "http://initd.org/psycopg/", "postgresql"),
DBMS.ORACLE: (ORACLE_ALIASES, "python cx_Oracle", "http://cx-oracle.sourceforge.net/", "oracle"), DBMS.ORACLE: (ORACLE_ALIASES, "python cx_Oracle", "https://oracle.github.io/python-cx_Oracle/", "oracle"),
DBMS.SQLITE: (SQLITE_ALIASES, "python-sqlite", "http://packages.ubuntu.com/quantal/python-sqlite", "sqlite"), 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.ACCESS: (ACCESS_ALIASES, "python-pyodbc", "https://github.com/mkleehammer/pyodbc", "access"),
DBMS.FIREBIRD: (FIREBIRD_ALIASES, "python-kinterbasdb", "http://kinterbasdb.sourceforge.net/", "firebird"), DBMS.FIREBIRD: (FIREBIRD_ALIASES, "python-kinterbasdb", "http://kinterbasdb.sourceforge.net/", "firebird"),
DBMS.MAXDB: (MAXDB_ALIASES, None, None, "maxdb"), DBMS.MAXDB: (MAXDB_ALIASES, None, None, "maxdb"),
+5 -5
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -140,7 +140,7 @@ class Dump(object):
try: try:
elements = set(elements) elements = set(elements)
elements = list(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: except:
pass pass
@@ -191,7 +191,7 @@ class Dump(object):
userSettings = userSettings[0] userSettings = userSettings[0]
users = userSettings.keys() 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: if conf.api:
self._write(userSettings, content_type=content_type) self._write(userSettings, content_type=content_type)
@@ -285,7 +285,7 @@ class Dump(object):
colType = None colType = None
colList = columns.keys() 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: for column in colList:
colType = columns[column] colType = columns[column]
@@ -377,7 +377,7 @@ class Dump(object):
if count is None: if count is None:
count = "Unknown" 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: for table in tables:
blank1 = " " * (maxlength1 - len(normalizeUnicode(table) or unicode(table))) blank1 = " " * (maxlength1 - len(normalizeUnicode(table) or unicode(table)))
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+13 -9
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -692,7 +692,7 @@ def _setMetasploit():
errMsg = "sqlmap requires third-party module 'pywin32' " errMsg = "sqlmap requires third-party module 'pywin32' "
errMsg += "in order to use Metasploit functionalities on " errMsg += "in order to use Metasploit functionalities on "
errMsg += "Windows. You can download it from " 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) raise SqlmapMissingDependence(errMsg)
if not conf.msfPath: if not conf.msfPath:
@@ -784,7 +784,7 @@ def _setMetasploit():
if not msfEnvPathExists: if not msfEnvPathExists:
errMsg = "unable to locate Metasploit Framework installation. " 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) raise SqlmapFilePathException(errMsg)
def _setWriteFile(): def _setWriteFile():
@@ -1376,7 +1376,7 @@ def _setHTTPAuthentication():
except ImportError: except ImportError:
errMsg = "sqlmap requires Python NTLM third-party library " errMsg = "sqlmap requires Python NTLM third-party library "
errMsg += "in order to authenticate via NTLM, " 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) raise SqlmapMissingDependence(errMsg)
authHandler = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(kb.passwordMgr) authHandler = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(kb.passwordMgr)
@@ -1488,8 +1488,8 @@ def _setHTTPUserAgent():
userAgent = random.sample(kb.userAgents or [_defaultHTTPUserAgent()], 1)[0] userAgent = random.sample(kb.userAgents or [_defaultHTTPUserAgent()], 1)[0]
infoMsg = "fetched random HTTP User-Agent header from " infoMsg = "fetched random HTTP User-Agent header value '%s' from " % userAgent
infoMsg += "file '%s': '%s'" % (paths.USER_AGENTS, userAgent) infoMsg += "file '%s'" % paths.USER_AGENTS
logger.info(infoMsg) logger.info(infoMsg)
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, userAgent)) conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, userAgent))
@@ -1661,6 +1661,9 @@ def _cleanupOptions():
if conf.delay: if conf.delay:
conf.delay = float(conf.delay) conf.delay = float(conf.delay)
if conf.url:
conf.url = conf.url.strip()
if conf.rFile: if conf.rFile:
conf.rFile = ntToPosixSlashes(normalizePath(conf.rFile)) conf.rFile = ntToPosixSlashes(normalizePath(conf.rFile))
@@ -1886,6 +1889,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.cache.addrinfo = {} kb.cache.addrinfo = {}
kb.cache.content = {} kb.cache.content = {}
kb.cache.encoding = {} kb.cache.encoding = {}
kb.cache.alphaBoundaries = None
kb.cache.intBoundaries = None kb.cache.intBoundaries = None
kb.cache.parsedDbms = {} kb.cache.parsedDbms = {}
kb.cache.regex = {} kb.cache.regex = {}
@@ -2097,11 +2101,11 @@ def _useWizardInterface():
choice = readInput(message, default='1') choice = readInput(message, default='1')
if choice == '2': if choice == '2':
map(lambda x: conf.__setitem__(x, True), WIZARD.INTERMEDIATE) map(lambda _: conf.__setitem__(_, True), WIZARD.INTERMEDIATE)
elif choice == '3': elif choice == '3':
map(lambda x: conf.__setitem__(x, True), WIZARD.ALL) map(lambda _: conf.__setitem__(_, True), WIZARD.ALL)
else: 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") logger.debug("muting sqlmap.. it will do the magic for you")
conf.verbose = 0 conf.verbose = 0
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+23 -9
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 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 from lib.core.enums import OS
# sqlmap version (<major>.<minor>.<month>.<monthly commit>) # sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.1.11.0" VERSION = "1.2"
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE) VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
@@ -76,7 +76,7 @@ CHAR_INFERENCE_MARK = "%c"
PRINTABLE_CHAR_REGEX = r"[^\x00-\x1f\x7f-\xff]" PRINTABLE_CHAR_REGEX = r"[^\x00-\x1f\x7f-\xff]"
# Regular expression used for extraction of table names (useful for (e.g.) MsAccess) # 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 # Regular expression used for recognition of textual content-type
TEXT_CONTENT_TYPE_REGEX = r"(?i)(text|form|message|xml|javascript|ecmascript|json)" TEXT_CONTENT_TYPE_REGEX = r"(?i)(text|form|message|xml|javascript|ecmascript|json)"
@@ -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 # Regular expression used for recognition of generic permission messages
PERMISSION_DENIED_REGEX = r"(command|permission|access)\s*(was|is)?\s*denied" 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 # 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 # Maximum consecutive connection errors before asking the user if he wants to continue
MAX_CONSECUTIVE_CONNECTION_ERRORS = 15 MAX_CONSECUTIVE_CONNECTION_ERRORS = 15
@@ -193,8 +196,8 @@ UNKNOWN_DBMS = "Unknown"
# String used for representation of unknown DBMS version # String used for representation of unknown DBMS version
UNKNOWN_DBMS_VERSION = "Unknown" UNKNOWN_DBMS_VERSION = "Unknown"
# Dynamicity mark length used in dynamicity removal engine # Dynamicity boundary length used in dynamicity removal engine
DYNAMICITY_MARK_LENGTH = 32 DYNAMICITY_BOUNDARY_LENGTH = 20
# Dummy user prefix used in dictionary attack # Dummy user prefix used in dictionary attack
DUMMY_USER_PREFIX = "__dummy__" DUMMY_USER_PREFIX = "__dummy__"
@@ -202,6 +205,11 @@ DUMMY_USER_PREFIX = "__dummy__"
# Reference: http://en.wikipedia.org/wiki/ISO/IEC_8859-1 # Reference: http://en.wikipedia.org/wiki/ISO/IEC_8859-1
DEFAULT_PAGE_ENCODING = "iso-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 # URL used in dummy runs
DUMMY_URL = "http://foo/bar?id=1" DUMMY_URL = "http://foo/bar?id=1"
@@ -300,8 +308,11 @@ BLANK = "<blank>"
# String representation for current database # String representation for current database
CURRENT_DB = "CD" 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 # 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"(?P<result>[^<>'\"]+?)['\"]? on line \d+", r"(?:[>(\[\s])(?P<result>[A-Za-z]:[\\/][\w. \\/-]*)", r"(?:[>(\[\s])(?P<result>/\w[/\w.~-]+)", r"href=['\"]file://(?P<result>/[^'\"]+)")
# Regular expressions used for parsing error messages (--parse-errors) # Regular expressions used for parsing error messages (--parse-errors)
ERROR_PARSING_REGEXES = ( ERROR_PARSING_REGEXES = (
@@ -479,7 +490,7 @@ PICKLE_REDUCE_WHITELIST = (types.BooleanType, types.DictType, types.FloatType, t
DUMMY_SQL_INJECTION_CHARS = ";()'" DUMMY_SQL_INJECTION_CHARS = ";()'"
# Simple check against dummy users # 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 # 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") 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 +531,9 @@ ROTATING_CHARS = ('\\', '|', '|', '/', '-')
# Approximate chunk length (in bytes) used by BigArray objects (only last chunk and cached one are held in memory) # Approximate chunk length (in bytes) used by BigArray objects (only last chunk and cached one are held in memory)
BIGARRAY_CHUNK_SIZE = 1024 * 1024 BIGARRAY_CHUNK_SIZE = 1024 * 1024
# Compress (zlib) level used for storing BigArray chunks to disk (0-9)
BIGARRAY_COMPRESS_LEVEL = 9
# Maximum number of socket pre-connects # Maximum number of socket pre-connects
SOCKET_PRE_CONNECT_QUEUE_SIZE = 3 SOCKET_PRE_CONNECT_QUEUE_SIZE = 3
@@ -639,7 +653,7 @@ VALID_TIME_CHARS_RUN_THRESHOLD = 100
CHECK_ZERO_COLUMNS_THRESHOLD = 10 CHECK_ZERO_COLUMNS_THRESHOLD = 10
# Boldify all logger messages containing these "patterns" # Boldify all logger messages containing these "patterns"
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA", "specific response") 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 www root directory names
GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "httpdocs", "public", "wwwroot", "www") GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "httpdocs", "public", "wwwroot", "www")
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+8 -4
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 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 REFERER_ALIASES
from lib.core.settings import RESTORE_MERGED_OPTIONS from lib.core.settings import RESTORE_MERGED_OPTIONS
from lib.core.settings import RESULTS_FILE_FORMAT 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 SUPPORTED_DBMS
from lib.core.settings import UNENCODED_ORIGINAL_VALUE from lib.core.settings import UNENCODED_ORIGINAL_VALUE
from lib.core.settings import UNICODE_ENCODING from lib.core.settings import UNICODE_ENCODING
@@ -396,6 +397,9 @@ def _setRequestParams():
raise SqlmapGenericException(errMsg) raise SqlmapGenericException(errMsg)
else: else:
for place in (PLACE.GET, PLACE.POST, PLACE.COOKIE): for place in (PLACE.GET, PLACE.POST, PLACE.COOKIE):
if conf.csrfToken:
break
for parameter in conf.paramDict.get(place, {}): for parameter in conf.paramDict.get(place, {}):
if any(parameter.lower().count(_) for _ in CSRF_TOKEN_PARAMETER_INFIXES): if any(parameter.lower().count(_) for _ in CSRF_TOKEN_PARAMETER_INFIXES):
message = "%s parameter '%s' appears to hold anti-CSRF token. " % (place, parameter) 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): if readInput(message, default='N', boolean=True):
conf.csrfToken = getUnicode(parameter) conf.csrfToken = getUnicode(parameter)
break break
def _setHashDB(): def _setHashDB():
""" """
@@ -411,7 +415,7 @@ def _setHashDB():
""" """
if not conf.hashDBFile: 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 os.path.exists(conf.hashDBFile):
if conf.flushSession: if conf.flushSession:
@@ -545,7 +549,7 @@ def _setResultsFile():
if not conf.resultsFP: if not conf.resultsFP:
conf.resultsFilename = os.path.join(paths.SQLMAP_OUTPUT_PATH, time.strftime(RESULTS_FILE_FORMAT).lower()) conf.resultsFilename = os.path.join(paths.SQLMAP_OUTPUT_PATH, time.strftime(RESULTS_FILE_FORMAT).lower())
try: try:
conf.resultsFP = openFile(conf.resultsFilename, "w+", UNICODE_ENCODING, buffering=0) conf.resultsFP = openFile(conf.resultsFilename, "a", UNICODE_ENCODING, buffering=0)
except (OSError, IOError), ex: except (OSError, IOError), ex:
try: try:
warnMsg = "unable to create results file '%s' ('%s'). " % (conf.resultsFilename, getUnicode(ex)) warnMsg = "unable to create results file '%s' ('%s'). " % (conf.resultsFilename, getUnicode(ex))
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+7 -4
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -64,9 +64,6 @@ class _ThreadData(threading.local):
ThreadData = _ThreadData() ThreadData = _ThreadData()
def getCurrentThreadUID():
return hash(threading.currentThread())
def readInput(message, default=None, checkBatch=True, boolean=False): def readInput(message, default=None, checkBatch=True, boolean=False):
# It will be overwritten by original from lib.core.common # It will be overwritten by original from lib.core.common
pass pass
@@ -98,6 +95,9 @@ def exceptionHandledFunction(threadFunction, silent=False):
if not silent: if not silent:
logger.error("thread %s: %s" % (threading.currentThread().getName(), ex.message)) logger.error("thread %s: %s" % (threading.currentThread().getName(), ex.message))
if conf.verbose > 1:
traceback.print_exc()
def setDaemon(thread): def setDaemon(thread):
# Reference: http://stackoverflow.com/questions/190010/daemon-threads-explanation # Reference: http://stackoverflow.com/questions/190010/daemon-threads-explanation
if PYVERSION >= "2.6": if PYVERSION >= "2.6":
@@ -188,6 +188,9 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
kb.threadException = True kb.threadException = True
logger.error("thread %s: %s" % (threading.currentThread().getName(), ex.message)) logger.error("thread %s: %s" % (threading.currentThread().getName(), ex.message))
if conf.verbose > 1:
traceback.print_exc()
except: except:
from lib.core.common import unhandledExceptionMessage from lib.core.common import unhandledExceptionMessage
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -626,7 +626,7 @@ def cmdLineParser(argv=None):
general.add_option("--batch", dest="batch", general.add_option("--batch", dest="batch",
action="store_true", action="store_true",
help="Never ask for user input, use the default behaviour") help="Never ask for user input, use the default behavior")
general.add_option("--binary-fields", dest="binaryFields", general.add_option("--binary-fields", dest="binaryFields",
help="Result fields having binary values (e.g. \"digest\")") help="Result fields having binary values (e.g. \"digest\")")
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+21 -7
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 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 extractRegexResult
from lib.core.common import getPublicTypeMembers from lib.core.common import getPublicTypeMembers
from lib.core.common import getUnicode from lib.core.common import getUnicode
from lib.core.common import isListLike
from lib.core.common import randomStr from lib.core.common import randomStr
from lib.core.common import readInput from lib.core.common import readInput
from lib.core.common import resetCookieJar from lib.core.common import resetCookieJar
from lib.core.common import singleTimeLogMessage from lib.core.common import singleTimeLogMessage
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage
from lib.core.common import unArrayizeValue
from lib.core.data import conf from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
@@ -150,6 +152,9 @@ def checkCharEncoding(encoding, warn=True):
'utf8' 'utf8'
""" """
if isListLike(encoding):
encoding = unArrayizeValue(encoding)
if encoding: if encoding:
encoding = encoding.lower() encoding = encoding.lower()
else: else:
@@ -254,12 +259,22 @@ def decodePage(page, contentEncoding, contentType):
if not page or (conf.nullConnection and len(page) < 2): if not page or (conf.nullConnection and len(page) < 2):
return getUnicode(page) return getUnicode(page)
if 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: if not kb.pageCompress:
return None return None
try: 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 data = StringIO.StringIO(zlib.decompress(page, -15)) # Reference: http://stackoverflow.com/questions/1089662/python-inflate-and-deflate-implementations
else: else:
data = gzip.GzipFile("", "rb", 9, StringIO.StringIO(page)) data = gzip.GzipFile("", "rb", 9, StringIO.StringIO(page))
@@ -284,13 +299,12 @@ def decodePage(page, contentEncoding, contentType):
httpCharset, metaCharset = None, None httpCharset, metaCharset = None, None
# Reference: http://stackoverflow.com/questions/1020892/python-urllib2-read-to-unicode # 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]) httpCharset = checkCharEncoding(contentType.split("charset=")[-1])
metaCharset = checkCharEncoding(extractRegexResult(META_CHARSET_REGEX, page)) metaCharset = checkCharEncoding(extractRegexResult(META_CHARSET_REGEX, page))
if (any((httpCharset, metaCharset)) and not all((httpCharset, metaCharset)))\ if (any((httpCharset, metaCharset)) and not all((httpCharset, metaCharset))) or (httpCharset == metaCharset and 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 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 debugMsg = "declared web page charset '%s'" % kb.pageEncoding
singleTimeLogMessage(debugMsg, logging.DEBUG, debugMsg) singleTimeLogMessage(debugMsg, logging.DEBUG, debugMsg)
@@ -300,7 +314,7 @@ def decodePage(page, contentEncoding, contentType):
kb.pageEncoding = conf.encoding kb.pageEncoding = conf.encoding
# can't do for all responses because we need to support binary files too # can't do for all responses because we need to support binary files too
if contentType and not isinstance(page, unicode) and "text/" in contentType.lower(): if not isinstance(page, unicode) and "text/" in contentType:
if kb.heuristicMode: if kb.heuristicMode:
kb.pageEncoding = kb.pageEncoding or checkCharEncoding(getHeuristicCharEncoding(page)) kb.pageEncoding = kb.pageEncoding or checkCharEncoding(getHeuristicCharEncoding(page))
page = getUnicode(page, kb.pageEncoding) page = getUnicode(page, kb.pageEncoding)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+15 -10
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -49,7 +49,7 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
threadData = getCurrentThreadData() threadData = getCurrentThreadData()
if kb.testMode: 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.lastComparisonPage = page
threadData.lastComparisonCode = code threadData.lastComparisonCode = code
@@ -57,7 +57,7 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
return None return None
if any((conf.string, conf.notString, conf.regexp)): 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 # String to match in page when the query is True and/or valid
if conf.string: 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" # Preventing "Unicode equal comparison failed to convert both arguments to Unicode"
# (e.g. if one page is PDF and the other is HTML) # (e.g. if one page is PDF and the other is HTML)
if isinstance(seqMatcher.a, str) and isinstance(page, unicode): 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): 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: if any(_ is None for _ in (page, seqMatcher.a)):
ratio = 1 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)): 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 not page or not seqMatcher.a:
if ratio > 1: return float(seqMatcher.a == page)
ratio = 1. / ratio else:
ratio = 1. * len(seqMatcher.a) / len(page)
if ratio > 1:
ratio = 1. / ratio
else: else:
seq1, seq2 = None, None seq1, seq2 = None, None
+10 -7
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -796,6 +796,8 @@ class Connect(object):
raise404 = place != PLACE.URI if raise404 is None else raise404 raise404 = place != PLACE.URI if raise404 is None else raise404
method = method or conf.method method = method or conf.method
postUrlEncode = kb.postUrlEncode
value = agent.adjustLateValues(value) value = agent.adjustLateValues(value)
payload = agent.extractPayload(value) payload = agent.extractPayload(value)
threadData = getCurrentThreadData() threadData = getCurrentThreadData()
@@ -804,8 +806,8 @@ class Connect(object):
headers = OrderedDict(conf.httpHeaders) headers = OrderedDict(conf.httpHeaders)
contentType = max(headers[_] if _.upper() == HTTP_HEADER.CONTENT_TYPE.upper() else None for _ in headers.keys()) 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: if (kb.postHint or conf.skipUrlEncode) and postUrlEncode:
kb.postUrlEncode = False postUrlEncode = False
conf.httpHeaders = [_ for _ in conf.httpHeaders if _[1] != contentType] conf.httpHeaders = [_ for _ in conf.httpHeaders if _[1] != contentType]
contentType = POST_HINT_CONTENT_TYPES.get(kb.postHint, PLAIN_TEXT_CONTENT_TYPE) contentType = POST_HINT_CONTENT_TYPES.get(kb.postHint, PLAIN_TEXT_CONTENT_TYPE)
conf.httpHeaders.append((HTTP_HEADER.CONTENT_TYPE, contentType)) conf.httpHeaders.append((HTTP_HEADER.CONTENT_TYPE, contentType))
@@ -849,7 +851,7 @@ class Connect(object):
value = agent.replacePayload(value, payload) value = agent.replacePayload(value, payload)
else: else:
# GET, POST, URI and Cookie payload needs to be thoroughly URL encoded # GET, POST, URI and Cookie payload needs to be thoroughly URL encoded
if (place in (PLACE.GET, PLACE.URI, PLACE.COOKIE) or place == PLACE.CUSTOM_HEADER and value.split(',')[0] == 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 skip = False
if place == PLACE.COOKIE or place == PLACE.CUSTOM_HEADER and value.split(',')[0] == HTTP_HEADER.COOKIE: if place == PLACE.COOKIE or place == PLACE.CUSTOM_HEADER and value.split(',')[0] == HTTP_HEADER.COOKIE:
@@ -862,6 +864,7 @@ class Connect(object):
if not skip: if not skip:
payload = urlencode(payload, '%', False, place != PLACE.URI) # spaceplus is handled down below payload = urlencode(payload, '%', False, place != PLACE.URI) # spaceplus is handled down below
value = agent.replacePayload(value, payload) value = agent.replacePayload(value, payload)
postUrlEncode = False
if conf.hpp: if conf.hpp:
if not any(conf.url.lower().endswith(_.lower()) for _ in (WEB_API.ASP, WEB_API.ASPX)): if not any(conf.url.lower().endswith(_.lower()) for _ in (WEB_API.ASP, WEB_API.ASPX)):
@@ -1129,7 +1132,7 @@ class Connect(object):
found = True found = True
uri = re.sub(regex.replace(r"\A", r"\?"), "\g<1>%s\g<3>" % value.replace('\\', r'\\'), uri) 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 "")): if re.search(regex, (cookie or "")):
found = True found = True
cookie = re.sub(regex, "\g<1>%s\g<3>" % value.replace('\\', r'\\'), cookie) cookie = re.sub(regex, "\g<1>%s\g<3>" % value.replace('\\', r'\\'), cookie)
@@ -1148,7 +1151,7 @@ class Connect(object):
if post is not None: if post is not None:
if place not in (PLACE.POST, PLACE.CUSTOM_POST) and hasattr(post, UNENCODED_ORIGINAL_VALUE): if place not in (PLACE.POST, PLACE.CUSTOM_POST) and hasattr(post, UNENCODED_ORIGINAL_VALUE):
post = getattr(post, UNENCODED_ORIGINAL_VALUE) post = getattr(post, UNENCODED_ORIGINAL_VALUE)
elif kb.postUrlEncode: elif postUrlEncode:
post = urlencode(post, spaceplus=kb.postSpaceToPlus) post = urlencode(post, spaceplus=kb.postSpaceToPlus)
if timeBasedCompare and not conf.disableStats: if timeBasedCompare and not conf.disableStats:
@@ -1159,7 +1162,7 @@ class Connect(object):
if conf.tor: if conf.tor:
warnMsg = "it's highly recommended to avoid usage of switch '--tor' for " 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) singleTimeWarnMessage(warnMsg)
warnMsg = "[%s] [WARNING] %stime-based comparison requires " % (time.strftime("%X"), "(case) " if kb.responseTimeMode else "") 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 #!/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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+11 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 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 INFERENCE_MARKER
from lib.core.settings import MAX_TECHNIQUES_PER_VALUE from lib.core.settings import MAX_TECHNIQUES_PER_VALUE
from lib.core.settings import SQL_SCALAR_REGEX from lib.core.settings import SQL_SCALAR_REGEX
from lib.core.settings import UNICODE_ENCODING
from lib.core.threads import getCurrentThreadData from lib.core.threads import getCurrentThreadData
from lib.request.connect import Connect as Request from lib.request.connect import Connect as Request
from lib.request.direct import direct 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 "" warnMsg += "or switch '--hex'" if Backend.getIdentifiedDbms() not in (DBMS.ACCESS, DBMS.FIREBIRD) else ""
singleTimeWarnMessage(warnMsg) 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) return extractExpectedValue(value, expected)
def goStacked(expression, silent=False): def goStacked(expression, silent=False):
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -501,7 +501,7 @@ class Metasploit:
send_all(proc, "getsystem\n") 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 += "Choose which user you want to impersonate by "
infoMsg += "using incognito's command 'impersonate_token' if " infoMsg += "using incognito's command 'impersonate_token' if "
infoMsg += "'getsystem' does not success to elevate privileges" infoMsg += "'getsystem' does not success to elevate privileges"
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+4 -4
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -266,9 +266,9 @@ class Web:
directories = _ directories = _
backdoorName = "tmpb%s.%s" % (randomStr(lowercase=True), self.webApi) 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: for directory in directories:
if not directory: if not directory:
@@ -323,7 +323,7 @@ class Web:
os.close(handle) os.close(handle)
with open(filename, "w+b") as f: with open(filename, "w+b") as f:
_ = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stager.%s_" % self.webApi)) _ = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stagers", "stager.%s_" % self.webApi))
_ = _.replace("WRITABLE_DIR", utf8encode(directory.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else directory)) _ = _.replace("WRITABLE_DIR", utf8encode(directory.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else directory))
f.write(_) f.write(_)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+16 -19
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -110,7 +110,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if partialValue: if partialValue:
firstChar = len(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 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())): 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 firstChar = int(conf.firstChar) - 1
@@ -121,7 +121,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
else: else:
firstChar = 0 firstChar = 0
if "LENGTH(" in expression.upper() or "LEN(" in expression.upper(): if re.search(r"(?i)\b(LENGTH|LEN)\(", expression):
lastChar = 0 lastChar = 0
elif dump and conf.lastChar is not None and (isinstance(conf.lastChar, int) or (isinstance(conf.lastChar, basestring) and conf.lastChar.isdigit())): 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) lastChar = int(conf.lastChar)
@@ -343,7 +343,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if result: if result:
minValue = posValue minValue = posValue
if type(charTbl) != xrange: if not isinstance(charTbl, xrange):
charTbl = charTbl[position:] charTbl = charTbl[position:]
else: else:
# xrange() - extended virtual charset used for memory/space optimization # xrange() - extended virtual charset used for memory/space optimization
@@ -351,7 +351,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
else: else:
maxValue = posValue maxValue = posValue
if type(charTbl) != xrange: if not isinstance(charTbl, xrange):
charTbl = charTbl[:position] charTbl = charTbl[:position]
else: else:
charTbl = xrange(charTbl[0], charTbl[position]) charTbl = xrange(charTbl[0], charTbl[position])
@@ -390,7 +390,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if timeBasedCompare: if timeBasedCompare:
if kb.adjustTimeDelay is not ADJUST_TIME_DELAY.DISABLE: if kb.adjustTimeDelay is not ADJUST_TIME_DELAY.DISABLE:
conf.timeSec += 1 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) logger.warn(warnMsg)
if kb.adjustTimeDelay is ADJUST_TIME_DELAY.YES: if kb.adjustTimeDelay is ADJUST_TIME_DELAY.YES:
@@ -461,18 +461,15 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
threadData = getCurrentThreadData() threadData = getCurrentThreadData()
while kb.threadContinue: 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: threadData.shared.index[0] += 1
kb.locks.index.release() currentCharIndex = threadData.shared.index[0]
return
threadData.shared.index[0] += 1
currentCharIndex = threadData.shared.index[0]
kb.locks.index.release()
if kb.threadContinue: if kb.threadContinue:
charStart = time.time() start = time.time()
val = getChar(currentCharIndex, asciiTbl, not(charsetType is None and conf.charset)) val = getChar(currentCharIndex, asciiTbl, not(charsetType is None and conf.charset))
if val is None: if val is None:
val = INFERENCE_UNKNOWN_CHAR val = INFERENCE_UNKNOWN_CHAR
@@ -485,7 +482,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if kb.threadContinue: if kb.threadContinue:
if showEta: if showEta:
progress.progress(time.time() - charStart, threadData.shared.index[0]) progress.progress(calculateDeltaSeconds(start), threadData.shared.index[0])
elif conf.verbose >= 1: elif conf.verbose >= 1:
startCharIndex = 0 startCharIndex = 0
endCharIndex = 0 endCharIndex = 0
@@ -553,7 +550,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
while True: while True:
index += 1 index += 1
charStart = time.time() start = time.time()
# Common prediction feature (a.k.a. "good samaritan") # Common prediction feature (a.k.a. "good samaritan")
# NOTE: to be used only when multi-threading is not set for # 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? # Did we have luck?
if result: if result:
if showEta: if showEta:
progress.progress(time.time() - charStart, len(commonValue)) progress.progress(calculateDeltaSeconds(start), len(commonValue))
elif conf.verbose in (1, 2) or conf.api: elif conf.verbose in (1, 2) or conf.api:
dataToStdout(filterControlChars(commonValue[index - 1:])) 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 threadData.shared.value = partialValue = partialValue + val
if showEta: if showEta:
progress.progress(time.time() - charStart, index) progress.progress(calculateDeltaSeconds(start), index)
elif conf.verbose in (1, 2) or conf.api: elif conf.verbose in (1, 2) or conf.api:
dataToStdout(filterControlChars(val)) dataToStdout(filterControlChars(val))
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+8 -5
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -76,7 +76,10 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False):
current = MAX_ERROR_CHUNK_LENGTH current = MAX_ERROR_CHUNK_LENGTH
while current >= MIN_ERROR_CHUNK_LENGTH: while current >= MIN_ERROR_CHUNK_LENGTH:
testChar = str(current % 10) 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)) result = unArrayizeValue(_oneShotErrorUse(testQuery, chunkTest=True))
if (result or "").startswith(testChar): 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, (\ output = reduce(lambda x, y: x if x is not None else y, (\
extractRegexResult(check, page), \ extractRegexResult(check, page), \
extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None), \ 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)), \ extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None)), \
None) None)
@@ -142,7 +145,7 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False):
else: else:
trimmed = extractRegexResult(trimcheck, page) \ trimmed = extractRegexResult(trimcheck, page) \
or extractRegexResult(trimcheck, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None) \ 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) or extractRegexResult(trimcheck, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None)
if trimmed: if trimmed:
@@ -330,7 +333,7 @@ def errorUse(expression, dump=False):
else: else:
stopLimit = int(count) stopLimit = int(count)
infoMsg = "the SQL query used returns " infoMsg = "used SQL query returns "
infoMsg += "%d entries" % stopLimit infoMsg += "%d entries" % stopLimit
logger.info(infoMsg) logger.info(infoMsg)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+9 -13
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -115,7 +115,7 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
if not isNullValue(kb.uChar): if not isNullValue(kb.uChar):
for regex in (kb.uChar, r'>\s*%s\s*<' % 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: if len(filter(lambda _: _[1], contains)) == 1:
retVal = filter(lambda _: _[1], contains)[0][0] retVal = filter(lambda _: _[1], contains)[0][0]
break break
@@ -178,7 +178,7 @@ def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLO
for position in positions: for position in positions:
# Prepare expression with delimiters # Prepare expression with delimiters
randQuery = randomStr(charCount) 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) randQueryProcessed = agent.concatQuery("\'%s\'" % randQuery)
randQueryUnescaped = unescaper.escape(randQueryProcessed) randQueryUnescaped = unescaper.escape(randQueryProcessed)
@@ -188,9 +188,7 @@ def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLO
# Perform the request # Perform the request
page, headers, _ = Request.queryPage(payload, place=place, content=True, raise404=False) page, headers, _ = Request.queryPage(payload, place=place, content=True, raise404=False)
content = "%s%s".lower() % (removeReflectiveValues(page, payload) or "", \ content = ("%s%s" % (removeReflectiveValues(page, payload) or "", removeReflectiveValues(listToStrValue(headers.headers if headers else None), payload, True) or "")).lower()
removeReflectiveValues(listToStrValue(headers.headers if headers else None), \
payload, True) or "")
if content and phrase in content: if content and phrase in content:
validPayload = payload validPayload = payload
@@ -200,7 +198,7 @@ def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLO
if where == PAYLOAD.WHERE.ORIGINAL: if where == PAYLOAD.WHERE.ORIGINAL:
# Prepare expression with delimiters # Prepare expression with delimiters
randQuery2 = randomStr(charCount) 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) randQueryProcessed2 = agent.concatQuery("\'%s\'" % randQuery2)
randQueryUnescaped2 = unescaper.escape(randQueryProcessed2) randQueryUnescaped2 = unescaper.escape(randQueryProcessed2)
@@ -210,7 +208,7 @@ def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLO
# Perform the request # Perform the request
page, headers, _ = Request.queryPage(payload, place=place, content=True, raise404=False) 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)): if not all(_ in content for _ in (phrase, phrase2)):
vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, True) 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 # Perform the request
page, headers, _ = Request.queryPage(payload, place=place, content=True, raise404=False) page, headers, _ = Request.queryPage(payload, place=place, content=True, raise404=False)
content = "%s%s".lower() % (removeReflectiveValues(page, payload) or "", \ content = ("%s%s" % (removeReflectiveValues(page, payload) or "", removeReflectiveValues(listToStrValue(headers.headers if headers else None), payload, True) or "")).lower()
removeReflectiveValues(listToStrValue(headers.headers if headers else None), \
payload, True) or "")
if content.count(phrase) > 0 and content.count(phrase) < LIMITED_ROWS_TEST_NUMBER: 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" warnMsg = "output with limited number of rows detected. Switching to partial mode"
logger.warn(warnMsg) logger.warn(warnMsg)
@@ -277,7 +273,7 @@ def _unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix)
if count: if count:
validPayload, vector = _unionConfirm(comment, place, parameter, prefix, suffix, 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 = "if UNION based SQL injection is not detected, "
warnMsg += "please consider " warnMsg += "please consider "
@@ -298,7 +294,7 @@ def _unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix)
warnMsg += "forcing the " warnMsg += "forcing the "
warnMsg += "back-end DBMS (e.g. '--dbms=mysql') " 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) singleTimeWarnMessage(warnMsg)
return validPayload, vector return validPayload, vector
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -262,7 +262,7 @@ def unionUse(expression, unpack=True, dump=False):
else: else:
stopLimit = int(count) stopLimit = int(count)
infoMsg = "the SQL query used returns " infoMsg = "used SQL query returns "
infoMsg += "%d entries" % stopLimit infoMsg += "%d entries" % stopLimit
logger.info(infoMsg) logger.info(infoMsg)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*- # -*- 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 See the file 'LICENSE' for copying permission
""" """
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -278,7 +278,7 @@ def columnExists(columnFile, regex=None):
kb.data.cachedColumns[conf.db] = {conf.tbl: columns} 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: if _ not in kb.brute.columns:
kb.brute.columns.append(_) kb.brute.columns.append(_)
+3 -3
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/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 See the file 'LICENSE' for copying permission
""" """
@@ -64,14 +64,14 @@ def crawl(target):
if current: if current:
content = Request.getPage(url=current, crawling=True, raise404=False)[0] content = Request.getPage(url=current, crawling=True, raise404=False)[0]
except SqlmapConnectionException, ex: except SqlmapConnectionException, ex:
errMsg = "connection exception detected (%s). skipping " % getSafeExString(ex) errMsg = "connection exception detected ('%s'). skipping " % getSafeExString(ex)
errMsg += "URL '%s'" % current errMsg += "URL '%s'" % current
logger.critical(errMsg) logger.critical(errMsg)
except SqlmapSyntaxException: except SqlmapSyntaxException:
errMsg = "invalid URL detected. skipping '%s'" % current errMsg = "invalid URL detected. skipping '%s'" % current
logger.critical(errMsg) logger.critical(errMsg)
except httplib.InvalidURL, ex: except httplib.InvalidURL, ex:
errMsg = "invalid URL detected (%s). skipping " % getSafeExString(ex) errMsg = "invalid URL detected ('%s'). skipping " % getSafeExString(ex)
errMsg += "URL '%s'" % current errMsg += "URL '%s'" % current
logger.critical(errMsg) logger.critical(errMsg)

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