Ejemplo n.º 1
0
        public static string GetRelevantRecordDumpString(WorkbookStream wbs, bool dumpHexBytes = false, bool showAttrInfo = false)
        {
            int numBytesToDump = 0;

            if (dumpHexBytes)
            {
                numBytesToDump = 0x1000;
            }

            List <BiffRecord> relevantRecords = wbs.Records.Where(rec => RecordHelper.RelevantTypes.Contains(rec.Id)).ToList();

            relevantRecords = RecordHelper.ConvertToSpecificRecords(relevantRecords);

            relevantRecords = PtgHelper.UpdateGlobalsStreamReferences(relevantRecords);

            string dumpString = "";

            foreach (var record in relevantRecords)
            {
                dumpString += record.ToHexDumpString(numBytesToDump, showAttrInfo);
                dumpString += "\n";
            }

            return(dumpString);
        }
Ejemplo n.º 2
0
        public static string GetRelevantRecordDumpString(WorkbookStream wbs, bool dumpHexBytes = false, bool showAttrInfo = false)
        {
            int numBytesToDump = 0;

            if (dumpHexBytes)
            {
                numBytesToDump = 0x1000;
            }

            bool hasPassword = wbs.HasPasswordToOpen();

            List <BiffRecord> relevantRecords = wbs.Records.Where(rec => RecordHelper.RelevantTypes.Contains(rec.Id)).ToList();

            //We can only interpret the data of these records if they are not encrypted
            if (!hasPassword)
            {
                relevantRecords = RecordHelper.ConvertToSpecificRecords(relevantRecords);
                relevantRecords = PtgHelper.UpdateGlobalsStreamReferences(relevantRecords);
            }

            string dumpString = "";

            foreach (var record in relevantRecords)
            {
                dumpString += record.ToHexDumpString(numBytesToDump, showAttrInfo);
                dumpString += "\n";
            }

            return(dumpString);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Dumps information about BIFF records that are relevant for analysis. Defaults to sheet, label, and formula data.
        /// </summary>
        /// <param name="path">Path to the XLS file to dump</param>
        /// <param name="dumpAll">Dump all BIFF records, not the most commonly used by maldocs</param>
        /// <param name="showAttrInfo">Explicitly display PtgAttr information in Formula strings. Defaults to False.</param>
        /// <param name="dumpHexBytes">Dump the byte content of each BIFF record in addition to its content summary. Defaults to False.</param>
        public static void Dump(FileInfo path, bool dumpAll = false, bool showAttrInfo = false, bool dumpHexBytes = false)
        {
            if (path == null)
            {
                Console.WriteLine("path argument must be specified in Dump mode. Run dump -h for usage instructions.");
                return;
            }

            if (path.Exists == false)
            {
                Console.WriteLine("path file does not exist.");
                return;
            }

            WorkbookStream wbs = new WorkbookStream(path.FullName);

            List <RecordType> relevantTypes = new List <RecordType>()
            {
                RecordType.BoundSheet8,     //Sheet definitions (Defines macro sheets + hides them)
                RecordType.Lbl,             //Named Cells (Contains Auto_Start)
                RecordType.Formula,         //The meat of most cell content
                RecordType.SupBook,         //Contains information for cross-sheet references
                RecordType.ExternSheet      //Contains the XTI records mapping ixti values to BoundSheet8
            };

            int numBytesToDump = 0;

            if (dumpHexBytes)
            {
                numBytesToDump = 0x1000;
            }

            if (dumpAll)
            {
                WorkbookStream fullStream = new WorkbookStream(PtgHelper.UpdateGlobalsStreamReferences(wbs.Records));
                foreach (var record in fullStream.Records)
                {
                    Console.WriteLine(record.ToHexDumpString(numBytesToDump, showAttrInfo));
                }
            }
            else
            {
                List <BiffRecord> relevantRecords = wbs.Records.Where(rec => relevantTypes.Contains(rec.Id)).ToList();
                relevantRecords = RecordHelper.ConvertToSpecificRecords(relevantRecords);

                relevantRecords = PtgHelper.UpdateGlobalsStreamReferences(relevantRecords);
                foreach (var record in relevantRecords)
                {
                    string dumpString = "";
                    dumpString += record.ToHexDumpString(numBytesToDump, showAttrInfo);
                    Console.WriteLine(dumpString);
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Dumps information about BIFF records that are relevant for analysis. Defaults to sheet, label, and formula data.
        /// </summary>
        /// <param name="path">Path to the XLS file to dump</param>
        /// <param name="dumpAll">Dump all BIFF records, not the most commonly used by maldocs</param>
        /// <param name="showAttrInfo">Explicitly display PtgAttr information in Formula strings. Defaults to False.</param>
        /// <param name="dumpHexBytes">Dump the byte content of each BIFF record in addition to its content summary.</param>
        /// <param name="password">XOR Obfuscation decryption password to try. Defaults to VelvetSweatshop if FilePass record is found.</param>
        /// <param name="disableDecryption">Use this flag in order to skip decryption of the file before dumping.</param>
        public static void Dump(FileInfo path, bool dumpAll = false, bool showAttrInfo = false, bool dumpHexBytes = false, string password = "******", bool disableDecryption = false)
        {
            if (path == null)
            {
                Console.WriteLine("path argument must be specified in Dump mode. Run dump -h for usage instructions.");
                return;
            }

            if (path.Exists == false)
            {
                Console.WriteLine("path file does not exist.");
                return;
            }

            WorkbookStream wbs = new WorkbookStream(path.FullName);

            if (wbs.HasPasswordToOpen() && !disableDecryption)
            {
                Console.WriteLine("FilePass record found - attempting to decrypt with password " + password);
                XorObfuscation xorObfuscation = new XorObfuscation();
                try
                {
                    wbs = xorObfuscation.DecryptWorkbookStream(wbs, password);
                }
                catch (ArgumentException argEx)
                {
                    Console.WriteLine("Password " + password + " does not match the verifier value of the document FilePass. Try a different password.");
                    return;
                }
            }

            int numBytesToDump = 0;

            if (dumpHexBytes)
            {
                numBytesToDump = 0x1000;
            }

            if (dumpAll)
            {
                List <BiffRecord> records;
                WorkbookStream    fullStream = new WorkbookStream(PtgHelper.UpdateGlobalsStreamReferences(wbs.Records));
                records = fullStream.Records;
                foreach (var record in records)
                {
                    Console.WriteLine(record.ToHexDumpString(numBytesToDump, showAttrInfo));
                }
            }
            else
            {
                string dumpString = RecordHelper.GetRelevantRecordDumpString(wbs, dumpHexBytes, showAttrInfo);
                Console.WriteLine(dumpString);
            }
        }
Ejemplo n.º 5
0
        public void TestFormulaToStringConversion()
        {
            WorkbookStream wbs = TestHelpers.GetMacroLoopWorkbookStream();

            List <RecordType> relevantTypes = new List <RecordType>()
            {
                RecordType.BoundSheet8, //Sheet definitions (Defines macro sheets + hides them)
                RecordType.Lbl,         //Named Cells (Contains Auto_Start)
                RecordType.Formula      //The meat of most cell content
            };

            List <BiffRecord> relevantRecords = wbs.Records.Where(rec => relevantTypes.Contains(rec.Id)).ToList();

            relevantRecords = RecordHelper.ConvertToSpecificRecords(relevantRecords);

            relevantRecords = PtgHelper.UpdateGlobalsStreamReferences(relevantRecords);

            List <string> results = relevantRecords.Select(r => r.ToHexDumpString()).ToList();


            string b1formula = results.Where(res => res.StartsWith("Formula[B1]")).First();

            Assert.AreEqual("Formula[B1]: invokeChar=A11", b1formula);

            string b2formula = results.Where(res => res.StartsWith("Formula[B2]")).First();

            Assert.AreEqual("Formula[B2]: var=999", b2formula);

            string b5formula = results.Where(res => res.StartsWith("Formula[B5]")).First();

            Assert.AreEqual("Formula[B5]: InvokeFormula(\"=HALT()\",A1)", b5formula);

            string b6formula = results.Where(res => res.StartsWith("Formula[B6]")).First();

            Assert.AreEqual("Formula[B6]: WProcessMemory(-1,B2+(D1*255),ACTIVE.CELL(),LEN(ACTIVE.CELL()),0)", b6formula);

            string a11formula = results.Where(res => res.StartsWith("Formula[A11]")).First();

            Assert.AreEqual("Formula[A11]: RETURN(CHAR(var))", a11formula);

            string a12formula = results.Where(res => res.StartsWith("Formula[A12]")).First();

            Assert.AreEqual("Formula[A12]: RETURN(FORMULA(arg1,arg2))", a12formula);

            string d13formula = results.Where(res => res.StartsWith("Formula[D13]")).First();

            Assert.AreEqual("Formula[D13]: stringToBuild=stringToBuild&invokeChar()", d13formula);

            string d14formula = results.Where(res => res.StartsWith("Formula[D14]")).First();

            Assert.AreEqual("Formula[D14]: curCell=ABSREF(\"R[1]C\",curCell)", d14formula);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Dumps information about BIFF records that are relevant for analysis. Defaults to sheet, label, and formula data.
        /// </summary>
        /// <param name="path">Path to the XLS file to dump</param>
        /// <param name="dumpAll">Dump all BIFF records, not the most commonly used by maldocs</param>
        /// <param name="showAttrInfo">Explicitly display PtgAttr information in Formula strings. Defaults to False.</param>
        /// <param name="dumpHexBytes">Dump the byte content of each BIFF record in addition to its content summary. Defaults to False.</param>
        public static void Dump(FileInfo path, bool dumpAll = false, bool showAttrInfo = false, bool dumpHexBytes = false)
        {
            if (path == null)
            {
                Console.WriteLine("path argument must be specified in Dump mode. Run dump -h for usage instructions.");
                return;
            }

            if (path.Exists == false)
            {
                Console.WriteLine("path file does not exist.");
                return;
            }

            WorkbookStream wbs = new WorkbookStream(path.FullName);



            int numBytesToDump = 0;

            if (dumpHexBytes)
            {
                numBytesToDump = 0x1000;
            }

            if (dumpAll)
            {
                WorkbookStream fullStream = new WorkbookStream(PtgHelper.UpdateGlobalsStreamReferences(wbs.Records));
                foreach (var record in fullStream.Records)
                {
                    Console.WriteLine(record.ToHexDumpString(numBytesToDump, showAttrInfo));
                }
            }
            else
            {
                string dumpString = RecordHelper.GetRelevantRecordDumpString(wbs, dumpHexBytes, showAttrInfo);
                Console.WriteLine(dumpString);
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Dumps information about BIFF records that are relevant for analysis. Defaults to sheet, label, and formula data.
        /// </summary>
        /// <param name="path">Path to the XLS file to dump</param>
        /// <param name="dumpAll">Dump all BIFF records, not the most commonly used by maldocs</param>
        /// <param name="showAttrInfo">Explicitly display PtgAttr information in Formula strings. Defaults to False.</param>
        /// <param name="dumpHexBytes">Dump the byte content of each BIFF record in addition to its content summary.</param>
        /// <param name="password">XOR Obfuscation decryption password to try. Defaults to VelvetSweatshop if FilePass record is found.</param>
        /// <param name="disableDecryption">Use this flag in order to skip decryption of the file before dumping.</param>
        public static void Dump(FileInfo path, bool dumpAll = false, bool showAttrInfo = false, bool dumpHexBytes = false, string password = "******", bool disableDecryption = false)
        {
            if (path == null)
            {
                Console.WriteLine("path argument must be specified in Dump mode. Run dump -h for usage instructions.");
                return;
            }

            if (path.Exists == false)
            {
                Console.WriteLine("path file does not exist.");
                return;
            }

            WorkbookStream wbs = new WorkbookStream(path.FullName);

            if (wbs.HasPasswordToOpen() && !disableDecryption)
            {
                FilePass fpRecord = wbs.GetAllRecordsByType <FilePass>().First();

                if (fpRecord.wEncryptionType == 0 && fpRecord.xorObfuscationKey != 0)
                {
                    XorObfuscation xorObfuscation = new XorObfuscation();
                    Console.WriteLine("FilePass record found - attempting to decrypt with password " + password);
                    try
                    {
                        wbs = xorObfuscation.DecryptWorkbookStream(wbs, password);
                    }
                    catch (ArgumentException argEx)
                    {
                        Console.WriteLine("Password " + password + " does not match the verifier value of the document FilePass. Try a different password.");
                        return;
                    }
                }
                else if (fpRecord.wEncryptionType == 1 && fpRecord.vMajor > 1)
                {
                    Console.WriteLine("FilePass record for CryptoAPI Found - Currently Unsupported.");
                    string verifierSalt = BitConverter.ToString(fpRecord.encryptionVerifier.Salt).Replace("-", "");
                    string verifier     = BitConverter.ToString(fpRecord.encryptionVerifier.EncryptedVerifier).Replace("-", "");
                    string verifierHash = BitConverter.ToString(fpRecord.encryptionVerifier.EncryptedVerifierHash).Replace("-", "");
                    Console.WriteLine("Salt is: " + verifierSalt);
                    Console.WriteLine("Vrfy is: " + verifier);
                    Console.WriteLine("vHsh is: " + verifierHash);
                    Console.WriteLine("Algo is: " + string.Format("{0:x8}", fpRecord.encryptionHeader.AlgID));
                }

                else if (fpRecord.wEncryptionType == 1 && fpRecord.vMajor == 1)
                {
                    Console.WriteLine("FilePass record for RC4 Binary Document Encryption Found - Currently Unsupported.");
                }
            }

            int numBytesToDump = 0;

            if (dumpHexBytes)
            {
                numBytesToDump = 0x1000;
            }

            if (dumpAll)
            {
                List <BiffRecord> records;
                WorkbookStream    fullStream = new WorkbookStream(PtgHelper.UpdateGlobalsStreamReferences(wbs.Records));
                records = fullStream.Records;
                foreach (var record in records)
                {
                    Console.WriteLine(record.ToHexDumpString(numBytesToDump, showAttrInfo));
                }
            }
            else
            {
                string dumpString = RecordHelper.GetRelevantRecordDumpString(wbs, dumpHexBytes, showAttrInfo);
                Console.WriteLine(dumpString);
            }
        }