/usr/share/pyshared/impacket/examples/serviceinstall.py is in python-impacket 0.9.10-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | # Copyright (c) 2003-2012 CORE Security Technologies
#
# This software is provided under under a slightly modified version
# of the Apache Software License. See the accompanying LICENSE file
# for more information.
#
# $Id: serviceinstall.py 698 2012-08-25 18:18:10Z bethus@gmail.com $
#
# Service Install Helper library used by psexec and smbrelayx
# You provide an already established connection and an exefile
# (or class that mimics a file class) and this will install and
# execute the service, and then uninstall (install(), uninstall().
# It tries to take care as much as possible to leave everything clean.
#
# Author:
# Alberto Solino (bethus@gmail.com)
#
import random
from impacket.dcerpc import srvsvc, dcerpc, svcctl, transport
from impacket import smb,smb3
from impacket.smbconnection import *
import string
class ServiceInstall():
def __init__(self, SMBObject, exeFile):
self._rpctransport = 0
self.__service_name = ''.join([random.choice(string.letters) for i in range(4)])
self.__binary_service_name = ''.join([random.choice(string.letters) for i in range(8)]) + '.exe'
self.__exeFile = exeFile
# We might receive two different types of objects, always end up
# with a SMBConnection one
if isinstance(SMBObject, smb.SMB) or isinstance(SMBObject, smb3.SMB3):
self.connection = SMBConnection(existingConnection = SMBObject)
else:
self.connection = SMBObject
self.share = ''
def getShare(self):
return self.share
def getShares(self):
# Setup up a DCE SMBTransport with the connection already in place
print "[*] Requesting shares on %s....." % (self.connection.getRemoteHost())
try:
self._rpctransport = transport.SMBTransport('','',filename = r'\srvsvc', smb_connection = self.connection)
self._dce = dcerpc.DCERPC_v5(self._rpctransport)
self._dce.connect()
self._dce.bind(srvsvc.MSRPC_UUID_SRVSVC)
srv_svc = srvsvc.DCERPCSrvSvc(self._dce)
resp = srv_svc.get_share_enum_1(self._rpctransport.get_dip())
return resp
except:
print "[!] Error requesting shares on %s, aborting....." % (self.connection.getRemoteHost())
raise
def createService(self, handle, share, path):
print "[*] Creating service %s on %s....." % (self.__service_name, self.connection.getRemoteHost())
# First we try to open the service in case it exists. If it does, we remove it.
try:
resp = self.rpcsvc.OpenServiceW(handle, self.__service_name.encode('utf-16le'))
except Exception, e:
if e.get_error_code() == svcctl.ERROR_SERVICE_DOES_NOT_EXISTS:
# We're good, pass the exception
pass
else:
raise
else:
# It exists, remove it
self.rpcsvc.DeleteService(resp['ContextHandle'])
self.rpcsvc.CloseServiceHandle(resp['ContextHandle'])
# Create the service
command = '%s\\%s' % (path, self.__binary_service_name)
try:
resp = self.rpcsvc.CreateServiceW(handle, self.__service_name.encode('utf-16le'), self.__service_name.encode('utf-16le'), command.encode('utf-16le'))
except:
print "[!] Error creating service %s on %s" % (self.__service_name, self.connection.getRemoteHost())
raise
else:
return resp['ContextHandle']
def openSvcManager(self):
print "[*] Opening SVCManager on %s....." % self.connection.getRemoteHost()
# Setup up a DCE SMBTransport with the connection already in place
self._rpctransport = transport.SMBTransport('','',filename = r'\svcctl', smb_connection = self.connection)
self._dce = dcerpc.DCERPC_v5(self._rpctransport)
self._dce.connect()
self._dce.bind(svcctl.MSRPC_UUID_SVCCTL)
self.rpcsvc = svcctl.DCERPCSvcCtl(self._dce)
try:
resp = self.rpcsvc.OpenSCManagerW()
except:
print "[!] Error opening SVCManager on %s....." % self.connection.getRemoteHost()
return 0
else:
return resp['ContextHandle']
def copy_file(self, src, tree, dst):
print "[*] Uploading file %s" % dst
if isinstance(src, str):
# We have a filename
fh = open(src, 'rb')
else:
# We have a class instance, it must have a read method
fh = src
f = dst
pathname = string.replace(f,'/','\\')
try:
self.connection.putFile(tree, pathname, fh.read)
except:
print "[!] Error uploading file %s, aborting....." % dst
raise
fh.close()
def findWritableShare(self, shares):
# Check we can write a file on the shares, stop in the first one
for i in shares:
if i['Type'] == smb.SHARED_DISK or i['Type'] == smb.SHARED_DISK_HIDDEN:
share = i['NetName'].decode('utf-16le')[:-1]
try:
self.connection.createDirectory(share,'BETO')
except:
# Can't create, pass
print '[!] No written share found, aborting...'
raise
else:
print '[*] Found writable share %s' % share
self.connection.deleteDirectory(share,'BETO')
return str(share)
return None
def install(self):
if self.connection.isGuestSession():
print "[!] Authenticated as Guest. Aborting"
self.connection.logoff()
del(self.connection)
else:
fileCopied = False
serviceCreated = False
# Do the stuff here
try:
# Let's get the shares
shares = self.getShares()
self.share = self.findWritableShare(shares)
res = self.copy_file(self.__exeFile ,self.share,self.__binary_service_name)
fileCopied = True
svcManager = self.openSvcManager()
if svcManager != 0:
serverName = self.connection.getServerName()
if serverName != '':
path = '\\\\%s\\%s' % (serverName, self.share)
else:
path = '\\\\127.0.0.1\\' + self.share
service = self.createService(svcManager, self.share, path)
serviceCreated = True
if service != 0:
parameters = [ '%s\\%s' % (path,self.__binary_service_name), '%s\\%s' % (path, '') ]
# Start service
print '[*] Starting service %s.....' % self.__service_name
try:
self.rpcsvc.StartServiceW(service)
except:
pass
self.rpcsvc.CloseServiceHandle(service)
self.rpcsvc.CloseServiceHandle(svcManager)
except Exception, e:
print "[!] Error performing the installation, cleaning up: %s" %e
try:
self.rpcsvc.StopService(service)
except:
pass
if fileCopied is True:
try:
self.connection.deleteFile(self.share, self.__binary_service_name)
except:
pass
if serviceCreated is True:
try:
self.rpcsvc.DeleteService(service)
except:
pass
def uninstall(self):
fileCopied = True
serviceCreated = True
# Do the stuff here
try:
# Let's get the shares
svcManager = self.openSvcManager()
if svcManager != 0:
resp = self.rpcsvc.OpenServiceA(svcManager, self.__service_name)
service = resp['ContextHandle']
print '[*] Stoping service %s.....' % self.__service_name
try:
self.rpcsvc.StopService(service)
except:
pass
print '[*] Removing service %s.....' % self.__service_name
self.rpcsvc.DeleteService(service)
self.rpcsvc.CloseServiceHandle(service)
self.rpcsvc.CloseServiceHandle(svcManager)
print '[*] Removing file %s.....' % self.__binary_service_name
self.connection.deleteFile(self.share, self.__binary_service_name)
except Exception, e:
print "[!] Error performing the uninstallation, cleaning up"
try:
self.rpcsvc.StopService(service)
except:
pass
if fileCopied is True:
try:
self.connection.deleteFile(self.share, self.__binary_service_name)
except:
try:
self.connection.deleteFile(self.share, self.__binary_service_name)
except:
pass
pass
if serviceCreated is True:
try:
self.rpcsvc.DeleteService(service)
except:
pass
|