使用VBA破解表密码

时间:2013-11-13 12:36:45

标签: excel vba excel-vba

我发现这个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字符串可以用作特定工作簿中工作表的密码?

6 个答案:

答案 0 :(得分:12)

Excel工作表密码保护的工作原理是将输入密码转换为哈希并存储它。哈希是一种单向算法,可以对比特进行处理,在此过程中丢失一些信息,但生成原始数据的指纹。由于数据丢失,无法反转哈希以获取原始密码,但将来如果有人输入密码,则可以对其进行哈希处理并与存储的哈希进行比较。这(通常)使得它比仅仅将密码存储为字符串以进行比较更安全。

强制Excel哈希算法的粗暴行为的best description by far I've encountered位于Torben Klein发布的@mehow链接页面上。他的回答可以概括为:

  1. Excel哈希函数将可能密码的大空间映射到可能的哈希值的小空间。
  2. 因为哈希算法会生成15位的小哈希值,所以哈希值的数量为2 ^ 15 = 32768个哈希值。
  3. 32768是应用计算能力时要尝试的一小部分事情。 Klein派生了一个输入密码的子集,涵盖了所有可能的哈希值。
  4. 基于this description of Excel's hashing function,以下代码生成与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
    

答案 1 :(得分:1)

这不适用于受Excel 2016保护的工作表,但是考虑到它向后兼容,这很容易解决。

如果解压缩xlsx / xlsm并转到xl\worksheets文件夹,则会在工作簿中找到与工作表相对应的xml文件列表。

打开与受保护的工作表相对应的文件,然后搜索“ sheetProtection”,在这种情况下,Excel似乎已将SHA-512与盐混合使用,这根本就不容易破解:

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

因此,我没有尝试破解它,而是将其更改为我知道密码的值:

<sheetProtection password="EB81" sheet="1" objects="1" scenarios="1"/>

该哈希的密码为AAABAABAABB|,现在也可以通过问题所显示的所有可能的哈希值来破解。

保存该xml文件后,重新压缩文件内容,并将其命名为xlsx / xlsm,然后使用上面的密码来保护工作表。

答案 2 :(得分: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

答案 3 :(得分:0)

除了@Alexander Don'valderath 解决方案之外,您可能还想确保每次打开工作表时都没有 vba 重新保护工作表。

(改编自 Joji Thomas Eapen 的原版 answer
要解锁受密码保护的 vbaProject,

  1. 用十六进制编辑器打开 vbaProject.bin 文件,我用的是 HxD
  2. 搜索 DPB= 并将其替换为 DPx=
  3. 保存文件并将其复制回 zip(同样,拖放工作)
  4. 打开 XLSM/XLSX 文件并确认“意外错误 (40230)”错误
  5. 将其保存到一个新文件并在 VBA 编辑器中查看代码

答案 4 :(得分:-1)

如果 VBA 不工作,因为您有新的 Excel,只需另存为与 Excel 2003 兼容的文件,如果要求额外的安全性,请选择否。 那么所有使用 vsb 和一个可用密码的都是 AAAAAAAAA :D

答案 5 :(得分:-2)

对于所有excel文件,包括.xlsm(2007+版本),有人制作了一个工作的vba代码,将vba保护密码更改为“macro”。你可以通过浏览他的代码来了解它是如何工作的。

这是个人博客(信用到期):http://lbeliarl.blogspot.com/2014/03/excel-removing-password-from-vba.html

以下是完成工作的文件:https://docs.google.com/file/d/0B6sFi5sSqEKbLUIwUTVhY3lWZE0/edit

从他博客的上一篇文章中粘贴:

对于Excel 2007/2010(.xlsm)文件,请执行以下步骤:

  1. 创建一个新的.xlsm文件。
  2. 在VBA部分中,设置一个简单的密码(例如'macro')。
  3. 保存文件并退出。
  4. 将文件扩展名更改为“.zip”,由任何归档程序打开。
  5. 找到文件:'vbaProject.bin'(在'xl'文件夹中)。
  6. 从存档中提取。
  7. 使用十六进制编辑器打开刚解压缩的文件。
  8. 查找并复制参数DPB中的值(引号中的值),例如:     DPB = “282A84CBA1CBA1345FCCB154E20721DE77F7D2378D0EAC90427A22021A46E9CE6F17188A”。 (为“宏”密码生成此值。您可以使用此DPB值跳过步骤1-8)

  9. 对于密码未知的文件(要解锁的文件)执行步骤4-7。

  10. 根据您在步骤8中复制的值更改此文件中的DBP值。

      
        

    如果复制的值比加密文件中的短,则应使用0(零)填充缺少的字符。如果值更长 - 这不是问题(按原样粘贴)。

      
  11. 保存'vbaProject.bin'文件并退出十六进制编辑器。

  12. 将现有的'vbaProject.bin'文件替换为已修改的文件。
  13. 将“.zip”的扩展名更改回“.xlsm”
  14. 现在,打开您需要查看VBA代码的excel文件.VBA代码的密码 将只是宏(如我在这里展示的例子)。