public void TestSaveEncryptedDocstream() { WorkbookStream obfuscatedStream = TestHelpers.GetXorObfuscatedWorkbookStream(); ExcelDocWriter writer = new ExcelDocWriter(); XorObfuscation xorObfuscation = new XorObfuscation(); WorkbookStream deobfuscatedStream = xorObfuscation.DecryptWorkbookStream(obfuscatedStream); WorkbookStream reObfuscatedStream = xorObfuscation.EncryptWorkbookStream(deobfuscatedStream); writer.WriteDocument("C:\\Users\\Weber\\source\\repos\\michaelweber\\Macrome\\bin\\Debug\\netcoreapp2.0\\test-encrypted2.xls", reObfuscatedStream); }
/// <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); } }
/// <summary> /// Deobfuscate a legacy XLS document to enable simpler analysis. /// </summary> /// <param name="path">Path to the XLS file to deobfuscate</param> /// <param name="neuterFile">Flag to insert a HALT() expression into all Auto_Open start locations. NOT IMPLEMENTED</param> /// <param name="password">XOR Obfuscation decryption password to try. Defaults to VelvetSweatshop if FilePass record is found.</param> /// <param name="outputFileName">The output filename used for the generated document. Defaults to deobfuscated.xls</param> public static void Deobfuscate(FileInfo path, bool neuterFile = false, string password = "******", string outputFileName = "deobfuscated.xls") { if (path == null) { Console.WriteLine("path argument must be specified in Deobfuscate mode. Run deobfuscate -h for usage instructions."); return; } if (path.Exists == false) { Console.WriteLine("path file does not exist."); return; } if (neuterFile) { throw new NotImplementedException("XLS Neutering Not Implemented Yet"); } WorkbookStream wbs = new WorkbookStream(path.FullName); if (wbs.HasPasswordToOpen()) { 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; } } WorkbookEditor wbEditor = new WorkbookEditor(wbs); wbEditor.NormalizeAutoOpenLabels(); wbEditor.UnhideSheets(); ExcelDocWriter writer = new ExcelDocWriter(); string outputPath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + outputFileName; Console.WriteLine("Writing deobfuscated document to {0}", outputPath); writer.WriteDocument(outputPath, wbEditor.WbStream); }
public void TestEncryptDoc() { WorkbookStream obfuscatedStream = TestHelpers.GetXorObfuscatedWorkbookStream(); XorObfuscation xorObfuscation = new XorObfuscation(); WorkbookStream deobfuscatedStream = xorObfuscation.DecryptWorkbookStream(obfuscatedStream); WorkbookStream reObfuscatedStream = xorObfuscation.EncryptWorkbookStream(deobfuscatedStream); foreach (var record in reObfuscatedStream.Records) { Console.WriteLine(record.ToHexDumpString(0x1000, false)); } CodePage originalCpRecord = obfuscatedStream.GetAllRecordsByType <CodePage>().First(); CodePage newCpRecord = reObfuscatedStream.GetAllRecordsByType <CodePage>().First(); Assert.AreEqual(originalCpRecord.cv, newCpRecord.cv); }
public void TestDecryptObfuscatedDoc() { WorkbookStream obfuscatedStream = TestHelpers.GetXorObfuscatedWorkbookStream(); XorObfuscation xorObfuscation = new XorObfuscation(); WorkbookStream deobfuscatedStream = xorObfuscation.DecryptWorkbookStream(obfuscatedStream); foreach (var record in deobfuscatedStream.Records) { Console.WriteLine(record.ToHexDumpString(0x1000, false)); } List <Lbl> AutoOpenLabels = deobfuscatedStream.GetAutoOpenLabels(); Assert.AreEqual(1, AutoOpenLabels.Count); List <FilePass> filePassRecords = deobfuscatedStream.GetAllRecordsByType <FilePass>(); Assert.AreEqual(0, filePassRecords.Count); }
/// <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); } }