public NamedPipeSniffer(ChromeMonitor chromeMonitor, string wiresharkPipeName, string nameFilter = "", bool recordOnlyNewMojoPipes = false) { this.wiresharkSender = new WiresharkSender(wiresharkPipeName, 1); this.namedPipeFiles = new Dictionary <string, NamedPipeInfo>(); this.destoryedNamedPipes = new List <string>(); this.chromeMonitor = chromeMonitor; this.recordingOnlyNewMojoPipes = recordOnlyNewMojoPipes; this.pipeNameFilter = nameFilter; this.lastDropTime = DateTime.Now; this.numPacketsProcessed = 0; }
/// <summary> /// Downloads and analyses the legacy IPC files from the chromium git repository, /// in case a cache does not exist /// </summary> /// <param name="force"></param> /// <returns>The cached interfaces chromium verison</returns> public static string UpdateInterfacesInfoIfNeeded(string chromeVersion, bool force = false) { if (!force) { Console.WriteLine("[+] Checking legacy IPC interfaces information"); if (File.Exists(CACHE_FILENAME)) { dynamic interfaceInfo = JsonConvert.DeserializeObject(File.ReadAllText(CACHE_FILENAME)); string cachedVersion = interfaceInfo["metadata"]["version"]; return(cachedVersion); } } string commit = ChromeMonitor.GetCommitForVersion(chromeVersion); Console.WriteLine("[+] Matching commit is " + commit); DownloadAndAnalyzeLegacyIpcFiles(messageFiles, commit, chromeVersion); return(chromeVersion); }
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); }