使用VBA破解Excel表格密码

19

我找到了这段VBA代码,可以在不知道密码的情况下解锁工作表:

Sub PasswordBreaker()

  Dim i As Integer, j As Integer, k As Integer
  Dim l As Integer, m As Integer, n As Integer
  Dim i1 As Integer, i2 As Integer, i3 As Integer
  Dim i4 As Integer, i5 As Integer, i6 As Integer
  On Error Resume Next
  For i = 65 To 66: For j = 65 To 66: For k = 65 To 66
  For l = 65 To 66: For m = 65 To 66: For i1 = 65 To 66
  For i2 = 65 To 66: For i3 = 65 To 66: For i4 = 65 To 66
  For i5 = 65 To 66: For i6 = 65 To 66: For n = 32 To 126


 ActiveSheet.Unprotect Chr(i) & Chr(j) & Chr(k) & _
      Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & Chr(i3) & _
      Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
  If ActiveSheet.ProtectContents = False Then
      MsgBox "One usable password is "& Chr(i) & Chr(j) & _
          Chr(k) & Chr(l)& Chr(m) & Chr(i1) & Chr(i2) & _
          Chr(i3) & Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
   ActiveWorkbook.Sheets(1).Select
   Range("a1").FormulaR1C1 = Chr(i) & Chr(j) & _
          Chr(k) & Chr(l)& Chr(m) & Chr(i1) & Chr(i2) & _
          Chr(i3) & Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
       Exit Sub
  End If
  Next: Next: Next: Next: Next: Next
  Next: Next: Next: Next: Next: Next
End Sub

我的问题是:它使用什么样的漏洞来工作?

换句话说,为什么这个由A和B组成的生成字符串可以用作特定工作簿中一个表格的密码?


不清楚代码,但也许它是这个漏洞的某种迭代:http://davidbugden.com/?p=16 - Hansi
3
听起来像是在寻找哈希碰撞。 - I'm with Monica
2
您可以在此处找到简短的解释:http://www.mcgimpsey.com/excel/removepwords.html。 - Joachim Rohde
2
可能是Excel的工作表密码保护是如何工作的的重复问题。 - user2140173
1
@mehow - 先生,你值得一杯冰凉的饮品!非常感谢,这正是我一直在寻找的。 - Mariusz Górski
5个回答

17

Excel工作表密码保护的原理是将输入的密码转换为哈希值并存储。哈希是一种单向算法,它将位数压缩起来,在此过程中失去了一些信息,但生成了原始数据的指纹。由于数据的丢失,不可能通过哈希反向获取原始密码,但将来如果有人输入一个密码,它可以被哈希并与存储的哈希进行比较。这通常比简单地将密码存储为字符串进行比较更安全。

迄今为止我遇到的最好的描述Excel哈希算法暴力破解的方式是@mehow链接到的页面上Torben Klein发布的答案。他的答案可以总结如下:

  1. Excel哈希函数将可能的密码空间映射到可能的哈希空间。
  2. 由于哈希算法生成的哈希值很小,只有15位,因此可能的哈希值数量为2^15 = 32768个。
  3. 当计算能力得到应用时,32768是一种微不足道的尝试次数。Klein推导出涵盖所有可能哈希值的输入密码子集。
基于 Excel哈希函数的描述,以下代码生成与Excel相同的哈希值,您可以使用它来测试Klein的函数。
Option Explicit
'mdlExcelHash

Public Function getExcelPasswordHash(Pass As String)
    Dim PassBytes() As Byte
    PassBytes = StrConv(Pass, vbFromUnicode)
    Dim cchPassword As Long
    cchPassword = UBound(PassBytes) + 1
    Dim wPasswordHash As Long
    If cchPassword = 0 Then
        getExcelPasswordHash = wPasswordHash
        Exit Function
    End If

    Dim pch As Long
    pch = cchPassword - 1
    While pch >= 0
        wPasswordHash = wPasswordHash Xor PassBytes(pch)
        wPasswordHash = RotateLeft_15bit(wPasswordHash, 1)
        pch = pch - 1
    Wend

    wPasswordHash = wPasswordHash Xor cchPassword
    wPasswordHash = wPasswordHash Xor &HCE4B&
    getExcelPasswordHash = wPasswordHash
End Function

Private Function RotateLeft_15bit(num As Long, Count As Long) As Long
    Dim outLong As Long
    Dim i As Long
    outLong = num
    For i = 0 To Count - 1
        outLong = ((outLong \ 2 ^ 14) And &H1) Or ((outLong * 2) And &H7FFF) 'Rotates left around 15 bits, kind of a signed rotateleft
    Next
    RotateLeft_15bit = outLong
