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;
 }
Exemplo n.º 2
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);
        }
Exemplo n.º 3
0
        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);
        }