Industry Trends
FortiGuard Labs disclosed a heap overflow vulnerability earlier this week in Windows Journal, a notetaking application developed by Microsoft that is included in Windows XP Tablet PC Edition, Windows Vista, Windows 7, Windows 8, and Windows 10. Windows Journal allows users to create and organize handwritten notes and drawings and save them in native JNT files or export them in TIFF files. It also allows users to simply use an ordinary computer mouse to compose a handwritten note, as well as a graphics tablet or a Tablet PC.
The vulnerability is caused by an error that occurs when the vulnerable software attempts to open a specially crafted .jnt file. It could lead to remote code execution, with particular implications for those using Windows accounts with administrator privileges.
Specifically, the vulnerability is caused by an error while parsing the ‘BPGR’ structure in a specially crafted jnt file. Let’s look into the jnt file:
0002bb10h: 00 42 50 47 52 02 00 00 00 06 00 93 00 3D 00 00 ; .BPGR.......?=..
0002bb20h: 00 06 09 20 08 53 A9 45 2D 02 12 60 08 00 60 0A ; ... .S〦-..`..`.
0002bb30h: 24 42 A4 82 D5 12 B5 50 85 C8 00 05 28 4A 82 E8 ; $B?礟吶..(J傝
0002bb40h: 00 43 05 38 36 87 29 00 14 00 6E 00 42 50 47 52 ; .C.86?...n.BPGR
0002bb50h: 02 00 00 00 03 00 00 00 3D 00 00 00 03 41 ED 80 ; ........=....A韤
0002bb60h: F5 4A AA A0 00 A1 BF 36 C1 1B 21 0A 84 22 40 14 ; 鮆獱.】6?!.?@.
0002bb70h: 00 6E 00 42 50 47 52 02 00 00 00 0B 00 00 00 12 ; .n.BPGR.........
0002bb80h: 00 00 00 0B 54 4B 00 ; ....TK.
Since the specification of JNT file format is not available, we guess that the four bytes marked in red |06 00 93 00| should be a size field. The value in little-endian is 0x00930060, which is crafted by us.
The function CDecbp::Decode(short *, unsigned __int64, int *) is used to parse the ‘BPGR’ structure, and the function flow chart is shown below:
Let’s set breakpoint in function NBDoc!CDecbp::Decode for further analysis:
0:000> r
rax=00000060ec9ecfc0 rbx=00000060ec9eaf80 rcx=00000060dc7ed3a0
rdx=00000060ec9e8f80 rsi=00000060ec9e2fc0 rdi=00000060ec9e6fd0
rip=00007ffd6164ebb0 rsp=00000060dc7ed2a8 rbp=00000060dc7ed3b0
r8=000000000000003d r9=00000060dc7ed2f0 r10=00000060ec9ecfc0
r11=00000060dc7ece50 r12=000000008007000e r13=0000000000000000
r14=00000060ec9e8f80 r15=00000060ec9e4fd0
iopl=0 nv up ei pl nz na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
00007ffd`6164ebb0 48895c2410 mov qword ptr [rsp+10h],rbx ss:00000060`dc7ed2b8=00000060ec9eaf80
0:000> dd 00000060`dc7ed3a0 //this pointer points to a CDecbp object
00000060`dc7ed3a0 00000002 00930006 0000003d 00000000 //the four bytes marked in red are from the specially crafted ‘BPGR’ structure
00000060`dc7ed3b0 ec9b8f50 00000060 000000ac 00000000
00000060`dc7ed3c0 ec9df000 00000060 850ca996 00007ffd
00000060`dc7ed3d0 e03f0000 00000060 e03f0000 00000060
00000060`dc7ed3e0 00000000 00000000 00000000 00000000
00000060`dc7ed3f0 fffffffe ffffffff ec9eaf80 00000060
00000060`dc7ed400 ec9e6fd0 00000060 ec9e2fc0 00000060
00000060`dc7ed410 ec9e8f80 00000060 ec9e4fd0 00000060
0:000> dd 00000060`ec9b8f50
00000060`ec9b8f50 2d45a953`08200906 240a6000`08601202
00000060`ec9b8f60 8550b512`d582a442 00e8824a`280500c8
00000060`ec9b8f70 14002987`36380543 02524750`42006e00
00000060`ec9b8f80 3d000000`03000000 f580ed41`03000000
00000060`ec9b8f90 c136bfa1`00a0aa4a 00144022`840a211b
00000060`ec9b8fa0 00025247`5042006e 00120000`000b0000
00000060`ec9b8fb0 0200004b`540b0000 0055d3db`60e96240
00000060`ec9b8fc0 ef070014`d6807174 2c40ef8a`8096d0c0
From the above flow chart of the function CDecbp::Decode, we can see there is a while loop, and the condition used in it is as follows:
NBDoc!CDecbp::Decode+0x1d4:
00007ffd`6164ed84 453bf9 cmp r15d,r9d
00007ffd`6164ed87 0f8cddfeffff jl NBDoc!CDecbp::Decode+0xba (00007ffd`6164ec6a) // if r15d < r9d, it continues to loop
0:000> r
rax=0000000000000003 rbx=0000000000000000 rcx=00000060dc7ed3a0
rdx=00000060dc7ed2b0 rsi=0000000000000000 rdi=00000060dc7ed3a0
rip=00007ffd6164ed84 rsp=00000060dc7ed240 rbp=00000060ec9ecfc0
r8=00000060ec9ecffc r9=0000000000930006 r10=0000000000000001
r11=0000000000000008 r12=0000000000000004 r13=000000000000003d
r14=00000060ec9e8f80 r15=0000000000000001
iopl=0 nv up ei pl nz na pe nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
NBDoc!CDecbp::Decode+0x1d4:
00007ffd`6164ed84 453bf9 cmp r15d,r9d
0:000> u
NBDoc!CDecbp::Decode+0x1d4:
00007ffd`6164ed84 453bf9 cmp r15d,r9d
00007ffd`6164ed87 0f8cddfeffff jl NBDoc!CDecbp::Decode+0xba (00007ffd`6164ec6a)
00007ffd`6164ed8d 488bb42488000000 mov rsi,qword ptr [rsp+88h]
00007ffd`6164ed95 395f08 cmp dword ptr [rdi+8],ebx
00007ffd`6164ed98 7e21 jle NBDoc!CDecbp::Decode+0x20b (00007ffd`6164edbb)
00007ffd`6164ed9a 488bcd mov rcx,rbp
00007ffd`6164ed9d f60101 test byte ptr [rcx],1
00007ffd`6164eda0 740b je NBDoc!CDecbp::Decode+0x1fd (00007ffd`6164edad)
The value of the register r15d is 0x1 and the value of the register r9d is 0x00930006 which is from the specially crafted ‘BPGR’ structure. 0x00930006 is a very large integer and causes the loop to execute many times. In each loop, this pointer points to a CDecbp object and poi(this +0x10) is increased by one several times. Some code snippets are shown below:
NBDoc!CDecbp::Decode+0x6b:
00007ffd`6164ec1b 488b4710 mov rax,qword ptr [rdi+10h] ---> rdx points to this pointer.
00007ffd`6164ec1f 0fb608 movzx ecx,byte ptr [rax]
00007ffd`6164ec22 48ffc0 inc rax ---> poi(this+10h) is increased by one
00007ffd`6164ec25 448bc9 mov r9d,ecx
00007ffd`6164ec28 48894710 mov qword ptr [rdi+10h],rax ---> update the value of this+10h
00007ffd`6164ec2c 488d42ff lea rax,[rdx-1]
NBDoc!CDecbp::Decode+0xec:
00007ffd`6164ec9c 488b4f10 mov rcx,qword ptr [rdi+10h] ---> rdi points to this pointer.
00007ffd`6164eca0 c7472808000000 mov dword ptr [rdi+28h],8
00007ffd`6164eca7 0fb601 movzx eax,byte ptr [rcx]
00007ffd`6164ecaa 894724 mov dword ptr [rdi+24h],eax
00007ffd`6164ecad 488d4101 lea rax,[rcx+1] ---> poi(this+10h) is increased by one
00007ffd`6164ecb1 48894710 mov qword ptr [rdi+10h],rax ---> update the value of this+10h
00007ffd`6164ecb5 ff4f28 dec dword ptr [rdi+28h]
00007ffd`6164ecb8 48634f28 movsxd rcx,dword ptr [rdi+28h]
NBDoc!CDecbp::DecGRAdapt+0x96:
00007ffd`6164ee96 498b4910 mov rcx,qword ptr [r9+10h] ---> r9 points to this pointer.
00007ffd`6164ee9a 45895928 mov dword ptr [r9+28h],r11d
00007ffd`6164ee9e 0fb601 movzx eax,byte ptr [rcx]
00007ffd`6164eea1 41894124 mov dword ptr [r9+24h],eax
00007ffd`6164eea5 488d4101 lea rax,[rcx+1] ---> poi(this+10h) is increased by one
00007ffd`6164eea9 49894110 mov qword ptr [r9+10h],rax ---> update the value of this+10h
00007ffd`6164eead 41ff4928 dec dword ptr [r9+28h]
00007ffd`6164eeb1 418d4001 lea eax,[r8+1]
NBDoc!CDecbp::DecGRAdapt+0x48:
00007ffd`6164ee48 488b4910 mov rcx,qword ptr [rcx+10h] ---> rcx points to this pointer.
00007ffd`6164ee4c 0fb601 movzx eax,byte ptr [rcx]
00007ffd`6164ee4f 41894124 mov dword ptr [r9+24h],eax
00007ffd`6164ee53 488d4101 lea rax,[rcx+1] ---> poi(this+10h) is increased by one
00007ffd`6164ee57 49894110 mov qword ptr [r9+10h],rax ---> update the value of this+10h
00007ffd`6164ee5b 41ff4928 dec dword ptr [r9+28h]
00007ffd`6164ee5f 488d35d2bb0900 lea rsi,[NBDoc!`string'+0x2f8 (00007ffd`616eaa38)]
00007ffd`6164ee66 49634928 movsxd rcx,dword ptr [r9+28h]
NBDoc!CDecbp::DecGRAdapt+0x11a:
00007ffd`6164ef1a 498b4910 mov rcx,qword ptr [r9+10h] --->r9 points to this pointer.
00007ffd`6164ef1e 45895928 mov dword ptr [r9+28h],r11d
00007ffd`6164ef22 0fb601 movzx eax,byte ptr [rcx]
00007ffd`6164ef25 41894124 mov dword ptr [r9+24h],eax
00007ffd`6164ef29 488d4101 lea rax,[rcx+1] ---> poi(this+10h) is increased by one
00007ffd`6164ef2d 49894110 mov qword ptr [r9+10h],rax ---> update the value of this+10h
00007ffd`6164ef31 41ff4928 dec dword ptr [r9+28h]
00007ffd`6164ef35 4d634128 movsxd r8,dword ptr [r9+28h]
NBDoc!CDecbp::DecGRAdapt+0x225:
00007ffd`6164f025 498b5110 mov rdx,qword ptr [r9+10h] --->r9 points to this pointer.
00007ffd`6164f029 418b4924 mov ecx,dword ptr [r9+24h]
00007ffd`6164f02d c1e108 shl ecx,8
00007ffd`6164f030 0fb602 movzx eax,byte ptr [rdx]
00007ffd`6164f033 0bc8 or ecx,eax
00007ffd`6164f035 488d4201 lea rax,[rdx+1] ---> poi(this+10h) is increased by one
00007ffd`6164f039 49894110 mov qword ptr [r9+10h],rax ---> update the value of this+10h
00007ffd`6164f03d 498d46ff lea rax,[r14-1]
Because the loop is executed too many times, finally the value of this+10h points to an invalid memory address and it causes an out-of-bound access in heap memory. The crash location is as follows:
NBDoc!CDecbp::Decode+0xec:
00007ffd`6164ec9c 488b4f10 mov rcx,qword ptr [rdi+10h]
00007ffd`6164eca0 c7472808000000 mov dword ptr [rdi+28h],8
00007ffd`6164eca7 0fb601 movzx eax,byte ptr [rcx] --->crash here
00007ffd`6164ecaa 894724 mov dword ptr [rdi+24h],eax
00007ffd`6164ecad 488d4101 lea rax,[rcx+1]
00007ffd`6164ecb1 48894710 mov qword ptr [rdi+10h],rax
00007ffd`6164ecb5 ff4f28 dec dword ptr [rdi+28h]
00007ffd`6164ecb8 48634f28 movsxd rcx,dword ptr [rdi+28h]
(3488.3858): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
NBDoc!CDecbp::Decode+0xf7:
00007ffd`6164eca7 0fb601 movzx eax,byte ptr [rcx] ds:00000060`ec9b9000=??
0:000> r
rax=0000000000000003 rbx=0000000000000000 rcx=00000060ec9b9000
rdx=0000000000000000 rsi=0000000000004000 rdi=00000060dc7ed3a0
rip=00007ffd6164eca7 rsp=00000060dc7ed240 rbp=00000060ec9ecfc0
r8=00000060ec9e8f80 r9=0000000000930006 r10=00000060ec9ecfc0
r11=0000000000000000 r12=00000000ffffffee r13=000000000000003d
r14=00000060ec9e8f80 r15=0000000000000017
iopl=0 nv up ei pl nz na pe nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202
NBDoc!CDecbp::Decode+0xf7:
00007ffd`6164eca7 0fb601 movzx eax,byte ptr [rcx] ds:00000060`ec9b9000=??
0:000> dp rdi
00000060`dc7ed3a0 00930006`00000002 00000000`0000003d
00000060`dc7ed3b0 00000060`ec9b9000 00000000`000000a2 //rcx is [rdi+10h], 00000060`ec9b9000 points to an invalid heap memory address
00000060`dc7ed3c0 00000000`00000580 00007f01`00000008
00000060`dc7ed3d0 00000060`00000003 00000008`00000002
00000060`dc7ed3e0 00000000`00000000 00000000`00000000
00000060`dc7ed3f0 ffffffff`fffffffe 00000060`ec9eaf80
00000060`dc7ed400 00000060`ec9e6fd0 00000060`ec9e2fc0
00000060`dc7ed410 00000060`ec9e8f80 00000060`ec9e4fd0
0:000> kb
# RetAddr : Args to Child : Call Site
00 00007ffd`6164597e : 00000060`00000000 00000060`ec9eaf80 00000000`00930006 00000060`dc7ed2f0 : NBDoc!CDecbp::Decode+0xf7
01 00007ffd`616454b9 : 00000000`00000000 00000000`00000000 00000000`00000000 00000060`ec9c8fc0 : NBDoc!DecodePos+0x2c6
02 00007ffd`6164ca28 : 00000060`e1351750 00000060`dc7ee7c0 00000060`e1351750 00000060`ec9c4fe0 : NBDoc!CBLCDecode::DecodeWithClusters+0x73d
03 00007ffd`61691873 : 00000000`000005a5 00000000`000005a5 00000000`0000072a 00000060`ec9c4fe0 : NBDoc!CBLCDecode::Decode+0xb8
04 00007ffd`616a1e41 : 00000060`ec9b8e00 00000060`ec9bafa0 00000000`000001fc 00000000`00000060 : NBDoc!DecodeBlcToCanvas+0x213
05 00007ffd`616a2465 : 00ffffff`00000000 00000060`ec9bafa0 00000060`dc7eea00 00000060`00000000 : NBDoc!CEPMRCFormatReader::LoadBLCToCanvas+0xd1
06 00007ffd`61693c95 : 00000000`00000000 00000060`ec8c7fd0 00000000`00000000 00000060`e1021ff0 : NBDoc!CEPMRCFormatReader::RgnsToImageLayers+0x225
07 00007ffd`61692af8 : 00000000`00000000 00000000`00000000 00000000`00000000 00000060`e0fbbf68 : NBDoc!CIFD::GetMRCImages+0x375
08 00007ffd`61692680 : 00000060`dc7eede8 00000060`e0e49e10 00000000`0000270f 00007ffd`616265e2 : NBDoc!CIFD::GetCompositeLayer+0x218
09 00007ffd`6162aeb7 : 00000000`00000001 00000060`dc7eed90 00000000`00000000 00000060`e1093f40 : NBDoc!CIFD::GetImageLayerEx+0xf0
0a 00007ffd`6162acbc : 00000060`00000001 00000060`e1093f40 00000060`ec8b1f98 00000060`00000001 : NBDoc!CEPEditablePageTiffImpl::InternalGetImageLayer+0x1bf
0b 00007ffd`63f3b48c : 00000060`00000000 00000060`e1093f40 00007ffd`615b6f20 00000060`00000000 : NBDoc!CEPEditablePageTiffImpl::GetImageLayer+0x7c
0c 00007ffd`63f4773e : 00000060`00000000 00007ffd`63f45310 00000060`e1093f40 00000060`ec8b1f40 : MSPVWCTL!CPage::EnableImageLayer+0x100
0d 00007ffd`63f34c16 : 00007ffd`63f47270 00000060`00000000 00000060`dc7eef80 00000000`00000001 : MSPVWCTL!CPageDisplay::SetPageNum+0xe6
0e 00007ffd`63f361ba : 00000000`00000001 00007ffd`63f4acd0 00000060`00000000 00000060`00000000 : MSPVWCTL!CMultiPageDisplayViewBase::AddPageD+0x1ca
0f 00007ffd`63f4207b : 00007ffd`63f7eba8 00007ffd`63f42040 00000000`00000003 00000060`eda366e0 : MSPVWCTL!CDocViewBaseImpl::UpdateViewLayout+0x3ba
10 00007ffd`63f3553c : 00000060`eda36601 00007ffd`63f40b00 00000000`00000011 000001b5`000003dc : MSPVWCTL!CDocMarkupView::UpdateViewLayout+0x3b
11 00007ffd`63f409e6 : 00007ffd`63f3c8a0 00000060`dc7ef290 00000000`00000000 00007ffd`63f7e778 : MSPVWCTL!CDocViewBaseImpl::Recalc+0x4c
12 00007ffd`63f408c4 : 00000000`00000000 00000000`00000009 00000060`eda366f0 00007ffd`00000000 : MSPVWCTL!CDocReadingViewBase::MoveToSubpage+0xf6
13 00007ffd`63f4283b : 00000000`00000000 00000060`dc7ef380 00007ffd`63f42460 00000060`eda366e0 : MSPVWCTL!CDocReadingViewBase::OnVScroll+0xb4
14 00007ffd`63f424ac : 00000000`0000ff88 00000060`e06a38f0 00007ffd`63f42460 00000060`eda36700 : MSPVWCTL!CDocMarkupView::OnVScroll+0x2bb
15 00007ffd`63f1ae50 : 00000000`00000000 ffffffff`00000000 ffffffff`ff880000 ffffffff`ff880000 : MSPVWCTL!CDocMarkupView::OnMouseWheel+0x4c
16 00007ffd`63f2826d : 00000000`0000020a 00000060`dc7ef4c0 00000000`00000001 ffffffff`ff880000 : MSPVWCTL!CEPDocView::OnMouseWheel+0xa0
17 00007ffd`63f2cbe4 : 00007ffd`63f27ed0 00000000`00080acc 00000000`00080acc 00000000`00000000 : MSPVWCTL!CEPDocView::ProcessWindowMessage+0x39d
18 00007ffd`84d100dc : 00000000`00000000 00000000`00000000 00000000`00000001 00000000`00000000 : MSPVWCTL!ATL::CWindowImplBaseT<CEPDocViewWindow,ATL::CWinTraits<1442840576,0> >::WindowProc+0x84
19 00007ffd`84d0fc07 : 00000060`e17e4480 00007ffd`80181080 00000000`00080acc 00007ff7`c9dcc800 : USER32!UserCallWinProcCheckWow+0x1fc
1a 00007ffd`636fa79a : 00007ff7`cab89410 00007ff7`cab89410 00000000`00000000 00000000`00000000 : USER32!DispatchMessageWorker+0x1a7
1b 00007ffd`636facc8 : 00007ff7`cab1afd0 00007ff7`cab89410 00000000`00000000 00007ff7`caa75ebc : MFC42u!CWinThread::PumpMessage+0x6a
1c 00007ffd`636f28ed : 00007ff7`cab1afc0 00007ff7`caa60000 00000000`00000000 00000060`de08ef7e : MFC42u!CWinThread::Run+0x88
1d 00007ff7`cab1bc26 : 00007ff7`cab26218 00000000`00000000 00000000`0000001f 00000000`00000001 : MFC42u!AfxWinMain+0xad
1e 00007ffd`83172d92 : 00007ff7`cab1bcd0 00007ff7`c9dce000 00007ff7`c9dce000 00000000`00000000 : Journal!CWnd::GetRuntimeClass+0x316
1f 00007ffd`850a9f64 : 00007ffd`83172d70 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x22
20 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x34
0:000> !heap -p -a rcx
address 00000060ec9b9000 found in
_DPH_HEAP_ROOT @ 60e03f1000
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
60f825ddd0: 60ec9b8e00 1fc - 60ec9b8000 2000
00007ffd8518ba7b ntdll!RtlDebugAllocateHeap+0x0000000000000047
00007ffd85146292 ntdll!RtlpAllocateHeap+0x00000000000757b2
00007ffd850ceed2 ntdll!RtlpAllocateHeapInternal+0x0000000000000292
00007ffd83309c30 msvcrt!malloc+0x0000000000000070
00007ffd616c6db3 NBDoc!operator new+0x0000000000000023
00007ffd616a238d NBDoc!CEPMRCFormatReader::RgnsToImageLayers+0x000000000000014d
00007ffd61693c95 NBDoc!CIFD::GetMRCImages+0x0000000000000375
00007ffd61692af8 NBDoc!CIFD::GetCompositeLayer+0x0000000000000218
00007ffd61692680 NBDoc!CIFD::GetImageLayerEx+0x00000000000000f0
00007ffd6162aeb7 NBDoc!CEPEditablePageTiffImpl::InternalGetImageLayer+0x00000000000001bf
00007ffd6162acbc NBDoc!CEPEditablePageTiffImpl::GetImageLayer+0x000000000000007c
00007ffd63f3b48c MSPVWCTL!CPage::EnableImageLayer+0x0000000000000100
00007ffd63f4773e MSPVWCTL!CPageDisplay::SetPageNum+0x00000000000000e6
00007ffd63f34c16 MSPVWCTL!CMultiPageDisplayViewBase::AddPageD+0x00000000000001ca
00007ffd63f361ba MSPVWCTL!CDocViewBaseImpl::UpdateViewLayout+0x00000000000003ba
00007ffd63f4207b MSPVWCTL!CDocMarkupView::UpdateViewLayout+0x000000000000003b
00007ffd63f3553c MSPVWCTL!CDocViewBaseImpl::Recalc+0x000000000000004c
00007ffd63f409e6 MSPVWCTL!CDocReadingViewBase::MoveToSubpage+0x00000000000000f6
00007ffd63f408c4 MSPVWCTL!CDocReadingViewBase::OnVScroll+0x00000000000000b4
00007ffd63f4283b MSPVWCTL!CDocMarkupView::OnVScroll+0x00000000000002bb
00007ffd63f424ac MSPVWCTL!CDocMarkupView::OnMouseWheel+0x000000000000004c
00007ffd63f1ae50 MSPVWCTL!CEPDocView::OnMouseWheel+0x00000000000000a0
00007ffd63f2826d MSPVWCTL!CEPDocView::ProcessWindowMessage+0x000000000000039d
00007ffd63f2cbe4 MSPVWCTL!ATL::CWindowImplBaseT<CEPDocViewWindow,ATL::CWinTraits<1442840576,0> >::WindowProc+0x0000000000000084
00007ffd84d100dc USER32!UserCallWinProcCheckWow+0x00000000000001fc
00007ffd84d0fc07 USER32!DispatchMessageWorker+0x00000000000001a7
00007ffd636fa79a MFC42u!CWinThread::PumpMessage+0x000000000000006a
00007ffd636facc8 MFC42u!CWinThread::Run+0x0000000000000088
00007ffd636f28ed MFC42u!AfxWinMain+0x00000000000000ad
00007ff7cab1bc26 Journal!CWnd::GetRuntimeClass+0x0000000000000316
00007ffd83172d92 KERNEL32!BaseThreadInitThunk+0x0000000000000022
00007ffd850a9f64 ntdll!RtlUserThreadStart+0x0000000000000034
0:000> db 60ec9b8e00 L1fc+16
00000060`ec9b8e00 02 00 00 00 00 00 00 ff-ff ff 96 00 42 4c 43 54 ............BLCT
00000060`ec9b8e10 20 00 2a 07 00 00 a5 05-00 00 96 00 98 00 d5 db .*.............
00000060`ec9b8e20 3c a5 79 55 49 40 9f 26-f8 53 24 85 f6 8f 57 00 <.yUI@.&.S$...W.
00000060`ec9b8e30 00 00 00 00 00 00 05 00-00 00 44 00 00 00 58 00 ..........D...X.
00000060`ec9b8e40 00 00 bb 00 00 00 09 01-00 00 12 01 00 00 42 49 ..............BI
00000060`ec9b8e50 54 56 08 00 00 00 3d 00-00 00 00 00 00 00 00 00 TV....=.........
00000060`ec9b8e60 00 00 50 54 52 53 5b 00-00 00 3d 00 00 00 00 3d ..PTRS[...=....=
00000060`ec9b8e70 00 00 00 4e 00 00 00 00-30 d0 03 89 00 00 00 08 ...N....0.......
00000060`ec9b8e80 00 00 00 0a 00 00 00 66-79 28 2a 5f 2c 28 73 28 .......fy(*_,(s(
00000060`ec9b8e90 1b 27 6b 27 32 1e 1b 28-fa fa fa 24 24 fb fb fb .'k'2..(...$$...
00000060`ec9b8ea0 72 0f 72 6a 6a 8c 18 55-6a 80 6a 72 0a 1c 6a 8c r.rjj..Uj.jr..j.
00000060`ec9b8eb0 55 72 6a 6e 72 70 00 38-55 72 0b 0d 15 15 14 0d Urjnrp.8Ur......
00000060`ec9b8ec0 6a 8c 55 72 00 52 45 53-49 46 00 00 00 96 00 42 j.Ur.RESIF.....B
00000060`ec9b8ed0 4c 43 52 20 00 2a 07 00-00 a5 05 00 00 a0 a0 a0 LCR .*..........
00000060`ec9b8ee0 a0 a0 a0 a0 a0 a0 a0 a0-a0 a0 a0 a0 a0 a0 a0 a0 ................
00000060`ec9b8ef0 a0 a0 a0 a0 a0 a0 a0 a0-a0 7f ff ff ff ff f8 7f ................
00000060`ec9b8f00 ff ff ff ff ff ff ff ff-c0 00 00 22 ba 80 52 04 ..........."..R.
00000060`ec9b8f10 00 a0 a0 50 41 47 45 01-00 00 00 00 50 4f 53 49 ...PAGE.....POSI
00000060`ec9b8f20 d8 00 00 00 04 00 2a 00-3d 00 00 00 13 00 00 00 ......*.=.......
00000060`ec9b8f30 3d 00 00 00 81 00 0f f1-06 11 d8 00 14 00 6e 00 =.............n.
00000060`ec9b8f40 42 50 47 52 02 00 00 00-06 00 93 00 3d 00 00 00 BPGR........=...
00000060`ec9b8f50 06 09 20 08 53 a9 45 2d-02 12 60 08 00 60 0a 24 .. .S.E-..`..`.$
00000060`ec9b8f60 42 a4 82 d5 12 b5 50 85-c8 00 05 28 4a 82 e8 00 B.....P....(J...
00000060`ec9b8f70 43 05 38 36 87 29 00 14-00 6e 00 42 50 47 52 02 C.86.)...n.BPGR.
00000060`ec9b8f80 00 00 00 03 00 00 00 3d-00 00 00 03 41 ed 80 f5 .......=....A...
00000060`ec9b8f90 4a aa a0 00 a1 bf 36 c1-1b 21 0a 84 22 40 14 00 J.....6..!.."@..
00000060`ec9b8fa0 6e 00 42 50 47 52 02 00-00 00 0b 00 00 00 12 00 n.BPGR..........
00000060`ec9b8fb0 00 00 0b 54 4b 00 00 02-40 62 e9 60 db d3 55 00 ...TK...@b.`..U.
00000060`ec9b8fc0 74 71 80 d6 14 00 07 ef-c0 d0 96 80 8a ef 40 2c tq............@,
00000060`ec9b8fd0 74 c0 14 00 6e 00 42 50-47 52 02 00 00 00 0b 00 t...n.BPGR......
00000060`ec9b8fe0 00 00 12 00 00 00 0b 80-00 00 80 80 80 a6 90 84 ................
00000060`ec9b8ff0 ff 10 00 60 00 82 00 bd-00 89 4f c0 d0 d0 d0 d0 ...`......O.....
00000060`ec9b9000 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
00000060`ec9b9010 ?? ?? ??
From the above, 00000060`ec9b9000 points to an invalid heap memory address and causes a heap overflow. It could lead to arbitrary code execution.
Special thanks to Kai Liu of FortiGuard Labs, who discovered this vulnerability.
And now, for your weekend bonus:
Back in July, we disclosed a QuickTime heap overflow vulnerability, also discovered by FortiGuard Labs. We discovered another such vulnerability that was patched by Apple in August, so for a weekend treat, here's our take. Yes, August is a long time ago in security-land, but it's timely as rich media comes under increasing scrutiny as an attack vector.
Specifically, FortiGuard Labs discovered a memory corruption vulnerability in QuickTime. This vulnerability is caused due to insufficient validation of the value of ‘sample_size’ field when parsing the ‘stsz’ atom. It may lead to an unexpected application termination or arbitrary code execution.A memory corruption vulnerability has been discovered in QuickTime. This vulnerability is caused due to insufficient validation of the value of ‘sample_size’ field when parsing ‘stsz’ atom. It may lead to an unexpected application termination or arbitrary code execution.
We use 010 Editor to parse the structure of the 3gp file. FG-VD-15-040_original.3gp is the original good 3gp file. FG-VD-15-040_PoC.3gp is the crafted 3gp file. From following screen shots, you can see the difference between the two:
Figure 1. Structure of FG-VD-15-040_original.3gp
Figure 2. Structure of FG-VD-15-040_PoC.3gp
The ‘stsz’ atom specifies the size of each sample in a sample table. The definition of its structure is shown below:
Figure 3. Definition of ‘stsz’ Structure
The value of the ‘SampleSize’ field in atom 'stsz' should be 0x00000000. When we modify it to a very large value (e.g. 0x0000F200), this vulnerability can be triggered.
Again, thanks to Kai Liu of FortiGuard Labs for discovering this vulnerability.