public void CreateProfile(String ssid, SecurityModes securityMode, Byte[] key = null, Byte keyIndex = 0, Byte channel = 0) { if ((key == null || key.Length == 0) && securityMode != SecurityModes.Open) { throw new ArgumentException("Invalid profile informations"); } var pf = new ConnectionProfile(ssid, securityMode, key, keyIndex, channel); if (_profilesCount == 1) { Reset(ResetModes.Hard); } Init(pf.Num); }
public ConnectionProfile(String pSSID, SecurityModes pSecurityMode, Byte[] pKey = null, Byte pKeyIndex = 0, Byte pChannel = 0) { if (_profilesCount == 2) { throw new InvalidOperationException(); } Num = _profilesCount; SSID = pSSID; SecurityMode = pSecurityMode; SecurityKey = pKey; KeyIndex = pKeyIndex; Channel = pChannel; _profiles[_profilesCount] = this; _profilesCount++; }
private bool SmbUpdateContextWithResponsePacket(SmbClientConnection connection, SmbPacket response) { if (response == null) { return false; } int connectionId = connection.ConnectionId; SmbHeader smbHeader = response.SmbHeader; // only process the response packet. if (response.PacketType != SmbPacketType.BatchedResponse && response.PacketType != SmbPacketType.SingleResponse) { return false; } // packet status SmbStatus packetStatus = (SmbStatus)smbHeader.Status; // filter error packet if (packetStatus != SmbStatus.STATUS_SUCCESS && packetStatus != SmbStatus.STATUS_MORE_PROCESSING_REQUIRED && packetStatus != SmbStatus.STATUS_BUFFER_OVERFLOW) { return false; } // process each special command switch (smbHeader.Command) { #region Negotiate Response case SmbCommand.SMB_COM_NEGOTIATE: // implicit ntlm, decode using cifs sdk. if (!smbClient.Capability.IsSupportsExtendedSecurity) { return false; } // down cast to negotiate response packet. SmbNegotiateResponsePacket negotiate = response as SmbNegotiateResponsePacket; // set negotiate flag connection.NegotiateSent = true; #region update security mode SecurityModes securityModes = negotiate.SmbParameters.SecurityMode; if (SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_ENABLED == (securityModes & SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) { connection.ServerSigningState = SignState.ENABLED; } else if (SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED == (securityModes & SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED)) { connection.ServerSigningState = SignState.REQUIRED; } else { connection.ServerSigningState = SignState.DISABLED; } if (SecurityModes.NEGOTIATE_USER_SECURITY == (securityModes & SecurityModes.NEGOTIATE_USER_SECURITY)) { connection.UsesSharePasswords = false; } else { connection.UsesSharePasswords = true; } if (SecurityModes.NEGOTIATE_ENCRYPT_PASSWORDS == (securityModes & SecurityModes.NEGOTIATE_ENCRYPT_PASSWORDS)) { connection.IsClientEncryptPasswords = true; } else { connection.IsClientEncryptPasswords = false; } // update IsSignActive using the combination of the client's // MessageSigningPolicy and the connection's ServerSigningState smbClient.Context.UpdateSigningActive(connection); #endregion #region update server capabilities connection.ServerCapabilities = (Capabilities)negotiate.SmbParameters.Capabilities; if (Capabilities.CAP_INFOLEVEL_PASSTHRU == (connection.ServerCapabilities & Capabilities.CAP_INFOLEVEL_PASSTHRU)) { smbClient.Capability.IsUsePassThrough = true; } #endregion #region update maxbuffersize connection.MaxBufferSize = negotiate.SmbParameters.MaxBufferSize; #endregion this.AddOrUpdateConnection(connection); break; #endregion #region Session Setup Response case SmbCommand.SMB_COM_SESSION_SETUP_ANDX: // implicit ntlm, decode using cifs sdk. if (!smbClient.Capability.IsSupportsExtendedSecurity) { return false; } // the session to operation on. SmbClientSession session = null; // down-case the packet SmbSessionSetupAndxResponsePacket packet = response as SmbSessionSetupAndxResponsePacket; // if session exists, use it. if (this.GetSession(connectionId, smbHeader.Uid) != null) { session = new SmbClientSession(this.GetSession(connectionId, smbHeader.Uid)); } else { session = new SmbClientSession(); } // if success, update context and session key. if (packetStatus == SmbStatus.STATUS_SUCCESS) { // if spng, the SessionKey is null and the SecurityBlob from server contains data // in this situation, need to initialize the SecurityBlob of server to generate the SessionKey if (connection.GssApi.SessionKey == null && packet.SecurityBlob != null && packet.SecurityBlob.Length > 0) { connection.GssApi.Initialize(packet.SecurityBlob); } // get session key and store in the context session.SessionKey = connection.GssApi.SessionKey; // reset the gss api of connection connection.GssApi = null; // reset the securityblob when success packet.SecurityBlob = null; } // update the security blob from server connection.SecurityBlob = packet.SecurityBlob; this.AddOrUpdateConnection(connection); // update session session.SessionUid = smbHeader.Uid; session.ConnectionId = connectionId; this.AddOrUpdateSession(session); break; #endregion default: return false; } return true; }
/// <summary> /// Create SMB_COM_NEGOTIATE response /// </summary> /// <param name="connection">the connection identified the client</param> /// <param name = "securityMode"> /// An 8-bit field, indicating the security modes supported or REQUIRED by the server /// </param> /// <param name = "maxBufferSize"> /// The maximum size, in bytes, of the largest SMB message the server can receive. This is the size of the /// SMB message that the client MAY send to the server. SMB message size includes the size of the SMB /// parameter, and data blocks. This size does not include any transport-layer framing or other data. The /// server MUST provide a MaxBufferSize of 1024 bytes (1Kbyte) or larger. If CAP_RAW_MODE is then the /// SMB_COM_WRITE_RAW command can bypass the MaxBufferSize limit. Otherwise, SMB messages sent to server /// MUST have a total size less than or equal to the MaxBufferSize value. This includes AndX chained /// </param> /// <param name="maxMpxCount"> /// The maximum number of outstanding SMB operations the server supports. This value includes existing /// OpLocks, the NT_TRANSACT_NOTIFY_CHANGE subcommand, and any other command that are pending on the server. /// If the negotiated MaxMpxCount is one, then OpLock support MUST be disabled for this session. The /// MaxMpxCount MUST be greater than zero. This parameter has no specific relationship to the /// SMB_COM_READ_MPX and SMB_COM_WRITE_MPX commands. /// </param> /// <returns>a smb negotiate response packet </returns> /// <exception cref="ArgumentNullException">connection must not be null</exception> /// <exception cref="NotImplementedException">the security package is invalid</exception> public virtual SmbNegotiateResponsePacket CreateSmbComNegotiateResponse( SmbServerConnection connection, SecurityModes securityMode, uint maxBufferSize, ushort maxMpxCount) { if (connection == null) { throw new ArgumentNullException("connection"); } SmbNegotiateResponsePacket packet = new SmbNegotiateResponsePacket(); // create smb packet header packet.SmbHeader = CifsMessageUtils.CreateSmbHeader( SmbCommand.SMB_COM_NEGOTIATE, connection.ProcessId, connection.MessageId, 0, 0, (SmbFlags)connection.Capability.Flag, (SmbFlags2)connection.Capability.Flags2); // update smb parameters SMB_COM_NEGOTIATE_NtLanManagerResponse_SMB_Parameters smbParameters = packet.SmbParameters; ushort dialectIndex = 0x00; byte wordCount = 0x00; connection.GetPreferedDialectIndex(out dialectIndex, out wordCount); smbParameters.WordCount = wordCount; smbParameters.DialectIndex = dialectIndex; smbParameters.SecurityMode = securityMode; smbParameters.MaxBufferSize = maxBufferSize; smbParameters.MaxMpxCount = maxMpxCount; smbParameters.Capabilities = connection.ServerCapabilities; smbParameters.SystemTime.Time = (ulong)DateTime.Now.ToFileTime(); // update smb data SMB_COM_NEGOTIATE_NtLanManagerResponse_SMB_Data smbData = packet.SmbData; if (connection.GssApi == null) { connection.GssApi = new SspiServerSecurityContext( SecurityPackageType.Negotiate, this.credential, "cifs/" + Environment.MachineName, ServerSecurityContextAttribute.Connection, SecurityTargetDataRepresentation.SecurityNetworkDrep); } // to generate the token. connection.GssApi.Accept(null); smbData.SecurityBlob = connection.GssApi.Token; // update smbData.ByteCount smbData.ByteCount = 0; smbData.ByteCount += (ushort)CifsMessageUtils.GetSize<Guid>(smbData.ServerGuid); if (smbData.SecurityBlob != null) { smbData.ByteCount += (ushort)smbData.SecurityBlob.Length; } // store the parameters and data to packet. packet.SmbParameters = smbParameters; packet.SmbData = smbData; return packet; }
/// <summary> /// Create SMB_COM_NEGOTIATE response /// </summary> /// <param name="connection">the connection identified the client</param> /// <param name = "securityMode"> /// An 8-bit field, indicating the security modes supported or REQUIRED by the server /// </param> /// <param name = "maxBufferSize"> /// The maximum size, in bytes, of the largest SMB message the servercan receive. This is the size of the SMB /// message that the clientMAY send to the server. SMB message size includes the size of the SMB header, and /// data blocks. This size does not include any transport-layer framing or other transport-layer data. server /// MUSTprovide a MaxBufferSize of 1024 bytes (1Kbyte) or larger.If CAP_RAW_MODE is negotiated, then /// SMB_COM_WRITE_RAW commandcan bypass the MaxBufferSize limit. Otherwise, SMB messages sent to the server /// have a total size less than or equal to the MaxBufferSize value.This includes AndX chained default /// MaxBufferSize on Windows NT server is 4356 bytes(4KB + 260Bytes) if the server has 512MB of or less. If /// the server has more than 512MB of memory, then the default MaxBufferSize is 16644 bytes (16KB 260Bytes). /// Windows NT servers always use a MaxBufferSize value that is a multiple of four (4). The can be configured /// through the following registry setting: /// </param> /// <param name="maxMpxCount"> /// The maximum number of outstanding SMB operations the server /// supports. This value includes existing OpLocks, /// the NT_TRANSACT_NOTIFY_CHANGE subcommand, and any other command /// that are pending on the server. If the negotiated MaxMpxCount is one, /// then OpLock support MUST be disabled for this session. The MaxMpxCount /// MUST be greater than zero. This parameter has no specific /// relationship to the SMB_COM_READ_MPX and SMB_COM_WRITE_MPX commands. /// </param> /// <returns>a smb implicit ntlm negotiate response packet </returns> /// <exception cref="ArgumentNullException">connection must not be null</exception> public virtual SmbNegotiateImplicitNtlmResponsePacket CreateSmbComNegotiateImplicitNtlmResponse( SmbServerConnection connection, SecurityModes securityMode, uint maxBufferSize, ushort maxMpxCount) { if (connection == null) { throw new ArgumentNullException("connection"); } Cifs.SmbNegotiateResponsePacket packet = new Cifs.SmbNegotiateResponsePacket(); // create smb packet header packet.SmbHeader = CifsMessageUtils.CreateSmbHeader( SmbCommand.SMB_COM_NEGOTIATE, connection.ProcessId, connection.MessageId, 0, 0, (SmbFlags)connection.Capability.Flag, (SmbFlags2)connection.Capability.Flags2); // update smb parameters Cifs.SMB_COM_NEGOTIATE_NtLanManagerResponse_SMB_Parameters smbParameters = packet.SmbParameters; ushort dialectIndex = 0x00; byte wordCount = 0x00; connection.GetPreferedDialectIndex(out dialectIndex, out wordCount); smbParameters.WordCount = wordCount; smbParameters.DialectIndex = dialectIndex; smbParameters.SecurityMode = securityMode; smbParameters.MaxBufferSize = maxBufferSize; smbParameters.MaxMpxCount = maxMpxCount; smbParameters.Capabilities = (Cifs.Capabilities)connection.ServerCapabilities; smbParameters.SystemTime.Time = (ulong)connection.SystemTime; smbParameters.ChallengeLength = (byte)connection.NtlmEncryptionKey.Length; // update smb data Cifs.SMB_COM_NEGOTIATE_NtLanManagerResponse_SMB_Data smbData = packet.SmbData; smbData.Challenge = connection.NtlmEncryptionKey; // update smbData.ByteCount smbData.ByteCount = 0; if (smbData.Challenge != null) { smbData.ByteCount += (ushort)smbData.Challenge.Length; } if (smbData.DomainName != null) { smbData.ByteCount += (ushort)smbData.DomainName.Length; } // store the parameters and data to packet. packet.SmbParameters = smbParameters; packet.SmbData = smbData; return new SmbNegotiateImplicitNtlmResponsePacket(packet); }
public SmbNegotiateResponsePacket CreateNegotiateResponse( CifsServerPerConnection connection, SmbNegotiateRequestPacket request, SecurityModes securityMode) { SmbNegotiateResponsePacket response = new SmbNegotiateResponsePacket(); response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request); Stack<string> dialectStrings = new Stack<string>(); for (int offset = 0; offset < request.SmbData.Dialects.Length; offset++) { string dialectString = CifsMessageUtils.ToSmbString(request.SmbData.Dialects, offset, true); dialectStrings.Push(dialectString); offset += sizeof(byte) + dialectString.Length; } while(dialectStrings.Count > 0) { string dialectString = dialectStrings.Pop(); if(dialectString == CifsMessageUtils.DIALECT_NTLANMAN) { SMB_COM_NEGOTIATE_NtLanManagerResponse_SMB_Parameters smbParameters = response.SmbParameters; smbParameters.WordCount = (byte)((Marshal.SizeOf(response.SmbParameters) - sizeof(byte)) / 2); smbParameters.DialectIndex = (ushort)dialectStrings.Count; smbParameters.SecurityMode = securityMode; smbParameters.MaxMpxCount = (ushort)this.context.MaxMpxCount; smbParameters.MaxNumberVcs = (ushort)this.context.MaxNumberVcs; smbParameters.MaxBufferSize = (ushort)this.context.MaxBufferSize; smbParameters.MaxRawSize = (ushort)this.context.MaxRawSize; smbParameters.SessionKey = 0; smbParameters.Capabilities = this.context.Capabilities; FileTime fileTime = new FileTime(); fileTime.Time = (ulong)DateTime.Now.ToFileTime(); smbParameters.SystemTime = fileTime; smbParameters.ServerTimeZone = (short)TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).Minutes; smbParameters.ChallengeLength = (byte)connection.NTLMChallenge.Length; response.SmbParameters = smbParameters; SMB_COM_NEGOTIATE_NtLanManagerResponse_SMB_Data smbData = response.SmbData; smbData.Challenge = connection.NTLMChallenge; smbData.DomainName = CifsMessageUtils.ToSmbStringBytes(this.context.DomainName, true); smbData.ByteCount = (ushort)(smbData.Challenge.Length + smbData.DomainName.Length); response.SmbData = smbData; return response; } else if (dialectString == CifsMessageUtils.DIALECT_PCLAN || dialectString == CifsMessageUtils.DIALECT_PCNETWORK_PROGRAM) { SMB_COM_NEGOTIATE_NtLanManagerResponse_SMB_Parameters smbParameters = response.SmbParameters; smbParameters.WordCount = 0x1; smbParameters.DialectIndex = (ushort)dialectStrings.Count; response.SmbParameters = smbParameters; SMB_COM_NEGOTIATE_NtLanManagerResponse_SMB_Data smbData = response.SmbData; smbData.Challenge = connection.NTLMChallenge; smbData.DomainName = CifsMessageUtils.ToSmbStringBytes(this.context.DomainName, true); smbData.ByteCount = (ushort)(smbData.Challenge.Length + smbData.DomainName.Length); response.SmbData = smbData; return response; } } throw new NotSupportedException("None of these dialects is supported."); }
/// <summary> /// Connect share specified by shareName, this function does not issue tcp or netbios /// connect, it does Negotiate -> SessionSetup -> TreeConnect /// </summary> /// <param name="serverName">The server name</param> /// <param name="domain">The domain</param> /// <param name="userName">The user name</param> /// <param name="password">The password</param> /// <param name="shareName">The share name</param> /// <param name="securityPackage">The security package</param> private void InternalConnectShare(string serverName, string domain, string userName, string password, string shareName, SecurityPackageType securityPackage) { SmbPacket request; SmbPacket response; uint status; // Negotiate: request = this.smbClient.CreateNegotiateRequest( defaultSignState, new string[] { DialectNameString.NTLANMAN }); response = this.SendAndExpectSmbPacket(request, internalTimeout, out status); if (status != 0) { throw new InvalidOperationException("Negotiate Failed. ErrorCode: " + status); } SecurityModes securityMode = (response as SmbNegotiateResponsePacket).SmbParameters.SecurityMode; this.isSignRequired = (securityMode & SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) == SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED; SmbSecurityPackage secPkg; switch (securityPackage) { case SecurityPackageType.Ntlm: secPkg = SmbSecurityPackage.NTLM; break; case SecurityPackageType.Kerberos: secPkg = SmbSecurityPackage.Kerberos; break; case SecurityPackageType.Negotiate: secPkg = SmbSecurityPackage.Negotiate; break; default: throw new ArgumentException("Unsupported securityPackage: " + securityPackage.ToString()); } // Session setup: request = this.smbClient.CreateFirstSessionSetupRequest(secPkg, serverName, domain, userName, password); response = this.SendAndExpectSmbPacket(request, internalTimeout, out status); while (status != 0) { if ((int)status == (int)SmbStatus.STATUS_MORE_PROCESSING_REQUIRED) { this.uid = (response as SmbSessionSetupAndxResponsePacket).SmbHeader.Uid; request = this.smbClient.CreateSecondSessionSetupRequest(this.uid, secPkg); response = this.SendAndExpectSmbPacket(request, internalTimeout, out status); } else { throw new InvalidOperationException("Session Setup Failed. ErrorCode: " + status); } } this.uid = (response as SmbSessionSetupAndxResponsePacket).SmbHeader.Uid; if (isSignRequired) { CifsClientPerSession session = this.smbClient.Context.GetSession( this.smbClient.Context.Connection.ConnectionId, this.uid); this.sessionKey = session.SessionKey; } // Tree connect: string sharePath = "\\\\" + serverName + '\\' + shareName; request = this.smbClient.CreateTreeConnectRequest(this.uid, sharePath); if (this.isSignRequired) { request.Sign(this.NextSequenceNumber, this.sessionKey); } response = this.SendAndExpectSmbPacket(request, internalTimeout, out status); if (status != 0) { throw new InvalidOperationException("Tree Connect Failed. ErrorCode: " + status); } this.treeId = (response as SmbTreeConnectAndxResponsePacket).SmbHeader.Tid; }