通过互操作/自动化进行暴力密码搜索






2.76/5 (8投票s)
如何使用 Microsoft Interop/Automation 实现 Microsoft Office 文件密码的并行搜索。
引言
是否可以通过自动化恢复 Microsoft Office 文件中遗忘的密码?答案是肯定的,通过自动化/互操作、多线程和大量可量化的 CPU 时间进行暴力破解。
该软件的主要目标是验证互操作打开受密码保护文件的能力,并检查密码何时足够强大以抵御攻击。但该软件也可以在实际生活中使用,以查找您拥有文件的遗忘密码。事实上,它正是为了打开所有者忘记确切密码的文件而编写的。
在哪里获取?
包含算法的表单可以从此处下载 (^) 并插入到您的新 Visual Studio 项目中。
为什么要使用互操作/自动化?
Microsoft Interop 允许开发人员管理 MS Office 文件,并使其易于创建使用暴力破解查找遗忘密码的程序。
- 它在 Microsoft Office 文档上运行良好。
- 易于实现。
- 它允许避免研究加密算法(及其可能存在的非标准实现)或花费时间研究和理解每种文件类型(Excel .xls 和 .xlsx、Word .doc 和 .docx 等)的文件结构。
反之
- 在打开受密码保护的文件操作上,它的时间性能不佳。
软件要求
要使用由 Visual Studio 2017 开发的软件。目标计算机上需要安装 Microsoft Office(或 Excel 或 Word,根据要处理的文件类型)。
错误 CS0234
如果您遇到错误 CS0234,这意味着您需要引用 Office 库。打开菜单“项目”,选择“添加引用...”,然后选择“COM”选项卡,滚动列表到“Microsoft Word 16.0 对象库”或其他您拥有的版本。
完成任务所需时间
暴力破解攻击完成任务所需的时间是可预测的。它可以计算为可接受的char
s 组合的乘方,其中乘方数为可测试的最大密码长度。
例如,如果我们要破解一个只由大写字母组成且长度在1到6之间的密码,那么我们有26个字符要测试,从“A
”重复到“ZZZZZZ
”。
要测试的总组合数(更准确的数学术语是排列)为
- 1 个字符('A' 到 'Z'):26 ^ 1 = 26;
- 2 个字符('AA' 到 'ZZ'):26 ^ 2 = 676;
- 3 个字符('AAA' 到 'ZZZ'):26 ^ 3 = 17,576;
- 4 个字符('AAAA' 到 'ZZZZ'):26 ^ 4 = 456,976;
- 5 个字符('AAAAA' 到 'ZZZZZ'):26 ^ 5 = 11,881,376;
- 6 个字符('AAAAAA' 到 'ZZZZZZ'):26 ^ 6 = 308,915,776;
总和是 321,272,406
个可能的密码。
现在,计算时间的最后一步是添加时间因素。
用于测试的旧硬件获得的每分钟测试量约为1500次。那么
- 321,272,406 组合数 / 1,500 次测试/分钟 = 214,182 分钟
- 214,182 分钟 / 60 分钟/小时 = 3,570 小时
- 3,570 小时 / 24 小时/天 = 148 天(或 5 个月)。
在最坏情况下,148 天的情况由“ZZZZZZ
”表示。最好的情况是密码只填充“A
”,它会立即被测试并找到。
可以跳过过短的密码,例如,从 4 个字符长度的密码(即“AAAA
”)开始。
当然,如果我们知道密码长度,那将大大节省时间。
通过算法避免诸如“RKWLPG
”或“TMQNTZ
”(仅仅因为它们毫无意义,因此难以记住或位于键盘的无序位置——与“QWERTY”相反——)等绝对不可能的密码来减少组合数,这是不可能的,并且存在跳过正确密码的具体风险。
要测试的标准字符集
为了完善信息,记住实际组合必须基于包含所有可能性的字符集是很有用的。至少
- 小写字母:'a' 到 'z':26 个
- 大写字母:'A' 到 'Z':26 个
- 数字:'0' 到 '9':10 个
- 特殊字符:括号(六个)、空格、货币符号(三个或更多)、标点符号(六个或更多)以及其他:超过 20 个。
总计 26+26+10+10 超过 70 个字符。因此,如果密码长度为 5 个字符,我们将得到 70^1 + 70^2 + 70^3 + 70^4 + 70^5 = 1,680,700,000 个可能的密码需要测试(而如果使用单个字母表集,则为 308,915,776 个,如前所述)。
我必须强调,如果此软件用于您的文件,它将非常有用,因为您可以降低所有可能性的复杂性。事实上,您知道
- 哪些
char
集适用或不适用(例如,如果您从未使用某些特殊char
或大写字母集,则可以将其从测试中排除)。 - 密码的最小长度(例如,如果您使用8个或更多
char
的密码,这意味着您从该长度开始处理,从而节省大量时间)
梦想更快的 CPU 速度
测试由一台非常老的 Intel i5 760 2.80GHz 4 核处理器进行。对于那些需要性能的人来说,预计在 2018 年底,将推出 Intel® Core™ i9 Extreme Edition 处理器,拥有 18 核和 36 线程,其速度可以表示为一个 teraflop(1012 FLOPS):建议的计算时间将大大缩短。我猜从 1 个月缩短到 1 周。
如果您没有时间等待,现在存在一种每秒可以进行 200,000 万亿次计算的新型超级计算机(200 petaflops,200x 1015 FLOPS)。我猜时间将从一个月缩短到一天或更短。
可参数化内容
该软件提供了选择以下内容的可能性
- 可用于猜测密码的字符类型:大写字母、小写字母、数字。目前,特殊字符未作为可用字符集插入。
- 密码长度范围:要检查的最小和最大长度:这对于避免浪费时间验证过短的密码非常有用。
- 要使用的核心数量:此功能旨在限制 CPU 负载,以保持日常负责的计算机。此外,任务以低优先级模式执行,因此它们不影响正常使用。
Using the Code
该软件使用一个表单,创建并启动多个线程:每个线程循环顺序测试由 PasswordNext()
函数获得的密码,直到 StopSearch()
为 false
。当找到密码时,将通过 StopSearch(true)
设置一个标志。
测试字符集
允许的 char
集合通过表单中的一些复选框定义,它将由 AllowedCharsToString()
函数返回:目前可以管理
- 小写字母
- 大写字母
- 数字
创建非侵入式线程
暴力破解是一个大量消耗 CPU 资源的工具,它会将计算机变成僵尸。为了让您能够在几乎正常的情况下继续使用计算机,线程是以最低优先级创建的。CPU 会一直保持 100% 忙碌,但您通过其他软件或工作的交互具有优先权:操作系统将为您服务,并根据需要暂停暴力破解。
下面是创建和启动所有线程的代码:它们将被插入到 List<Thread>
中,以便后续引用。指令 T.Priority
用于将线程设置为最低优先级。
TTCll = new System.Collections.Generic.List<System.Threading.Thread>();
for (int numt = 0; numt < ThreadToUse; numt++)
{
TextBox NumTxt = (TextBox)(EsecuzioneTLP.Controls
["NumThread" + numt.ToString("00") + "Txt"]);
var T = new System.Threading.Thread(() => { Runner(NumTxt); });
T.Priority = System.Threading.ThreadPriority.Lowest;
T.Start();
TTCll.Add(T);
}
显示运行状态
当面对长时间运行的循环时,告知用户一切正常且没有卡住非常重要。该软件可以使用可选数量的核,因此表单中将使用 TableLayoutPanel
,其中将包含启动时生成的 Labels
和 Textboxes
:每个都将绑定到不同的线程,并用于显示当前正在测试的密码。
int ThreadToUse = int.Parse(MaxTasksTxt.Text);
ThreadPanel_Create(ThreadToUse );
运行时表单如下所示。底部灰色背景区域,显示了 TableLayoutPanel
,其中有四个编号从“00
”到“03
”的线程,分别显示它们当前正在测试的密码:“6K
”、“6L
”、“6J
”、“6M
”。
建议
如果您将启动测试,请记住禁用计算机的睡眠/待机功能,否则第二天您可能会发现计算机停止运行。
线程函数:Runner()
每个线程使用的主要函数名为 Runner()
。使用参数 NumTxt
,它是一个 TextBox
,循环可以更新表单上当前要测试的密码。该 TextBox
是在 TableLayoutPanel
中动态创建的。
创建实例
线程创建一个软件实例,用于尝试打开受密码保护的文件
var WApp = new Microsoft.Office.Interop.Word.Application();
主循环
测试各种可能密码的循环是一个 while
,它通过 StopSearch()
检查线程是否必须停止,因为找到了正确的密码。
该函数的核心调用 Open()
,参数为从 PasswordNext()
获取的密码。
如果密码正确
如果测试的密码能够打开文件,则例程将执行以下步骤
- 调用
StopSearch(true)
来设置一个标志。 - 调用
Achieved()
并使用密码作为参数来更新用户界面。
然后,可以释放资源 WDoc
。
try
{
WDoc = WApp.Documents.Open(FileName, PasswordDocument: test , ReadOnly: true);
StopSearch(true);
Achivied(test);
WDoc.Close();
System.Runtime.InteropServices.Marshal.ReleaseComObject(WDoc);
}
如果密码不正确
在受密码保护的文件上使用错误的密码调用 WApp.Documents.Open()
会引发异常。这就是为什么需要用 try
/catch
包装该指令的原因。
在 catch
内部不需要执行任何操作。事实上,WDoc
为 null
。如果您想对异常做些什么,ex.Message
字符串比较必须根据计算机上使用的语言进行更改。
if (ex.Message.Contains("La password non è corretta. Word non può aprire il documento."))
线程结束
例程的最后一步是使用指令释放 Interop 实例
ReleaseComObject(WApp);
为了使其更健壮,ReleaseComObject()
由 try
/catch
保护。
下一个密码是什么?
名为 PasswordNext()
的函数返回下一个要测试的密码。第一个值是“A
”,后面将依次是每个字母,直到“Z
”;之后,将从“a
”到“z
”以及从“0
”到“9
”开始(构成序列的字符类型来自 AllowedCharsToString()
)。
private char [] PasswordNext()
{
char[] GiveBack;
lock (SyncLockerobjNewPassword)
{
// --- password to verify
GiveBack = new char[PasswordToVerify.Length];
// --- password to prepare to next round
PasswordToVerify.CopyTo(GiveBack,0);
// prepare next pwd
bool riporto = false;
for (int i = PasswordToVerify.Length - 1; i >= 0; i--)
{
// last char of the set?
if (PasswordToVerify[i] != AllowedCC[AllowedlattertIdx])
{
// increment
PasswordToVerify[i] =
AllowedCC[(ammessistr.IndexOf(PasswordToVerify[i]) + 1)];
riporto = false ;
break;
}
else
{
// zero
PasswordToVerify[i] = AllowedCC[0];
riporto = true;
}
}
// --- insert new starting char on left side
if ( riporto)
{
char [] tmp = new char[PasswordToVerify.Length ];
PasswordToVerify.CopyTo( tmp,0) ;
PasswordToVerify = new char[PasswordToVerify.Length + 1];
PasswordToVerify[0] = AllowedCC[0];
tmp.CopyTo(PasswordToVerify, 1);
}
}
return GiveBack ;
}
我找到了!
这是处理结束时,找到密码后的表单。它报告了以下信息
- 每个线程最后测试的密码(无用)
- 找到的密码(本例中为“
AB0
”) - 开始时间
- 结束时间
- 完成任务所用的时间
启动按钮保持禁用状态,以防止用户不小心启动另一次运行。要运行另一次测试,必须重新启动软件。
更改目标文件
要针对 Excel 文件使用代码,需要修改的行是 WApp
声明,将其更改为
var WApp = new Microsoft.Office.Interop.Excel.Application();
次要关注点
对于使用 TableLayoutPanel
的新开发者,ThreadPanel_Create()
是一个有用的函数,可以帮助理解如何在运行时创建列,并插入 Label
和 TextBox
等控件。需要注意的是,此控件始终有一个列。
对于接触线程的人来说,有一个关于创建和同步线程的很好的例子,可以根据其中一个线程变为真实的情况来停止它们。
结论
如果 Microsoft 密码保护遵循任何密码的简单规则:长度(超过 8 个字符)、使用大范围字符集:大写和小写字母、数字和特殊字符,那么它就足够强大。但是,如果您正在寻找丢失的密码,那么您有很大的机会恢复它。当然,如果您不着急的话!
历史
- 2018 年 6 月 14 日:初始版本