public static void Process(NetworkTrace trace) { foreach (ConversationData c in trace.conversations) { if (c.sourcePort == 88) { TDSParser.reverseSourceDest(c); } if (c.destPort != 88) { continue; } KerberosData KerbData = null; try { if (c.isUDP) // UDP { KerbData = ProcessUDP(c); } else // TCP { KerbData = ProcessTCP(c); } // ignore non KRB_TGS requests // ignore responses without an associated request - we don't want to log errors for unidentified request types // ignore SNames we don't know what they are ... or how to read them //if (KerbData.RequestType == MessageTypes.KRB_TGS_REQ // && (KerbData.SNameType == 2 || KerbData.SNameType == 10)) if (KerbData.RequestType == MessageTypes.KRB_TGS_REQ) { trace.KerbResponses.Add(KerbData); } } catch (Exception ex) { Console.WriteLine("Exception during Kerberos processing." + "\r\n" + ex.Message + "\r\n" + ex.StackTrace); Program.logDiagnostic("Exception during Kerberos processing." + "\r\n" + ex.Message + "\r\n" + ex.StackTrace); } // catch } // foreach } // void Process(...)
static void Main(string[] args) { string fileSpec = null; string outFile = null; string diagOutFile = null; string statOutFile = null; ArrayList sqlHints = new ArrayList(); ActivityTimer T = new ActivityTimer(); // // Set command-line rules and parse the command-line // CommandLineParser cp = new CommandLineParser(); cp.AddRule(new ArgRule("", true, false, true, true)); // file name is required cp.AddRule(new ArgRule("output", true, false, true, false)); // -output filename is optional and case-insensitive, one time only cp.AddRule(new ArgRule("sql", true, true, false, false)); // -sql 10:10:10:10,1433 -sql 10.10.10.11,1433 ... -sql ip,port 0..n times (ipv4 or ipv6) cp.AddRule(new ArgRule("convList", false, false, true, false)); // -convList outputs a rather lengthy report segment that is normally not required cp.AddRule(new ArgRule("filterFmt", true, false, true, false)); // -filterFmt NETMON|WireShark replaces the Client IP address and port columns with a filter string, instead string ruleViolation = cp.Parse(args); if (ruleViolation != "") { Console.WriteLine("Bad arguments: " + ruleViolation); displayUsage(); return; // exit the application } else // for case-insensitive argument names, use lower-case to match { ArrayList values = null; // // set filename -> fileSpec // values = cp.GetArgs(""); fileSpec = ((CommandLineArgs)values[0]).value; // required, so it's here or we'd get a ruleViolation earlier // // set outputFile -> outFile // values = cp.GetArgs("output"); if (values.Count != 0) // argument supplied { outFile = ((CommandLineArgs)values[0]).value; } else // argument omitted { outFile = utility.getLogFileName(fileSpec); } diagOutFile = utility.getDiagLogFileName(outFile); statOutFile = utility.getStatLogFileName(outFile); // // set sqlHints // values = cp.GetArgs("sql"); if (values.Count != 0) // argument supplied { foreach (CommandLineArgs value in values) { sqlHints.Add(value.value); } } // // set outputConversationList // values = cp.GetArgs("convlist"); if (values.Count != 0) { outputConversationList = true; } // // set filterFormat // values = cp.GetArgs("filterfmt"); if (values.Count != 0) { string value = ((CommandLineArgs)values[0]).value.ToUpper(); switch (value) { case "NETMON": { filterFormat = "N"; break; } case "WIRESHARK": { filterFormat = "W"; break; } case "AUTO": { filterFormat = "A"; // gets set to N or W based on the file type of the first file opened break; } default: { Console.WriteLine("Bad arguments: filterFmt"); displayUsage(); return; // exit the application } } } } commandLine = string.Join(" ", args); try { diagFile = new StreamWriter(diagOutFile); // output diagnostic header logDiagnostic("SQL Server Network Analyzer " + VERSION_NUMBER); logDiagnostic("Command line arguments: " + string.Join(" ", args)); logDiagnostic("Analysis run on: " + DateTime.Now.ToString(utility.DATE_FORMAT)); // open log file CurrentActivity = "opening log file: " + outFile; logFile = new StreamWriter(outFile); NetworkTrace Trace = new NetworkTrace(); // add SQL hints foreach (string value in sqlHints) { bool isIPV6 = false; ushort port = 0; uint ipv4 = 0; ulong ipv6hi = 0, ipv6lo = 0; utility.ParseIPPortString(value, ref isIPV6, ref port, ref ipv4, ref ipv6hi, ref ipv6lo); Trace.GetSQLServer(ipv4, ipv6hi, ipv6lo, port, isIPV6); // creates an entry in the SQl Server table if not one already - allows for duplicate -sql command-line arguments } // read files and parse into memory structures CurrentActivity = "parsing input file(s) from the folder."; Parser.ParseFileSpec(fileSpec, Trace); //Post Processing CurrentActivity = "processing data."; T.start("\nReversing backward conversations"); Parser.ReverseBackwardConversations(Trace); T.stop(); T.start("Finding retransmitted packets"); Parser.FindRetransmits(Trace); T.stop(); T.start("Finding retransmitted Keep-Alive packets"); Parser.FindKeepAliveRetransmits(Trace); T.stop(); T.start("Finding continuation packets"); Parser.FindContinuationFrames(Trace); T.stop(); T.start("Parsing TDS frames"); TDSParser.ProcessTDS(Trace); T.stop(); T.start("Finding stray SQL conversations"); TDSParser.FindStraySQLConversations(Trace); T.stop(); T.start("Finding stray SQL Servers"); TDSParser.FindStraySQLServers(Trace); T.stop(); T.start("Creating packets from frames for SQL Conversations"); TDSParser.CreatingPacketsFromFrames(Trace); T.stop(); T.start("Parsing UDP frames"); SSRPParser.ProcessUDP(Trace); T.stop(); T.start("Parsing DNS frames"); NameResolutionParser.ProcessUDP(Trace); T.stop(); T.start("Parsing Kerberos frames"); //CurrentActivity = "analyzing data."; KerberosParser.Process(Trace); T.stop(); T.start("Locating Domain Controllers"); //CurrentActivity = "analyzing data."; DomainControllerParser.Process(Trace); T.stop(); //Analysis CurrentActivity = "writing report."; statFile = new StreamWriter(statOutFile); OutputText.TextReport(Trace); statFile.Close(); statFile = null; } catch (Exception ex) { Console.WriteLine("An error occurred while " + CurrentActivity + "\r\n" + ex.Message + "\r\n" + ex.StackTrace); logDiagnostic("An error occurred while " + CurrentActivity + "\r\n" + ex.Message + "\r\n" + ex.StackTrace); } finally { if (logFile != null) { logFile.Close(); } if (diagFile != null) { diagFile.Close(); } if (statFile != null) { statFile.Close(); } } }
public static void ProcessUDP(NetworkTrace trace) { foreach (ConversationData c in trace.conversations) { if (c.isUDP && c.sourcePort == 1434) { TDSParser.reverseSourceDest(c); } //parse only UDP conversations that are on port 1434 if ((!c.isUDP) || ((c.isUDP) && (c.destPort != 1434))) { continue; } SSRPData SSRPRequest = trace.GetSSRPRequest(c.destIP, c.destIPHi, c.destIPLo, c.isIPV6); if (!SSRPRequest.hasConversation(c)) { SSRPRequest.conversations.Add(c); } foreach (FrameData fd in c.frames) { try { if ((byte)(fd.payload[0]) == (byte)3) // CLNT_UCAST_EX { SSRPRequest.hasResponse = false; } else if ((byte)(fd.payload[0]) == (byte)4) // Request for specific instance (CLNT_UCAST_INST) { SSRPRequest.hasResponse = false; if (c.frames.Count == 1) { SSRPRequest.hasNoResponse = true; } ushort Length = utility.ReadUInt16(fd.payload, 1); SSRPRequest.instanceRequested = utility.ReadAnsiString(fd.payload, 3, Length); //SSRPRequest.clientPort = c.sourcePort; //SSRPRequest.clientIP = (c.isIPV6) ? utility.FormatIPV6Address(c.sourceIPHi, c.sourceIPLo) : utility.FormatIPV4Address(c.sourceIP); SSRPRequest.sqlIP = c.destIP; SSRPRequest.sqlIPHi = c.destIPHi; SSRPRequest.sqlIPLo = c.destIPLo; } else if ((byte)(fd.payload[0]) == (byte)5) // Response of specifric instance (SVR_RESP) { SSRPRequest.hasResponse = true; ushort Length = utility.ReadUInt16(fd.payload, 1); String Response = utility.ReadAnsiString(fd.payload, 3, Length); ParseSSRPResponse(Response, SSRPRequest, trace); //if (SSRPRequest.sqlPort != 0) //{ // SQLServer s = trace.GetSQLServer(SSRPRequest.sqlIP, SSRPRequest.sqlIPHi, SSRPRequest.sqlIPLo, SSRPRequest.sqlPort, SSRPRequest.isIPV6); // if (s != null) // { // if (s.sqlHostName == "") s.sqlHostName = SSRPRequest.sqlHostName; // if (s.instanceName == "") s.instanceName = SSRPRequest.instanceName; // if (s.isClustered == "") s.isClustered = SSRPRequest.isClustered; // if (s.serverVersion == "") s.serverVersion = SSRPRequest.serverVersion; // if (s.namedPipe == "") s.namedPipe = SSRPRequest.namedPipe; // } } } catch (Exception ex) { Program.logDiagnostic("SSRP Parser: Problem parsing frame " + fd.frameNo + " in file " + fd.file.filePath + "."); Program.logDiagnostic(ex.Message); } } } } // Process UDP