# impacket SMB extension for MS17-010 exploit. # this file contains only valid SMB packet format operation. from impacket import smb, smbconnection from impacket.dcerpc.v5 import transport from struct import pack import os import random def getNTStatus(self): return (self['ErrorCode'] << 16) | (self['_reserved'] << 8) | self['ErrorClass'] setattr(smb.NewSMBPacket, "getNTStatus", getNTStatus) ############# SMB_COM_TRANSACTION_SECONDARY (0x26) class SMBTransactionSecondary_Parameters(smb.SMBCommand_Parameters): structure = ( ('TotalParameterCount','H', len(req)) + req # assume length is <65536 def send_raw(self, data): self.get_socket().send(data) def create_trans_packet(self, setup, param='', data='', mid=None, maxSetupCount=None, totalParameterCount=None, totalDataCount=None, maxParameterCount=None, maxDataCount=None, pid=None, tid=None, noPad=False): if maxSetupCount is None: maxSetupCount = len(setup) if totalParameterCount is None: totalParameterCount = len(param) if totalDataCount is None: totalDataCount = len(data) if maxParameterCount is None: maxParameterCount = totalParameterCount if maxDataCount is None: maxDataCount = totalDataCount transCmd = smb.SMBCommand(smb.SMB.SMB_COM_TRANSACTION) transCmd['Parameters'] = smb.SMBTransaction_Parameters() transCmd['Parameters']['TotalParameterCount'] = totalParameterCount transCmd['Parameters']['TotalDataCount'] = totalDataCount transCmd['Parameters']['MaxParameterCount'] = maxParameterCount transCmd['Parameters']['MaxDataCount'] = maxDataCount transCmd['Parameters']['MaxSetupCount'] = maxSetupCount transCmd['Parameters']['Flags'] = 0 transCmd['Parameters']['Timeout'] = 0xffffffff transCmd['Parameters']['ParameterCount'] = len(param) transCmd['Parameters']['DataCount'] = len(data) transCmd['Parameters']['Setup'] = setup _put_trans_data(transCmd, param, data, noPad) return self.create_smb_packet(transCmd, mid, pid, tid) def send_trans(self, setup, param='', data='', mid=None, maxSetupCount=None, totalParameterCount=None, totalDataCount=None, maxParameterCount=None, maxDataCount=None, pid=None, tid=None, noPad=False): self.send_raw(self.create_trans_packet(setup, param, data, mid, maxSetupCount, totalParameterCount, totalDataCount, maxParameterCount, maxDataCount, pid, tid, noPad)) return self.recvSMB() def create_trans_secondary_packet(self, mid, param='', paramDisplacement=0, data='', dataDisplacement=0, pid=None, tid=None, noPad=False): transCmd = smb.SMBCommand(smb.SMB.SMB_COM_TRANSACTION_SECONDARY) transCmd['Parameters'] = SMBTransactionSecondary_Parameters() transCmd['Parameters']['TotalParameterCount'] = len(param) transCmd['Parameters']['TotalDataCount'] = len(data) transCmd['Parameters']['ParameterCount'] = len(param) transCmd['Parameters']['ParameterDisplacement'] = paramDisplacement transCmd['Parameters']['DataCount'] = len(data) transCmd['Parameters']['DataDisplacement'] = dataDisplacement _put_trans_data(transCmd, param, data, noPad) return self.create_smb_packet(transCmd, mid, pid, tid) def send_trans_secondary(self, mid, param='', paramDisplacement=0, data='', dataDisplacement=0, pid=None, tid=None, noPad=False): self.send_raw(self.create_trans_secondary_packet(mid, param, paramDisplacement, data, dataDisplacement, pid, tid, noPad)) def create_trans2_packet(self, setup, param='', data='', mid=None, maxSetupCount=None, totalParameterCount=None, totalDataCount=None, maxParameterCount=None, maxDataCount=None, pid=None, tid=None, noPad=False): if maxSetupCount is None: maxSetupCount = len(setup) if totalParameterCount is None: totalParameterCount = len(param) if totalDataCount is None: totalDataCount = len(data) if maxParameterCount is None: maxParameterCount = totalParameterCount if maxDataCount is None: maxDataCount = totalDataCount transCmd = smb.SMBCommand(smb.SMB.SMB_COM_TRANSACTION2) transCmd['Parameters'] = smb.SMBTransaction2_Parameters() transCmd['Parameters']['TotalParameterCount'] = totalParameterCount transCmd['Parameters']['TotalDataCount'] = totalDataCount transCmd['Parameters']['MaxParameterCount'] = maxParameterCount transCmd['Parameters']['MaxDataCount'] = maxDataCount transCmd['Parameters']['MaxSetupCount'] = len(setup) transCmd['Parameters']['Flags'] = 0 transCmd['Parameters']['Timeout'] = 0xffffffff transCmd['Parameters']['ParameterCount'] = len(param) transCmd['Parameters']['DataCount'] = len(data) transCmd['Parameters']['Setup'] = setup _put_trans_data(transCmd, param, data, noPad) return self.create_smb_packet(transCmd, mid, pid, tid) def send_trans2(self, setup, param='', data='', mid=None, maxSetupCount=None, totalParameterCount=None, totalDataCount=None, maxParameterCount=None, maxDataCount=None, pid=None, tid=None, noPad=False): self.send_raw(self.create_trans2_packet(setup, param, data, mid, maxSetupCount, totalParameterCount, totalDataCount, maxParameterCount, maxDataCount, pid, tid, noPad)) return self.recvSMB() def create_trans2_secondary_packet(self, mid, param='', paramDisplacement=0, data='', dataDisplacement=0, pid=None, tid=None, noPad=False): transCmd = smb.SMBCommand(smb.SMB.SMB_COM_TRANSACTION2_SECONDARY) transCmd['Parameters'] = SMBTransaction2Secondary_Parameters() transCmd['Parameters']['TotalParameterCount'] = len(param) transCmd['Parameters']['TotalDataCount'] = len(data) transCmd['Parameters']['ParameterCount'] = len(param) transCmd['Parameters']['ParameterDisplacement'] = paramDisplacement transCmd['Parameters']['DataCount'] = len(data) transCmd['Parameters']['DataDisplacement'] = dataDisplacement _put_trans_data(transCmd, param, data, noPad) return self.create_smb_packet(transCmd, mid, pid, tid) def send_trans2_secondary(self, mid, param='', paramDisplacement=0, data='', dataDisplacement=0, pid=None, tid=None, noPad=False): self.send_raw(self.create_trans2_secondary_packet(mid, param, paramDisplacement, data, dataDisplacement, pid, tid, noPad)) def create_nt_trans_packet(self, function, setup='', param='', data='', mid=None, maxSetupCount=None, totalParameterCount=None, totalDataCount=None, maxParameterCount=None, maxDataCount=None, pid=None, tid=None, noPad=False): if maxSetupCount is None: maxSetupCount = len(setup) if totalParameterCount is None: totalParameterCount = len(param) if totalDataCount is None: totalDataCount = len(data) if maxParameterCount is None: maxParameterCount = totalParameterCount if maxDataCount is None: maxDataCount = totalDataCount transCmd = smb.SMBCommand(smb.SMB.SMB_COM_NT_TRANSACT) transCmd['Parameters'] = smb.SMBNTTransaction_Parameters() transCmd['Parameters']['MaxSetupCount'] = maxSetupCount transCmd['Parameters']['TotalParameterCount'] = totalParameterCount transCmd['Parameters']['TotalDataCount'] = totalDataCount transCmd['Parameters']['MaxParameterCount'] = maxParameterCount transCmd['Parameters']['MaxDataCount'] = maxDataCount transCmd['Parameters']['ParameterCount'] = len(param) transCmd['Parameters']['DataCount'] = len(data) transCmd['Parameters']['Function'] = function transCmd['Parameters']['Setup'] = setup _put_trans_data(transCmd, param, data, noPad) return self.create_smb_packet(transCmd, mid, pid, tid) def send_nt_trans(self, function, setup='', param='', data='', mid=None, maxSetupCount=None, totalParameterCount=None, totalDataCount=None, maxParameterCount=None, maxDataCount=None, pid=None, tid=None, noPad=False): self.send_raw(self.create_nt_trans_packet(function, setup, param, data, mid, maxSetupCount, totalParameterCount, totalDataCount, maxParameterCount, maxDataCount, pid, tid, noPad)) return self.recvSMB() def create_nt_trans_secondary_packet(self, mid, param='', paramDisplacement=0, data='', dataDisplacement=0, pid=None, tid=None, noPad=False): transCmd = smb.SMBCommand(smb.SMB.SMB_COM_NT_TRANSACT_SECONDARY) transCmd['Parameters'] = SMBNTTransactionSecondary_Parameters() transCmd['Parameters']['TotalParameterCount'] = len(param) transCmd['Parameters']['TotalDataCount'] = len(data) transCmd['Parameters']['ParameterCount'] = len(param) transCmd['Parameters']['ParameterDisplacement'] = paramDisplacement transCmd['Parameters']['DataCount'] = len(data) transCmd['Parameters']['DataDisplacement'] = dataDisplacement _put_trans_data(transCmd, param, data, noPad) return self.create_smb_packet(transCmd, mid, pid, tid) def send_nt_trans_secondary(self, mid, param='', paramDisplacement=0, data='', dataDisplacement=0, pid=None, tid=None, noPad=False): self.send_raw(self.create_nt_trans_secondary_packet(mid, param, paramDisplacement, data, dataDisplacement, pid, tid, noPad)) def recv_transaction_data(self, mid, minLen): data = '' while len(data) < minLen: recvPkt = self.recvSMB() if recvPkt['Mid'] != mid: continue resp = smb.SMBCommand(recvPkt['Data'][0]) data += resp['Data'][1:] # skip padding #print(len(data)) return data