r12 is the base address of a structure. The instruction reads a word value from the structure using a delta value that is RCX*2. In our case, RCX is 0`ffffffff which cannot be a valid delta value as the size of the memory region of the structure is only 4000 bytes as seen below. Therefore by executing the instruction it reads out of the bounds of the structure, that is likely an invalid memory address.

As seen below, movzx now tries to access to a valid memory region recently allocated by .dvalloc, filled with zeroes. If we let the program execute now it doesn't crash. Even if we refresh the SVG file it doesn't cause a read access violation because now the memory movzx tries to access is a valid address in the virtual address space.

Using the PoC, later on the execution the program doesn't read the tainted data from the second structure that is verified by processor breakpoint.

The tainted word value was zero as .dvalloc filled the memory with zeroes. Since we know the address of the word value we can try all the 65536 possibilities and watch what happens when processing the different word values. To achieve this I wrote a wrapper HTML which calls the SVG file periodically. Also, I set up the below commands which does the job automatically, so in every iteration we provide different tainted input in range of 0 to 65535.

If this code can be reached when [rdi+7c] is the tainted data that might have consequence due to the complexity of the code paths in this function. I however was unable to reach this code path in my experience.

The address of invalid read is predictable by the attacker as it's always 2 x 0`ffffffff plus something which can be filled with attacker controlled data. But this doesn't seem to be relevant as Microsoft just confirmed that they had finished their investigation into this crash and as they say "[we] can confirm that this crash is caused by a read AV which is not exploitable." I believe them and I no longer investigate this but will focus on other crashes, but thought to share this.

November 12, 2012

When performing security testing of the native application I often attach Windbg to the target process. The obvious benefit of this methodology is that when an exception occurs it's possible to immediately analyze and save the state information of the program. There is one more important benefit, and that is you can get additional information of the running application if you set certain options beforehand. For example, sxn ud command sets up the debugger to send notification when a module is unloaded. I find very useful to analyze Windbg log during security testing, rather than just relying to find exception or memory corruption.

Some time ago, during testing Internet Explorer 9, I noticed that Windbg screen had been flooded with the following messages.

The application continued running without displaying more of these messages and there was no sign the integrity of the application corrupted. My first thought was it's the result of one of Windbg commands I set up earlier just before executing the test. The second thought was that it is unlikely because it seems to be a CRT error message, that most likely comes from the runtime DLL. I knew there is a way to send message to the debugger from an executable and that is to call OutputDebugString function.

I set up a breakpoint for OutputDebugString, and rerun the test. Here is the call stack when the breakpoint hit.

string2 and count both look healthy however string1 is NULL but the API documentation expects a string.

To make sure everything is ok with string2 let's check.

