CVE-2016-3594
A memory corruption vulnerability exists in file parsing code of
Oracle Outside In Technology libim_psi2 library. Specifically, a
integer overflow leading to an undersized memory allocation and a
memory copy operation leading to buffer overflow in psiparse
function can
write 8 controlled bytes into adjacent memory, possibly leading to code execution.
http://www.oracle.com/technetwork/middleware/content-management/oit-all-085236.html
While parsing a PSI image file, a 2 byte size field is read and sign extended.
This value is then used in memory allocation and a subsequent memmove
call.
Read size value is increased by 8 before an actuall memory area is allocated,
but the original size is used in memmove
call.
As an example, the vulnerability is triggered in the ixsample
demo application
supplied in the SDK.
PSI file is being parsed by parsepsi
function. Vulnerability occurs around the following
code:
psiparse+659 mov [esp+17Ch+var_170], 0FBh ; jumptable 000E1BDD case 6
psiparse+661 lea ebp, (a__________V_44 - 0B74D2F10h)[ebx]
psiparse+667 mov [esp+17Ch+alloc_size+4], ebp
psiparse+66B mov eax, [esp+17Ch+size]
psiparse+66F mov [esp+17Ch+alloc_size], eax [1]
psiparse+673 mov eax, [esp+17Ch+arg_0]
psiparse+67A mov [esp+17Ch+var_17C], eax
psiparse+67D call _psalloc_ [2]
psiparse+682 mov edx, [esp+17Ch+arg_8]
psiparse+689 mov [edx+8], eax
psiparse+68C mov ecx, [edi]
psiparse+68E mov edx, [esp+17Ch+size] [3]
psiparse+692 mov [esp+17Ch+alloc_size+4], edx
psiparse+696 mov [esp+17Ch+alloc_size], eax
psiparse+69A mov [esp+17Ch+var_17C], edi
psiparse+69D call dword ptr [ecx+24h] [4]
psiparse+6A0 cmp eax, [esp+17Ch+size]
psiparse+6A4 jz short loc_B73BB230
At [1] size read from a file is used as size argument to a memory allocation function
called at [2]. At [3] size is used as an argument to a function called at [4].
In the vulnerable process path, function called at [4] is located at offset 0xad3dc
into libim_pis2 library which, in essence, is a memmove
wrapper.
Size argument is parsed in PSCAN_Next function. Specifically, a function at offset 0x904ab:
.text:B73694AB mov ecx, eax
.text:B73694AD test edx, edx
.text:B73694AF jz short loc_B73694C2
.text:B73694B1 movzx eax, byte ptr [eax]
.text:B73694B4 shl eax, 8
.text:B73694B7 movzx dx, byte ptr [ecx+1]
.text:B73694BC or edx, eax
.text:B73694BE movsx eax, dx
.text:B73694C1 retn
.text:B73694C2 ; ---------------------------------------------------------------------------
.text:B73694C2
.text:B73694C2 loc_B73694C2: ; CODE XREF: getsFFFFFF+4j
.text:B73694C2 movzx eax, byte ptr [eax+1]
.text:B73694C6 shl eax, 8
.text:B73694C9 movzx dx, byte ptr [ecx]
.text:B73694CD or edx, eax
.text:B73694CF movsx eax, dx
.text:B73694D2 retn
Depending edx, this function reads either little or big endian 16 bit integer and returns its sign extended value.
In the supplied testcase, big endian 0xFFF9 is being sign extended into info
0xFFFFFFF9 which gets overflown by adding 8 during memory allocation function
passing the checks, but leads to a crash during memmove
.
It is worth noting, the buffer that is being copied during memmove
is located
just after he 2 byte size value in the supplied crashing testcase.
2015-10-19 - Discovery
2016-04-20 - Initial Vendor Communication
2016-07-19 - Public Release
Discovered by Aleksandar Nikolic of Cisco Talos.