public NamedPipeInfo DeterminePipeFromPacket(dm_NotifyHdr notificationHeader, dm_ReadWriteNotifyParams writeParams) { UInt64 fileObject = writeParams.fileIdentifier; // Search for the pipe by the file object List <NamedPipeInfo> matchingPipes = namedPipeFiles.Values.Where((x) => x.FileObjects.Contains(fileObject)).ToList(); if (matchingPipes.Count == 1) { return(matchingPipes[0]); } if (destoryedNamedPipes.Contains(fileObject.ToString("X"))) { return(null); } if (matchingPipes.Count == 0) { // We didn't see this file object before. if (this.recordingOnlyNewMojoPipes) { // are we missing create packets? // we probably do, because we can't read fast enough. throw new Exception("I will not suffer inconsistencies."); } // // Try to get the pipe name from the file object // string pipeName = HandlesUtility.GetFilePathFromFileObject(new IntPtr((long)fileObject)); if (pipeName != null && pipeName.Contains(@"\Device\NamedPipe")) { pipeName = pipeName.Substring(@"\Device\NamedPipe".Length); if (!namedPipeFiles.ContainsKey(pipeName)) { // We don't know this pipe // create it then namedPipeFiles[pipeName] = new NamedPipeInfo(fileObject, pipeName, notificationHeader.processId); } return(namedPipeFiles[pipeName]); } else { // either the pipe does not exist anymore, or its handle was closed, or NtQueryObject got hang } } else { // this file object must be dead, because it's used in two pipes throw new Exception("I will not suffer inconsistencies."); } //Console.WriteLine("[-] Could not find pipe name for " + fileObject.ToString("X")); destoryedNamedPipes.Add(fileObject.ToString("X")); return(null); }
static void Main(string[] args) { Console.WriteLine(); Console.WriteLine("Chrome IPC Sniffer v" + Assembly.GetExecutingAssembly().GetName().Version.ToString()); Console.WriteLine(); // // Parse the arguments // bool onlyNewPipes = false; bool forceFetchInterfacesInfo = false; bool forceExtractMethodNames = false; bool onlyMojo = false; foreach (string argument in args) { if (argument.Contains("--update-interfaces-info")) { forceFetchInterfacesInfo = true; forceExtractMethodNames = true; } else if (argument.Contains("--only-new-mojo-pipes")) { onlyNewPipes = true; } else if (argument.Contains("--extract-method-names")) { forceExtractMethodNames = true; } else if (argument.Contains("--only-mojo")) { onlyMojo = true; } else if (argument.Contains("-h") || argument.Contains("--help") || argument.Contains("/?")) { ShowUsage(); return; } else { Console.WriteLine("[!] Unrecognized argument '{0}'", argument); return; } } Console.WriteLine("Type -h to get usage help and extended options"); Console.WriteLine(); Console.WriteLine("[+] Starting up"); // // Prepare // ChromeMonitor chromeMonitor = new ChromeMonitor(); string mojoVersion = MojoInterfacesFetcher.UpdateInterfacesInfoIfNeeded(chromeMonitor.ChromeVersion, force: forceFetchInterfacesInfo); string legacyIpcversion = LegacyIpcInterfacesFetcher.UpdateInterfacesInfoIfNeeded(chromeMonitor.ChromeVersion, force: forceFetchInterfacesInfo); if (mojoVersion != chromeMonitor.ChromeVersion || legacyIpcversion != chromeMonitor.ChromeVersion) { Console.WriteLine("[!] Cached info is for " + mojoVersion + ", you may run --update-interfaces-info"); } MojoMethodHashesExtractor.ExtractMethodNames(chromeMonitor.DLLPath, force: forceExtractMethodNames); bool success = UpdateWiresharkConfiguration(); if (!success) { return; } Console.WriteLine("[+] Enumerating existing chrome pipes"); HandlesUtility.EnumerateExistingHandles(ChromeMonitor.GetRunningChromeProcesses()); // // Start sniffing // string outputPipeName = "chromeipc"; string outputPipePath = @"\\.\pipe\" + outputPipeName; Console.WriteLine("[+] Starting sniffing of chrome named pipe to " + outputPipePath + "."); NamedPipeSniffer pipeMonitor = new NamedPipeSniffer(chromeMonitor, outputPipeName, onlyMojo ? "mojo" : "", onlyNewPipes); bool isMonitoring = pipeMonitor.Start(); if (isMonitoring) { if (Process.GetProcessesByName("Wireshark").Length == 0) { Console.WriteLine("[+] Opening Wirehark"); Process.Start(@"C:\Program Files\Wireshark\Wireshark.exe", "-k -i " + outputPipePath); } Console.WriteLine("[+] Capturing packets..."); } // // Set up clean up routines // Console.CancelKeyPress += delegate { Thread.CurrentThread.IsBackground = false; pipeMonitor.Stop(); }; }
public void OnReadWritePacketReceived(dm_NotifyHdr notificationHeader, dm_ReadWriteNotifyParams writeParams, byte[] data, bool isWriting) { UInt64 fileObject = writeParams.fileIdentifier; UInt32 processId = notificationHeader.processId; if (!chromeMonitor.IsChromeProcess(processId)) { return; } // Find out on which pipe this packet was sent NamedPipeInfo pipe = DeterminePipeFromPacket(notificationHeader, writeParams); string pipeName = pipe != null ? pipe.PipeFileName : "<Unknown " + fileObject.ToString("X") + ">"; if (pipe != null) { // Update this pipe's information namedPipeFiles[pipeName].AddProcessIfNeeded(processId); namedPipeFiles[pipeName].AddFileObjectIfNeeded(fileObject); } if (!pipeName.Contains(this.pipeNameFilter)) { return; } // // Find out what is the destination process of this packet // UInt32 destinationPID = 0; if (pipe != null) { if (pipe.InvolvedProcesses.Count < 2 && !destoryedNamedPipes.Contains(pipe.PipeFileName)) { // // try to find the destination process using Windows handle query // List <int> legalPIDs = ChromeMonitor.GetRunningChromeProcesses().Select(process => process.Id).ToList(); string fullPipePath = @"\Device\NamedPipe" + pipe.PipeFileName; namedPipeFiles[pipeName].InvolvedProcesses = HandlesUtility.GetProcessesUsingFile(fullPipePath, legalPIDs); if (namedPipeFiles[pipeName].InvolvedProcesses.Count < 2) { // TODO: because we are doing heavy caching on the handle information, // it happens sometimes that we reach here but the pipe actually is in fact valid. //Console.WriteLine("[-] Could not find destination PID for " + pipeName); destoryedNamedPipes.Add(pipe.PipeFileName); } } if (pipe.InvolvedProcesses.Count >= 2) { List <uint> involvedProcesses = pipe.InvolvedProcesses.ToList(); involvedProcesses.Remove(notificationHeader.processId); destinationPID = involvedProcesses.Last(); } } if (!isWriting) { return; } if (data.Length == 0) { return; } // // Send it off // this.numPacketsProcessed++; byte[] wiresharkPacket = GenerateWiresharkPacket(notificationHeader, writeParams, pipeName, destinationPID, data); wiresharkSender.SendToWiresharkAsEthernet(wiresharkPacket, 0); }