Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / productivity / Office / MS-Word

Brute Force Password Search by Interop/Automation

2.76/5 (8 votes)
14 Jun 2018CPOL10 min read 11.8K   319  
How to use the Microsoft Interop/Automation to implement parallel research of a Microsoft Office file password.

Introduction

Is it possible to recover a forgotten password for a Microsoft Office file using automation? The answer is yes, by the brute force via automation/Interop, the multithreading and a lot of quantifiable CPU time.

The main goal of this software is verify the capability of Interop to open the password protected file and also to check when a password is strong enough to resist attacks. But this software can be also used in a real world, to find a forgotten password about your owned files. In fact, it was written to open a file that the owner forgive the exact password.

Where to Get It?

The form with algorithm can be downloaded from here (^) and inserted in a your new Visual Studio project.

Why Use Interop / Automation ?

Microsoft Interop allows developers to manage the MS Office files and makes it easy to create a program that uses brute force to find a forgotten password:

  • It works very well on the Microsoft Office documents.
  • It's easy to implement.
  • It permits to avoid studying the cryptographic algorithm (and its eventually non-standard implementation) or to spend time studying and understanding the file structure of each kind (Excel .xls and .xlsx, Word .doc and .docx and so on).

On the opposite side:

  • It's not a time performant on the open file password protected operations.

Software Requirements

To use the software developed by Visual Studio 2017. It is required to have installed the Microsoft Office (or Excel or Word, according to the file type to work on) on the target computer .

error CS0234

If you have the error CS0234 , it means you need to reference the Office library. Open the menu Project, Add reference... and select the tab COM and scroll the list to Microsoft Word 16.0 Object Library or other version you have.

Image 1

Time Needed to Accomplish the Job

The brute force attack has a predictable amount of time needed to accomplish the job. It can be computed as combinations of ammissible chars powered by the maximum password testable length.

For example, if we work on a password composed just by uppercase letters and having the length in range between 1 and 6, then we have 26 chars to test, repeating them from 'A' to 'ZZZZZZ'.

The total combinations (mathematically more correctly term is dispositions) to be tested are:

  • 1 char ('A' to 'Z') : 26 ^ 1 = 26;
  • 2 chars ('AA' to 'ZZ': 26 ^ 2 = 676;
  • 3 chars ('AAA' to 'ZZZ'): 26 ^ 3 = 17.576;
  • 4 chars ('AAAA' to 'ZZZZ'): 26 ^ 4 = 456.976;
  • 5 chars ('AAAAA' to 'ZZZZZ'): 26 ^ 5 = 11.881.376;
  • 6 chars ('AAAAAA' to 'ZZZZZZ'): 26 ^ 6 = 308.915.776;

The sum is 321.272.406 of possible passwords.

Now, the last step for computing the time, is adding the time factor.

The old hardware used for testing obtained c.a. 1.500 test/minute. Then:

  • 321.272.406 combinations / 1.500 test/minute = 214.182 minutes
  • 214.182 minutes / 60 min/h = 3.570 hours
  • 3.570 hours / 24 h/day = 148 days (or 5 months).

The situation of 148 days in the worst case is represented by 'ZZZZZZ'. The best one is the password filled by just 'A' that is immediately tested and found.

It is possible to skip too short a password, starting, for example, from a 4 char length passwords (i.e., 'AAAA')
Of course, if we know the password length, it's a great improvement about the time we can save.

Reduced combinations avoiding the absolute unlikely password as 'RKWLPG' or 'TMQNTZ' (just because those are meaningless, then hard to remember or located in a nonsense order of the keyboards -to the opposite to 'QWERTY' that is it-) is not possible by algorithm and is a concrete risk to jump over the right one.

Standard Set of Chars to be Tested

To complete the information, it is useful to remember the real combinations have to be based on the set of chars that include all the possibilities. At least:

  • lowercase: 'a' to 'z': 26
  • uppercase 'A' to 'Z': 26
  • numbers: '0' to '9': 10
  • special chars: parenthesis (six), space, currency symbols (three or more), interpunctuation (six or more) and other: more than 20.

It sum up to 26+26+10+10 over 70 chars. then, if the password have a size of 5 chars, we obtain 70^1 +70^2 +70 ^3 +70^4 +70^5 =1.680.700.000 possible passwords to test (against 308.915.776 if used a single alphabet set as seen before).

I have to underline this software can useful if it will be used on your files, because you can reduce the complexity of all the possibilities. In fact, you know:

  • which char set is or is not applicable (for example, if you never used some special char or the uppercase set, you can exclude them from testing).
  • the minimum length of the password (for example, if you use password of 8 or more chars, it means you start the elaboration from that length saving a lot ot time)
Dreaming More CPU Speed

The test was conducted by a very old Intel i5 760 2.80GHz 4 cores. For those who need performance, around the end of 2018, it is planned processor Intel® Core™ i9 Extreme Edition having 18 cores and 36 threads, with a speed that can be represented by one teraflop (1012 FLOPS): the proposed computation time will be incredibly shrunk. I suppose from 1 month, it became 1 week.
Just to smile if you have no time to wait, now exists a a new supercomputer that can release 200,000 trillion calculations per second (200 petaflops, 200x 1015 FLOPS). I suppose the time will be shortened from a month to a single day or less.

What Can Be Parametrized

The software presented provides the possibility to choose:

  • The kind of characters that can be tried to guess the password: uppercase, lowercase, numbers. Actually, special characters are not inserted as available char set.
  • The password length range: the minimum and the maximum length to check: it is very useful to avoid to trash time to verify the too short passwords.
  • The number of core to be used: this feature is intended to limit the payload on the CPU, to maintain an every day responsible computer. More, the jobs are executed in a low priority mode, then they don't affect the regular usage.

Using the Code

The software uses a single form, that creates and starts multiple threads: each one loop tests sequentially a password obtained by the function PasswordNext() until the StopSearch() is false. When the password is achieved, a flag will be set by StopSearch(true).

Testing Char Set

The set of admitted chars is defined in the form through some checkboxes and it will be returned by the function AllowedCharsToString(): actually can manage:

  • lowercase letters
  • uppercase letters
  • numbers

Creating Non Invasive Threads

Brute force is a heavy CPU resource consumer and it transforms the computer in zombie. To allow you to continue to use it in almost normal conditions, the threads are created with a lowest priority. The CPU remains busy to 100% all the time along, but your interaction by other software or works have the priority: the operating system will serve you and will suspend the brute force until necessary.

Image 2

Below is the code that creates and starts all the threads: they will be inserted in a List<Thread> to reference them further. The instruction T.Priority is used to set the thread to the lowest priority.

C#
TTCll = new System.Collections.Generic.List<System.Threading.Thread>();
for (int numt = 0; numt < ThreadToUse; numt++)
{
    TextBox NumTxt = (TextBox)(EsecuzioneTLP.Controls
                     ["NumThread" + numt.ToString("00") + "Txt"]);
    var T = new System.Threading.Thread(() => { Runner(NumTxt); });
    T.Priority = System.Threading.ThreadPriority.Lowest;
    T.Start();
    TTCll.Add(T);                
}

Showing the Running Status

When we face with a very long running loops, it is very important to inform the user that everything is working and is not stuck. The software can use a selectable number of cores, then will be used TableLayoutPanel in the form that will contain startup generated Labels and Textboxes: each one will be bound to a different thread and they will be used to show the currently tested passwords.

C#
int ThreadToUse = int.Parse(MaxTasksTxt.Text);
ThreadPanel_Create(ThreadToUse );

Here, the form when it is running. At the bottom, with a more gray background, is visible the TableLayoutPanel with four threads numbered from '00' to '03', displaying the password they are currently testing: '6K', '6L', '6J', '6M'.

Image 3

Suggestions

If you will start a test, remember to disable the sleep/stand by function of your computer, otherwise the day after you could find the computer stopped.

The thread Function: Runner()

The main function, used by each thread, is named Runner(). Using the parameter NumTxt that is a TextBox, the loop can update the form about the current password to be tested. That TextBox was dynamically created in the TableLayoutPanel.

Creating Instance

The thread creates an instance of the software to be used to try to open the file protected password:

C#
var WApp = new Microsoft.Office.Interop.Word.Application(); 

The Main Loop

The loop that tests the various possible password is a while that checks, by StopSearch(), if the thread must stop because the right password was found.

The function's core call Open() with a password obtained by PasswordNext().

If It is the Right Password

If the tested password can open the file, then the routine performs those steps:

  • StopSearch(true) is called to set a flag.
  • Achivied() is called using the password as parameter to update the user interface.

Then, the resource WDoc can be released.

C#
try
{
    WDoc = WApp.Documents.Open(FileName, PasswordDocument: test , ReadOnly: true);
    StopSearch(true);

    Achivied(test); 

    WDoc.Close();
    System.Runtime.InteropServices.Marshal.ReleaseComObject(WDoc);
}

If It is Not the Right One

Calling WApp.Documents.Open() on a password protected file using a wrong one, raise an exception. This is the reason to wrap that instruction by try/catch.

Inside the catch is not necessary to perform any operation. In fact, WDoc is null. In case you want to do something with exception, the ex.Message string comparison must be changed according to the language used on the computer.

C#
if (ex.Message.Contains("La password non è corretta. Word non può aprire il documento."))

The Thread Ends

Last job of the routine is to release the Interop instance using the instruction:

C#
ReleaseComObject(WApp);

To make it more robust, the ReleaseComObject() is backed by a try/catch.

Which Password Next?

The function named PasswordNext() returns the password to be tested next. The first value is 'A' and will be followed by each single letter to arrive to 'Z'; after, will starts form 'a' to 'z' and '0' to '9' (the type of chars that compose the series come out from AllowedCharsToString().

C#
private char []  PasswordNext()
{
    char[] GiveBack; 

    lock (SyncLockerobjNewPassword)
    {
        // --- password to verify
        GiveBack = new char[PasswordToVerify.Length]; 

        // --- password to prepare to next round
        PasswordToVerify.CopyTo(GiveBack,0);
        //  prepare next pwd 
        bool riporto = false;
        for (int i = PasswordToVerify.Length - 1; i >= 0; i--)
        {
            // last char of the set?
            if (PasswordToVerify[i] != AllowedCC[AllowedlattertIdx])
            {       
                // increment
                PasswordToVerify[i] = 
                AllowedCC[(ammessistr.IndexOf(PasswordToVerify[i]) + 1)];                 
                riporto = false ;
                break;
            }
            else
            { 
                // zero
                PasswordToVerify[i] = AllowedCC[0];
                riporto = true;
            }
        }
        // --- insert new starting char on left side
        if ( riporto)
        {
            char [] tmp = new char[PasswordToVerify.Length ];
            PasswordToVerify.CopyTo( tmp,0) ;

            PasswordToVerify = new char[PasswordToVerify.Length + 1];
            PasswordToVerify[0] = AllowedCC[0];
            tmp.CopyTo(PasswordToVerify, 1);
        }
    }

    return GiveBack ;
}

I Got It !

Here, the form at the end of elaboration, when the password is found. It reports information about:

  • the last password tested by each thread (it is useless)
  • the password found (in this case, is "AB0")
  • the start time
  • the end time
  • the elapsed time to accomplish the job

Image 4

The start button remains disabled to prevent the user from inadvertently launching another run. To run another test, the software has to be restarted.

Change File to Target

To use the code against an Excel file, the line to modify is the WApp declaration, changing it to:

C#
var WApp = new Microsoft.Office.Interop.Excel.Application();      

Secondary Points of Interest

For new developer using the TableLayoutPanel, ThreadPanel_Create() can be a useful function to understand how to create columns at runtime, inserting controls like Label and TextBox. To note this control have always a column.

For who approach the Threading, there is nice example about the creation and synchronization to stop them according to a situation that became true in one of them.

Conclusions

The Microsoft password protection is strong enough if it respects the simple rule of any password: length (more than 8 chars), the usage of a large set of chars: uppercase and lowercase, numbers and special chars. But if you are looking for your lost password, you have a good change to recover it. If you are not in hurry, of course!

History

  • 14th June, 2018: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)