mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-10-12 02:22:55 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d72660ef04 | ||
|
|
4833fb3aa6 | ||
|
|
f437a54561 | ||
|
|
f05f84b6e5 | ||
|
|
871ebfdb70 | ||
|
|
d34619232f | ||
|
|
5168daf6ce | ||
|
|
95e476d5c9 | ||
|
|
cc8209d648 | ||
|
|
6ec6e86937 | ||
|
|
018908c2b1 | ||
|
|
9e69d6076d | ||
|
|
ad785ea0a2 | ||
|
|
b51f02c2ca | ||
|
|
ea3de16f24 | ||
|
|
f29c4e1e07 | ||
|
|
e8871b8a99 | ||
|
|
8b88bb82d3 | ||
|
|
30fba849e2 | ||
|
|
617c336813 | ||
|
|
89a5892dd9 | ||
|
|
af8a2afde1 | ||
|
|
ceaf387533 | ||
|
|
e5a1377c36 | ||
|
|
bb61b08c83 | ||
|
|
2d63441cc4 |
@@ -192,6 +192,17 @@
|
||||
/var/log/mysqld.log
|
||||
/var/www/index.php
|
||||
|
||||
# Reference: https://github.com/sqlmapproject/sqlmap/blob/master/lib/core/settings.py#L809-L810
|
||||
|
||||
/var/www/index.php
|
||||
/usr/local/apache/index.php
|
||||
/usr/local/apache2/index.php
|
||||
/usr/local/www/apache22/index.php
|
||||
/usr/local/www/apache24/index.php
|
||||
/usr/local/httpd/index.php
|
||||
/var/www/nginx-default/index.php
|
||||
/srv/www/index.php
|
||||
|
||||
# Reference: https://www.gracefulsecurity.com/path-traversal-cheat-sheet-linux
|
||||
|
||||
/etc/passwd
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
References:
|
||||
* https://en.wikipedia.org/wiki/Debian_version_history
|
||||
-->
|
||||
|
||||
<root>
|
||||
<regexp value="^([\d\.\-]+)[\-\_\ ].*">
|
||||
<info dbms_version="1"/>
|
||||
@@ -36,19 +41,27 @@
|
||||
</regexp>
|
||||
|
||||
<regexp value="^([\d\.]+)[\-\_]Debian[\-\_][\d\.]+wheezy">
|
||||
<info dbms_version="1" type="Linux" distrib="Debian" release="7.0" codename="wheezy"/>
|
||||
<info dbms_version="1" type="Linux" distrib="Debian" release="7" codename="wheezy"/>
|
||||
</regexp>
|
||||
|
||||
<regexp value="^([\d\.]+)[\-\_]Debian[\-\_][\d\.]+jessie">
|
||||
<info dbms_version="1" type="Linux" distrib="Debian" release="8.0" codename="jessie"/>
|
||||
<info dbms_version="1" type="Linux" distrib="Debian" release="8" codename="jessie"/>
|
||||
</regexp>
|
||||
|
||||
<regexp value="^([\d\.]+)[\-\_]Debian[\-\_][\d\.]+stretch">
|
||||
<info dbms_version="1" type="Linux" distrib="Debian" release="9.0" codename="stretch"/>
|
||||
<info dbms_version="1" type="Linux" distrib="Debian" release="9" codename="stretch"/>
|
||||
</regexp>
|
||||
|
||||
<regexp value="^([\d\.]+)[\-\_]Debian[\-\_][\d\.]+buster">
|
||||
<info dbms_version="1" type="Linux" distrib="Debian" release="10.0" codename="buster"/>
|
||||
<info dbms_version="1" type="Linux" distrib="Debian" release="10" codename="buster"/>
|
||||
</regexp>
|
||||
|
||||
<regexp value="^([\d\.]+)[\-\_]Debian[\-\_][\d\.]+bullseye">
|
||||
<info dbms_version="1" type="Linux" distrib="Debian" release="11" codename="bullseye"/>
|
||||
</regexp>
|
||||
|
||||
<regexp value="^([\d\.]+)[\-\_]Debian[\-\_][\d\.]+bookworm">
|
||||
<info dbms_version="1" type="Linux" distrib="Debian" release="12" codename="bookworm"/>
|
||||
</regexp>
|
||||
|
||||
<regexp value="^([\d\.]+)[\-\_]Debian[\-\_][\d\.]+(sid|unstable)">
|
||||
|
||||
+13
-4
@@ -15,11 +15,13 @@ BEEP_WAV_FILENAME = os.path.join(os.path.dirname(__file__), "beep.wav")
|
||||
|
||||
def beep():
|
||||
try:
|
||||
if sys.platform == "nt":
|
||||
if sys.platform.startswith("win"):
|
||||
_win_wav_play(BEEP_WAV_FILENAME)
|
||||
elif sys.platform == "darwin":
|
||||
elif sys.platform.startswith("darwin"):
|
||||
_mac_beep()
|
||||
elif sys.platform.startswith("linux"):
|
||||
elif sys.platform.startswith("cygwin"):
|
||||
_cygwin_beep(BEEP_WAV_FILENAME)
|
||||
elif any(sys.platform.startswith(_) for _ in ("linux", "freebsd")):
|
||||
_linux_wav_play(BEEP_WAV_FILENAME)
|
||||
else:
|
||||
_speaker_beep()
|
||||
@@ -34,6 +36,10 @@ def _speaker_beep():
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
# Reference: https://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00815.html
|
||||
def _cygwin_beep(filename):
|
||||
os.system("play-sound-file '%s' 2>/dev/null" % filename)
|
||||
|
||||
def _mac_beep():
|
||||
import Carbon.Snd
|
||||
Carbon.Snd.SysBeep(1)
|
||||
@@ -57,7 +63,10 @@ def _linux_wav_play(filename):
|
||||
class struct_pa_sample_spec(ctypes.Structure):
|
||||
_fields_ = [("format", ctypes.c_int), ("rate", ctypes.c_uint32), ("channels", ctypes.c_uint8)]
|
||||
|
||||
pa = ctypes.cdll.LoadLibrary("libpulse-simple.so.0")
|
||||
try:
|
||||
pa = ctypes.cdll.LoadLibrary("libpulse-simple.so.0")
|
||||
except OSError:
|
||||
return
|
||||
|
||||
wave_file = wave.open(filename, "rb")
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
To use safe2bin.py you need to pass it the original file,
|
||||
and optionally the output file name.
|
||||
|
||||
Example:
|
||||
|
||||
$ python ./safe2bin.py -i output.txt -o output.txt.bin
|
||||
|
||||
This will create an binary decoded file output.txt.bin. For example,
|
||||
if the content of output.txt is: "\ttest\t\x32\x33\x34\nnewline" it will
|
||||
be decoded to: " test 234
|
||||
newline"
|
||||
|
||||
If you skip the output file name, general rule is that the binary
|
||||
file names are suffixed with the string '.bin'. So, that means that
|
||||
the upper example can also be written in the following form:
|
||||
|
||||
$ python ./safe2bin.py -i output.txt
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'LICENSE' for copying permission
|
||||
"""
|
||||
|
||||
pass
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#/usr/bin/env bash
|
||||
|
||||
# source ./extra/shutils/autocompletion.sh
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
WORDLIST=`python "$DIR/../../sqlmap.py" -hh | grep -Eo '\s\--?\w[^ =,]*' | grep -vF '..' | paste -sd "" -`
|
||||
|
||||
complete -W "$WORDLIST" sqlmap
|
||||
complete -W "$WORDLIST" ./sqlmap.py
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
export SQLMAP_DREI=1
|
||||
#for i in $(find . -iname "*.py" | grep -v __init__); do python3 -c 'import '`echo $i | cut -d '.' -f 2 | cut -d '/' -f 2- | sed 's/\//./g'`''; done
|
||||
for i in $(find . -iname "*.py" | grep -v __init__); do PYTHONWARNINGS=all python3.7 -m compileall $i; done
|
||||
for i in $(find . -iname "*.py" | grep -v __init__); do PYTHONWARNINGS=all python3.7 -m compileall $i | sed 's/Compiling/Checking/g'; done
|
||||
unset SQLMAP_DREI
|
||||
source `dirname "$0"`"/junk.sh"
|
||||
|
||||
|
||||
+5
-4
@@ -5,7 +5,6 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'LICENSE' for copying permission
|
||||
"""
|
||||
|
||||
import base64
|
||||
import re
|
||||
|
||||
from lib.core.common import Backend
|
||||
@@ -27,6 +26,7 @@ from lib.core.common import unArrayizeValue
|
||||
from lib.core.common import urlencode
|
||||
from lib.core.common import zeroDepthSearch
|
||||
from lib.core.compat import xrange
|
||||
from lib.core.convert import encodeBase64
|
||||
from lib.core.convert import getUnicode
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
@@ -50,6 +50,7 @@ from lib.core.settings import PAYLOAD_DELIMITER
|
||||
from lib.core.settings import REPLACEMENT_MARKER
|
||||
from lib.core.settings import SINGLE_QUOTE_MARKER
|
||||
from lib.core.settings import SLEEP_TIME_MARKER
|
||||
from lib.core.settings import UNICODE_ENCODING
|
||||
from lib.core.unescaper import unescaper
|
||||
from thirdparty import six
|
||||
|
||||
@@ -170,8 +171,8 @@ class Agent(object):
|
||||
|
||||
if re.sub(r" \(.+", "", parameter) in conf.base64Parameter:
|
||||
# TODO: support for POST_HINT
|
||||
newValue = base64.b64encode(newValue)
|
||||
origValue = base64.b64encode(origValue)
|
||||
newValue = encodeBase64(newValue, binary=False, encoding=conf.encoding or UNICODE_ENCODING)
|
||||
origValue = encodeBase64(origValue, binary=False, encoding=conf.encoding or UNICODE_ENCODING)
|
||||
|
||||
if place in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER):
|
||||
_ = "%s%s" % (origValue, kb.customInjectionMark)
|
||||
@@ -654,7 +655,7 @@ class Agent(object):
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
|
||||
_ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM "))
|
||||
concatenatedQuery = "%s||'%s'%s" % (concatenatedQuery[:_], kb.chars.stop, concatenatedQuery[_:])
|
||||
concatenatedQuery = re.sub(r"('%s'\|\|)(.+)(%s)" % (kb.chars.start, re.escape(castedFields)), r"\g<2>\g<1>\g<3>", concatenatedQuery)
|
||||
concatenatedQuery = re.sub(r"('%s'\|\|)(.+?)(%s)" % (kb.chars.start, re.escape(castedFields)), r"\g<2>\g<1>\g<3>", concatenatedQuery)
|
||||
elif fieldsSelect:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
|
||||
concatenatedQuery += "||'%s'" % kb.chars.stop
|
||||
|
||||
+2
-2
@@ -46,7 +46,6 @@ from xml.sax import SAXParseException
|
||||
|
||||
from extra.beep.beep import beep
|
||||
from extra.cloak.cloak import decloak
|
||||
from extra.safe2bin.safe2bin import safecharencode
|
||||
from lib.core.bigarray import BigArray
|
||||
from lib.core.compat import cmp
|
||||
from lib.core.compat import round
|
||||
@@ -180,6 +179,7 @@ from lib.core.settings import VERSION_STRING
|
||||
from lib.core.settings import ZIP_HEADER
|
||||
from lib.core.settings import WEBSCARAB_SPLITTER
|
||||
from lib.core.threads import getCurrentThreadData
|
||||
from lib.utils.safe2bin import safecharencode
|
||||
from lib.utils.sqlalchemy import _sqlalchemy
|
||||
from thirdparty import six
|
||||
from thirdparty.clientform.clientform import ParseResponse
|
||||
@@ -623,7 +623,7 @@ def paramToDict(place, parameters=None):
|
||||
if parameter in (conf.base64Parameter or []):
|
||||
try:
|
||||
oldValue = value
|
||||
value = decodeBase64(value, binary=False)
|
||||
value = decodeBase64(value, binary=False, encoding=conf.encoding or UNICODE_ENCODING)
|
||||
parameters = re.sub(r"\b%s(\b|\Z)" % re.escape(oldValue), value, parameters)
|
||||
except:
|
||||
errMsg = "parameter '%s' does not contain " % parameter
|
||||
|
||||
+7
-7
@@ -184,7 +184,7 @@ def encodeHex(value, binary=True):
|
||||
|
||||
return retVal
|
||||
|
||||
def decodeBase64(value, binary=True):
|
||||
def decodeBase64(value, binary=True, encoding=None):
|
||||
"""
|
||||
Returns a decoded representation of provided Base64 value
|
||||
|
||||
@@ -197,11 +197,11 @@ def decodeBase64(value, binary=True):
|
||||
retVal = base64.b64decode(value)
|
||||
|
||||
if not binary:
|
||||
retVal = getText(retVal)
|
||||
retVal = getText(retVal, encoding)
|
||||
|
||||
return retVal
|
||||
|
||||
def encodeBase64(value, binary=True):
|
||||
def encodeBase64(value, binary=True, encoding=None):
|
||||
"""
|
||||
Returns a decoded representation of provided Base64 value
|
||||
|
||||
@@ -212,12 +212,12 @@ def encodeBase64(value, binary=True):
|
||||
"""
|
||||
|
||||
if isinstance(value, six.text_type):
|
||||
value = value.encode(UNICODE_ENCODING)
|
||||
value = value.encode(encoding or UNICODE_ENCODING)
|
||||
|
||||
retVal = base64.b64encode(value)
|
||||
|
||||
if not binary:
|
||||
retVal = getText(retVal)
|
||||
retVal = getText(retVal, encoding)
|
||||
|
||||
return retVal
|
||||
|
||||
@@ -305,7 +305,7 @@ def getUnicode(value, encoding=None, noneToNull=False):
|
||||
except UnicodeDecodeError:
|
||||
return six.text_type(str(value), errors="ignore") # encoding ignored for non-basestring instances
|
||||
|
||||
def getText(value):
|
||||
def getText(value, encoding=None):
|
||||
"""
|
||||
Returns textual value of a given value (Note: not necessary Unicode on Python2)
|
||||
|
||||
@@ -318,7 +318,7 @@ def getText(value):
|
||||
retVal = value
|
||||
|
||||
if isinstance(value, six.binary_type):
|
||||
retVal = getUnicode(value)
|
||||
retVal = getUnicode(value, encoding)
|
||||
|
||||
if six.PY2:
|
||||
try:
|
||||
|
||||
+1
-1
@@ -13,7 +13,6 @@ import shutil
|
||||
import tempfile
|
||||
import threading
|
||||
|
||||
from extra.safe2bin.safe2bin import safechardecode
|
||||
from lib.core.common import Backend
|
||||
from lib.core.common import checkFile
|
||||
from lib.core.common import dataToDumpFile
|
||||
@@ -53,6 +52,7 @@ from lib.core.settings import UNICODE_ENCODING
|
||||
from lib.core.settings import UNSAFE_DUMP_FILEPATH_REPLACEMENT
|
||||
from lib.core.settings import VERSION_STRING
|
||||
from lib.core.settings import WINDOWS_RESERVED_NAMES
|
||||
from lib.utils.safe2bin import safechardecode
|
||||
from thirdparty import six
|
||||
from thirdparty.magic import magic
|
||||
|
||||
|
||||
+19
-4
@@ -341,7 +341,8 @@ def _setCrawler():
|
||||
if conf.bulkFile:
|
||||
targets = getFileItems(conf.bulkFile)
|
||||
else:
|
||||
targets = parseSitemap(conf.sitemapUrl)
|
||||
targets = list(parseSitemap(conf.sitemapUrl))
|
||||
|
||||
for i in xrange(len(targets)):
|
||||
try:
|
||||
target = targets[i]
|
||||
@@ -473,10 +474,13 @@ def _findPageForms():
|
||||
if conf.bulkFile:
|
||||
targets = getFileItems(conf.bulkFile)
|
||||
elif conf.sitemapUrl:
|
||||
targets = parseSitemap(conf.sitemapUrl)
|
||||
targets = list(parseSitemap(conf.sitemapUrl))
|
||||
elif conf.googleDork:
|
||||
targets = [_[0] for _ in kb.targets]
|
||||
kb.targets.clear()
|
||||
else:
|
||||
targets = []
|
||||
|
||||
for i in xrange(len(targets)):
|
||||
try:
|
||||
target = targets[i]
|
||||
@@ -1273,8 +1277,8 @@ def _setHTTPAuthentication():
|
||||
from ntlm import HTTPNtlmAuthHandler
|
||||
except ImportError:
|
||||
errMsg = "sqlmap requires Python NTLM third-party library "
|
||||
errMsg += "in order to authenticate via NTLM, "
|
||||
errMsg += "https://github.com/mullender/python-ntlm"
|
||||
errMsg += "in order to authenticate via NTLM. Download from "
|
||||
errMsg += "'https://github.com/mullender/python-ntlm'"
|
||||
raise SqlmapMissingDependence(errMsg)
|
||||
|
||||
authHandler = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(kb.passwordMgr)
|
||||
@@ -2447,6 +2451,13 @@ def _basicOptionValidation():
|
||||
errMsg = "invalid regular expression '%s' ('%s')" % (conf.regexp, getSafeExString(ex))
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if conf.paramExclude:
|
||||
try:
|
||||
re.compile(conf.paramExclude)
|
||||
except Exception as ex:
|
||||
errMsg = "invalid regular expression '%s' ('%s')" % (conf.paramExclude, getSafeExString(ex))
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if conf.crawlExclude:
|
||||
try:
|
||||
re.compile(conf.crawlExclude)
|
||||
@@ -2490,6 +2501,10 @@ def _basicOptionValidation():
|
||||
errMsg = "option '--csrf-url' requires usage of option '--csrf-token'"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if conf.csrfMethod and not conf.csrfToken:
|
||||
errMsg = "option '--csrf-method' requires usage of option '--csrf-token'"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if conf.csrfToken and conf.threads > 1:
|
||||
errMsg = "option '--csrf-url' is incompatible with option '--threads'"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
@@ -61,6 +61,7 @@ optDict = {
|
||||
"skipUrlEncode": "boolean",
|
||||
"csrfToken": "string",
|
||||
"csrfUrl": "string",
|
||||
"csrfMethod": "string",
|
||||
"forceSSL": "boolean",
|
||||
"chunked": "boolean",
|
||||
"hpp": "boolean",
|
||||
|
||||
@@ -7,13 +7,13 @@ See the file 'LICENSE' for copying permission
|
||||
|
||||
import sqlite3
|
||||
|
||||
from extra.safe2bin.safe2bin import safechardecode
|
||||
from lib.core.common import getSafeExString
|
||||
from lib.core.common import unsafeSQLIdentificatorNaming
|
||||
from lib.core.exception import SqlmapConnectionException
|
||||
from lib.core.exception import SqlmapGenericException
|
||||
from lib.core.exception import SqlmapValueException
|
||||
from lib.core.settings import UNICODE_ENCODING
|
||||
from lib.utils.safe2bin import safechardecode
|
||||
|
||||
class Replication(object):
|
||||
"""
|
||||
|
||||
@@ -18,7 +18,7 @@ from lib.core.enums import OS
|
||||
from thirdparty.six import unichr as _unichr
|
||||
|
||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||
VERSION = "1.3.9.0"
|
||||
VERSION = "1.3.10.0"
|
||||
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
||||
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
||||
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
||||
|
||||
+7
-6
@@ -151,12 +151,13 @@ def _setRequestParams():
|
||||
conf.data = re.sub(r'("(?P<name>[^"]+)"\s*:\s*".+?)"(?<!\\")', functools.partial(process, repl=r'\g<1>%s"' % kb.customInjectionMark), conf.data)
|
||||
conf.data = re.sub(r'("(?P<name>[^"]+)"\s*:\s*)(-?\d[\d\.]*)\b', functools.partial(process, repl=r'\g<1>\g<3>%s' % kb.customInjectionMark), conf.data)
|
||||
conf.data = re.sub(r'("(?P<name>[^"]+)"\s*:\s*)((true|false|null))\b', functools.partial(process, repl=r'\g<1>\g<3>%s' % kb.customInjectionMark), conf.data)
|
||||
match = re.search(r'(?P<name>[^"]+)"\s*:\s*\[([^\]]+)\]', conf.data)
|
||||
if match and not (conf.testParameter and match.group("name") not in conf.testParameter):
|
||||
_ = match.group(2)
|
||||
_ = re.sub(r'("[^"]+)"', r'\g<1>%s"' % kb.customInjectionMark, _)
|
||||
_ = re.sub(r'(\A|,|\s+)(-?\d[\d\.]*\b)', r'\g<0>%s' % kb.customInjectionMark, _)
|
||||
conf.data = conf.data.replace(match.group(0), match.group(0).replace(match.group(2), _))
|
||||
for match in re.finditer(r'(?P<name>[^"]+)"\s*:\s*\[([^\]]+)\]', conf.data):
|
||||
if not (conf.testParameter and match.group("name") not in conf.testParameter):
|
||||
_ = match.group(2)
|
||||
if kb.customInjectionMark not in _: # Note: only for unprocessed (simple) forms - i.e. non-associative arrays (e.g. [1,2,3])
|
||||
_ = re.sub(r'("[^"]+)"', r'\g<1>%s"' % kb.customInjectionMark, _)
|
||||
_ = re.sub(r'(\A|,|\s+)(-?\d[\d\.]*\b)', r'\g<0>%s' % kb.customInjectionMark, _)
|
||||
conf.data = conf.data.replace(match.group(0), match.group(0).replace(match.group(2), _))
|
||||
|
||||
kb.postHint = POST_HINT.JSON
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ class Wordlist(six.Iterator):
|
||||
def adjust(self):
|
||||
self.closeFP()
|
||||
if self.index > len(self.filenames):
|
||||
raise StopIteration
|
||||
return # Note: https://stackoverflow.com/a/30217723 (PEP 479)
|
||||
elif self.index == len(self.filenames):
|
||||
self.iter = iter(self.custom)
|
||||
else:
|
||||
|
||||
+32
-11
@@ -44,6 +44,26 @@ finally:
|
||||
def get_groups(parser):
|
||||
return getattr(parser, "option_groups", None) or getattr(parser, "_action_groups")
|
||||
|
||||
def get_all_options(parser):
|
||||
retVal = set()
|
||||
|
||||
for option in get_actions(parser):
|
||||
if hasattr(option, "option_strings"):
|
||||
retVal.update(option.option_strings)
|
||||
else:
|
||||
retVal.update(option._long_opts)
|
||||
retVal.update(option._short_opts)
|
||||
|
||||
for group in get_groups(parser):
|
||||
for option in get_actions(group):
|
||||
if hasattr(option, "option_strings"):
|
||||
retVal.update(option.option_strings)
|
||||
else:
|
||||
retVal.update(option._long_opts)
|
||||
retVal.update(option._short_opts)
|
||||
|
||||
return retVal
|
||||
|
||||
from lib.core.common import checkOldOptions
|
||||
from lib.core.common import checkSystemEncoding
|
||||
from lib.core.common import dataToStdout
|
||||
@@ -245,6 +265,9 @@ def cmdLineParser(argv=None):
|
||||
request.add_argument("--csrf-url", dest="csrfUrl",
|
||||
help="URL address to visit for extraction of anti-CSRF token")
|
||||
|
||||
request.add_argument("--csrf-method", dest="csrfMethod",
|
||||
help="HTTP method to use during anti-CSRF token page visit")
|
||||
|
||||
request.add_argument("--force-ssl", dest="forceSSL", action="store_true",
|
||||
help="Force usage of SSL/HTTPS")
|
||||
|
||||
@@ -841,18 +864,10 @@ def cmdLineParser(argv=None):
|
||||
parser.usage = ""
|
||||
cmdLineOptions.sqlmapShell = True
|
||||
|
||||
_ = ["x", "q", "exit", "quit", "clear"]
|
||||
commands = set(("x", "q", "exit", "quit", "clear"))
|
||||
commands.update(get_all_options(parser))
|
||||
|
||||
for option in get_actions(parser):
|
||||
_.extend(option._long_opts)
|
||||
_.extend(option._short_opts)
|
||||
|
||||
for group in get_groups(parser):
|
||||
for option in get_actions(group):
|
||||
_.extend(option._long_opts)
|
||||
_.extend(option._short_opts)
|
||||
|
||||
autoCompletion(AUTOCOMPLETE_TYPE.SQLMAP, commands=_)
|
||||
autoCompletion(AUTOCOMPLETE_TYPE.SQLMAP, commands=commands)
|
||||
|
||||
while True:
|
||||
command = None
|
||||
@@ -887,8 +902,11 @@ def cmdLineParser(argv=None):
|
||||
raise SqlmapSyntaxException("something went wrong during command line parsing ('%s')" % getSafeExString(ex))
|
||||
|
||||
for i in xrange(len(argv)):
|
||||
longOptions = set(re.findall(r"\-\-([^= ]+?)=", parser.format_help()))
|
||||
if argv[i] == "-hh":
|
||||
argv[i] = "-h"
|
||||
elif i == 1 and argv[i].startswith("http"):
|
||||
argv[i] = "--url=%s" % argv[i]
|
||||
elif len(argv[i]) > 1 and all(ord(_) in xrange(0x2018, 0x2020) for _ in ((argv[i].split('=', 1)[-1].strip() or ' ')[0], argv[i][-1])):
|
||||
dataToStdout("[!] copy-pasting illegal (non-console) quote characters from Internet is, well, illegal (%s)\n" % argv[i])
|
||||
raise SystemExit
|
||||
@@ -934,6 +952,9 @@ def cmdLineParser(argv=None):
|
||||
found = True
|
||||
if not found:
|
||||
get_groups(parser).remove(group)
|
||||
elif '=' in argv[i] and not argv[i].startswith('-') and argv[i].split('=')[0] in longOptions and re.search(r"\A-\w\Z", argv[i - 1]) is None:
|
||||
dataToStdout("[!] detected usage of long-option without a starting hyphen ('%s')\n" % argv[i])
|
||||
raise SystemExit
|
||||
|
||||
for verbosity in (_ for _ in argv if re.search(r"\A\-v+\Z", _)):
|
||||
try:
|
||||
|
||||
@@ -22,7 +22,6 @@ except ImportError:
|
||||
class WebSocketException(Exception):
|
||||
pass
|
||||
|
||||
from extra.safe2bin.safe2bin import safecharencode
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import asciifyUrl
|
||||
from lib.core.common import calculateDeltaSeconds
|
||||
@@ -125,6 +124,7 @@ from lib.request.basic import processResponse
|
||||
from lib.request.comparison import comparison
|
||||
from lib.request.direct import direct
|
||||
from lib.request.methodrequest import MethodRequest
|
||||
from lib.utils.safe2bin import safecharencode
|
||||
from thirdparty import six
|
||||
from thirdparty.odict import OrderedDict
|
||||
from thirdparty.six import unichr as _unichr
|
||||
@@ -1039,7 +1039,7 @@ class Connect(object):
|
||||
return retVal
|
||||
|
||||
token = AttribDict()
|
||||
page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.data if conf.csrfUrl == conf.url else None, method=conf.method if conf.csrfUrl == conf.url else None, cookie=conf.parameters.get(PLACE.COOKIE), direct=True, silent=True, ua=conf.parameters.get(PLACE.USER_AGENT), referer=conf.parameters.get(PLACE.REFERER), host=conf.parameters.get(PLACE.HOST))
|
||||
page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.data if conf.csrfUrl == conf.url else None, method=conf.csrfMethod or (conf.method if conf.csrfUrl == conf.url else None), cookie=conf.parameters.get(PLACE.COOKIE), direct=True, silent=True, ua=conf.parameters.get(PLACE.USER_AGENT), referer=conf.parameters.get(PLACE.REFERER), host=conf.parameters.get(PLACE.HOST))
|
||||
page = urldecode(page) # for anti-CSRF tokens with special characters in their name (e.g. 'foo:bar=...')
|
||||
|
||||
match = re.search(r"(?i)<input[^>]+\bname=[\"']?(?P<name>%s)\b[^>]*\bvalue=[\"']?(?P<value>[^>'\"]*)" % conf.csrfToken, page or "", re.I)
|
||||
|
||||
@@ -7,7 +7,6 @@ See the file 'LICENSE' for copying permission
|
||||
|
||||
import time
|
||||
|
||||
from extra.safe2bin.safe2bin import safecharencode
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import Backend
|
||||
from lib.core.common import calculateDeltaSeconds
|
||||
@@ -26,6 +25,7 @@ from lib.core.enums import DBMS
|
||||
from lib.core.enums import EXPECTED
|
||||
from lib.core.enums import TIMEOUT_STATE
|
||||
from lib.core.settings import UNICODE_ENCODING
|
||||
from lib.utils.safe2bin import safecharencode
|
||||
from lib.utils.timeout import timeout
|
||||
|
||||
def direct(query, content=True):
|
||||
|
||||
@@ -9,7 +9,6 @@ from __future__ import print_function
|
||||
|
||||
import sys
|
||||
|
||||
from extra.safe2bin.safe2bin import safechardecode
|
||||
from lib.core.common import Backend
|
||||
from lib.core.common import dataToStdout
|
||||
from lib.core.common import getSQLSnippet
|
||||
@@ -28,6 +27,7 @@ from lib.request import inject
|
||||
from lib.takeover.udf import UDF
|
||||
from lib.takeover.web import Web
|
||||
from lib.takeover.xp_cmdshell import XP_cmdshell
|
||||
from lib.utils.safe2bin import safechardecode
|
||||
from thirdparty.six.moves import input as _input
|
||||
|
||||
class Abstraction(Web, UDF, XP_cmdshell):
|
||||
|
||||
@@ -10,7 +10,6 @@ from __future__ import division
|
||||
import re
|
||||
import time
|
||||
|
||||
from extra.safe2bin.safe2bin import safecharencode
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import Backend
|
||||
from lib.core.common import calculateDeltaSeconds
|
||||
@@ -58,6 +57,7 @@ from lib.core.threads import runThreads
|
||||
from lib.core.unescaper import unescaper
|
||||
from lib.request.connect import Connect as Request
|
||||
from lib.utils.progress import ProgressBar
|
||||
from lib.utils.safe2bin import safecharencode
|
||||
from lib.utils.xrange import xrange
|
||||
|
||||
def bisection(payload, expression, length=None, charsetType=None, firstChar=None, lastChar=None, dump=False):
|
||||
|
||||
@@ -8,7 +8,6 @@ See the file 'LICENSE' for copying permission
|
||||
import re
|
||||
import time
|
||||
|
||||
from extra.safe2bin.safe2bin import safecharencode
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import Backend
|
||||
from lib.core.common import calculateDeltaSeconds
|
||||
@@ -33,6 +32,7 @@ from lib.core.settings import MAX_DNS_LABEL
|
||||
from lib.core.settings import PARTIAL_VALUE_MARKER
|
||||
from lib.core.unescaper import unescaper
|
||||
from lib.request.connect import Connect as Request
|
||||
from lib.utils.safe2bin import safecharencode
|
||||
|
||||
def dnsUse(payload, expression):
|
||||
"""
|
||||
|
||||
@@ -10,7 +10,6 @@ from __future__ import print_function
|
||||
import re
|
||||
import time
|
||||
|
||||
from extra.safe2bin.safe2bin import safecharencode
|
||||
from lib.core.agent import agent
|
||||
from lib.core.bigarray import BigArray
|
||||
from lib.core.common import Backend
|
||||
@@ -60,6 +59,7 @@ from lib.core.threads import runThreads
|
||||
from lib.core.unescaper import unescaper
|
||||
from lib.request.connect import Connect as Request
|
||||
from lib.utils.progress import ProgressBar
|
||||
from lib.utils.safe2bin import safecharencode
|
||||
from thirdparty import six
|
||||
|
||||
def _oneShotErrorUse(expression, field=None, chunkTest=False):
|
||||
|
||||
@@ -10,7 +10,6 @@ import re
|
||||
import time
|
||||
import xml.etree.ElementTree
|
||||
|
||||
from extra.safe2bin.safe2bin import safecharencode
|
||||
from lib.core.agent import agent
|
||||
from lib.core.bigarray import BigArray
|
||||
from lib.core.common import arrayizeValue
|
||||
@@ -62,6 +61,7 @@ from lib.core.threads import runThreads
|
||||
from lib.core.unescaper import unescaper
|
||||
from lib.request.connect import Connect as Request
|
||||
from lib.utils.progress import ProgressBar
|
||||
from lib.utils.safe2bin import safecharencode
|
||||
from thirdparty import six
|
||||
from thirdparty.odict import OrderedDict
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ See the file 'LICENSE' for copying permission
|
||||
|
||||
import re
|
||||
|
||||
from extra.safe2bin.safe2bin import safechardecode
|
||||
from lib.core.agent import agent
|
||||
from lib.core.bigarray import BigArray
|
||||
from lib.core.common import Backend
|
||||
@@ -33,6 +32,7 @@ from lib.core.settings import MAX_INT
|
||||
from lib.core.settings import NULL
|
||||
from lib.core.unescaper import unescaper
|
||||
from lib.request import inject
|
||||
from lib.utils.safe2bin import safechardecode
|
||||
from thirdparty.six import unichr as _unichr
|
||||
|
||||
def pivotDumpTable(table, colList, count=None, blind=True, alias=None):
|
||||
|
||||
+2
-1
@@ -15,6 +15,7 @@ import string
|
||||
from lib.core.common import getSafeExString
|
||||
from lib.core.common import openFile
|
||||
from lib.core.compat import xrange
|
||||
from lib.core.convert import getUnicode
|
||||
from lib.core.data import logger
|
||||
from thirdparty.six import unichr as _unichr
|
||||
|
||||
@@ -84,4 +85,4 @@ def purge(directory):
|
||||
try:
|
||||
shutil.rmtree(directory)
|
||||
except OSError as ex:
|
||||
logger.error("problem occurred while removing directory '%s' ('%s')" % (directory, getSafeExString(ex)))
|
||||
logger.error("problem occurred while removing directory '%s' ('%s')" % (getUnicode(directory), getSafeExString(ex)))
|
||||
|
||||
@@ -1,23 +1,15 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
safe2bin.py - Simple safe(hex) to binary format converter
|
||||
|
||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'LICENSE' for copying permission
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import binascii
|
||||
import re
|
||||
import string
|
||||
import os
|
||||
import sys
|
||||
|
||||
from optparse import OptionError
|
||||
from optparse import OptionParser
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
xrange = range
|
||||
text_type = str
|
||||
@@ -49,10 +41,10 @@ def safecharencode(value):
|
||||
"""
|
||||
Returns safe representation of a given basestring value
|
||||
|
||||
>>> safecharencode(u'test123')
|
||||
u'test123'
|
||||
>>> safecharencode(u'test\x01\x02\xff')
|
||||
u'test\\01\\02\\03\\ff'
|
||||
>>> safecharencode(u'test123') == u'test123'
|
||||
True
|
||||
>>> safecharencode(u'test\x01\x02\xaf') == u'test\\\\x01\\\\x02\\xaf'
|
||||
True
|
||||
"""
|
||||
|
||||
retVal = value
|
||||
@@ -107,37 +99,3 @@ def safechardecode(value, binary=False):
|
||||
retVal[i] = safechardecode(value[i])
|
||||
|
||||
return retVal
|
||||
|
||||
def main():
|
||||
usage = '%s -i <input file> [-o <output file>]' % sys.argv[0]
|
||||
parser = OptionParser(usage=usage, version='0.1')
|
||||
|
||||
try:
|
||||
parser.add_option('-i', dest='inputFile', help='Input file')
|
||||
parser.add_option('-o', dest='outputFile', help='Output file')
|
||||
|
||||
(args, _) = parser.parse_args()
|
||||
|
||||
if not args.inputFile:
|
||||
parser.error('Missing the input file, -h for help')
|
||||
|
||||
except (OptionError, TypeError) as ex:
|
||||
parser.error(ex)
|
||||
|
||||
if not os.path.isfile(args.inputFile):
|
||||
print('ERROR: the provided input file \'%s\' is not a regular file' % args.inputFile)
|
||||
sys.exit(1)
|
||||
|
||||
f = open(args.inputFile, 'r')
|
||||
data = f.read()
|
||||
f.close()
|
||||
|
||||
if not args.outputFile:
|
||||
args.outputFile = args.inputFile + '.bin'
|
||||
|
||||
f = open(args.outputFile, 'wb')
|
||||
f.write(safechardecode(data))
|
||||
f.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -76,7 +76,8 @@ class SQLAlchemy(GenericConnector):
|
||||
pass
|
||||
elif "invalid literal for int() with base 10: '0b" in traceback.format_exc():
|
||||
raise SqlmapConnectionException("SQLAlchemy connection issue ('https://bitbucket.org/zzzeek/sqlalchemy/issues/3975')")
|
||||
raise
|
||||
else:
|
||||
pass
|
||||
except SqlmapFilePathException:
|
||||
raise
|
||||
except Exception as ex:
|
||||
|
||||
@@ -96,7 +96,7 @@ class Fingerprint(GenericFingerprint):
|
||||
infoMsg = "actively fingerprinting %s" % DBMS.INFORMIX
|
||||
logger.info(infoMsg)
|
||||
|
||||
for version in ("12.1", "11.7", "11.5"):
|
||||
for version in ("14.1", "12.1", "11.7", "11.5", "10.0"):
|
||||
output = inject.checkBooleanExpression("EXISTS(SELECT 1 FROM SYSMASTER:SYSDUAL WHERE DBINFO('VERSION,'FULL') LIKE '%%%s%%')" % version)
|
||||
|
||||
if output:
|
||||
|
||||
@@ -94,7 +94,8 @@ class Fingerprint(GenericFingerprint):
|
||||
("2008", "SYSDATETIME()=SYSDATETIME()"),
|
||||
("2012", "CONCAT(NULL,NULL)=CONCAT(NULL,NULL)"),
|
||||
("2014", "CHARINDEX('12.0.2000',@@version)>0"),
|
||||
("2016", "ISJSON(NULL) IS NULL")
|
||||
("2016", "ISJSON(NULL) IS NULL"),
|
||||
("2017", "TRIM(NULL) IS NULL")
|
||||
):
|
||||
result = inject.checkBooleanExpression(check)
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ class Fingerprint(GenericFingerprint):
|
||||
(50600, 50646), # MySQL 5.6
|
||||
(50700, 50726), # MySQL 5.7
|
||||
(60000, 60014), # MySQL 6.0
|
||||
(80000, 80015), # MySQL 8.0
|
||||
(80000, 80017), # MySQL 8.0
|
||||
)
|
||||
|
||||
index = -1
|
||||
|
||||
@@ -105,7 +105,7 @@ class Fingerprint(GenericFingerprint):
|
||||
logger.info(infoMsg)
|
||||
|
||||
# Reference: https://en.wikipedia.org/wiki/Oracle_Database
|
||||
for version in ("18c", "12c", "11g", "10g", "9i", "8i"):
|
||||
for version in ("18c", "12c", "11g", "10g", "9i", "8i", "7"):
|
||||
number = int(re.search(r"([\d]+)", version).group(1))
|
||||
output = inject.checkBooleanExpression("%d=(SELECT SUBSTR((VERSION),1,%d) FROM SYS.PRODUCT_COMPONENT_VERSION WHERE ROWNUM=1)" % (number, 1 if number < 10 else 2))
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import os
|
||||
from lib.core.common import Backend
|
||||
from lib.core.common import checkFile
|
||||
from lib.core.common import decloakToTemp
|
||||
from lib.core.common import flattenValue
|
||||
from lib.core.common import isListLike
|
||||
from lib.core.common import isStackingAvailable
|
||||
from lib.core.common import randomStr
|
||||
@@ -104,7 +105,7 @@ class Takeover(GenericTakeover):
|
||||
output = inject.getValue(query, resumeValue=False)
|
||||
|
||||
if isListLike(output):
|
||||
output = os.linesep.join(output)
|
||||
output = os.linesep.join(flattenValue(output))
|
||||
|
||||
self._cleanupCmd = "DROP TABLE %s" % self.cmdTblName
|
||||
inject.goStacked(self._cleanupCmd)
|
||||
|
||||
+5
-2
@@ -180,16 +180,19 @@ safeReqFile =
|
||||
# Default: 0
|
||||
safeFreq = 0
|
||||
|
||||
# Skip URL encoding of payload data
|
||||
# Skip URL encoding of payload data.
|
||||
# Valid: True or False
|
||||
skipUrlEncode = False
|
||||
|
||||
# Parameter used to hold anti-CSRF token
|
||||
# Parameter used to hold anti-CSRF token.
|
||||
csrfToken =
|
||||
|
||||
# URL address to visit to extract anti-CSRF token
|
||||
csrfUrl =
|
||||
|
||||
# HTTP method to use during anti-CSRF token page visit.
|
||||
csrfMethod =
|
||||
|
||||
# Force usage of SSL/HTTPS
|
||||
# Valid: True or False
|
||||
forceSSL = False
|
||||
|
||||
@@ -263,6 +263,11 @@ def main():
|
||||
logger.critical(errMsg)
|
||||
raise SystemExit
|
||||
|
||||
elif all(_ in excMsg for _ in ("Access is denied", "subprocess", "metasploit")):
|
||||
errMsg = "permission error occurred while running Metasploit"
|
||||
logger.critical(errMsg)
|
||||
raise SystemExit
|
||||
|
||||
elif all(_ in excMsg for _ in ("No such file", "_'")):
|
||||
errMsg = "corrupted installation detected ('%s'). " % excMsg.strip().split('\n')[-1]
|
||||
errMsg += "You should retrieve the latest development version from official GitHub "
|
||||
|
||||
+14
-5
@@ -16,20 +16,29 @@ def dependencies():
|
||||
pass
|
||||
|
||||
def randomIP():
|
||||
numbers = []
|
||||
octets = []
|
||||
|
||||
while not numbers or numbers[0] in (10, 172, 192):
|
||||
numbers = random.sample(xrange(1, 255), 4)
|
||||
while not octets or octets[0] in (10, 172, 192):
|
||||
octets = random.sample(xrange(1, 255), 4)
|
||||
|
||||
return '.'.join(str(_) for _ in numbers)
|
||||
return '.'.join(str(_) for _ in octets)
|
||||
|
||||
def tamper(payload, **kwargs):
|
||||
"""
|
||||
Append a fake HTTP header 'X-Forwarded-For'
|
||||
Append a fake HTTP header 'X-Forwarded-For' (and alike)
|
||||
"""
|
||||
|
||||
headers = kwargs.get("headers", {})
|
||||
headers["X-Forwarded-For"] = randomIP()
|
||||
headers["X-Client-Ip"] = randomIP()
|
||||
headers["X-Real-Ip"] = randomIP()
|
||||
headers["CF-Connecting-IP"] = randomIP()
|
||||
headers["True-Client-IP"] = randomIP()
|
||||
|
||||
# Reference: https://developer.chrome.com/multidevice/data-compression-for-isps#proxy-connection
|
||||
headers["Via"] = "1.1 Chrome-Compression-Proxy"
|
||||
|
||||
# Reference: https://wordpress.org/support/topic/blocked-country-gaining-access-via-cloudflare/#post-9812007
|
||||
headers["CF-IPCountry"] = random.sample(('GB', 'US', 'FR', 'AU', 'CA', 'NZ', 'BE', 'DK', 'FI', 'IE', 'AT', 'IT', 'LU', 'NL', 'NO', 'PT', 'SE', 'ES', 'CH'), 1)[0]
|
||||
|
||||
return payload
|
||||
|
||||
+1
-1
@@ -894,7 +894,7 @@ class Tag(PageElement):
|
||||
|
||||
def recursiveChildGenerator(self):
|
||||
if not len(self.contents):
|
||||
raise StopIteration
|
||||
return # Note: https://stackoverflow.com/a/30217723 (PEP 479)
|
||||
stopNode = self._lastRecursiveChild().next
|
||||
current = self.contents[0]
|
||||
while current is not stopNode:
|
||||
|
||||
Vendored
+3
-1
@@ -227,6 +227,9 @@ def unescape(data, entities, encoding=DEFAULT_ENCODING):
|
||||
if data is None or "&" not in data:
|
||||
return data
|
||||
|
||||
if isinstance(data, six.string_types):
|
||||
encoding = None
|
||||
|
||||
def replace_entities(match, entities=entities, encoding=encoding):
|
||||
ent = match.group()
|
||||
if ent[1] == "#":
|
||||
@@ -279,7 +282,6 @@ def get_entitydefs():
|
||||
entitydefs["&%s;" % name] = _unichr(codepoint)
|
||||
return entitydefs
|
||||
|
||||
|
||||
def issequence(x):
|
||||
try:
|
||||
x[0]
|
||||
|
||||
Reference in New Issue
Block a user