The blog continues at suszter.com/ReversingOnWindows

April 28, 2012

Testing Firefox and Chrome on fuzzed SVG files

Fuzzer: My first SVG fuzzer (called SVGz)
Options: Switch two randomly selected tags (which is the only one mode at the moment)
Number of template files: 659
Size of the smallest template file: 140 byte
Size of the largest template file: 32M
Number of mutated files to test with: 222,888

Firefox: One crash - Bug 747661
Chrome: Some crashes with similar state - Issue 124585

Neither of crashes are exploitable for code execution.

The SVG files were processed in the same browser instance until crash occurred, to save some time that bootstrap and shutdown would require. Firefox and Chrome were tested simultaneously, and the test took about 4 days to complete.

April 16, 2012

Undefined behavior in strncpy() explained

Microsoft says the behavior of strncpy() is undefined if the source and destination strings overlap. Below is the x86 disassembly code of msvcr100.dll!strncpy to see what behavior we can expect in certain scenarios.

The function is longer than functionally required because, when it's possible, it uses dword size to access to the memory, otherwise it uses byte size.

In the disassembly code below, I highlighted the memory read and write instructions as well as the instructions increment the pointers to the source and destination strings. We will focus on the highlighted areas.

ESI is the pointer in the source string, EDI is the pointer in the destination string. Each time when the memory is read or written either the source or destination pointer is incremented. The value of the increment is either byte or word size.

Let's assume the strings overlap. There are three possible scenarios.

Scenario #1. The pointer to the source string is greater than the pointer to the destination string. We copy the data from the higher memory address to the lower memory address, and we know the strings overlap. Therefore, we will overwrite data in the source string. Since the data is read before it is overwritten, it doesn't lead to misbehavior.

Scenario #2. The pointer to the source string is equal to the pointer to the destination string. Same as Scenario #1.

Scenario #3. The pointer to the destination string is greater than the pointer to the source string. We copy the data from the lower memory address to the higher memory address, and we know the strings overlap. The data in the source string is overwritten before it is read leading to misbehavior.
6E9A2AD0  mov         ecx,dword ptr [esp+0Ch]
6E9A2AD4  push        edi
6E9A2AD5  test        ecx,ecx
6E9A2AD7  je          6E9A2B6F
6E9A2ADD  push        esi
6E9A2ADE  push        ebx
6E9A2ADF  mov         ebx,ecx
6E9A2AE1  mov         esi,dword ptr [esp+14h]
6E9A2AE5  test        esi,3
6E9A2AEB  mov         edi,dword ptr [esp+10h]
6E9A2AEF  jne         6E9A2AFC
6E9A2AF1  shr         ecx,2
6E9A2AF4  jne         6E9A2B7F
6E9A2AFA  jmp         6E9A2B23
6E9A2AFC  mov         al,byte ptr [esi]
6E9A2AFE  add         esi,1
6E9A2B01  mov         byte ptr [edi],al
6E9A2B03  add         edi,1
6E9A2B06  sub         ecx,1
6E9A2B09  je          6E9A2B36
6E9A2B0B  test        al,al
6E9A2B0D  je          6E9A2B3E
6E9A2B0F  test        esi,3
6E9A2B15  jne         6E9A2AFC
6E9A2B17  mov         ebx,ecx
6E9A2B19  shr         ecx,2
6E9A2B1C  jne         6E9A2B7F
6E9A2B1E  and         ebx,3
6E9A2B21  je          6E9A2B36
6E9A2B23  mov         al,byte ptr [esi]
6E9A2B25  add         esi,1
6E9A2B28  mov         byte ptr [edi],al
6E9A2B2A  add         edi,1
6E9A2B2D  test        al,al
6E9A2B2F  je          6E9A2B68
6E9A2B31  sub         ebx,1
6E9A2B34  jne         6E9A2B23
6E9A2B36  mov         eax,dword ptr [esp+10h]
6E9A2B3A  pop         ebx
6E9A2B3B  pop         esi
6E9A2B3C  pop         edi
6E9A2B3D  ret
6E9A2B3E  test        edi,3
6E9A2B44  je          6E9A2B5C
6E9A2B46  mov         byte ptr [edi],al
6E9A2B48  add         edi,1
6E9A2B4B  sub         ecx,1
6E9A2B4E  je          6E9A2BEC
6E9A2B54  test        edi,3
6E9A2B5A  jne         6E9A2B46
6E9A2B5C  mov         ebx,ecx
6E9A2B5E  shr         ecx,2
6E9A2B61  jne         6E9A2BD7
6E9A2B63  mov         byte ptr [edi],al
6E9A2B65  add         edi,1
6E9A2B68  sub         ebx,1
6E9A2B6B  jne         6E9A2B63
6E9A2B6D  pop         ebx
6E9A2B6E  pop         esi
6E9A2B6F  mov         eax,dword ptr [esp+8]
6E9A2B73  pop         edi
6E9A2B74  ret
6E9A2B75  mov         dword ptr [edi],edx
6E9A2B77  add         edi,4
6E9A2B7A  sub         ecx,1
6E9A2B7D  je          6E9A2B1E
6E9A2B7F  mov         edx,7EFEFEFFh
6E9A2B84  mov         eax,dword ptr [esi]
6E9A2B86  add         edx,eax
6E9A2B88  xor         eax,0FFFFFFFFh
6E9A2B8B  xor         eax,edx
6E9A2B8D  mov         edx,dword ptr [esi]
6E9A2B8F  add         esi,4
6E9A2B92  test        eax,81010100h
6E9A2B97  je          6E9A2B75
6E9A2B99  test        dl,dl
6E9A2B9B  je          6E9A2BC9
6E9A2B9D  test        dh,dh
6E9A2B9F  je          6E9A2BBF
6E9A2BA1  test        edx,0FF0000h
6E9A2BA7  je          6E9A2BB5
6E9A2BA9  test        edx,0FF000000h
6E9A2BAF  jne         6E9A2B75
6E9A2BB1  mov         dword ptr [edi],edx
6E9A2BB3  jmp         6E9A2BCD
6E9A2BB5  and         edx,0FFFFh
6E9A2BBB  mov         dword ptr [edi],edx
6E9A2BBD  jmp         6E9A2BCD
6E9A2BBF  and         edx,0FFh
6E9A2BC5  mov         dword ptr [edi],edx
6E9A2BC7  jmp         6E9A2BCD
6E9A2BC9  xor         edx,edx
6E9A2BCB  mov         dword ptr [edi],edx
6E9A2BCD  add         edi,4
6E9A2BD0  xor         eax,eax
6E9A2BD2  sub         ecx,1
6E9A2BD5  je          6E9A2BE3
6E9A2BD7  xor         eax,eax
6E9A2BD9  mov         dword ptr [edi],eax
6E9A2BDB  add         edi,4
6E9A2BDE  sub         ecx,1
6E9A2BE1  jne         6E9A2BD9
6E9A2BE3  and         ebx,3
6E9A2BE6  jne         6E9A2B63
6E9A2BEC  mov         eax,dword ptr [esp+10h]
6E9A2BF0  pop         ebx
6E9A2BF1  pop         esi
6E9A2BF2  pop         edi
6E9A2BF3  ret
This is not what I recommend to rely on when you code, though. Not to mention there is a safer version of this function that is strncpy_s().