0:005> du @rdx00000000`60903848 "http://"

It's fine, so the only problem with parameter string1 and the problem is that a NULL pointer is passed rather than a pointer to the string.

Microsoft long time ago added security enhancements in the CRT library. One of them involves to call invalid parameter handler which, for example, checks for NULL pointer parameters, and we terminate gracefully rather than with invalid memory access exception.

As you can see the return value is the highest positive value that can be represented in signed 32-bit. If the application is not prepared to handle this edge value it could cause problem later on the execution. Fortunately, that was not the case with Internet Explorer.

October 8, 2012

The Windows version of Adobe Flash Player in Firefox has protected mode functionality. The concept of this mode is similar to the sandbox concept in Chrome: there is a broker process and a renderer process. The renderer process is running in low-integrity mode, and communicating with the broker process. The broker process is to give permission for legitimate system change but to reject questionable request made by the renderer process. The basic idea is the flash file is loaded and executed by the renderer process so, any non-legitimate invocation occurs by a vulnerability it will be rejected by the broker process.

Possible ways to circumvent the protection provided by protected mode include the followings. Corrupt the borkerer process to accept non-legitimate request from the renderer process. Or find Windows vulnerability to escalate right in low-integrity (i.e. renderer) process. Since the previous implementation when we didn't have the protected mode functionality is still available in the Flash Player it sounds to be logical by the attacker to disable protected mode functionality so the flash file is loaded and executed without sandbox protection. I'm exploring the latter further.

I examined NPSWF32_11_4_402_278.dll (11,264,432 bytes) file that is used in Firefox. In my test environment the DLL was located in C:\Windows\SysWOW64\Macromed\Flash folder. This file has the logic to decide if the flash file should be loaded and executed with or without sandbox protection. Flash Player uses a global pointer variable at fixed address (RVA: 0a2be70h) to store if sandbox mode should be used (1/0: with/without sandbox).

The value via the global pointer set to 1 by default (sandbox enabled) but it can be overwritten by adding ProtectedMode = 0 line to mms.cfg file that is located in the folder mentioned above.

Both the value and the page of the global pointer have the memory protection flags of read and write and since the global pointer is at a fixed address it's possible to overwrite it without changing memory protection flags or guessing the address.

Even though there is a need for a vulnerability to overwrite the global pointer table from security point of view it would be logical to discard the fixed address method and the writable memory protection flag. Using random address with read only page (apply writable flag when it's needed) would be more appropriate.

Here come some research artifacts.

Hijacking global pointer in Windbg. Higlighted dword is our new protected mode flag that is disabled.

September 9, 2012

This blog post discusses the idea to use Windbg as hex editor. It consists of the followings: the advantage of using this approach, and the initial steps to getting started. Possible risks are discussed at the end of the post.

I often use hex editor to examine binaries. Even though some of them have rich feature set built-in sometimes there is a need to use special functionality that goes beyond the capability of any hex editor. Some hex editors have plugin interface so for them it's possible to write special functionality that accounts people needs. Although this is true, I have some plugin commands already written for Windbg, and there should not be a reason to code them again to work with some hex-editor, too. That would mean I should maintain both code base in the future which is not what I want.

In the recent days, I was thinking about what if I give it a try to tentatively use Windbg as a static hex editor. I was thinking about that I could use my plugin commands, and many built-in Windbg commands. It sounds very good because those commands are powerful. My second thought was if there was anything that I can achieve in hex editor but cannot in Windbg. I can't name anything so far. Beyond that, I don't even miss the graphical interface.

To use Windbg as hex editor the first things that needs to be done is to open an application (say notepad.exe) to get Windbg prompt. In the further steps, there is nothing to do with the application. Once the prompt is given it waits for command to execute. .dvalloc command is used to allocate memory. .readmem command is to copy the the content of the file to the allocated memory area. There is a script called LoadFile.wds [SkyDrive] that does the job so it's enough to execute this with the correct parameters. Below is the script.

Important safety note is that the script uses .dvalloc command to allocate the memory for the data. As a consequence, the memory area has the protection flag of PAGE_EXECUTE_READWRITE. Therefore code execution from the memory page is possible even though it requires series of mistakes to make.

September 2, 2012

In today's post I'm writing about an arbitrary address write bug in Flash Player in Firefox (CVE-2012-4171) that is now fixed.

The issue was reported to Mozilla, but the fix made by Adobe as it turned out it was a bug in the Flash Player. The bug was tracked in Mozilla's bug tracking system (BugZilla) here [still restricted at the time of writing].

To trigger this vulnerability there is no requirement to use malformed data in any way. All the constructs can be legitimate. The PoC demonstrates when the security dialog box is shown it is possible to navigate to an other page that pops up another security dialog while the first dialog is still visible. When the second dialog is OK'd Flash Player crashes.

At line (1) [ESI+4] is an address in a valid heap region. The heap can be arranged to contain user controlled data. Therefore, at line (2) an attacker can write arbitrary address using add instruction. Due to depending on add instruction the attacker has limited control what data to write.

Below is the timeline for the fix.

Days

Date

Channel

Action

0 days

25-Jan-2010

E-mail

Report sent to Mozilla.

0 days

25-Jan-2010

E-mail

Mozilla confirms the behavior described in the report. A case opened in the bug tracking database (BugZilla).

731 days

26-Jan-2012

BugZilla

A Mozilla engineer says he can reproduce the issue with Firefox 9 on Windows 7 but cannot reproduce with nightly build.

731 days

26-Jan-2012

BugZilla

An Adobe engineer says they will triage this issue ASAP.

749 days

13-Feb-2012

BugZilla

A Mozilla engineer asks for status update from Adobe.

749 days

13-Feb-2012

BugZilla

An Adobe engineer confirms he cannot reproduce the crash.

749 days

13-Feb-2012

BugZilla

An Adobe engineer confirms he can reproduce the crash by experimenting with waiting times before clicking "OK" on the prompt.

749 days

13-Feb-2012

BugZilla

Reporter recommends to switch off plugin-container introduced since the report to get consistent crash state.

August 28, 2012

During the Bank Holiday weekend I was working on testing and stabilizing one of my Windbg extension commands which detects read-before-write bugs. According to the test result some detection appeared to be false positive, and in this post I discuss a case that is interesting to me.

Instead of analyzing the test result in the Windbg log file I decided to do it in IDA. I took the errors from the Windbg log and simply highlighted the instructions causing read-before-write in IDA. The highlight idea was borrowed from team ZDI (thanks).

Below is the code snippet wherein an error detected that appears to be a false positive.

There are two questions need answering:

Why is it a false positive detection?

Why the detection was mistakenly issued?

Answering why is it a false positive question is very straightforward. void* is pushed onto the stack that is a parameter for delete(). delete() uses cdecl calling convention so it doesn't clean-up void* on the stack but pop ecx in the red line does. pop ecx reads void*. The memory address void* read from has been written by push instruction. So the red line cannot be a read-before-write access.

Answering the second question: why the detection was mistakenly issued is a bit more complex and requires knowledge how my Windbg plugin extension works - read the principles here if you like. When push [ebp+var_78] is executed it does the followings. First, it reads var_78 local variable, then it writes (pushes) var_78 onto the stack. The address of the read access and the address of the write access are both stack memory addresses. In this example, the protection flags were set on stack memory region by the Windbg command extension. As mentioned above when push is executed read access occurs first. We handle this by removing the protection flags and let the push execute. Since the memory protection flags removed push didn't have a chance to cause a write access exception, therefore the address is not added to the list of written addresses. Later on the execution, pop causes a read access violation and the plugin checks if the address has been written. Since the address is not on the list of written addresses it issues a read-before-write notification, mistakenly. The answer in short is because we didn't catch the write access of push.

The current implementation wrongly assumes that an instruction could cause either read or write access. As seen above, in fact, an instruction could cause both read and write accesses. A possible fix would be to deal with the situation of multiple accesses. However, I don't think it's a priority to implement at the moment because it's possible to do a post process on the output log to mark or to remove these situations when showed in IDA.

August 20, 2012

In 2009 Mozilla fixed one of the vulnerability (CVE-2009-2467) I reported them. It had allowed to reference freed object leading to code execution. Some time after this in 2010 I got interested researching this class of security bugs. I pursued dynamic approach to discover them but I wanted different approach than feeding the application with fuzzed data. It was also a requirement to discover these problems in binaries without having source code or debug information available.

I thought it would be nice to make it visible if a pointer is dangling. I knew detecting the pointer that is dangling could come with lots of false positives because some of them cannot be referenced from the execution flow.

Anyway, I came up with the following train of thought. malloc() is used to allocate a region of memory on the heap. The pointer referencing to the region of memory can be on the stack or on another region of the heap. So we need to handle the situation in a different way if a pointer is a dangling pointer on the stack or on the heap.

I kept working on this approach and thought we need to maintain a structure what region of memory was allocated and freed. I thought when free() is called we could check if there is a reference to the freed memory. Here is a skeleton of the approach I draw back in 2010 - it's unprofessional and not so important so you might wanna continue reading instead... :)

The solution above wouldn't have worked in practice however. The conceptual problem here is if there is a reference to a freed object it doesn't mean the code would use the pointer is reachable. When a region of memory is freed the reference might exist to the freed object even if you explicitly set it to NULL. This is because the compiler optimizes this out if it cannot be reached. Another conceptual problem is the original idea itself that is we depend on the check for the references only when free() is called.

I had discussed this idea to people how could this be improved but concluded none of the solutions would be practically applicable. Possible improvements involve timing, and applied static analysis. Static analysis in dynamic approach might be an area to explore further but this would require significant research effort and showed only a little benefit that time.

The low-level constructs are complex so I knew we could detect something that indicates the presence of dangling pointer because in a complex environment it's so big the playground. I suspended working on this for a long time, however, with the fact in my mind that I have a solution that show the sign of working. It was just not optimal enough to use it in practice.

Couple of weeks ago I started working on a debugger extension to place data breakpoint on arbitrary size of the memory. I had a huge success and already built twofunctionalities on it - both of them detect possible security problems. Thought why not give it a try to explore the old dangling pointer project further involving this new approach.

From the previous posts, you might know that it's possible to track data access, and to determine the kind of the access that is either read or write access. By applying hook on malloc() and on free() we can maintain a list of allocated and freed memory blocks. When there is a read data access to a pointer to freed memory we can issue a notification: pointer to freed memory has been read.

When a freed pointer is read it might not cause a crash later on the execution but definitely could do if the pointer is dereferenced. It is possible, for example, a lot of fuzzing cases cause the application to read freed pointer but the bugs remain undetected because they are not dereferenced. I'm particularly interested researching this approach further on JIT emitted code.

Anyway, here is the assembly code for the above C code. I highlighted the area when the pointer to the freed memory is read.

Here come the details of the code that is built on the top of the functionality involving detecting uninitialized read access to stack memory.

With the current implementation it's possible to make it visible how certain integers on the stack are being treated: whether signed or unsigned. This means if there is an integer that is accessed from multiple locations in the execution flow and we successfully determined how the integer was treated at each location in the execution flow we are able to tell if the integer is treated both signed and unsigned.

When there is a read access to the stack memory (a local variable read) and the instruction causing the read access exception is CMP we read the next instruction. If the next instruction is one of the followings the comparison is signed because these jumps based on signed comparisons: JG, JGE, JL, JLE, JNG, JNGE, JNL, JNLE. If the next instruction is one of the following the comparison is unsigned: JA, JAE, JB, JBE, JNA, JNAE, JNB, JNBE. Below is an example.

Signedness conversion is not a vulnerability but easily could be. For example, when the developer eliminates a signed/unsigned mismatch compiler warning in an if() condition by using explicit typecast. This could lead to the situation the program works normally but when the variable contains an unexpected value the execution continues on a different code path than it should due to the signedness conversion.

And here is the corresponding log of the program that is a Windbg extension. The log is verbose showing both read and write stack memory accesses. I highlighted the parts when the signedness of the comparison determined so you can match the parts to the source code above. You can also see when a variable is treated both as signed and as unsigned. U stands for unsigned comparison, S stands for signed comparison.

In the log l-t is set to disable step to next source line and use step to next instruction instead. sxi av is used to let the event callback implementation handle the exception. 18f000 is stack base address 1000 is the size. 56 is to set some flags including verbose logging, etc.

August 8, 2012

Data that is read from the memory can be treated as signed integer or unsigned integer. It's possible that at some stage of the execution the integer is treated as unsigned integer but other point of the execution it's treated as signed integer. When it comes to write code there could be circumstances when you might not be immediately aware how the integer is treated unless you take an extra care, for example, by looking at the compiled code. This is definitely an attack surface, and the root cause of lots of published vulnerabilities.

In case you want to see some examples what I mean, earlier last year, I wrote a little about experiences regarding signed/unsigned comparisons.

Some time ago, I started developing a Windbg plugin command that has a tracing functionality, and the ability to break in the debugger when a signed comparison is reached. However, if EIP is not in user defined range e.g. due to an API call, the program executes normally. When EIP is in the user defined range again the program resumes tracing.

I was able to trace some function in a Visual C++ project, but it was needed to run l-t command beforehand to step by assembly instructions rather than source lines. Here is how to use Windbg in VS.

This plugin can be extended to work with other signed instructions than signed comparison ones. In addition, the plugin can be extended to execute the program until comparison is reached rather than to trace, in a similar way to the working of the ph command.

One possible area to explore further is to record how the data that is read from the memory is treated in point of signedness. Also, to detect any weak points to attack, or even to detect signedness conversions.

July 24, 2012

As I mentioned in the previous post I developed a program that is able to trace when the stack memory is being accessed. This time, I improved this program so if there is a read access to the portion of the stack memory that was not written before it issues a read-before-write notification. This happens when for example an uninitialized variable is being read.

Here is one of the erroneous C program I tested my test tool with. The C program reads uninitialized variable both in process and process2 functions from the CONTEXT structure. Highlighted the lines accessing uninitialized memory.

July 8, 2012

In the previous post I wrote about a concept to intercept when arbitrary region of the memory is being accessed.

Below is an example output of the Windbg extension. I set it to monitor when the stack memory of the current thread (Address: 18d000 Size: 3000) is being accessed, and to break in when there is a call to other module (Break reason: 2).

In the log you can see the address where the memory access occurred and the instruction caused the memory access. Also, you can see the address of the data being accessed, and the type of the data access (R for read, W for write).

July 1, 2012

When debugging data formats I sometimes think about how cool would be to have a debugger command that would allow me to place data access breakpoint on arbitrary region of the memory. Certainly, I can put hardware breakpoint on memory region with the restrictions that the size of the region is either 1, 2 or 4 bytes on IA32 architecture.

But what if I want to place a breakpoint on a data dump that has a size of greater than 4 bytes. For example, I want to do this to see what location within the region would be first accessed. Normally, there is no way to do this because of the lack of the support IA32 architecture provides. Software solution is possible but not implemented in debuggers such as in Ollydbg and in Windbg.

What you could do in these circumstances is to guess where the code parsing the data starts, and place a breakpoint on the execution flow, so when you break in the debugger you can trace the code from that point and watch the data flow. This is likely to be tedious process because you spend time stepping through code you are not interested. The other ideas tend to be even more tedious, and require prepration work (hooking etc.) We shouldn't forget that the reason we want to place breakpoint on memory region is usually to narrow down the scope of total debugging.

Some time ago I've seen how Armadillo protection uses debugge/debugger process to mark encrypted pages and when there is an access to the page it gets decrypted and executed on-the-fly. Also, EMET (Enhanced Mitigation Experience Toolkit) in the heap spray mitigation function uses to mark certain pages as unaccessible so the system cannot allocate memory to that address. This has inspired me how to write a plugin that allows me to place data breakpoint on arbitrary memory region. Yay!

Using VirtualProtect it's possible to disable all access to the memory page in the process address space. I however don't use VirtualProtect in the plugin but use VirtualProtectEx instead because the extended version allows me to disable all access to the memory in specified process rather than the current process.

The prototype has been developed as an extension command for Windbg. It requires two parameters describing the breakpoint: the address and the size of the region. When data is accessed within this region the we break in the debugger.

When the extension command runs it locates the base address of the memory page the specified region belongs to. Next, PAGE_NOACCESS protection flag is set for the memory page. This allows us to filter any access to the memory page via exception handling.

When the target runs in the debugger, and if there is an attempt to read from the protected page it results in an access violation. Due to this, the exception event callback implemented in the Windbg extension is executed. This callback verifies if the address of inaccessible data is within the region of the data breakpoint. If it is we restore the original protection flags for the page and break in the debugger - breakpoint hit. Otherwise, we restore the original protection flag to execute the single instruction previously generated the exception. Then we restore the protection flags do disable all access and continue to run the application until there is an attempt to read from the protected page resulting in an access violation.

The exception information is stored in EXCEPTION_RECORD structure which is available in the exception even callback function. Exception->ExceptionAddress is the address where the exception occurred. Exception->ExceptionInformation[1] is the address of the inaccessible data. More information on exception is available here.

Before I run the plugin command I also run sxn av so if access violation occurs we don't break in the debugger but get notification of the exception. Thus we let the event callback handle the exception.

When the memory page is too big - irrespectively of the breakpoint size - it might be possible it's being accessed too many times. In this case, the debugging tends to be extremely slow because of the frequent context switches between the target process and the debugger.

An enhancement of this plugin would be to let the execution continue when a data is accessed but to record each address being accessed so we can trace the memory access for certain memory regions.

Add the following code that calls the C# function. But make sure to to copy ExtensionUtils.tlb and ExtensionUtils.dll files to directory that has been added to the (additional) include directories in the project settings.