sexta-feira, 7 de outubro de 2011

Not all bugs are exploitable

Those who are, we call them vulnerabilities. Which is not the case of the bug I found in Notepad++ and it’s the subject of this post. The bug is triggered when setting the parsing Language of an opened document to "User-Defined"; exit Notepad++ while the document is still open, and then, start Notepad++. Every time Notepad++ is run it will crash with a message stating the error:



At the crash point we can observe the thread state:

k
ChildEBP RetAddr 
WARNING: Stack unwind information not available. Following frames may be wrong.
000df0d8 1001c863 SciLexer!Scintilla_DirectFunction+0x42e65
000df0f4 1001ca7b SciLexer+0x1c863
000e1090 100044fa SciLexer+0x1ca7b
000e10b8 10025c2b SciLexer+0x44fa
000e10dc 100272ec SciLexer+0x25c2b
000e1190 10029ca7 SciLexer+0x272ec
*** WARNING: Unable to verify checksum for npp.exe
*** ERROR: Module load completed but symbols could not be loaded for npp.exe
000e11a0 0047a597 SciLexer+0x29ca7
000e11c0 004811cd npp+0x7a597
000e11d4 0043b88c npp+0x811cd
000e1698 000e1688 npp+0x3b88c
000e169c 000e19ac 0xe1688
000e16a0 004d0ee8 0xe19ac
000e19ac 00400000 npp+0xd0ee8
000e19b0 00040278 npp
000e19b4 000302a8 0x40278
000e19b8 00000000 0x302a8

r
eax=00000000 ebx=00000000 ecx=00eadc40 edx=003b0608 esi=000df118 edi=00eaddf0
eip=1006cb0d esp=000def10 ebp=000df0d8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00010202
SciLexer!Scintilla_DirectFunction+0x42e65:
1006cb0d 8b38            mov     edi,dword ptr [eax]  ds:0023:00000000=????????

It seems that we have a null dereferenced pointer in the SciLexer module; with EAX=0, and, as there’s no null page allocated, we get a crash with access denied error. Let’s give it a look. EAX comes from ESI, so let’s see what’s there:

!address 00eaddf0
Failed to map Heaps (error 80004005)
Usage:                 
Allocation Base:        00e90000
Base Address:           00e90000
End Address:            00eb6000
Region Size:            00026000
Type:                   00020000  MEM_PRIVATE
State:                  00001000  MEM_COMMIT
Protect:                00000004  PAGE_READWRITE

!heap -x 00eaddf0
Entry     User      Heap      Segment       Size  PrevSize  Unused    Flags
-----------------------------------------------------------------------------
00eadde8  00eaddf0  003b0000  00e90000       428        58        18  busy extra fill

There’s no information of interest from the heap allocator as Notepad++ uses its own allocator. So, I started digging a little more to know if I could somehow influence this null reference to become something else more interesting from security viewpoint. Reversing some code of the application and analyzing the dump, I managed to get to some conclusions.
What is happening is that the document parsing language is saved in the session.xml file. The file is kept by Notepad++ in the AppData\Roaming\Notepad++ profile directory. This configuration file is always updated and saved when Notepad++ is closed by the user.

 
As there’s no “User-Defined” language defined, Notepad++ will allocate a language object that’s initialized with zeros by the time it is allocated. When parsing the file it will apply this empty object without verifying that there’s no valid data in it.


We got a "use an un-initialized object", and in consequence a crash. Although the object is not initialized, "sadly" it isn’t exploitable because as I said it is zeroed out on allocation.  This conclusions can be validated by doing the following:

1. Create a user defined language file. Menu View, open User-Defined dialog.
2. Name it User-Defined. 
3. Save it.


If you try now to do the same thing as described before, Notepad++ won’t crash anymore. If you go to the Language menu you will see a weird thing, there will be now two “User-Defined” items. Whichever you choose you'll get the same results, it will apply the previously defined "User-Defined" parsing language and no crash.


While the bug is not corrected by the Notepad++ developer team, you can solve this issue just by deleting the session.xml file. It will be recreated next time you start Notepad++.

Again, not all bugs are exploitable. Those who aren't remain just... bugs!

Sem comentários: