Skip to content
This repository was archived by the owner on Dec 6, 2023. It is now read-only.

Commit 6472937

Browse files
author
byt3bl33d3r
committed
Updated execution methods and user enumeration for better
non-standard smb port support - Fixed bug where current path was included in command output when using the smbexec exec method - Batch file name generation is now randomized on every command executed rather than on object initialization
1 parent 9af1ab5 commit 6472937

File tree

3 files changed

+43
-31
lines changed

3 files changed

+43
-31
lines changed

cme/enum/users.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,18 @@
1919
from impacket.nt_errors import STATUS_MORE_ENTRIES
2020
from impacket.dcerpc.v5 import transport, samr
2121
from impacket.dcerpc.v5.rpcrt import DCERPCException
22+
from impacket.smb import SMB_DIALECT
2223

2324
class ListUsersException(Exception):
2425
pass
2526

2627
class SAMRDump:
27-
KNOWN_PROTOCOLS = {
28-
'139/SMB': (r'ncacn_np:%s[\pipe\samr]', 139),
29-
'445/SMB': (r'ncacn_np:%s[\pipe\samr]', 445),
30-
}
3128

32-
def __init__(self, logger, protocol, connection):
29+
def __init__(self, logger, protocol, connection, port=445):
3330

3431
self.__username = connection.username
3532
self.__addr = connection.host
33+
self.__port = port
3634
self.__password = connection.password
3735
self.__domain = connection.domain
3836
self.__hash = connection.hash
@@ -51,19 +49,26 @@ def __init__(self, logger, protocol, connection):
5149

5250
def enum(self):
5351
"""Dumps the list of users and shares registered present at
54-
addr. Addr is a valid host name or IP address.
52+
remoteName. remoteName is a valid host name or IP address.
5553
"""
5654

57-
logging.info('Retrieving endpoint list from %s' % self.__addr)
58-
59-
# Try all requested protocols until one works.
6055
entries = []
6156

62-
protodef = SAMRDump.KNOWN_PROTOCOLS['{}/SMB'.format(self.__protocol)]
63-
port = protodef[1]
57+
logging.info('Retrieving endpoint list from %s' % self.__addr)
6458

65-
logging.info("Trying protocol %s..." % self.__protocol)
66-
rpctransport = transport.SMBTransport(self.__addr, port, r'\samr', self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, doKerberos = self.__doKerberos)
59+
stringbinding = 'ncacn_np:%s[\pipe\samr]' % self.__addr
60+
logging.debug('StringBinding %s'%stringbinding)
61+
rpctransport = transport.DCERPCTransportFactory(stringbinding)
62+
rpctransport.set_dport(self.__port)
63+
#rpctransport.setRemoteHost(self.__addr)
64+
65+
if hasattr(rpctransport,'preferred_dialect'):
66+
rpctransport.preferred_dialect(SMB_DIALECT)
67+
if hasattr(rpctransport, 'set_credentials'):
68+
# This method exists only for selected protocol sequences.
69+
rpctransport.set_credentials(self.__username, self.__password, self.__domain, self.__lmhash,
70+
self.__nthash)# self.__aesKey)
71+
#rpctransport.set_kerberos(self.__doKerberos, self.__kdcHost)
6772

6873
try:
6974
entries = self.__fetchList(rpctransport)

cme/execmethods/smbexec.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
1+
import logging
12
from gevent import sleep
23
from impacket.dcerpc.v5 import transport, scmr
34
from impacket.smbconnection import *
5+
from impacket.smb import SMB_DIALECT
46
from cme.helpers import gen_random_string
57

68
class SMBEXEC:
7-
KNOWN_PROTOCOLS = {
8-
'139/SMB': (r'ncacn_np:%s[\pipe\svcctl]', 139),
9-
'445/SMB': (r'ncacn_np:%s[\pipe\svcctl]', 445),
10-
}
119

