Example #1
0
        public void Pack(string challenge, string netBIOSName, string computerName, string dnsDomain, string dnsComputerName, string dnsTreeName, out byte[] challengeData)
        {
            NTLMChallenge ntlmChallenge = new NTLMChallenge();

            ntlmChallenge.ServerChallenge = ntlmChallenge.Challenge(challenge);
            challengeData = ntlmChallenge.ServerChallenge;
            byte[]     timestamp  = BitConverter.GetBytes(DateTime.Now.ToFileTime());
            NTLMAVPair ntlmAVPair = new NTLMAVPair();

            ntlmChallenge.Payload = ntlmAVPair.GetBytes(netBIOSName, computerName, dnsDomain, dnsComputerName, dnsTreeName, timestamp);
            byte[] ntlmChallengeData = ntlmChallenge.GetBytes(computerName);
            byte[] gssapiData        = ntlmChallenge.Encode(ntlmChallengeData);
            this.SecurityBufferLength = (ushort)gssapiData.Length;
            this.Buffer = gssapiData;
        }
        internal void ReceiveClient(object parameters)
        {
            object[]  parameterArray = parameters as object[];
            TcpClient tcpClient      = (TcpClient)parameterArray[0];
            string    type           = (string)parameterArray[1];
            int       port           = (int)parameterArray[2];

            try
            {
                string[]         supportedMethods    = { "GET", "HEAD", "OPTIONS", "CONNECT", "POST", "PROPFIND" };
                string           sourceIP            = ((IPEndPoint)(tcpClient.Client.RemoteEndPoint)).Address.ToString();
                string           sourcePort          = ((IPEndPoint)(tcpClient.Client.RemoteEndPoint)).Port.ToString();
                string           listenerPort        = ((IPEndPoint)(tcpClient.Client.LocalEndPoint)).Port.ToString();
                string           session             = sourceIP + ":" + sourcePort;
                string           ntlmChallenge       = "";
                int              ntlmStage           = 0;
                bool             proxyIgnoreMatch    = false;
                bool             wpadAuthIgnoreMatch = false;
                NetworkStream    tcpStream           = null;
                NetworkStream    httpStream          = null;
                SslStream        httpsStream         = null;
                X509Certificate2 certificate         = null;
                bool             isClientClose       = false;

                if (type.Equals("HTTPS"))
                {
                    byte[] certificateData = Convert.FromBase64String(Cert);
                    certificate = new X509Certificate2(certificateData, CertPassword, X509KeyStorageFlags.MachineKeySet);
                    tcpStream   = tcpClient.GetStream();
                    httpsStream = new SslStream(tcpStream, false);
                }
                else
                {
                    httpStream = tcpClient.GetStream();
                }

                while (tcpClient.Connected && isRunning)
                {
                    byte[] requestData = new byte[16384];

                    if (type.Equals("HTTPS"))
                    {
                        do
                        {
                            Thread.Sleep(100);
                        }while (!tcpStream.DataAvailable && tcpClient.Connected);
                    }
                    else
                    {
                        do
                        {
                            Thread.Sleep(100); // todo check
                        }while (!httpStream.DataAvailable && tcpClient.Connected);
                    }

                    if (String.Equals(type, "HTTPS"))
                    {
                        try
                        {
                            if (!httpsStream.IsAuthenticated)
                            {
                                httpsStream.AuthenticateAsServer(certificate, false, tls12, false);
                            }

                            while (tcpStream.DataAvailable)
                            {
                                httpsStream.Read(requestData, 0, requestData.Length);
                            }
                        }
                        catch (Exception ex)
                        {
                            if (!ex.Message.Contains("A call to SSPI failed, see inner exception.")) // todo check
                            {
                                Console.WriteLine(ex.Message);
                            }
                        }
                    }
                    else
                    {
                        while (httpStream.DataAvailable)
                        {
                            httpStream.Read(requestData, 0, requestData.Length);
                        }
                    }

                    HTTPRequest request = new HTTPRequest();

                    if (!Utilities.ArrayIsNullOrEmpty(requestData))
                    {
                        request.ReadBytes(requestData, 0);
                    }

                    if (!string.IsNullOrEmpty(request.Method))
                    {
                        OutputRequestMethod(type, listenerPort, sourceIP, sourcePort, request.URI, request.Method);
                    }

                    if (!string.IsNullOrEmpty(request.URI))
                    {
                        OutputHostHeader(type, listenerPort, sourceIP, sourcePort, request.Host);
                    }

                    if (!string.IsNullOrEmpty(request.UserAgent))
                    {
                        OutputUserAgent(type, listenerPort, sourceIP, sourcePort, request.UserAgent);
                    }

                    if (!string.IsNullOrEmpty(request.Method) && Array.Exists(supportedMethods, element => element == request.Method))
                    {
                        HTTPResponse response = new HTTPResponse
                        {
                            Version       = "HTTP/1.1",
                            StatusCode    = "401",
                            ReasonPhrase  = "Unauthorized",
                            Connection    = "close",
                            Server        = "Microsoft-HTTPAPI/2.0",
                            Date          = DateTime.Now.ToString("R"),
                            ContentType   = "text/html",
                            ContentLength = "0"
                        };

                        if (!Utilities.ArrayIsNullOrEmpty(IgnoreAgents) && WPADAuth.Equals("NTLM"))
                        {
                            foreach (string agent in IgnoreAgents)
                            {
                                if (request.UserAgent.ToUpper().Contains(agent.ToUpper()))
                                {
                                    wpadAuthIgnoreMatch = true;
                                }
                            }

                            if (wpadAuthIgnoreMatch)
                            {
                                OutputIgnore(type, listenerPort, sourceIP, sourcePort, "switching wpad.dat auth to anonymous due to user agent match"); // todo make better
                            }
                        }

                        if (type.Equals("Proxy"))
                        {
                            response.StatusCode        = "407";
                            response.ProxyAuthenticate = "NTLM";
                            response.WWWAuthenticate   = "";
                            response.Connection        = "close";
                        }
                        else if (EnabledWebDAV && request.Method.Equals("PROPFIND") && WebDAVAuth.StartsWith("NTLM"))
                        {
                            response.WWWAuthenticate = "NTLM";
                        }
                        else if (EnabledWebDAV && request.Method.Equals("PROPFIND") && WebDAVAuth.Equals("BASIC"))
                        {
                            response.WWWAuthenticate = string.Concat("Basic realm=", HTTPRealm);
                        }
                        else if (!string.Equals(request.URI, "/wpad.dat") && string.Equals(HTTPAuth, "ANONYMOUS") || string.Equals(request.URI, "/wpad.dat") && string.Equals(WPADAuth, "ANONYMOUS") || wpadAuthIgnoreMatch ||
                                 (EnabledWebDAV && request.Method.Equals("OPTIONS")))
                        {
                            response.StatusCode   = "200";
                            response.ReasonPhrase = "OK";
                        }
                        else if ((HTTPAuth.StartsWith("NTLM") && !string.Equals(request.URI, "/wpad.dat")) || (WPADAuth.StartsWith("NTLM") && string.Equals(request.URI, "/wpad.dat")))
                        {
                            response.WWWAuthenticate = "NTLM";
                        }
                        else if ((string.Equals(HTTPAuth, "BASIC") && !string.Equals(request.URI, "/wpad.dat")) || (string.Equals(WPADAuth, "BASIC") && string.Equals(request.URI, "/wpad.dat")))
                        {
                            response.WWWAuthenticate = string.Concat("Basic realm=", HTTPRealm);
                        }

                        if (!string.IsNullOrEmpty(request.Authorization) && (request.Authorization.ToUpper().StartsWith("NTLM ") || request.Authorization.ToUpper().StartsWith("NEGOTIATE ")) || (!string.IsNullOrEmpty(request.ProxyAuthorization)) && request.ProxyAuthorization.ToUpper().StartsWith("NTLM "))
                        {
                            string authorization = request.Authorization;

                            if (!string.IsNullOrEmpty(request.ProxyAuthorization))
                            {
                                authorization = request.ProxyAuthorization;
                            }

                            NTLMNegotiate ntlm = new NTLMNegotiate();
                            ntlm.ReadBytes(Convert.FromBase64String(request.Authorization.Split(' ')[1]), 0);

                            if (ntlm.MessageType == 1)
                            {
                                byte[]        timestamp     = BitConverter.GetBytes(DateTime.Now.ToFileTime());
                                NTLMChallenge challenge     = new NTLMChallenge(Challenge, NetbiosDomain, ComputerName, DNSDomain, ComputerName, DNSDomain);
                                byte[]        challengeData = challenge.GetBytes(ComputerName);
                                ntlmChallenge = BitConverter.ToString(challenge.ServerChallenge).Replace("-", "");
                                string sessionTimestamp = BitConverter.ToString(timestamp).Replace("-", "");
                                httpSessionTable[sessionTimestamp] = ntlmChallenge;
                                OutputChallenge(type, listenerPort, sourceIP, sourcePort, ntlmChallenge);

                                if (String.Equals(type, "Proxy"))
                                {
                                    response.StatusCode        = "407";
                                    response.ProxyAuthenticate = "NTLM " + Convert.ToBase64String(challengeData);
                                }
                                else
                                {
                                    if (request.Authorization.ToUpper().StartsWith("NEGOTIATE "))
                                    {
                                        response.WWWAuthenticate = "Negotiate " + Convert.ToBase64String(challengeData);
                                    }
                                    else
                                    {
                                        response.WWWAuthenticate = "NTLM " + Convert.ToBase64String(challengeData);
                                    }
                                }

                                response.Connection = "";
                            }
                            else if (ntlm.MessageType == 3)
                            {
                                response.StatusCode   = "200";
                                response.ReasonPhrase = "OK";
                                ntlmStage             = 3;
                                isClientClose         = true;
                                NTLMResponse ntlmResponse     = new NTLMResponse(Convert.FromBase64String(authorization.Split(' ')[1]), false);
                                string       domain           = Encoding.Unicode.GetString(ntlmResponse.DomainName);
                                string       user             = Encoding.Unicode.GetString(ntlmResponse.UserName);
                                string       host             = Encoding.Unicode.GetString(ntlmResponse.Workstation);
                                string       ntlmResponseHash = BitConverter.ToString(ntlmResponse.NtChallengeResponse).Replace("-", "");
                                string       lmResponseHash   = BitConverter.ToString(ntlmResponse.LmChallengeResponse).Replace("-", "");

                                if (string.IsNullOrEmpty(ntlmChallenge)) // NTLMv2 workaround to track sessions over different ports without a cookie
                                {
                                    try
                                    {
                                        byte[] timestamp = new byte[8];
                                        Buffer.BlockCopy(ntlmResponse.NtChallengeResponse, 24, timestamp, 0, 8);
                                        string sessionTimestamp = BitConverter.ToString(timestamp).Replace("-", "");
                                        ntlmChallenge = httpSessionTable[sessionTimestamp].ToString();
                                    }
                                    catch
                                    {
                                        ntlmChallenge = "";
                                    }
                                }

                                OutputNTLM(type, listenerPort, sourceIP, sourcePort, user, domain, host, ntlmChallenge, ntlmResponseHash, lmResponseHash);

                                if (type.Equals("Proxy"))
                                {
                                    if (!string.IsNullOrEmpty(HTTPResponse))
                                    {
                                        response.CacheControl = "no-cache, no-store";
                                    }
                                }
                            }
                        }
                        else if (!string.IsNullOrEmpty(request.Authorization) && request.Authorization.ToUpper().StartsWith("BASIC "))
                        {
                            response.StatusCode   = "200";
                            response.ReasonPhrase = "OK";
                            string httpHeaderAuthorizationBase64 = request.Authorization.Substring(6, request.Authorization.Length - 6);
                            string cleartextCredentials          = Encoding.UTF8.GetString(Convert.FromBase64String(httpHeaderAuthorizationBase64));
                            OutputCleartext(type, listenerPort, sourceIP, sourcePort, cleartextCredentials);
                        }

                        if (!string.IsNullOrEmpty(WPADResponse) && !proxyIgnoreMatch && string.Equals(request.URI, "/wpad.dat"))
                        {
                            response.ContentType = "application/x-ns-proxy-autoconfig";
                            response.Message     = Encoding.UTF8.GetBytes(WPADResponse);
                        }
                        else if (!string.IsNullOrEmpty(HTTPResponse))
                        {
                            response.Message = Encoding.UTF8.GetBytes(HTTPResponse);
                        }

                        if (EnabledWebDAV)
                        {
                            if (request.Method.Equals("OPTIONS"))
                            {
                                response.StatusCode   = "200";
                                response.ReasonPhrase = "OK";
                                response.Allow        = "OPTIONS, TRACE, GET, HEAD, POST, COPY, PROPFIND, LOCK, UNLOCK";
                                response.Public       = "OPTIONS, TRACE, GET, HEAD, POST, PROPFIND, PROPPATCH, MKCOL, PUT, DELETE, COPY, MOVE, LOCK, UNLOCK";
                                response.DAV          = "1,2,3";
                                response.Author       = "DAV";
                            }
                            else if (request.Method.Equals("PROPFIND"))
                            {
                                DateTime currentTime = DateTime.Now;
                                response.Message    = Encoding.UTF8.GetBytes("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\"http://www.w3.org/TR/html4/strict.dtd\">\r\n<HTML><HEAD><TITLE>Not Authorized</TITLE>\r\n<META HTTP-EQUIV=\"Content-Type\" Content=\"text/html; charset=us-ascii\"></HEAD>\r\n<BODY><h2>Not Authorized</h2>\r\n<hr><p>HTTP Error 401. The requested resource requires user authentication.</p>\r\n</BODY></HTML>\r\n");
                                response.Connection = "";

                                if (ntlmStage == 3 || (!string.IsNullOrEmpty(request.Authorization) && request.Authorization.ToUpper().StartsWith("BASIC ")) || HTTPAuth.Equals("ANONYMOUS"))
                                {
                                    response.Connection = "close";

                                    if (!request.URI.Contains("."))
                                    {
                                        response.ContentType = "text/xml";
                                        response.Message     = Encoding.UTF8.GetBytes("<?xml version=\"1.0\" encoding=\"utf-8\"?><D:multistatus xmlns:D=\"DAV:\"><D:response><D:href>http://" + sourceIP + request.URI + "</D:href><D:propstat><D:status>HTTP/1.1 200 OK</D:status><D:prop><D:getcontenttype/><D:getlastmodified>" + currentTime.ToString("R") + "</D:getlastmodified><D:lockdiscovery/><D:ishidden>0</D:ishidden><D:supportedlock><D:lockentry><D:lockscope><D:exclusive/></D:lockscope><D:locktype><D:write/></D:locktype></D:lockentry><D:lockentry><D:lockscope><D:shared/></D:lockscope><D:locktype><D:write/></D:locktype></D:lockentry></D:supportedlock><D:getetag/><D:displayname>webdav</D:displayname><D:getcontentlanguage/><D:getcontentlength>0</D:getcontentlength><D:iscollection>1</D:iscollection><D:creationdate>" + currentTime.ToString("yyyy-MM-ddThh:mm:ss.fffZ") + "</D:creationdate><D:resourcetype><D:collection/></D:resourcetype></D:prop></D:propstat></D:response></D:multistatus>");
                                    }
                                    else
                                    {
                                        response.ContentType = "text/plain";
                                    }
                                }
                            }
                        }

                        byte[] buffer = response.GetBytes();

                        if (type.Equals("HTTPS") && httpsStream.CanRead)
                        {
                            httpsStream.Write(buffer, 0, buffer.Length);
                            httpsStream.Flush();
                        }
                        else if (httpStream.CanRead)
                        {
                            httpStream.Write(buffer, 0, buffer.Length);
                            httpStream.Flush();
                        }

                        if (isClientClose)
                        {
                            if (type.Equals("Proxy"))
                            {
                                tcpClient.Client.Close();
                            }
                            else
                            {
                                tcpClient.Close();
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                OutputError(ex, type, port);
            }
        }
Example #3
0
        internal void ReceiveClient(object parameters)
        {
            object[]      parameterArray = parameters as object[];
            TcpClient     tcpClient      = (TcpClient)parameterArray[0];
            int           port           = (int)parameterArray[1];
            NetworkStream tcpStream      = tcpClient.GetStream();
            string        ntlmChallenge  = "";
            string        clientIP       = ((IPEndPoint)(tcpClient.Client.RemoteEndPoint)).Address.ToString();
            string        clientPort     = ((IPEndPoint)(tcpClient.Client.RemoteEndPoint)).Port.ToString();
            string        listenerPort   = ((IPEndPoint)(tcpClient.Client.LocalEndPoint)).Port.ToString();

            try
            {
                while (tcpClient.Connected && isRunning)
                {
                    byte[] requestData = new byte[4096];

                    do
                    {
                        Thread.Sleep(100);
                    }while (!tcpStream.DataAvailable && tcpClient.Connected);

                    while (tcpStream.DataAvailable)
                    {
                        tcpStream.Read(requestData, 0, requestData.Length);
                    }

                    LDAPMessage message = new LDAPMessage();
                    message.Decode(requestData);
                    LDAPMessage message2 = new LDAPMessage();
                    message2.MessageID = message.MessageID;
                    byte[] buffer = new byte[0];
                    OutputConnection(listenerPort, clientIP, clientPort, message.Tag);

                    if (message.Tag == 3)
                    {
                        LDAPMessage message3 = new LDAPMessage();
                        message3.MessageID = message.MessageID;
                        LDAPSearchRequest searchRequest = new LDAPSearchRequest();
                        searchRequest.ReadBytes((byte[][])message.ProtocolOp);

                        LDAPSearchResDone resdone = new LDAPSearchResDone();
                        resdone.ResultCode = 0;
                        LDAPSearchResEntry search = new LDAPSearchResEntry();

                        if (String.Equals(searchRequest.Attributes[0], "supportedCapabilities"))
                        {
                            LDAPSupportedCapabilities cap = new LDAPSupportedCapabilities();
                            search.Attributes = cap.Encode();
                        }
                        else if (String.Equals(searchRequest.Attributes[0], "supportedSASLMechanisms"))
                        {
                            LDAPSupportedSASLMechanisms mech = new LDAPSupportedSASLMechanisms();
                            search.Attributes = mech.Encode();
                        }

                        message2.ProtocolOp = search;
                        message3.ProtocolOp = resdone;
                        buffer = Utilities.BlockCopy(message2.Encode(4), message3.Encode(5));
                    }
                    else if (message.Tag == 0)
                    {
                        LDAPBindRequest bind = new LDAPBindRequest();
                        bind.ReadBytes((byte[][])message.ProtocolOp);
                        LDAPSaslCredentials sasl = new LDAPSaslCredentials();
                        sasl.ReadBytes(bind.Authentication);
                        NTLMNegotiate ntlm = new NTLMNegotiate();
                        ntlm.ReadBytes(sasl.Credentials, 0);

                        if (ntlm.MessageType == 1)
                        {
                            NTLMChallenge challenge     = new NTLMChallenge(Challenge, NetbiosDomain, ComputerName, DNSDomain, ComputerName, DNSDomain);
                            byte[]        challengeData = challenge.GetBytes(ComputerName);
                            ntlmChallenge = BitConverter.ToString(challenge.ServerChallenge).Replace("-", "");

                            LDAPBindResponse bindResponse = new LDAPBindResponse
                            {
                                ServerSaslCreds = challengeData
                            };

                            LDAPMessage bindMessage = new LDAPMessage
                            {
                                MessageID  = message.MessageID,
                                ProtocolOp = bindResponse
                            };

                            buffer = bindMessage.Encode(3);
                            OutputChallenge(listenerPort, clientIP, clientPort, ntlmChallenge);
                        }
                        else if (ntlm.MessageType == 3)
                        {
                            NTLMResponse ntlmResponse = new NTLMResponse(sasl.Credentials, false);
                            string       domain       = Encoding.Unicode.GetString(ntlmResponse.DomainName);
                            string       user         = Encoding.Unicode.GetString(ntlmResponse.UserName);
                            string       host         = Encoding.Unicode.GetString(ntlmResponse.Workstation);
                            string       response2    = BitConverter.ToString(ntlmResponse.NtChallengeResponse).Replace("-", "");
                            string       lmResponse   = BitConverter.ToString(ntlmResponse.LmChallengeResponse).Replace("-", "");
                            OutputNTLM("LDAP", listenerPort, clientIP, clientPort, user, domain, host, ntlmChallenge, response2, lmResponse);
                        }
                    }

                    tcpStream.Write(buffer, 0, buffer.Length);
                    tcpStream.Flush();
                }
            }
            catch (Exception ex)
            {
                OutputError(ex, port);
            }
        }
        internal static void ProcessSMB(byte[] data, string clientIP, string listenerIP, string clientPort, string listenerPort)
        {
            if (data.Length >= 4)
            {
                NetBIOSSessionService requestNetBIOSSessionService = new NetBIOSSessionService(data);
                SMBHeader             smbHeader  = new SMBHeader();
                SMB2Header            smb2Header = new SMB2Header();
                int sessionServiceIndex          = 0;

                if (requestNetBIOSSessionService.Type == 0)
                {
                    sessionServiceIndex = 4;
                }

                SMBHelper helper = new SMBHelper(data, sessionServiceIndex);
                string    session;
                string    challenge;

                if (helper.Protocol[0] == 0xff)
                {
                    smbHeader.ReadBytes(data, sessionServiceIndex);
                    string flags = Convert.ToString(smbHeader.Flags, 2).PadLeft(8, '0');

                    switch (smbHeader.Command)
                    {
                    case 0x72:
                    {
                        if (String.Equals(flags.Substring(0, 1), "0"))
                        {
                            Output.Queue(String.Format("[.] [{0}] SMB1({1}) negotiation request detected from {2}:{3}", Output.Timestamp(), listenerPort, clientIP, clientPort));
                        }
                    }

                    break;

                    case 0x73:
                    {
                        if (String.Equals(flags.Substring(0, 1), "1"))
                        {
                            SMBCOMSessionSetupAndXResponse smbCOMSessionSetupAndXResponse = new SMBCOMSessionSetupAndXResponse(data, 32 + sessionServiceIndex);

                            if (smbCOMSessionSetupAndXResponse.SecurityBlobLength > 0)
                            {
                                if (!BitConverter.ToString(smbCOMSessionSetupAndXResponse.SecurityBlob).Contains("2A-86-48-86-F7-12-01-02-02"))         // kerberos
                                {
                                    NTLMHelper ntlmHelper = new NTLMHelper(smbCOMSessionSetupAndXResponse.SecurityBlob);

                                    if (ntlmHelper.Signature.StartsWith("NTLMSSP"))
                                    {
                                        if (ntlmHelper.MessageType == 2)
                                        {
                                            NTLMChallenge ntlmChallenge = new NTLMChallenge(smbCOMSessionSetupAndXResponse.SecurityBlob);
                                            session   = String.Concat(listenerIP, ":", listenerPort);
                                            challenge = BitConverter.ToString(ntlmChallenge.ServerChallenge).Replace("-", "");
                                            Program.smbSessionTable[session] = challenge;
                                            Output.Queue(string.Format("[+] [{0}] SMB({1}) NTLM challenge [{2}] sent to {3}:{4}", Output.Timestamp(), clientPort, challenge, clientIP, listenerPort));
                                        }
                                    }
                                }
                                else
                                {
                                    Output.Queue(string.Format("[.] [{0}] SMB({1}) Kerberos authentication from {2}:{3}", Output.Timestamp(), clientPort, clientIP, listenerPort));
                                }
                            }
                        }
                        else
                        {
                            SMBCOMSessionSetupAndXRequest smbCOMSessionSetupAndXRequest = new SMBCOMSessionSetupAndXRequest(data, 32 + sessionServiceIndex);

                            if (smbCOMSessionSetupAndXRequest.SecurityBlobLength > 0)
                            {
                                if (!BitConverter.ToString(smbCOMSessionSetupAndXRequest.SecurityBlob).Contains("2A-86-48-86-F7-12-01-02-02"))         // kerberos
                                {
                                    NTLMHelper ntlmHelper = new NTLMHelper(smbCOMSessionSetupAndXRequest.SecurityBlob);

                                    if (ntlmHelper.Signature.StartsWith("NTLMSSP"))
                                    {
                                        if (ntlmHelper.MessageType == 3)
                                        {
                                            NTLMResponse ntlmResponse = new NTLMResponse(smbCOMSessionSetupAndXRequest.SecurityBlob);
                                            session   = String.Concat(clientIP, ":", clientPort);
                                            challenge = Program.smbSessionTable[session]?.ToString();
                                            string domain     = Encoding.Unicode.GetString(ntlmResponse.DomainName);
                                            string user       = Encoding.Unicode.GetString(ntlmResponse.UserName);
                                            string host       = Encoding.Unicode.GetString(ntlmResponse.Workstation);
                                            string response   = BitConverter.ToString(ntlmResponse.NtChallengeResponse).Replace("-", "");
                                            string lmResponse = BitConverter.ToString(ntlmResponse.LmChallengeResponse).Replace("-", "");
                                            Output.NTLMOutput(user, domain, challenge, response, clientIP, host, "SMB", listenerPort, clientPort, lmResponse);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break;
                    }
                }
                else if (helper.Protocol[0] == 0xfe)
                {
                    smb2Header.ReadBytes(data, sessionServiceIndex);
                    string flags = Convert.ToString(BitConverter.ToUInt16(smb2Header.Flags, 0), 2).PadLeft(smb2Header.Flags.Length * 8, '0');

                    switch (smb2Header.Command)
                    {
                    case 0:
                    {
                        if (String.Equals(flags.Substring(31, 1), "0"))
                        {
                            Output.Queue(String.Format("[.] [{0}] SMB2+({1}) negotiation request detected from {2}:{3}", Output.Timestamp(), listenerPort, clientIP, clientPort));
                        }
                    }
                    break;

                    case 1:
                    {
                        if (String.Equals(flags.Substring(31, 1), "1"))
                        {
                            SMB2SessionSetupResponse smb2SessionSetupResponse = new SMB2SessionSetupResponse(data, 64 + sessionServiceIndex);

                            if (smb2SessionSetupResponse.SecurityBufferLength > 0)
                            {
                                if (!BitConverter.ToString(smb2SessionSetupResponse.Buffer).Contains("2A-86-48-86-F7-12-01-02-02"))         // kerberos
                                {
                                    NTLMHelper ntlmHelper = new NTLMHelper(smb2SessionSetupResponse.Buffer);

                                    if (ntlmHelper.Signature.StartsWith("NTLMSSP"))
                                    {
                                        if (ntlmHelper.MessageType == 2)
                                        {
                                            NTLMChallenge ntlmChallenge = new NTLMChallenge(smb2SessionSetupResponse.Buffer);
                                            session   = BitConverter.ToString(smb2Header.SessionId).Replace("-", "");
                                            challenge = BitConverter.ToString(ntlmChallenge.ServerChallenge).Replace("-", "");
                                            Program.smbSessionTable[session] = challenge;
                                            Output.Queue(String.Format("[+] [{0}] SMB({1}) NTLM challenge [{2}] sent to {3}:{4}", Output.Timestamp(), clientPort, challenge, clientIP, listenerPort));
                                        }
                                    }
                                }
                                else
                                {
                                    Output.Queue(string.Format("[.] [{0}] SMB({1}) Kerberos authentication from {2}:{3}", Output.Timestamp(), clientPort, clientIP, listenerPort));
                                }
                            }
                        }
                        else
                        {
                            SMB2SessionSetupRequest smb2SessionSetupRequest = new SMB2SessionSetupRequest(data, 64 + sessionServiceIndex);

                            if (smb2SessionSetupRequest.SecurityBufferLength > 0)
                            {
                                if (!BitConverter.ToString(smb2SessionSetupRequest.Buffer).Contains("2A-86-48-86-F7-12-01-02-02"))         // kerberos
                                {
                                    NTLMHelper ntlmHelper = new NTLMHelper(smb2SessionSetupRequest.Buffer);

                                    if (ntlmHelper.Signature.StartsWith("NTLMSSP"))
                                    {
                                        if (ntlmHelper.MessageType == 3)
                                        {
                                            NTLMResponse ntlmResponse = new NTLMResponse(smb2SessionSetupRequest.Buffer);
                                            session   = BitConverter.ToString(smb2Header.SessionId).Replace("-", "");
                                            challenge = Program.smbSessionTable[session]?.ToString();
                                            string domain     = Encoding.Unicode.GetString(ntlmResponse.DomainName);
                                            string user       = Encoding.Unicode.GetString(ntlmResponse.UserName);
                                            string host       = Encoding.Unicode.GetString(ntlmResponse.Workstation);
                                            string response   = BitConverter.ToString(ntlmResponse.NtChallengeResponse).Replace("-", "");
                                            string lmResponse = BitConverter.ToString(ntlmResponse.LmChallengeResponse).Replace("-", "");
                                            Output.NTLMOutput(user, domain, challenge, response, clientIP, host, "SMB", listenerPort, clientPort, lmResponse);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break;
                    }
                }
            }
        }