public override void Search() { if (!Directory.Exists(SKYPE_PATH)) return; string[] folders = Directory.GetDirectories(SKYPE_PATH, "*", SearchOption.TopDirectoryOnly); foreach (string folder in folders) { if (!File.Exists(folder + @"\main.db")) continue; //Check if it's a user folder string skypename = Path.GetFileName(folder); SearchNode node = this.AddInformation(skypename, InformationType.Title, new TitleInfo("User folder", String.Format("Contains information about the Skype user '{0}'.", skypename))); //Skype avatars string avatarpath = folder + @"\Pictures\"; if (Directory.Exists(avatarpath)) { SearchNode anode = node.AddInformation("Avatars", InformationType.Title, new TitleInfo("Avatars", "Contains current and previous avatar images."), true); string[] files = Directory.GetFiles(avatarpath, "*", SearchOption.TopDirectoryOnly); foreach (string file in files) anode.AddInformation(Path.GetFileNameWithoutExtension(file), InformationType.ImageFile, file); } //Skype downloadable media cache string mediacache = folder + @"\media_messaging\media_cache\"; if (Directory.Exists(mediacache)) { SearchNode mnode = node.AddInformation("Media cache", InformationType.Title, new TitleInfo("Media cache", "Contains downloaded image data and downloadable-image thumbnails."), true); string[] files = Directory.GetFiles(mediacache, "*.jpg", SearchOption.TopDirectoryOnly); foreach (string file in files) { if (Main.SearchCanceled) return; Match m = Regex.Match(file, @"[\da-f]{32}"); if (!m.Success || m.Groups.Count < 1) continue; mnode.AddInformation(m.Groups[0].Value, InformationType.ImageFile, file); } } string maindb = folder + @"\main.db"; if (File.Exists(maindb)) { CSQLite kvc = new CSQLite(maindb); /*QueryResult res = kvc.QuickQuery("SELECT sql FROM sqlite_master WHERE type='table'"); StringBuilder sb = new StringBuilder(); sb.Append("eas.db structure\r\n--------------------------------------------------\r\n\r\n"); foreach (object[] obj in res.Rows) sb.Append((string)obj[0] + "\r\n"); SearchNode dbnode = node.AddInformation("eas.db", InformationType.Text, sb.ToString(), true);*/ SearchNode mainnode = node.AddInformation("main.db", InformationType.Title, new TitleInfo("main.db", "Contains user data"), true); QueryResult res = kvc.QuickQuery("SELECT partner_handle,partner_dispname,starttime,finishtime,filepath,filename,filesize,convo_id FROM Transfers"); if (res.Returned > 0) { List<ListViewItem> items = new List<ListViewItem>(); foreach (object[] obj in res.Rows) { if (Main.SearchCanceled) return; string starttime = (obj[2].GetType() == typeof(DBNull) || (long)obj[2] < 1 ? "" : Program.FormatUnixTimestamp((long)obj[2], "yyyy-MM-dd H:mm:ss")); string endtime = (obj[3].GetType() == typeof(DBNull) || (long)obj[3] < 1 ? "" : Program.FormatUnixTimestamp((long)obj[3], "yyyy-MM-dd H:mm:ss")); items.Add(new ListViewItem(new string[] { obj[7].ToString(), obj[0].ToString(), obj[5].ToString(), obj[6].ToString(), obj[4].ToString(), starttime, endtime })); } TableInfo tinfo = new TableInfo(new string[] { "Conversation ID", "Partner handle", "File name", "File size", "File location", "Start time", "Finish time" }, items.ToArray()); mainnode.AddInformation("Transfers", InformationType.Table, tinfo); } } } }
static void HistorySearch(string param, CSQLite kvc, List<ListViewItem> items, Color back) { QueryResult res = kvc.QuickQuery("SELECT id,title,url,visit_count,last_visit_time FROM urls " + param); if (res.Returned > 0) { foreach (object[] obj in res.Rows) { if (Main.SearchCanceled) return; string lastvisit = (obj[4].GetType() == typeof(DBNull) || (long)obj[4] < 1 ? "" : Program.FormatChromeTimestamp((long)obj[4] / 1000000, "yyyy-MM-dd H:mm:ss")); items.Add(new ListViewItem( new string[] { obj[0].ToString(), obj[1].ToString(), obj[2].ToString(), obj[3].ToString(), lastvisit, }) { BackColor = back }); } } }
public override void Search() { if (!Directory.Exists(CHROME_PATH)) return; string[] folders = Directory.GetDirectories(CHROME_PATH, "*", SearchOption.TopDirectoryOnly); foreach (string folder in folders) { if (!File.Exists(folder + @"\History")) continue; string profile = Path.GetFileName(folder); SearchNode node = this.AddInformation(profile, InformationType.Title, new TitleInfo("Profile folder", String.Format("Contains information about the Chrome profile '{0}'.", profile))); string placesdb = folder + @"\History"; CSQLite kvc = new CSQLite(placesdb); /* History */ List<ListViewItem> items = new List<ListViewItem>(); //Yellow - TOR/TOR related HistorySearch(Program.SUSPICIOUS_TOR, kvc, items, Color.Yellow); //Red - I2P/I2P related HistorySearch(Program.SUSPICIOUS_I2P, kvc, items, Color.Red); //Purple - Drugs/darknet HistorySearch(Program.SUSPICIOUS_DARKNET, kvc, items, Color.MediumPurple); //Cyan - Torrenting/Pirating HistorySearch(Program.SUSPICIOUS_PIRATING, kvc, items, Color.Cyan); //Gray - Hacking/Cracking HistorySearch(Program.SUSPICIOUS_HACKING, kvc, items, Color.Gray); if (items.Count > 0) { TableInfo tinfo = new TableInfo(new string[] { "ID", "Title", "URL", "Visit count", "Last visit" }, items.ToArray()); node.AddInformation("Suspicious history", InformationType.Table, tinfo); } /* Downloads */ QueryResult res = kvc.QuickQuery("SELECT id,target_path,start_time,total_bytes,end_time,mime_type,original_mime_type FROM downloads"); if (res.Returned > 0) { items = new List<ListViewItem>(); foreach (object[] obj in res.Rows) { items.Add(new ListViewItem( new string[] { obj[0].ToString(), obj[1].ToString(), obj[2].ToString(), obj[3].ToString(), obj[4].ToString(), obj[5].ToString(), obj[6].ToString(), })); } TableInfo tinfo = new TableInfo(new string[] { "ID", "target_path", "start_time count", "total_bytes", "end_time", "mime_type", "original_mime_type" }, items.ToArray()); node.AddInformation("Downloads", InformationType.Table, tinfo); } res = kvc.QuickQuery("SELECT id,chain_index,url FROM downloads_url_chains"); if (res.Returned > 0) { items = new List<ListViewItem>(); foreach (object[] obj in res.Rows) { items.Add(new ListViewItem( new string[] { obj[0].ToString(), obj[1].ToString(), obj[2].ToString(), })); } TableInfo tinfo = new TableInfo(new string[] { "ID", "chain_index", "url" }, items.ToArray()); node.AddInformation("Download url chains", InformationType.Table, tinfo); } /* Web data */ //TODO: Use autofill_profiles to build a table of information rather than having it fragmented as it currenty is string webdb = folder + @"\Web Data"; if (File.Exists(webdb)) { kvc = new CSQLite(webdb); SearchNode webnode = node.AddInformation("Web data", InformationType.Title, new TitleInfo("Web data", "Contains autofill data such as names, emails, and credit card information."), true); /* Names */ items = new List<ListViewItem>(); res = kvc.QuickQuery("SELECT guid,full_name,first_name,middle_name,last_name FROM autofill_profile_names"); if (res.Returned > 0) { foreach (object[] obj in res.Rows) { items.Add(new ListViewItem( new string[] { obj[0].ToString(), obj[1].ToString(), obj[2].ToString(), obj[3].ToString(), obj[4].ToString() })); } TableInfo tinfo = new TableInfo(new string[] { "Group ID", "Full name", "First name", "Middle name", "Last name" }, items.ToArray()); webnode.AddInformation("Names", InformationType.Table, tinfo); } /* Emails */ items = new List<ListViewItem>(); res = kvc.QuickQuery("SELECT guid,email FROM autofill_profile_emails"); if (res.Returned > 0) { foreach (object[] obj in res.Rows) { items.Add(new ListViewItem( new string[] { obj[0].ToString(), obj[1].ToString() })); } TableInfo tinfo = new TableInfo(new string[] { "Group ID", "Email" }, items.ToArray()); webnode.AddInformation("Emails", InformationType.Table, tinfo); } /* Credit card information */ List<ListViewItem> ccs = new List<ListViewItem>(); res = kvc.QuickQuery("SELECT name_on_card,expiration_month,expiration_year,origin FROM credit_cards"); if (res.Returned > 0) { foreach (object[] obj in res.Rows) { items.Add(new ListViewItem( new string[] { obj[0].ToString(), "XXXX XXXX XXXX XXXX", String.Format("{0}/{1}", obj[1].ToString(), obj[2].ToString()), obj[3].ToString() })); } } res = kvc.QuickQuery("SELECT name_on_card,last_four,exp_month,exp_year FROM masked_credit_cards"); if (res.Returned > 0) { foreach (object[] obj in res.Rows) { items.Add(new ListViewItem( new string[] { obj[0].ToString(), "XXXX XXXX XXXX " + obj[1].ToString(), String.Format("{0}/{1}", obj[2].ToString(), obj[3].ToString()), "" })); } } if (ccs.Count > 0) { TableInfo tinfo = new TableInfo(new string[] { "Full name", "Number", "Exp date", "Origin" }, ccs.ToArray()); webnode.AddInformation("Credit card information", InformationType.Table, tinfo); } } } }
public override void Search() { CacheDomains.Clear(); if (!Directory.Exists(FIREFOX_PATH)) return; string[] folders = Directory.GetDirectories(FIREFOX_PATH, "*", SearchOption.TopDirectoryOnly); foreach (string folder in folders) { if (!File.Exists(folder + @"\key3.db")) continue; string profile = Path.GetFileName(folder); SearchNode node = this.AddInformation(profile, InformationType.Title, new TitleInfo("Profile folder", String.Format("Contains information about the Firefox profile '{0}'.", profile))); string cookiedb = folder + @"\cookies.sqlite"; if (File.Exists(cookiedb)) { CSQLite kvc = new CSQLite(cookiedb); QueryResult res = kvc.QuickQuery("SELECT id,baseDomain,name,value,host,path,expiry,lastAccessed,creationTime,isSecure,isHttpOnly FROM moz_cookies"); if (res.Returned > 0) { List<ListViewItem> items = new List<ListViewItem>(); foreach (object[] obj in res.Rows) { if (Main.SearchCanceled) return; string expiry = (obj[6].GetType() == typeof(DBNull) || (long)obj[6] < 1 ? "" : Program.FormatUnixTimestamp((long)obj[6], "yyyy-MM-dd H:mm:ss")); string lastaccessed = (obj[7].GetType() == typeof(DBNull) || (long)obj[7] < 1 ? "" : Program.FormatUnixTimestamp((long)obj[7] / 1000000, "yyyy-MM-dd H:mm:ss")); string creationtime = (obj[8].GetType() == typeof(DBNull) || (long)obj[8] < 1 ? "" : Program.FormatUnixTimestamp((long)obj[8] / 1000000, "yyyy-MM-dd H:mm:ss")); items.Add(new ListViewItem( new string[] { obj[0].ToString(), obj[1].ToString(), obj[2].ToString(), obj[3].ToString(), obj[4].ToString(), obj[5].ToString(), expiry, lastaccessed, creationtime, ((long)obj[9] == 1 ? "True" : "False"), ((long)obj[10] == 1 ? "True" : "False"), })); } TableInfo tinfo = new TableInfo(new string[] { "ID", "Base domain", "Name", "Value", "Host", "Path", "Expires", "Last Accessed", "Created", "Is secure", "Is HTTP Only" }, items.ToArray()); node.AddInformation("Cookies", InformationType.Table, tinfo); } } string placesdb = folder + @"\places.sqlite"; if (File.Exists(placesdb)) { CSQLite kvc = new CSQLite(placesdb); List<ListViewItem> items = new List<ListViewItem>(); //Yellow - TOR/TOR related HistorySearch(Program.SUSPICIOUS_TOR, kvc, items, Color.Yellow); //Red - I2P/I2P related HistorySearch(Program.SUSPICIOUS_I2P, kvc, items, Color.Red); //Purple - Drugs/darknet HistorySearch(Program.SUSPICIOUS_DARKNET, kvc, items, Color.MediumPurple); //Cyan - Torrenting/Pirating HistorySearch(Program.SUSPICIOUS_PIRATING, kvc, items, Color.Cyan); //Gray - Hacking/Cracking HistorySearch(Program.SUSPICIOUS_HACKING, kvc, items, Color.Gray); if (items.Count > 0) { TableInfo tinfo = new TableInfo(new string[] { "ID", "Title", "URL", "Last visit" }, items.ToArray()); node.AddInformation("Suspicious history", InformationType.Table, tinfo); } } string frmdb = folder + @"\formhistory.sqlite"; if (File.Exists(frmdb)) { CSQLite kvc = new CSQLite(frmdb); QueryResult res = kvc.QuickQuery("SELECT id,fieldname,value,firstUsed,lastUsed FROM moz_formhistory ORDER BY fieldname"); if (res.Returned > 0) { List<ListViewItem> items = new List<ListViewItem>(); foreach (object[] obj in res.Rows) { if (Main.SearchCanceled) return; string created = (obj[3].GetType() == typeof(DBNull) || (long)obj[3] < 1 ? "" : Program.FormatUnixTimestamp((long)obj[3] / 1000000, "yyyy-MM-dd H:mm:ss")); string lastused = (obj[4].GetType() == typeof(DBNull) || (long)obj[4] < 1 ? "" : Program.FormatUnixTimestamp((long)obj[4] / 1000000, "yyyy-MM-dd H:mm:ss")); Color c = Color.White; string fname = obj[1].ToString(); if (fname.Contains("name")) c = Color.Orange; else if (fname.Contains("email")) c = Color.CornflowerBlue; else if (fname.Contains("address") || fname.Contains("country") || fname.Contains("postcode") || fname.Contains("areacode")) c = Color.Red; items.Add(new ListViewItem( new string[] { obj[0].ToString(), obj[1].ToString(), obj[2].ToString(), created, lastused, }) { BackColor = c }); } TableInfo tinfo = new TableInfo(new string[] { "ID", "Name", "Value", "Created", "Last used" }, items.ToArray()); node.AddInformation("Form history", InformationType.Table, tinfo); } } //downloads.sqlite empty??? /*string dldb = folder + @"\downloads.sqlite"; if (File.Exists(dldb)) { CSQLite kvc = new CSQLite(dldb); QueryResult res = kvc.QuickQuery("SELECT id,name,source,target,startTime,endTime,referrer,maxBytes,mimeType FROM moz_downloads"); if (res.Returned > 0) { List<ListViewItem> items = new List<ListViewItem>(); foreach (object[] obj in res.Rows) { //string starttime = (obj[4].GetType() == typeof(DBNull) || (long)obj[4] < 1 ? "" : Program.FormatUnixTimestamp((long)obj[4], "yyyy-MM-dd H:mm:ss")); //string endtime = (obj[5].GetType() == typeof(DBNull) || (long)obj[5] < 1 ? "" : Program.FormatUnixTimestamp((long)obj[5], "yyyy-MM-dd H:mm:ss")); items.Add(new ListViewItem( new string[] { obj[0].ToString(), obj[1].ToString(), obj[2].ToString(), obj[3].ToString(), obj[7].ToString(), obj[8].ToString(), obj[6].ToString(), obj[4].ToString(), obj[5].ToString(), })); } TableInfo tinfo = new TableInfo(new string[] { "ID", "Name", "Source", "Target", "Size", "Mime Type", "Referrer", "Start Time", "End Time" }, items.ToArray()); node.AddInformation("Downloads (Pre Firefox 21)", InformationType.Table, tinfo); } }*/ /* Cache */ string localfolder = FIREFOX_PATH_LOCAL + profile; string cachefolder = FIREFOX_PATH_LOCAL + profile + @"\cache2\entries"; if (Directory.Exists(localfolder) && Directory.Exists(cachefolder)) { string[] cachefiles = Directory.GetFiles(cachefolder); if (cachefiles.Length < 1) continue; SearchNode cachenode = node.AddInformation("Cache", InformationType.Title, new TitleInfo("Cache", String.Format("Contains data that Firefox has cached for the respective profile, such as images, videos, and style sheets.", profile)), true); byte[] intbuff = new byte[4]; byte[] headerbuff = new byte[3]; foreach (string cachefile in cachefiles) { if (Main.SearchCanceled) return; FileStream fcache = null; try { fcache = File.Open(cachefile, FileMode.Open, FileAccess.Read, FileShare.Read); if (fcache.Length < 16) continue; //Arbitrary minimum if (fcache.Read(headerbuff, 0, 3) != 3) continue; if (WinAPI.memcmp(headerbuff, PNG_HEADER, 3) != 0 && WinAPI.memcmp(headerbuff, JPG_HEADER, 3) != 0 && WinAPI.memcmp(headerbuff, GIF_HEADER, 3) != 0) continue; fcache.Seek(-4, SeekOrigin.End); if (fcache.Read(intbuff, 0, 4) != 4) continue; Program.SwapEndianness32(ref intbuff); int metaoffset = BitConverter.ToInt32(intbuff, 0); if (metaoffset < 16) continue; int hash = 4 + (int)Math.Ceiling((float)fcache.Length / (float)INT_256KB) * 2; fcache.Seek(metaoffset + hash, SeekOrigin.Begin); if (fcache.Read(intbuff, 0, 4) != 4) continue; Program.SwapEndianness32(ref intbuff); int metaversion = BitConverter.ToInt32(intbuff, 0); if (metaversion > 2) continue; fcache.Seek(0x14, SeekOrigin.Current); if (fcache.Read(intbuff, 0, 4) != 4) continue; Program.SwapEndianness32(ref intbuff); int metaurllen = BitConverter.ToInt32(intbuff, 0); if (metaurllen < 1) continue; if (metaversion == 2) fcache.Seek(0x04, SeekOrigin.Current); byte[] asciibuff = new byte[metaurllen]; if (fcache.Read(asciibuff, 0, metaurllen) != metaurllen) continue; string originurl = Encoding.ASCII.GetString(asciibuff); fcache.Seek(0, SeekOrigin.Begin); SearchNode rcachenode = null; Match m = Regex.Match(originurl, "^:(http|https|ftp)://(.*?)/"); if (m.Success && m.Groups[1].Success) { foreach (SearchNode cnode in CacheDomains) if (cnode.Title == m.Groups[2].Value) { rcachenode = cnode; break; } if (rcachenode == null) { rcachenode = cachenode.AddInformation(m.Groups[2].Value, InformationType.None, null, true); CacheDomains.Add(rcachenode); } originurl = originurl.Replace(m.Groups[0].Value, "/"); } else rcachenode = cachenode; rcachenode.AddInformation(originurl, InformationType.Delegate, (Action)delegate { Bridge.Interface.SwitchPanel(InformationType.Image); try { fcache = File.Open(cachefile, FileMode.Open, FileAccess.Read, FileShare.Read); byte[] bitmapbuff = new byte[metaoffset]; if (fcache.Read(bitmapbuff, 0, metaoffset) != metaoffset) return; Bridge.Interface.SetImage(null); if (ms != null) { ms.Close(); ms.Dispose(); } if (bt != null) { bt.Dispose(); } ms = new MemoryStream(bitmapbuff);//using (MemoryStream ms = new MemoryStream(bitmapbuff)) bt = new Bitmap(ms); Bridge.Interface.SetImage(bt); } catch (IOException) { } //Generic catch (UnauthorizedAccessException) { } //Lock error finally { if(fcache != null) fcache.Close(); } }); } catch (IOException) { } //Generic catch (UnauthorizedAccessException) { } //Lock error finally { if(fcache != null) fcache.Close(); } } } } }