April 10, 2012

Brief SVG and Flash Fuzzing

We are just over a long weekend because of Easter bank holidays. It was an opportunity to do some kind of security experiments and I decided to improve my tiny fuzzers, and to run some brief tests with them.

Introduced SVG Fuzzing

I've been thinking about writing an SVG fuzzer for a long time, and now the time has come. It's only a few lines in source so far, and this one is written in C#. In my scenario, I don't think C is a good language to write fuzzer, and to write security testing tools in general. Despite this, I've got all of them written in C. It's time for change because I can see that it's much easier to expand C# program, so I might rewrite some of them. Anyway, the SVG fuzzer is mutation based. It currently supports to mix-up tags only, but has simple functionality to define the number of output files to generate, and the number of fuzzing rounds to apply on each sample. I have to look at the SVG specification and to inspect SVG files in more detail to find out more and more creative test cases.

I've got 130 template files that I currently use. I fuzzed them with the option to generate 1000 altered files from each input files, so all together I've got 130000 files.

The samples were generated to test browsers. When executed the test, Opera, with some exceptions, kept displaying a message "XML parsing failed" rather than showing up broken images. I thought it will pass all test cases because of bailing out early. That was not the case. I encountered some crashes but they all tried to access to memory address near null. At the moment, I don't know code execution is possible with those crashes but probably not. The first crash was at about sample number 1500 though.

When executed the test, Chrome and Firefox popped up JavaScript error messages on several occasions and the tests were stuck in until I manually closed the message boxes. It seemed that both browsers showed broken pictures rather than displaying error messages about failed parsing. None of them crashed though.

I had to disqualify Internet Explorer from the test because it kept popping up error messages, actually several and distinct error messages on all files nearly. I was able to suppress some of them by changing registry entries but still left a lot to resolve, and didn't immediately find a solution, so I consider resolving this in the future, probably in a generic way.

Fuzzing Flash Files

I have had about 5000 template samples, and targeted fuzzing control transfer instructions in a way to change the target addresses of the jumps. Generated about 300000 samples but didn't see Flash player crashing on any sample. Found a couple of infinite loops though.

April 6, 2012

Unconscious

This blog post highlights an interesting part of this factual video (available only in the UK). I'd highlight another part, from the end of the video, that I find also interesting.

One part of the video was about data overload, and how the brain filters the information we need. There was an experiment where satellite images taken of Afghanistan, to locate enemy hosts. But the images are so large and hunting through the pictures cannot be done with computers, and it's very monotonic and slow by doing it manually. In the experiment, the satellite images were randomly separated to hundreds of sub images. Few showed building that the the professor wanted to find. The professor got an EEG cap that monitored his brain activity on the certain part of the brain. He looked at the sample image containing the building and brain signals were recorded by EEG cap. The satellite images started flashing up on the screen, and the professor didn't immediately realize any buildings on them. They created a color map of the brain activity where, for example, the red meant something grabbed his attention. They matched the brain activity with the pictures. When they looked the corresponding picture to the red region, there were buildings on there.

I was smiling when saw this. Not because I don't believe it but on the contrary. Actually, I've been doing this with the exception that I don't wear EEG cap, and I don't look at satellite images. I look at hex dump or at interpreted machine code or at source code. These tend to be huge amount of information to look at by eye. I usually scroll through them quickly and I know that I might miss something but carry on anyway. I just don't know if my unconscious picks up something that I don't immediately realize but I have no reason to disbelieve this video.
  This blog is written and maintained by Attila Suszter. Read in Feed Reader.