github.com/n00py/Slackor@v0.0.0-20200610224921-d007fcea1740/impacket/tests/SMB_RPC/test_smb.py (about) 1 import unittest 2 import os 3 import socket 4 import select 5 import errno 6 7 try: 8 import ConfigParser 9 except ImportError: 10 import configparser as ConfigParser 11 12 from binascii import unhexlify 13 from impacket.smbconnection import SMBConnection, smb 14 from impacket.smb3structs import SMB2_DIALECT_002,SMB2_DIALECT_21, SMB2_DIALECT_30 15 from impacket import nt_errors, nmb 16 17 # IMPORTANT NOTE: 18 # For some reason, under Windows 8, you cannot switch between 19 # dialects 002, 2_1 and 3_0 (it will throw STATUS_USER_SESSION_DELETED), 20 # but you can with SMB1. 21 # So, you can't run all test cases against the same machine. 22 # Usually running all the tests against a Windows 7 except SMB3 23 # would do the trick. 24 # ToDo: 25 # [ ] Add the rest of SMBConnection public methods 26 27 class SMBTests(unittest.TestCase): 28 def create_connection(self): 29 if self.dialects == smb.SMB_DIALECT: 30 # Only for SMB1 let's do manualNego 31 s = SMBConnection(self.serverName, self.machine, preferredDialect = self.dialects, sess_port = self.sessPort, manualNegotiate=True) 32 s.negotiateSession(self.dialects, flags2=self.flags2) 33 else: 34 s = SMBConnection(self.serverName, self.machine, preferredDialect = self.dialects, sess_port = self.sessPort) 35 return s 36 37 def test_aliasconnection(self): 38 smb = SMBConnection('*SMBSERVER', self.machine, preferredDialect=self.dialects, sess_port=self.sessPort) 39 smb.login(self.username, self.password, self.domain) 40 smb.listPath(self.share, '*') 41 smb.logoff() 42 43 def test_reconnect(self): 44 smb = self.create_connection() 45 smb.login(self.username, self.password, self.domain) 46 smb.listPath(self.share, '*') 47 smb.logoff() 48 smb.reconnect() 49 smb.listPath(self.share, '*') 50 smb.logoff() 51 52 def test_reconnectKerberosHashes(self): 53 lmhash, nthash = self.hashes.split(':') 54 smb = self.create_connection() 55 smb.kerberosLogin(self.username, '', self.domain, lmhash, nthash, '') 56 credentials = smb.getCredentials() 57 self.assertTrue( credentials == (self.username, '', self.domain, unhexlify(lmhash), unhexlify(nthash), '', None, None) ) 58 UNC = '\\\\%s\\%s' % (self.machine, self.share) 59 smb.connectTree(UNC) 60 smb.logoff() 61 smb.reconnect() 62 credentials = smb.getCredentials() 63 self.assertTrue( 64 credentials == (self.username, '', self.domain, unhexlify(lmhash), unhexlify(nthash), '', None, None)) 65 UNC = '\\\\%s\\%s' % (self.machine, self.share) 66 smb.connectTree(UNC) 67 smb.logoff() 68 69 def test_connectTree(self): 70 smb = self.create_connection() 71 smb.login(self.username, self.password, self.domain) 72 smb.connectTree(self.share) 73 UNC = '\\\\%s\\%s' % (self.machine, self.share) 74 smb.connectTree(UNC) 75 76 def test_connection(self): 77 smb = self.create_connection() 78 smb.login(self.username, self.password, self.domain) 79 credentials = smb.getCredentials() 80 self.assertTrue( credentials == (self.username, self.password, self.domain, '','','', None, None)) 81 smb.logoff() 82 del(smb) 83 84 def test_close_connection(self): 85 smb = self.create_connection() 86 smb.login(self.username, self.password, self.domain) 87 smb_connection_socket = smb.getSMBServer().get_socket() 88 self.assertTrue(self.__is_socket_opened(smb_connection_socket) == True) 89 smb.close() 90 self.assertTrue(self.__is_socket_opened(smb_connection_socket) == False) 91 del(smb) 92 93 def test_manualNego(self): 94 smb = self.create_connection() 95 smb.negotiateSession(self.dialects) 96 smb.login(self.username, self.password, self.domain) 97 credentials = smb.getCredentials() 98 self.assertTrue( credentials == (self.username, self.password, self.domain, '','','', None, None)) 99 smb.logoff() 100 del(smb) 101 102 def test_loginHashes(self): 103 lmhash, nthash = self.hashes.split(':') 104 smb = self.create_connection() 105 smb.login(self.username, '', self.domain, lmhash, nthash) 106 credentials = smb.getCredentials() 107 self.assertTrue( credentials == (self.username, '', self.domain, unhexlify(lmhash), unhexlify(nthash), '', None, None) ) 108 smb.logoff() 109 110 def test_loginKerberosHashes(self): 111 lmhash, nthash = self.hashes.split(':') 112 smb = self.create_connection() 113 smb.kerberosLogin(self.username, '', self.domain, lmhash, nthash, '') 114 credentials = smb.getCredentials() 115 self.assertTrue( credentials == (self.username, '', self.domain, unhexlify(lmhash), unhexlify(nthash), '', None, None) ) 116 UNC = '\\\\%s\\%s' % (self.machine, self.share) 117 smb.connectTree(UNC) 118 smb.logoff() 119 120 def test_loginKerberos(self): 121 smb = self.create_connection() 122 smb.kerberosLogin(self.username, self.password, self.domain, '', '', '') 123 credentials = smb.getCredentials() 124 self.assertTrue( credentials == (self.username, self.password, self.domain, '','','', None, None) ) 125 UNC = '\\\\%s\\%s' % (self.machine, self.share) 126 smb.connectTree(UNC) 127 smb.logoff() 128 129 def test_loginKerberosAES(self): 130 smb = self.create_connection() 131 smb.kerberosLogin(self.username, '', self.domain, '', '', self.aesKey) 132 credentials = smb.getCredentials() 133 self.assertTrue( credentials == (self.username, '', self.domain, '','',self.aesKey, None, None) ) 134 UNC = '\\\\%s\\%s' % (self.machine, self.share) 135 smb.connectTree(UNC) 136 smb.logoff() 137 138 def test_listPath(self): 139 smb = self.create_connection() 140 smb.login(self.username, self.password, self.domain) 141 smb.listPath(self.share, '*') 142 smb.logoff() 143 144 def test_createFile(self): 145 smb = self.create_connection() 146 smb.login(self.username, self.password, self.domain) 147 tid = smb.connectTree(self.share) 148 fid = smb.createFile(tid, self.file) 149 smb.closeFile(tid,fid) 150 smb.rename(self.share, self.file, self.file + '.bak') 151 smb.deleteFile(self.share, self.file + '.bak') 152 smb.disconnectTree(tid) 153 smb.logoff() 154 155 def test_readwriteFile(self): 156 smb = self.create_connection() 157 smb.login(self.username, self.password, self.domain) 158 tid = smb.connectTree(self.share) 159 fid = smb.createFile(tid, self.file) 160 smb.writeFile(tid, fid, "A"*65535) 161 data = b'' 162 offset = 0 163 remaining = 65535 164 while remaining>0: 165 data += smb.readFile(tid,fid, offset, remaining) 166 remaining = 65535 - len(data) 167 self.assertTrue(len(data) == 65535) 168 self.assertTrue(data == b"A"*65535) 169 smb.closeFile(tid,fid) 170 fid = smb.openFile(tid, self.file) 171 smb.closeFile(tid, fid) 172 smb.deleteFile(self.share, self.file) 173 smb.disconnectTree(tid) 174 175 smb.logoff() 176 177 def test_createdeleteDirectory(self): 178 smb = self.create_connection() 179 smb.login(self.username, self.password, self.domain) 180 smb.createDirectory(self.share, self.directory) 181 smb.deleteDirectory(self.share, self.directory) 182 smb.createDirectory(self.share, self.directory) 183 nested_dir = "%s\\%s" %(self.directory, self.directory) 184 smb.createDirectory(self.share, nested_dir) 185 try: 186 smb.deleteDirectory(self.share, self.directory) 187 except Exception as e: 188 if e.error == nt_errors.STATUS_DIRECTORY_NOT_EMPTY: 189 smb.deleteDirectory(self.share, nested_dir) 190 smb.deleteDirectory(self.share, self.directory) 191 smb.logoff() 192 193 def test_getData(self): 194 smb = self.create_connection() 195 smb.login(self.username, self.password, self.domain) 196 smb.getDialect() 197 smb.getServerName() 198 smb.getRemoteHost() 199 smb.getServerDomain() 200 smb.getServerOS() 201 smb.doesSupportNTLMv2() 202 smb.isLoginRequired() 203 smb.logoff() 204 205 def test_getServerName(self): 206 smb = self.create_connection() 207 smb.login(self.username, self.password, self.domain) 208 serverName = smb.getServerName() 209 self.assertTrue( serverName.upper() == self.serverName.upper() ) 210 smb.logoff() 211 212 def test_getServerDNSDomainName(self): 213 smb = self.create_connection() 214 smb.login(self.username, self.password, self.domain) 215 serverDomain = smb.getServerDNSDomainName() 216 self.assertTrue( serverDomain.upper() == self.domain.upper()) 217 smb.logoff() 218 219 def test_getServerDomain(self): 220 smb = self.create_connection() 221 smb.login(self.username, self.password, self.domain) 222 serverDomain = smb.getServerDomain() 223 self.assertTrue( serverDomain.upper() == self.domain.upper().split('.')[0]) 224 smb.logoff() 225 226 def test_getRemoteHost(self): 227 smb = self.create_connection() 228 smb.login(self.username, self.password, self.domain) 229 remoteHost = smb.getRemoteHost() 230 self.assertTrue( remoteHost == self.machine) 231 smb.logoff() 232 233 def test_getDialect(self): 234 smb = self.create_connection() 235 smb.login(self.username, self.password, self.domain) 236 dialect = smb.getDialect() 237 self.assertTrue( dialect == self.dialects) 238 smb.logoff() 239 240 def test_uploadDownload(self): 241 smb = self.create_connection() 242 smb.login(self.username, self.password, self.domain) 243 f = open(self.upload) 244 smb.putFile(self.share, self.file, f.read) 245 f.close() 246 f = open(self.upload + '2', 'wb+') 247 smb.getFile(self.share, self.file, f.write) 248 f.close() 249 os.unlink(self.upload + '2') 250 smb.deleteFile(self.share, self.file) 251 smb.logoff() 252 253 def test_listShares(self): 254 smb = self.create_connection() 255 smb.login(self.username, self.password, self.domain) 256 smb.listShares() 257 smb.logoff() 258 259 def test_getSessionKey(self): 260 smb = self.create_connection() 261 smb.login(self.username, self.password, self.domain) 262 smb.getSessionKey() 263 smb.logoff 264 265 def __is_socket_opened(self, s): 266 # We assume that if socket is selectable, it's open; and if it were not, it's closed. 267 # Note: this method is accurate as long as the file descriptor used for the socket is not re-used 268 is_socket_opened = True 269 try: 270 select.select([s], [], [], 0) 271 except socket.error as e: 272 if e[0] == errno.EBADF: 273 is_socket_opened = False 274 except ValueError: 275 is_socket_opened = False 276 return is_socket_opened 277 278 class SMB1Tests(SMBTests): 279 def setUp(self): 280 SMBTests.setUp(self) 281 # Put specific configuration for target machine with SMB1 282 configFile = ConfigParser.ConfigParser() 283 configFile.read('dcetests.cfg') 284 self.username = configFile.get('SMBTransport', 'username') 285 self.domain = configFile.get('SMBTransport', 'domain') 286 self.serverName = configFile.get('SMBTransport', 'servername') 287 self.password = configFile.get('SMBTransport', 'password') 288 self.machine = configFile.get('SMBTransport', 'machine') 289 self.hashes = configFile.get('SMBTransport', 'hashes') 290 self.aesKey = configFile.get('SMBTransport', 'aesKey128') 291 self.share = 'C$' 292 self.file = '/TEST' 293 self.directory= '/BETO' 294 self.upload = '../../impacket/nt_errors.py' 295 self.flags2 = smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_EXTENDED_SECURITY | smb.SMB.FLAGS2_LONG_NAMES 296 self.dialects = smb.SMB_DIALECT 297 self.sessPort = nmb.SMB_SESSION_PORT 298 299 class SMB1TestsNetBIOS(SMBTests): 300 def setUp(self): 301 SMBTests.setUp(self) 302 # Put specific configuration for target machine with SMB1 303 configFile = ConfigParser.ConfigParser() 304 configFile.read('dcetests.cfg') 305 self.username = configFile.get('SMBTransport', 'username') 306 self.domain = configFile.get('SMBTransport', 'domain') 307 self.serverName = configFile.get('SMBTransport', 'servername') 308 self.password = configFile.get('SMBTransport', 'password') 309 self.machine = configFile.get('SMBTransport', 'machine') 310 self.hashes = configFile.get('SMBTransport', 'hashes') 311 self.aesKey = configFile.get('SMBTransport', 'aesKey128') 312 self.share = 'C$' 313 self.file = '/TEST' 314 self.directory= '/BETO' 315 self.upload = '../../impacket/nt_errors.py' 316 self.flags2 = smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_EXTENDED_SECURITY | smb.SMB.FLAGS2_LONG_NAMES 317 self.dialects = smb.SMB_DIALECT 318 self.sessPort = nmb.NETBIOS_SESSION_PORT 319 320 class SMB1TestsUnicode(SMBTests): 321 def setUp(self): 322 SMBTests.setUp(self) 323 # Put specific configuration for target machine with SMB1 324 configFile = ConfigParser.ConfigParser() 325 configFile.read('dcetests.cfg') 326 self.username = configFile.get('SMBTransport', 'username') 327 self.domain = configFile.get('SMBTransport', 'domain') 328 self.serverName = configFile.get('SMBTransport', 'servername') 329 self.password = configFile.get('SMBTransport', 'password') 330 self.machine = configFile.get('SMBTransport', 'machine') 331 self.hashes = configFile.get('SMBTransport', 'hashes') 332 self.aesKey = configFile.get('SMBTransport', 'aesKey128') 333 self.share = 'C$' 334 self.file = '/TEST' 335 self.directory= '/BETO' 336 self.upload = '../../impacket/nt_errors.py' 337 self.flags2 = smb.SMB.FLAGS2_UNICODE | smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_EXTENDED_SECURITY | smb.SMB.FLAGS2_LONG_NAMES 338 self.dialects = smb.SMB_DIALECT 339 self.sessPort = nmb.SMB_SESSION_PORT 340 341 class SMB002Tests(SMBTests): 342 def setUp(self): 343 # Put specific configuration for target machine with SMB_002 344 SMBTests.setUp(self) 345 configFile = ConfigParser.ConfigParser() 346 configFile.read('dcetests.cfg') 347 self.username = configFile.get('SMBTransport', 'username') 348 self.domain = configFile.get('SMBTransport', 'domain') 349 self.serverName = configFile.get('SMBTransport', 'servername') 350 self.password = configFile.get('SMBTransport', 'password') 351 self.machine = configFile.get('SMBTransport', 'machine') 352 self.hashes = configFile.get('SMBTransport', 'hashes') 353 self.aesKey = configFile.get('SMBTransport', 'aesKey128') 354 self.share = 'C$' 355 self.file = '/TEST' 356 self.directory= '/BETO' 357 self.upload = '../../impacket/nt_errors.py' 358 self.dialects = SMB2_DIALECT_002 359 self.sessPort = nmb.SMB_SESSION_PORT 360 361 class SMB21Tests(SMBTests): 362 def setUp(self): 363 # Put specific configuration for target machine with SMB 2.1 364 SMBTests.setUp(self) 365 configFile = ConfigParser.ConfigParser() 366 configFile.read('dcetests.cfg') 367 self.username = configFile.get('SMBTransport', 'username') 368 self.domain = configFile.get('SMBTransport', 'domain') 369 self.serverName = configFile.get('SMBTransport', 'servername') 370 self.password = configFile.get('SMBTransport', 'password') 371 self.machine = configFile.get('SMBTransport', 'machine') 372 self.hashes = configFile.get('SMBTransport', 'hashes') 373 self.aesKey = configFile.get('SMBTransport', 'aesKey128') 374 self.share = 'C$' 375 self.file = '/TEST' 376 self.directory= '/BETO' 377 self.upload = '../../impacket/nt_errors.py' 378 self.dialects = SMB2_DIALECT_21 379 self.sessPort = nmb.SMB_SESSION_PORT 380 381 class SMB3Tests(SMBTests): 382 def setUp(self): 383 # Put specific configuration for target machine with SMB3 384 SMBTests.setUp(self) 385 configFile = ConfigParser.ConfigParser() 386 configFile.read('dcetests.cfg') 387 self.username = configFile.get('SMBTransport', 'username') 388 self.domain = configFile.get('SMBTransport', 'domain') 389 self.serverName = configFile.get('SMBTransport', 'servername') 390 self.password = configFile.get('SMBTransport', 'password') 391 self.machine = configFile.get('SMBTransport', 'machine') 392 self.hashes = configFile.get('SMBTransport', 'hashes') 393 self.aesKey = configFile.get('SMBTransport', 'aesKey128') 394 self.share = 'C$' 395 self.file = '/TEST' 396 self.directory= '/BETO' 397 self.upload = '../../impacket/nt_errors.py' 398 self.dialects = SMB2_DIALECT_30 399 self.sessPort = nmb.SMB_SESSION_PORT 400 401 if __name__ == "__main__": 402 suite = unittest.TestLoader().loadTestsFromTestCase(SMB1Tests) 403 suite.addTests(unittest.TestLoader().loadTestsFromTestCase(SMB1TestsNetBIOS)) 404 suite.addTests(unittest.TestLoader().loadTestsFromTestCase(SMB1TestsUnicode)) 405 suite.addTests(unittest.TestLoader().loadTestsFromTestCase(SMB002Tests)) 406 suite.addTests(unittest.TestLoader().loadTestsFromTestCase(SMB21Tests)) 407 suite.addTests(unittest.TestLoader().loadTestsFromTestCase(SMB3Tests)) 408 unittest.TextTestRunner(verbosity=1).run(suite)