mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-24 18:43:47 +03:00
Adding support for STDIN pipe (e.g. '... -r - ...')
This commit is contained in:
parent
bf83a4d1f8
commit
e7ffc8f9b1
|
@ -160,6 +160,7 @@ from lib.core.settings import REFLECTIVE_MISS_THRESHOLD
|
||||||
from lib.core.settings import SAFE_VARIABLE_MARKER
|
from lib.core.settings import SAFE_VARIABLE_MARKER
|
||||||
from lib.core.settings import SENSITIVE_DATA_REGEX
|
from lib.core.settings import SENSITIVE_DATA_REGEX
|
||||||
from lib.core.settings import SENSITIVE_OPTIONS
|
from lib.core.settings import SENSITIVE_OPTIONS
|
||||||
|
from lib.core.settings import STDIN_PIPE_DASH
|
||||||
from lib.core.settings import SUPPORTED_DBMS
|
from lib.core.settings import SUPPORTED_DBMS
|
||||||
from lib.core.settings import TEXT_TAG_REGEX
|
from lib.core.settings import TEXT_TAG_REGEX
|
||||||
from lib.core.settings import TIME_STDEV_COEFF
|
from lib.core.settings import TIME_STDEV_COEFF
|
||||||
|
@ -1165,6 +1166,14 @@ def getHeader(headers, key):
|
||||||
break
|
break
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
|
def checkPipedInput():
|
||||||
|
"""
|
||||||
|
Checks whether input to program has been provided via standard input (e.g. cat /tmp/req.txt | python sqlmap.py -r -)
|
||||||
|
# Reference: https://stackoverflow.com/a/33873570
|
||||||
|
"""
|
||||||
|
|
||||||
|
return not os.isatty(sys.stdin.fileno())
|
||||||
|
|
||||||
def checkFile(filename, raiseOnError=True):
|
def checkFile(filename, raiseOnError=True):
|
||||||
"""
|
"""
|
||||||
Checks for file existence and readability
|
Checks for file existence and readability
|
||||||
|
@ -1178,19 +1187,22 @@ def checkFile(filename, raiseOnError=True):
|
||||||
if filename:
|
if filename:
|
||||||
filename = filename.strip('"\'')
|
filename = filename.strip('"\'')
|
||||||
|
|
||||||
try:
|
if filename == STDIN_PIPE_DASH:
|
||||||
if filename is None or not os.path.isfile(filename):
|
return checkPipedInput()
|
||||||
valid = False
|
else:
|
||||||
except:
|
|
||||||
valid = False
|
|
||||||
|
|
||||||
if valid:
|
|
||||||
try:
|
try:
|
||||||
with open(filename, "rb"):
|
if filename is None or not os.path.isfile(filename):
|
||||||
pass
|
valid = False
|
||||||
except:
|
except:
|
||||||
valid = False
|
valid = False
|
||||||
|
|
||||||
|
if valid:
|
||||||
|
try:
|
||||||
|
with open(filename, "rb"):
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
valid = False
|
||||||
|
|
||||||
if not valid and raiseOnError:
|
if not valid and raiseOnError:
|
||||||
raise SqlmapSystemException("unable to read file '%s'" % filename)
|
raise SqlmapSystemException("unable to read file '%s'" % filename)
|
||||||
|
|
||||||
|
@ -3305,13 +3317,19 @@ def openFile(filename, mode='r', encoding=UNICODE_ENCODING, errors="replace", bu
|
||||||
Returns file handle of a given filename
|
Returns file handle of a given filename
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
if filename == STDIN_PIPE_DASH:
|
||||||
return codecs.open(filename, mode, encoding, errors, buffering)
|
if filename not in kb.cache.content:
|
||||||
except IOError:
|
kb.cache.content[filename] = sys.stdin.read()
|
||||||
errMsg = "there has been a file opening error for filename '%s'. " % filename
|
|
||||||
errMsg += "Please check %s permissions on a file " % ("write" if mode and ('w' in mode or 'a' in mode or '+' in mode) else "read")
|
return contextlib.closing(StringIO(readCachedFileContent(filename)))
|
||||||
errMsg += "and that it's not locked by another process."
|
else:
|
||||||
raise SqlmapSystemException(errMsg)
|
try:
|
||||||
|
return codecs.open(filename, mode, encoding, errors, buffering)
|
||||||
|
except IOError:
|
||||||
|
errMsg = "there has been a file opening error for filename '%s'. " % filename
|
||||||
|
errMsg += "Please check %s permissions on a file " % ("write" if mode and ('w' in mode or 'a' in mode or '+' in mode) else "read")
|
||||||
|
errMsg += "and that it's not locked by another process."
|
||||||
|
raise SqlmapSystemException(errMsg)
|
||||||
|
|
||||||
def decodeIntToUnicode(value):
|
def decodeIntToUnicode(value):
|
||||||
"""
|
"""
|
||||||
|
@ -4797,14 +4815,7 @@ def parseRequestFile(reqFile, checkParams=True):
|
||||||
if not(conf.scope and not re.search(conf.scope, url, re.I)):
|
if not(conf.scope and not re.search(conf.scope, url, re.I)):
|
||||||
yield (url, conf.method or method, data, cookie, tuple(headers))
|
yield (url, conf.method or method, data, cookie, tuple(headers))
|
||||||
|
|
||||||
checkFile(reqFile)
|
content = readCachedFileContent(reqFile)
|
||||||
try:
|
|
||||||
with openFile(reqFile, "rb") as f:
|
|
||||||
content = f.read()
|
|
||||||
except (IOError, OSError, MemoryError) as ex:
|
|
||||||
errMsg = "something went wrong while trying "
|
|
||||||
errMsg += "to read the content of file '%s' ('%s')" % (reqFile, getSafeExString(ex))
|
|
||||||
raise SqlmapSystemException(errMsg)
|
|
||||||
|
|
||||||
if conf.scope:
|
if conf.scope:
|
||||||
logger.info("using regular expression '%s' for filtering targets" % conf.scope)
|
logger.info("using regular expression '%s' for filtering targets" % conf.scope)
|
||||||
|
|
|
@ -226,7 +226,7 @@ def _setMultipleTargets():
|
||||||
errMsg = "the specified list of targets does not exist"
|
errMsg = "the specified list of targets does not exist"
|
||||||
raise SqlmapFilePathException(errMsg)
|
raise SqlmapFilePathException(errMsg)
|
||||||
|
|
||||||
if os.path.isfile(conf.logFile):
|
if checkFile(conf.logFile, False):
|
||||||
for target in parseRequestFile(conf.logFile):
|
for target in parseRequestFile(conf.logFile):
|
||||||
url, _, data, _, _ = target
|
url, _, data, _, _ = target
|
||||||
key = re.sub(r"(\w+=)[^%s ]*" % (conf.paramDel or DEFAULT_GET_POST_DELIMITER), r"\g<1>", "%s %s" % (url, data))
|
key = re.sub(r"(\w+=)[^%s ]*" % (conf.paramDel or DEFAULT_GET_POST_DELIMITER), r"\g<1>", "%s %s" % (url, data))
|
||||||
|
@ -292,7 +292,7 @@ def _setRequestFromFile():
|
||||||
conf.requestFile = safeExpandUser(conf.requestFile)
|
conf.requestFile = safeExpandUser(conf.requestFile)
|
||||||
seen = set()
|
seen = set()
|
||||||
|
|
||||||
if not os.path.isfile(conf.requestFile):
|
if not checkFile(conf.requestFile, False):
|
||||||
errMsg = "specified HTTP request file '%s' " % conf.requestFile
|
errMsg = "specified HTTP request file '%s' " % conf.requestFile
|
||||||
errMsg += "does not exist"
|
errMsg += "does not exist"
|
||||||
raise SqlmapFilePathException(errMsg)
|
raise SqlmapFilePathException(errMsg)
|
||||||
|
@ -309,7 +309,7 @@ def _setRequestFromFile():
|
||||||
if conf.secondReq:
|
if conf.secondReq:
|
||||||
conf.secondReq = safeExpandUser(conf.secondReq)
|
conf.secondReq = safeExpandUser(conf.secondReq)
|
||||||
|
|
||||||
if not os.path.isfile(conf.secondReq):
|
if not checkFile(conf.secondReq, False):
|
||||||
errMsg = "specified second-order HTTP request file '%s' " % conf.secondReq
|
errMsg = "specified second-order HTTP request file '%s' " % conf.secondReq
|
||||||
errMsg += "does not exist"
|
errMsg += "does not exist"
|
||||||
raise SqlmapFilePathException(errMsg)
|
raise SqlmapFilePathException(errMsg)
|
||||||
|
@ -411,7 +411,7 @@ def _setBulkMultipleTargets():
|
||||||
infoMsg = "parsing multiple targets list from '%s'" % conf.bulkFile
|
infoMsg = "parsing multiple targets list from '%s'" % conf.bulkFile
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
if not os.path.isfile(conf.bulkFile):
|
if not checkFile(conf.bulkFile, False):
|
||||||
errMsg = "the specified bulk file "
|
errMsg = "the specified bulk file "
|
||||||
errMsg += "does not exist"
|
errMsg += "does not exist"
|
||||||
raise SqlmapFilePathException(errMsg)
|
raise SqlmapFilePathException(errMsg)
|
||||||
|
|
|
@ -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.3.3.29"
|
VERSION = "1.3.3.30"
|
||||||
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)
|
||||||
|
@ -222,6 +222,9 @@ try:
|
||||||
except LookupError:
|
except LookupError:
|
||||||
DEFAULT_PAGE_ENCODING = "utf8"
|
DEFAULT_PAGE_ENCODING = "utf8"
|
||||||
|
|
||||||
|
# Marker for program piped input
|
||||||
|
STDIN_PIPE_DASH = '-'
|
||||||
|
|
||||||
# URL used in dummy runs
|
# URL used in dummy runs
|
||||||
DUMMY_URL = "http://foo/bar?id=1"
|
DUMMY_URL = "http://foo/bar?id=1"
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ try:
|
||||||
|
|
||||||
from lib.core.common import banner
|
from lib.core.common import banner
|
||||||
from lib.core.common import checkIntegrity
|
from lib.core.common import checkIntegrity
|
||||||
|
from lib.core.common import checkPipedInput
|
||||||
from lib.core.common import createGithubIssue
|
from lib.core.common import createGithubIssue
|
||||||
from lib.core.common import dataToStdout
|
from lib.core.common import dataToStdout
|
||||||
from lib.core.common import getSafeExString
|
from lib.core.common import getSafeExString
|
||||||
|
@ -131,6 +132,9 @@ def main():
|
||||||
cmdLineOptions.update(cmdLineParser().__dict__)
|
cmdLineOptions.update(cmdLineParser().__dict__)
|
||||||
initOptions(cmdLineOptions)
|
initOptions(cmdLineOptions)
|
||||||
|
|
||||||
|
if checkPipedInput():
|
||||||
|
conf.batch = True
|
||||||
|
|
||||||
if conf.get("api"):
|
if conf.get("api"):
|
||||||
# heavy imports
|
# heavy imports
|
||||||
from lib.utils.api import StdDbOut
|
from lib.utils.api import StdDbOut
|
||||||
|
|
|
@ -30,7 +30,7 @@ c1da277517c7ec4c23e953a51b51e203 lib/controller/handler.py
|
||||||
fb6be55d21a70765e35549af2484f762 lib/controller/__init__.py
|
fb6be55d21a70765e35549af2484f762 lib/controller/__init__.py
|
||||||
ed7874be0d2d3802f3d20184f2b280d5 lib/core/agent.py
|
ed7874be0d2d3802f3d20184f2b280d5 lib/core/agent.py
|
||||||
a932126e7d80e545c5d44af178d0bc0c lib/core/bigarray.py
|
a932126e7d80e545c5d44af178d0bc0c lib/core/bigarray.py
|
||||||
c775aa0369c9eb044efb5065f60a25cd lib/core/common.py
|
b096680d917729fd9658f9b75d44bb3b lib/core/common.py
|
||||||
de8d27ae6241163ff9e97aa9e7c51a18 lib/core/convert.py
|
de8d27ae6241163ff9e97aa9e7c51a18 lib/core/convert.py
|
||||||
abcb1121eb56d3401839d14e8ed06b6e lib/core/data.py
|
abcb1121eb56d3401839d14e8ed06b6e lib/core/data.py
|
||||||
f89512ef3ebea85611c5dde6c891b657 lib/core/datatype.py
|
f89512ef3ebea85611c5dde6c891b657 lib/core/datatype.py
|
||||||
|
@ -43,14 +43,14 @@ f89512ef3ebea85611c5dde6c891b657 lib/core/datatype.py
|
||||||
fb6be55d21a70765e35549af2484f762 lib/core/__init__.py
|
fb6be55d21a70765e35549af2484f762 lib/core/__init__.py
|
||||||
18c896b157b03af716542e5fe9233ef9 lib/core/log.py
|
18c896b157b03af716542e5fe9233ef9 lib/core/log.py
|
||||||
947f41084e551ff3b7ef7dda2f25ef20 lib/core/optiondict.py
|
947f41084e551ff3b7ef7dda2f25ef20 lib/core/optiondict.py
|
||||||
63c5c71af3fd05cd0a1c97dbbe7216b5 lib/core/option.py
|
94679a06c134ca5c1db1e435e1cb9fb1 lib/core/option.py
|
||||||
fe370021c6bc99daf44b2bfc0d1effb3 lib/core/patch.py
|
fe370021c6bc99daf44b2bfc0d1effb3 lib/core/patch.py
|
||||||
4b12aa67fbf6c973d12e54cf9cb54ea0 lib/core/profiling.py
|
4b12aa67fbf6c973d12e54cf9cb54ea0 lib/core/profiling.py
|
||||||
d5ef43fe3cdd6c2602d7db45651f9ceb lib/core/readlineng.py
|
d5ef43fe3cdd6c2602d7db45651f9ceb lib/core/readlineng.py
|
||||||
7d8a22c582ad201f65b73225e4456170 lib/core/replication.py
|
7d8a22c582ad201f65b73225e4456170 lib/core/replication.py
|
||||||
3179d34f371e0295dd4604568fb30bcd lib/core/revision.py
|
3179d34f371e0295dd4604568fb30bcd lib/core/revision.py
|
||||||
d6269c55789f78cf707e09a0f5b45443 lib/core/session.py
|
d6269c55789f78cf707e09a0f5b45443 lib/core/session.py
|
||||||
96b86cf1a93128720caa88a22f604ea1 lib/core/settings.py
|
2d4b155258f2ae85c7f287c58742e1fb lib/core/settings.py
|
||||||
4483b4a5b601d8f1c4281071dff21ecc lib/core/shell.py
|
4483b4a5b601d8f1c4281071dff21ecc lib/core/shell.py
|
||||||
10fd19b0716ed261e6d04f311f6f527c lib/core/subprocessng.py
|
10fd19b0716ed261e6d04f311f6f527c lib/core/subprocessng.py
|
||||||
10d7e4f7ba2502cce5cf69223c52eddc lib/core/target.py
|
10d7e4f7ba2502cce5cf69223c52eddc lib/core/target.py
|
||||||
|
@ -236,7 +236,7 @@ ec2ba8c757ac96425dcd2b97970edd3a shell/stagers/stager.asp_
|
||||||
0c48ddb1feb7e38a951ef05a0d48e032 shell/stagers/stager.jsp_
|
0c48ddb1feb7e38a951ef05a0d48e032 shell/stagers/stager.jsp_
|
||||||
2f9e459a4cf6a58680978cdce5ff7971 shell/stagers/stager.php_
|
2f9e459a4cf6a58680978cdce5ff7971 shell/stagers/stager.php_
|
||||||
41522f8ad02ac133ca0aeaab374c36a8 sqlmapapi.py
|
41522f8ad02ac133ca0aeaab374c36a8 sqlmapapi.py
|
||||||
a436dd078b06bf664637b27f42889a35 sqlmap.py
|
05fe39a2fbd1cff87cb43c5c36e64365 sqlmap.py
|
||||||
772fb3dd15edc9d4055ab9f9dee0c203 tamper/0x2char.py
|
772fb3dd15edc9d4055ab9f9dee0c203 tamper/0x2char.py
|
||||||
3d89a5c4c33d4d1d9303f5e3bd11f0ae tamper/apostrophemask.py
|
3d89a5c4c33d4d1d9303f5e3bd11f0ae tamper/apostrophemask.py
|
||||||
1fd0eec63970728c1e6628b2e4c21d81 tamper/apostrophenullencode.py
|
1fd0eec63970728c1e6628b2e4c21d81 tamper/apostrophenullencode.py
|
||||||
|
|
Loading…
Reference in New Issue
Block a user