CodeRed: the next generation

From: Marc Maiffret (marcat_private)
Date: Fri Jul 20 2001 - 11:47:30 PDT

  • Next message: Critical Watch Bugtraqqer: "Program and Source for Removal of IDA/IDQ Script Mappings (in response to Red Code Worm)"

    The following is a description of a "variant" "Code Red" worm that we have
    found to be in the wild. Sorry for the rough content but we thought it would
    be best to get this information out sooner and worry about pretty text
    formating later ;-]
    
    ----------------------
    In this text, we will be refering to the original "Code Red" worm as CRv1
    and the second generation "Code Red" worm as CRv2.  This does not preclude
    further generations/varioations still in the wild, it is just an analysis of
    the worms we have access to.
    
    This information is not currently public. Well, sort of is (we published the
    disassembly of CRv1, so CRv1 targeting info may be known), but the existance
    of CRv2 with different targeting has not been verified until now as far as
    we know. For the evidence surrounding the impetus for this second worm
    search, please examine Stuart Staniford's (stuartat_private)
    excellent statistical analysis of worm hit data.
    
    The CRv2 worm has the following charecteristics:
    second:milisecond randomness added to ip selection process removal of web
    page hack display (no notice to the end users via a defaced page)
    
    All other parts of the worm are the same. (still attacks whitehouse.gov (but
    the IP address has been blackholed), has time limits/definitions of attack,
    notworm lysine)
    
    The worst part about this means that our original tracking methodology
    (sensors early in the sequence) is no longer accurate, since CRv2 infected
    hosts do not contact early hosts, nor reliably contact any point (other than
    the blackholed IP address that use to point to whitehouse.gov).  This means
    that potentially ALL(ie: global, coprehensive) ids/logs data must be
    organized and sorted to find infected hosts.
    
    The Differences:
    It has 13 or so pertient bytes changed, adding a time based randomness
    factor and disabling page defacement.  The code had been there all along. It
    had intentially (we must assume) been disabled in CRv1 , then reenabled near
    the end of the cycle.  There has been discussion that this was a natural
    progression of the worm code, however, we do not beleive this is the
    case.  From analsysis of CRv1, there seems to be no distinct way to shift
    the nessecary bytes to generate CRv2. Hence, it is my belief that this is a
    modified worm, rereleased.  It has been posited that the CRv1 was a target
    aqusition mechanism, gathering data on infectable hosts to gain a high
    initital base for the following CRv2 infection.
    
    
    The Ip Selection Process:
    We will display the effecive CRv1(sequence), and the effective
    CRv2(timebased) ip selection processes.  This is a one byte change, at
    offset 9C2.  it changes the storage of some time based computations that
    were performed in CRv1 but discarded. The new byte changes the storage
    location from EBP-1B0( a general purpose holder stack var) to EBP - 18C(the
    location of the ip).  This means that the timevars are actively used in
    CRv2, while being discarded in CRv1.
    
    These are the targeting algorithms(complete, as far as we can discern) that
    are the asm in the CRv1 worm and also in the CRv2  worm.
    
    Seeding the "PRNG" for these examples seed is used for ip through the first
    iteration of the connect loop.  the seed does not change between CRv1 and
    CRv2, but each thread in the worm has a mildly different seed.
    
    seed = threadcount(based on 1) * 50F0668D;
    
    CRv1:
    The ipselection process in CRv1 is a simple sequence generator. This caused
    the early sequences that we noticed and refered to in our (eEye's) initital
    warning advisory:
    
    ip = (ip * 0x0CF3383) + 0x76BFE53;
    
    CRv2:
    The ipselection process in CRs2 is signifigantly more complex.  It takes use
    of time and a whole lot more input operations.  In the following  secmsec is
    the DWORD pair of seconds and mseconds returned from GetSystemTime
    
    ip = (ip + secmsec*secmsec*0x0CD59E3 +  secmsec*0x1E1B9) * 0x0CF3383 +
    0x76BFE53
    
    Other Details:
    Coincidentally, if this isn't general public knowledge, the worm is smart
    enough to avoid attacking the 127.x.x.x and 224.x.x.x subnets using the
    following logic after setting the ip.
    if( (ip & 0xFF == 0x7f) || (ip & 0xFF == 0xE0) )ip +=0x20DA9;
    
    
    
    the Hacked Page:
    The second difference between CRv1 and CRv2 is that CRv2 does not deface the
    webpage of an infected system.  It does this by having 12 bytes different
    from CRv1.
    
    When TcpSockSend is hooked(this still happens), CRv2 points this to a basic
    redirect that performs harmless actions and returns without actually
    changing any content. Crv1 pointed to a replacement, CRv2 points to
    basically a donothing function.
    
    what is happeinging is that the label "PADDING_BYTES" actually is padding
    bytes in CRv1(the code does not disassemble to any sane code).
    
    CRv1:
    We've used ida's data feature to show the "padding data" as dwords(instead
    of a bunch of bytes)
    
    CD4 - EB F8                        jmp     short near ptr
    HOOK_FAKE_TCPSOCKSEND+4 ; Jump
    CD6 - 22 6E 84 32               PADDING_BYTES   dd 32846E22h
    CDA - 03 75 B3 CA            dd 0CAB37503h
    CDE - 5A 04 56 34              dd 3456045Ah
    CE2 - 12 B8 78 56               dd 5678B812h
    CE6 - 34 12 B8 78               dd 78B81234h
    CEA - 56 34                         dw 3456h
    CEC - 12                              db  12h ;
    
    
    the code at CD4 jumps to the hooked TcpSockSend, sending the hacked Webpage.
    
    CRv2:
    what happens is that the CRv2 changes this, to:
    
    CD4 - B8 78 56 34 12 mov     eax,12345678h
    CD9 - B8 78 56 34 12 mov     eax,12345678h
    CDE - B8 78 56 34 12 mov     eax,12345678h
    CE3 - B8 78 56 34 12  mov     eax,12345678h
    CE8 - B8 78 56 34 12  mov     eax,12345678h
    
    
    basically doing nothing.  it then executes a chunk of code down at the below
    this:
    CED - 58                                 pop     eax
    CEE - 50                                 push    eax
    CEF - 8B BD 68 FE FF FF     mov     edi,[ebp-198h]
    CF5 - 89 47 F2                       mov     [edi-0Eh], eax
    CF8 - C3                                 retn
    
    This code basically replaces eax, saves it again(didn't make sense to me in
    the CRv1 context, but does here), sets edi to the data pointer, and resets a
    quick bit of code pointing to a ISAPI data struct that was on the stack
    beforehand.  This secodn bit of code is called at the start of the RVA
    processing, so all operations are already set by the time it gets here,
    making this code just a repeat.
    
    
    CRv2 fufills numerous questions that we had noticed in early analysis of
    CRv1, such as the nessecity of the self modifying code in CRv1.  although
    CRv1 did modify it's own code, it didn't ever really touch the modified
    code,  CRv2 makes use of this feature to implement the bypass.
    
    Credits:
    =============
    Stuart Staniford <stuartat_private>
    Nick FitzGerald  <nick@virus-l.demon.co.uk>
    Vern Paxson <vernat_private>
    Ryan Russel <ryanat_private>
    
    Signed,
    Ryan Permeh
    eEye Digital Security Team
    http://www.eEye.com/Retina -Network Security Scanner
    http://www.eEye.com/Iris -Network Traffic Analyzer
    



    This archive was generated by hypermail 2b30 : Fri Jul 20 2001 - 12:02:22 PDT