有朋友在对HackingTeam的分析过程中,在处理pst文件时遇到一些问题,我把部分代码发出来供参考吧。
以下C#代码主要功能是提取pst文件中的邮件部分关键要素,保存到本地csv,保存到mysql中,提取邮件附件保存到本地。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using MySql.Data; using MySql.Data.MySqlClient; using System.Data; using System.IO; using System.Collections; using Outlook = Microsoft.Office.Interop.Outlook; namespace HackingTeamEmailExtractor { class Program { public static int totalmails = 0; public static int totalitems = 0; public static int totalfolders = 0; public static string htmailcsv = @"G:\htmail.csv"; public static FileStream fs = null; public static StreamWriter sw = null; public static MySqlConnection conn = new MySql.Data.MySqlClient.MySqlConnection(); public static MySqlCommand cmd = new MySql.Data.MySqlClient.MySqlCommand(); public static int savemailinforeturn = -1; static void Main(string[] args) { string pstpath = @"G:\HackingTeam\mail"; string htmailcsv = @"G:\htmail.csv"; conn.ConnectionString = "server=192.168.159.129;user=root;database=HackingTeamEmails;port=3306;password=yourpassword;"; Console.WriteLine("Connecting to MySQL..."); conn.Open(); cmd.Connection = conn; if (File.Exists(htmailcsv)) { try { File.Delete(htmailcsv); Console.WriteLine("Deleted Csv File"); } catch(Exception e) { Console.WriteLine("Delete Csv File Error:"+e.Message); } } fs = new FileStream(htmailcsv, FileMode.Append); sw = new StreamWriter(fs); DirectoryInfo dir = new DirectoryInfo(pstpath); ArrayList pstfiles = GetAll(dir); foreach (string pstfile in pstfiles) { Console.WriteLine(string.Format("Processing {0} file...", pstpath + "\\" + pstfile)); ProcessPstFile(pstpath + "\\" + pstfile); } sw.Flush(); sw.Close(); fs.Close(); conn.Close(); Console.WriteLine("\nFinished Extract mails,Total Mails:{0} ,Total Folders:{1}\n\n", totalmails, totalfolders); Console.WriteLine("All Done!Press any key to Exit!\n\n"); Console.ReadKey(); } private static ArrayList GetAll(DirectoryInfo dir)//搜索文件夹中的文件 { ArrayList FileList = new ArrayList(); FileInfo[] allFile = dir.GetFiles("*.pst"); foreach (FileInfo fi in allFile) { FileList.Add(fi.Name); } DirectoryInfo[] allDir = dir.GetDirectories(); foreach (DirectoryInfo d in allDir) { GetAll(d); } return FileList; } private static void ProcessPstFile(string filename) { Outlook.Application app = new Outlook.Application(); Outlook.NameSpace outlookNs = app.GetNamespace("MAPI"); outlookNs.AddStore(filename); string rootname = filename.Substring(filename.LastIndexOf("\\") + 1, filename.Length - filename.LastIndexOf("\\") - 5); foreach (Outlook.Store store in outlookNs.Stores) { Console.WriteLine("Trying store: " + store.DisplayName + "\n"); if (store.DisplayName == rootname) { Console.WriteLine("found store!\n"); Outlook.MAPIFolder rootFolder = store.GetRootFolder(); // Outlook.MAPIFolder emailFolder = outlookNs.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox); Console.WriteLine("foldername: " + rootFolder.Name + " loaded\n"); displayfolder(rootFolder); outlookNs.RemoveStore(rootFolder); Console.WriteLine("foldername: " + rootFolder.Name + " disloaded\n"); } } } private static void displayfolder(Outlook.MAPIFolder mailfolder) { totalfolders++; Outlook.Items items = mailfolder.Items; totalitems += items.Count; Console.WriteLine(string.Format("Total {0} Items in {1} Folder", items.Count, mailfolder.Name)); foreach (object item in items) { if (item is Outlook.MailItem) { Outlook.MailItem mailItem = item as Outlook.MailItem; string toaddress = ""; if (mailItem.Recipients != null && mailItem.Recipients.Count > 0) { foreach (Outlook.Recipient recip in mailItem.Recipients) { totalmails++; // Console.WriteLine("Mail Subject" + mailItem.Subject + " From: " + mailItem.SenderEmailAddress + " TO: " + recip.Address + " Received Time: " + mailItem.ReceivedTime + "\n"); sw.WriteLine(string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8}", mailItem.ReceivedTime, mailItem.SenderEmailAddress, Treatsplit(mailItem.SenderName), recip.Address, Treatsplit(recip.Name), Treatsplit(mailItem.Subject), mailItem.Importance, Treatsplit(mailfolder.Name), recip.Type)); savemailinforeturn = SaveMailInfoToMysql(mailItem.ReceivedTime, mailItem.SenderEmailAddress, Treatsplit(mailItem.SenderName), recip.Address, Treatsplit(recip.Name), Treatsplit(mailItem.Subject), mailItem.Importance, Treatsplit(mailfolder.Name), recip.Type); Console.Write("."); } if (mailItem.Body != null && mailItem.Body != "") { SaveMailBodyToMysql(mailItem.Body, savemailinforeturn); } //SaveAttachement(mailItem); } else { totalmails++; Console.WriteLine("\nNo Recipients found!\n"); Console.WriteLine("Mail Subject" + mailItem.Subject + " From: " + mailItem.SenderEmailAddress + " TO: " + "NOT FOUND!" + " Received Time: " + mailItem.ReceivedTime + "\n"); } } } sw.Flush(); //System.Threading.Thread.Sleep(2000); try { foreach (Outlook.MAPIFolder folder in mailfolder.Folders) { Console.WriteLine("\nTreating folder:" + folder.Name + "\n"); displayfolder(folder); } } catch(Exception e) { Console.WriteLine("\nError:" + e.Message + "\n"); } } private static string Treatsplit(string ostr) { try { return ostr.Replace(',', ','); } catch { return ""; } } private static int SaveMailInfoToMysql(DateTime createtime,string mailfrom,string sendername,string mailto,string mailtoname,string subject,Outlook.OlImportance importance,string foldername,int mailtype) { try { cmd.CommandText = "INSERT INTO `HackingTeamEmails`.`AllEmails`VALUES(null,@FromAddress,@FromName,@ToAddress,@ToName,@ReceiveTime,@Subject,@Importance,@Folder,@SendMode); "; cmd.Prepare(); int mailimportance = 1; if (importance == Microsoft.Office.Interop.Outlook.OlImportance.olImportanceHigh) { mailimportance = 2; } if (importance == Microsoft.Office.Interop.Outlook.OlImportance.olImportanceLow) { mailimportance = 0; } cmd.Parameters.Clear(); cmd.Parameters.AddWithValue("@FromAddress", mailfrom); cmd.Parameters.AddWithValue("@FromName", sendername); cmd.Parameters.AddWithValue("@ToAddress", mailto); cmd.Parameters.AddWithValue("@ToName", mailtoname); cmd.Parameters.AddWithValue("@ReceiveTime", createtime); cmd.Parameters.AddWithValue("@Subject", subject); cmd.Parameters.AddWithValue("@Importance", mailimportance); cmd.Parameters.AddWithValue("@Folder", foldername); cmd.Parameters.AddWithValue("@SendMode", mailtype); cmd.Parameters.AddWithValue("@id", MySqlDbType.Int32); cmd.Parameters["@id"].Direction = ParameterDirection.Output; cmd.ExecuteNonQuery(); return (int)cmd.Parameters["@id"].Value; } catch (Exception ex) { Console.WriteLine("Save MailInfo To Mysql Error: "+ex.ToString()+"\n"); return -1; } } private static void SaveMailBodyToMysql(string MailBody, int MailInfoID) { try { cmd.CommandText = "INSERT INTO `HackingTeamEmails`.`EmailBody` VALUES(null,@Eid,@PlainText);"; cmd.Prepare(); cmd.Parameters.Clear(); cmd.Parameters.AddWithValue("@PlainText", MailBody); cmd.Parameters.AddWithValue("@Eid", MailInfoID); cmd.ExecuteNonQuery(); } catch (Exception ex) { Console.WriteLine("Save MailBody To Mysql Error: " + ex.ToString() + "\n"); } } private static void SaveAttachement(Outlook.MailItem mailitem) { try { if (mailitem.Attachments != null && mailitem.Attachments.Count > 0) { foreach (Outlook.Attachment attach in mailitem.Attachments) { string filename = @"G:\HTmailAttachment\" + mailitem.CreationTime.ToString("yyyyMMddHHmmssfff")+"_"+attach.FileName; StringBuilder rBuilder = new StringBuilder(filename); foreach (char rInvalidChar in Path.GetInvalidFileNameChars()) rBuilder.Replace(rInvalidChar.ToString(), string.Empty); if (attach.Size > 0 && attach.FileName!=null && attach.FileName != "") { attach.SaveAsFile(filename); Console.WriteLine("\nAttachment Extracted! File:" + filename + "\n"); } } } } catch (Exception e) { Console.WriteLine("\nErrors in Attachment Extract! Error:" + e.Message + "\n"); System.Threading.Thread.Sleep(2000); } } } }