12-
def __init__(self, host, protocol, username = '', password = '', domain = '', hashes = None, share = None):
10+
def __init__(self, host, protocol, username = '', password = '', domain = '', hashes = None, share = None, port=445):
1311
self.__host = host
12+
self.__port = port
1413
self.__username = username
1514
self.__password = password
1615
self.__serviceName = gen_random_string()
1716
self.__domain = domain
1817
self.__lmhash = ''
1918
self.__nthash = ''
2019
self.__share = share
21-
self.__output = '\\Windows\\Temp\\' + gen_random_string()
22-
self.__batchFile = '%TEMP%\\' + gen_random_string() + '.bat'
20+
self.__output = None
21+
self.__batchFile = None
2322
self.__outputBuffer = ''
2423
self.__shell = '%COMSPEC% /Q /c '
2524
self.__retOutput = False
@@ -40,20 +39,17 @@ def __init__(self, host, protocol, username = '', password = '', domain = '', ha
4039
if self.__password is None:
4140
self.__password = ''
4241

43-
protodef = SMBEXEC.KNOWN_PROTOCOLS['{}/SMB'.format(protocol)]
44-
port = protodef[1]
45-
46-
stringbinding = protodef[0] % self.__host
47-
42+
stringbinding = 'ncacn_np:%s[\pipe\svcctl]' % self.__host
43+
logging.debug('StringBinding %s'%stringbinding)
4844
self.__rpctransport = transport.DCERPCTransportFactory(stringbinding)
49-
self.__rpctransport.set_dport(port)
50-
45+
self.__rpctransport.set_dport(self.__port)
46+
#self.__rpctransport.setRemoteHost(self.__host)
5147
if hasattr(self.__rpctransport,'preferred_dialect'):
5248
self.__rpctransport.preferred_dialect(SMB_DIALECT)
5349
if hasattr(self.__rpctransport, 'set_credentials'):
5450
# This method exists only for selected protocol sequences.
5551
self.__rpctransport.set_credentials(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash)
56-
#rpctransport.set_kerberos(self.__doKerberos)
52+
#rpctransport.set_kerberos(self.__doKerberos, self.__kdcHost)
5753

5854
self.__scmr = self.__rpctransport.get_dce_rpc()
5955
self.__scmr.connect()
@@ -76,7 +72,10 @@ def execute(self, command, output=False):
7672
return self.__outputBuffer
7773

7874
def cd(self, s):
75+
ret_state = self.__retOutput
76+
self.__retOutput = False
7977
self.execute_remote('cd ' )
78+
self.__retOutput = ret_state
8079

8180
def get_output(self):
8281

@@ -96,13 +95,18 @@ def output_callback(data):
9695
sleep(2)
9796

9897
def execute_remote(self, data):
98+
self.__output = '\\Windows\\Temp\\' + gen_random_string()
99+
self.__batchFile = '%TEMP%\\' + gen_random_string() + '.bat'
100+
99101
if self.__retOutput:
100102
command = self.__shell + 'echo ' + data + ' ^> ' + self.__output + ' 2^>^&1 > ' + self.__batchFile + ' & ' + self.__shell + self.__batchFile
101103
else:
102104
command = self.__shell + 'echo ' + data + ' 2^>^&1 > ' + self.__batchFile + ' & ' + self.__shell + self.__batchFile
103105

104106
command += ' & ' + 'del ' + self.__batchFile
105107

108+
logging.debug('Executing command: ' + command)
109+
106110
resp = scmr.hRCreateServiceW(self.__scmr, self.__scHandle, self.__serviceName, self.__serviceName, lpBinaryPathName=command)
107111
service = resp['lpServiceHandle']
108112

cme/execmethods/wmiexec.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import ntpath
1+
import ntpath, logging
22

33
from gevent import sleep
44
from cme.helpers import gen_random_string
@@ -16,7 +16,7 @@ def __init__(self, target, username, password, domain, smbconnection, hashes=Non
1616
self.__nthash = ''
1717
self.__share = share
1818
self.__smbconnection = smbconnection
19-
self.__output = '\\' + gen_random_string(6)
19+
self.__output = None
2020
self.__outputBuffer = ''
2121
self.__shell = 'cmd.exe /Q /c '
2222
self.__pwd = 'C:\\'
@@ -61,13 +61,16 @@ def cd(self, s):
6161
self.__pwd = ntpath.normpath(ntpath.join(self.__pwd, s))
6262
self.execute_remote('cd ')
6363
self.__pwd = self.__outputBuffer.strip('\r\n')
64-
self.prompt = self.__pwd + '>'
6564
self.__outputBuffer = ''
6665

6766
def execute_remote(self, data):
67+
self.__output = '\\Windows\\Temp\\' + gen_random_string(6)
68+
6869
command = self.__shell + data
6970
if self.__retOutput:
7071
command += ' 1> ' + '\\\\127.0.0.1\\%s' % self.__share + self.__output + ' 2>&1'
72+
73+
logging.debug('Executing command: ' + command)
7174
self.__win32Process.Create(command, self.__pwd, None)
7275
self.get_output()
7376

0 commit comments

Comments
 (0)