Tuesday, 10 July 2007

Microsoft Outlook PSTs: Safe or not?

Well I had such a lot of fun looking at SourceSafe password protection, I thought I'd move on to another product that uses password protection, Microsoft Outlook.

I am working with Microsoft Outlook 2002 (10.6516.6626) SP3 at the moment, so I can't guarantee that any of the information included in this article will work for any other version.

The protection I am interested in today is protection on the Outlook Data (.PST) Files. I want to know if I can access the PST file data without a password, even if it is "secured" with one.

I have created a new PST file and set it to use password protection, with a password of 'adad'.

Upon opening Outlook, I try to open the PST (File -> Open -> Outlook Data File...) at which point I am presented with a password request dialog.

I type in a password ('fred') and click OK, to be presented with a message box telling me the password is incorrect.

At this point, I attach to Outlook using OllyDBG and start having a look around:

  1. Start Debug in "Execute until user code" mode

  2. Click OK on the wrong password dialog

  3. Breakpoint hit in OllyDBG in a message proc in the module MSPST32

  4. I want to get out of the message proc into something more useful so I start Debug again in "Execute until Return" mode

  5. Return from the proc, and the next one (it is the same thing)

  6. Find myself in the proc +2390 which is starting to look more interesting

  7. Notice a call to GetDlgItemTextA in the proc, which I guess is when the password I have entered is read, so set a breakpoint on the next line (+23AE)

  8. Run the code, and retry the password

  9. Breakpoint hits at +23AE, and notice my password ('fred') at EBP-10

The code looks like this in the proc I am examining:

+23A8CALLNEAR DWORD PTR DS:[<&USER32.GetDlgItemTextA>]
+23AELEAEAX, DWORD PTR SS:[EBP-10]
+23B1PUSHEAX
+23B2CALLMSPST32.+5AAF
+23B7MOVEBX, EAX
+23B9PUSH10
+23BBLEAEAX, DWORD PTR SS:[EBP-10]
+23BEPUSH0A
+23C0PUSHEAX
+23C1CALL<&MSVCRT.memset>
+23C6MOVESI, DWORD PTR SS:[EBP+C]
+23C9ADDESP, 0C
+23CCCMPDWORD PTR DS:[esi+1C], EBX
+23CFJEMSPST32.+2410

Upon stepping through the code, I can see my password being passed into the proc called at +23B2, and a value being returned in EAX from this. I presume that this proc is where the password is coded to whatever format is used by Outlook (I may explore this another day).

If I step down to the CMP at +23CC, I notice that the value in EAX (which was moved to EBX), is compared with a value at ESI+1C. If the value is different (which it will be), the JE is not taken at +23CF. If the JE is not taken, it is in the code following this point that the invalid password dialog is displayed to me. This leads me to concluce the ESI+1C must contain the password that is associated with the PST file.

To see if this is where the password is verified, I force the JE at +23CF by changing the Z register to on (1) and then continue execution - and the PST file opens in Outlook, and I have full access to it!

What is also interesting is that if I close the PST, and then reopen it (without closing Outlook) I am not presented with the password dialog again - it just opens as it did the first time. Outlook seems to cache the fact that the PST can be opened during this session and doesn't recheck the password security.

Just to see whether I can remove the security without manually forcing the JE at +23CF every time, I modify the JE to a JMP. I can then open any password protected PST by entering any password I want.

However, it is worth noting that modfiying the JE to a JMP doesn't always work. Sometimes the MSPST32 module is unloaded and reloaded into memory (by MSMAPI32) and the modified JE is overwritten.

I'm sure a memory patcher could be produced that would monitor and correct this automatically, or of course the actual DLL itself could be patched.

In conclusion, it appears that the PST password security could be relatively easily overcome in Outlook and that any password-protected PSTs cannot necessarily be considered secure.

No comments: