Раскручивание пароля с помощью 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 может использоваться в качестве пароля для листа внутри конкретной книги?

Ответ 1

Защита паролем листа Excel работает путем преобразования входного пароля в хеш и его сохранения. Хэш - это односторонний алгоритм, который разбивает биты, теряя некоторую информацию по пути, но генерируя отпечаток исходных данных. Из-за потери данных невозможно восстановить хеш, чтобы получить исходный пароль, но в будущем, если кто-то введет пароль, его можно будет хэшировать и сравнивать с сохраненным хешем. Это (обычно) делает его более безопасным, чем просто сохранение пароля в виде строки для сравнения.

Лучшее описание , которое я когда-либо встречал, о том, как работает алгоритм хеширования Excel, приведено на странице @mehow links, опубликованной Торбеном Кляйном. Его ответ можно сформулировать так:

  1. Хэш-функция Excel отображает большое количество возможных паролей на небольшое количество возможных хешей.
  2. Поскольку алгоритм хеширования генерирует такие маленькие хэши, 15 бит, число возможных хэшей составляет 2 ^ 15 = 32768 хешей.
  3. 32768 - это крошечное количество вещей, которые нужно попробовать при применении вычислительной мощности. Кляйн получает подмножество входных паролей, которые охватывают все возможные хеши.

Основываясь на этом описании функции хеширования Excel, следующий код генерирует тот же хэш, что и Excel, который можно использовать для тестирования функции Кляйна.

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

Ответ 2

Это не работает для листов, защищенных в 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, и защита полностью исчезнет. Вы можете сохранить как из старой версии в эту версию, если хотите использовать этот метод тоже.

Поэтому вместо того, чтобы взломать это, я просто изменил его на значение, к которому я знал пароль:

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

Пароль для этого хэша - AAABAABAABB|, и теперь он также может быть взломан при попытке использовать все возможные хэши, как показывает вопрос.

Повторно заархивируйте содержимое файла после сохранения этого XML файла, назовите его обратно xlsx/xlsm и откройте.

Ответ 3

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

Ответ 4

Кто-то сделал рабочий код vba, который изменяет пароль защиты vba на "макрос", для всех файлов excel, включая .xlsm(версии 2007+). Вы можете увидеть, как это работает, просматривая его код.

Здесь парень блог (кредиты, где он должен): http://lbeliarl.blogspot.com/2014/03/excel-removing-password-from-vba.html

Здесь файл, который выполняет работу: https://docs.google.com/file/d/0B6sFi5sSqEKbLUIwUTVhY3lWZE0/edit

Вставка из предыдущего сообщения из его блога:

Для файлов Excel 2007/2010 (.xlsm) выполните следующие действия:

  • Создайте новый .xlsm файл.
  • В части VBA установите простой пароль (например, "макрос" ).
  • Сохраните файл и выйдите.
  • Измените расширение файла на ".zip", откройте его любой программой архивирования.
  • Найдите файл: 'vbaProject.bin' (в папке 'xl').
  • Извлеките его из архива.
  • Откройте файл, который вы только что извлекли, с помощью шестнадцатеричного редактора.
  • Найдите и скопируйте значение из параметра DPB (значение в кавычке), например:   РОП = "282A84CBA1CBA1345FCCB154E20721DE77F7D2378D0EAC90427A22021A46E9CE6F17188A". (Это значение генерируется для пароля "macro". Вы можете использовать это значение DPB, чтобы пропустить шаги 1-8)

  • Сделайте шаги 4-7 для файла с неизвестным паролем (файл, который вы хотите разблокировать).

  • Измените значение DBP в этом файле на значение, которое вы скопировали на шаге 8.

    Если скопированное значение короче, чем в зашифрованном файле, вы должны заполнить отсутствующие символы с помощью 0 (ноль). Если значение больше - это не проблема (вставьте его как есть).

  • Сохраните файл vbaProject.bin и выйдите из шестнадцатеричного редактора.

  • Замените существующий файл 'vbaProject.bin' на измененный.
  • Измените расширение с .zip на '.xlsm'
  • Теперь откройте файл excel, который вам нужен, чтобы увидеть код VBA. Пароль для кода VBA будет просто макросом (как в примере, который я показываю здесь).