17

这段代码已经在网上流传了好几年——它显然能够提供一个密码来解密你不知道密码的 Excel 电子表格。

http://www.theofficeexperts.com/VBASamples/Excel02.htm

我对它的工作原理很感兴趣,但我似乎无法解决它。我假设它是在某个值下加密的,可以通过多种方式获得(网络上的一些地方说它会给你原始密码或另一个有效的密码)有点像公钥 -您可以拥有 100 个公钥,它们都可以与一个私钥一起使用。

在我看来,它似乎是在创建整数变量并用特定数字填充它们,然后再将该数字转换为相关字符。这些不总是一样的吗?如果是这样,是否有用于 Excel 保护的“主密码”?

谢谢大家!

编辑:我注意到我发布的示例代码中的For n = 32 To 126。与似乎是从空格到波浪号的所有字符的 ASCII 表进行交叉引用。这是某种我由于语法而无法理解的字典攻击吗?

4

5 回答 5

22
于 2012-10-12T04:36:38.237 回答
11

Edit (2020): From Excel 2013 on, apparently the protection scheme has changed. So the original answer only has historical significance anymore.

The new protection makes it near-impossible to retrieve the password by using state-of-the-art SHA-512 hashing. But why break it if you can simply pluck it out within seconds.

  • unzip the .xlsx or .xlsm file
  • edit xl/worksheets/sheet<num>.xml
  • search and remove <sheetProtection... /> tag
  • save, zip again, enjoy

Original answer (up to Excel 2010)

Fascinating - I knew the code snippet before, but not the explanation that brettdj posted. As the others explained, it is a brute-force search for hash collisions. Actually it seems to have been made by trial and error, since it does much more work than necessary (194560 combinations are generated, but there are only 32768 hashvalues possible.)

Excel's hash algorithm in short (as explained in http://chicago.sourceforge.net/devel/docs/excel/encrypt.html):

  1. Take the ascii code of each character of the passwort.
  2. Treat it as a 16-bit signed number. Shift its bits to the left, based on the position of the character (1 bit for first character, 2 for 2nd and so on)
  3. XOR all the characters together, giving a 16-bit signed int >=0.
  4. XOR that result with the length of the password and a magic number.

Knowing this, one can devise a brute-force search as follows:

  • The highest bit is always zero, so there are 15 bits to test.
  • Split them up into three counters each covering 5 bits. That way each counter can represent a printable ascii char.
  • Pack the ascii representation of those counters in a password string, in a way so that they do not affect each other.

The simplest way is to use a 11-character password and put the counters at position 1, 6 and 11. The bit-shifting in step 2 aligns the counter bits the right way: the first counter ("x") is shifted 1 bit, the second one ("y") 6 bits, the third one ("z") 11 bits. In a bitwise representation of the hash, the counters affect the following bits:

bit: 76543210 76543210
cnt: -zzzzyyy yyxxxxxz

The XOR operations can be ignored since the XOR argument is constant all the time. For the same reason, a constant offset (e.g. 64) can be added. Also it does not matter what character is used on the other password bytes (2-5, 7-10).

By iterating over all possible combinations of x, y, z you eventually find a password that gives the same hash value as the original one.

Public Sub demo()
    ' http://stackoverflow.com/questions/12852095/how-does-excels-worksheet-password-protection-work
    Dim x As Integer, y as Integer, z as Integer
    Dim part1 As String, part12 As String
    Dim sh As Worksheet
    Set sh = ThisWorkbook.Worksheets(1)

    sh.Protect "$ome_Insanely_Long_and_c0mplex_password! [(which i$ imp*ssible t0 re-member)]"

    For x = 64 To 95
        ' pad with dots, so that x, y and z affect nonoverlapping bits of the hash.
        part1 = Chr(x) + "...."
        For y = 64 To 95
            part12 = part1 + Chr(y) + "...."
            For z = 64 To 95
                On Error Resume Next
                    sh.Unprotect part12 + Chr(z)
                    If Err.Number = 0 Then
                        Debug.Print "Password: '" & part12 + Chr(z) & "'"
                        Exit Sub
                    End If
                On Error GoTo 0
            Next
        Next
    Next
End Sub
于 2012-10-18T10:08:18.950 回答
3

只是一个猜测,但在我看来,Excel 通过某种散列函数运行它来测试密码是否有效,该函数产生的结果范围非常小,并将其与存储的散列值进行比较。

据推测,这个函数正在做的是测试所有这些值,直到找到一个有效的值。从使用的值来看,散列函数产生了2^11*(126-31)个不同的值,所有这些值都可以由这段代码中产生的值产生。

我的分析假设这个例程有效。我没有测试过。

于 2012-10-12T04:20:41.820 回答
0

该代码使用加密密码 AAAAAAAAAA(SPACE) 到 BBBBBBBBBBB(~) 进行暴力搜索,其中 (SPACE) 是空格字符 (CHR(32)) 并且 (~) 当然是字符 126。找到密码后在消息框中显示密码。

当然,这意味着它只检查长度正好为 12 个字符且仅由大写字母 A (ASCII 65) 和 B (ASCII 66) 后跟可打印 ASCII 字符之一的密码。@mkingston 是正确的,它测试了 2^11*(126-31) 个不同的值。但是没有散列函数。我认为这不会破解许多电子表格。您最好使用AccessData 中的这些程序之一

有关 ActiveSheet.Protect 和 ActiveSheet.Unprotect 的更多详细信息,请参阅http://msdn.microsoft.com/en-us/library/office/aa191957(v=office.10).aspx

于 2012-10-12T04:26:03.113 回答
-3
Sub FindPassword()
    'Breaks worksheet password protection.
    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)
         Exit Sub
    End If
    Next: Next: Next: Next: Next: Next
    Next: Next: Next: Next: Next: Next
End Sub
于 2014-03-21T00:17:34.520 回答