End Function

13

对于使用SHA-512加密的Excel >2016受保护的工作表,接受的答案并不起作用,但考虑到Excel 2016使用开源的Office OpenXML规范,很容易绕过它。

这种方法也向后兼容,因此可以通过另一种方式打破旧的专有md5表格保护,而不是破解它。在尝试此方法之前,只需将版本从.xls另存为.xlsx即可。

方法

  1. .xlsx/.xlsm文件重命名为.zip
  2. 使用Windows资源管理器右键单击“全部提取”到一个文件夹中。
  3. 打开xl\worksheets文件夹,然后打开具有正确表格名称的文件。
  4. 搜索“sheetProtection”:

<sheetProtection algorithmName="SHA-512" hashValue="j1woDldvfHE8IVB1F82CN/pmfOdOkpxkkZURiZJSGISjkJRIfM1G7EFwJsEeE1H+sf7s6sLIYSCuHPJG5Tpozw==" saltValue="QX8YeX/qfspqhDemAUEwSw==" spinCount="100000" sheet="1" objects="1" scenarios="1"/>

  1. 删除整个节点并保存文件。
  2. 选择所有从提取文件的文件夹根目录中的文件,右键单击它并单击“发送到->压缩(zipped)文件夹”。
  3. 将生成的文件重命名为其原始的.xlsx/.xlsm扩展名。
打开文件后,该工作表上的保护将被取消。

1
实际上,它可以在Excel 2016受保护的工作表上运行,因为我刚刚使用它来解锁了这样一个文件。 - OutOfThisPlanet
我删除了整个sheetProtection Xml节点,在Excel 2016+上运行良好。谢谢! - Lugarini
1
它在2016年对我有效,关键是不要解压缩和重新压缩,而是像这个视频中所示覆盖文件。https://www.youtube.com/watch?v=Qwb0m15FN_0 - mgd
1
我在VS Code中使用以下正则表达式字符串进行替换:<sheetProtection[\S\s]*?/> - TheRizza
我尝试使用OP提供的代码和VBA代码来破解SHA-512 Excel工作表密码,但是VBA代码一直在运行,却没有成功。相反,删除<sheetProtection>确实起作用了。 - Kar.ma
这项工作也要在Excel文件中的VB脚本中完成吗? - undefined

0
Function breakIT()
   Dim pass, bin As String: Dim dec As Integer
   On Error Resume Next
   For dec = 0 To 2047
     bin = WorksheetFunction.Dec2Bin(dec)
     For char_last = 32 To 126
        pass = Right("0000000000" & bin, 11)
        pass = Replace(pass, "0", "A"): pass = Replace(pass, "1", "B")
        pass = pass & Chr(char_last)
        ActiveSheet.Unprotect pass
        If Not ActiveSheet.ProtectContents Then 
           MsgBox "Sheet unprotected! Optimal pass: " & pass: On Error GoTo 0: Exit function
        EndIf 
     Next
   Next
End Function


Sub Worksheet_pass_break()
If ActiveSheet.ProtectContents = True Then
    breakIT
Else
    Select Case MsgBox("Sheet not protected. Do you want to protect it now for testing?", vbYesNo, "Not protected")
     Case vbYes
        random_text = ""
        Randomize
        For i = 1 To 10: random_text = random_text & Chr(Int((94 * Rnd) + 32)): Next i
        ActiveSheet.Protect "#TEST_Pass#_123456" & random_text
        breakIT
    Case vbNo
        Exit Sub
    End Select
End If
End Sub

这只是问题中提供的代码示例的另一种形式,它并没有回答问题。 - robartsd

0

除了@Alexander Don'valderath的解决方法外,您可能还希望确保没有VBA在每次打开工作表时重新保护工作表。

(从Joji Thomas Eapen的原始answer编辑而来)
要解锁受密码保护的vbaProject:

  1. 使用十六进制编辑器(我使用的是HxD)打开vbaProject.bin文件
  2. 搜索“DPB=”并将其替换为“DPx=”
  3. 保存文件并将其复制回zip文件夹中(拖放操作即可)
  4. 打开XLSM/XLSX文件并确认出现“意外错误(40230)”错误
  5. 将其另存为新文件并审核VBA编辑器中的代码

-1

如果VBA不起作用,因为您有新的Excel,请将文件另存为与Excel 2003兼容的文件,如果要求额外安全性,请选择“否”。 然后所有带有VSB和一个可用密码的内容都将是AAAAAAAAA:D


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接