mIRC dcc port "randomization" (second, fixed now ;) (fwd)

From: scut (scutat_private-BERLIN.DE)
Date: Tue Dec 22 1998 - 13:30:55 PST

  • Next message: Richard Reiner: "[SecureXpert Labs Advisory SX-98.12.23-01] Widespread DoS"

    Sorry for the first message, I accidently send it while pasting source
    code.
    
    Hi.
    
    I wondered if the mIRC irc client contained a simple port choose
    algorithm as BitchX uses, so I examined the mIRC code, and since it is
    not free-source,
    I'd like to share the results with those who are still concerned about
    their DCC session being hijacked.
    
    On DCC send/chat request mIRC allocates a socket and sets the socket port
    to a random number between 1024 and 5000, that are 3976 possible ports.
    The random algorithm is similar to a congruence generator and uses a
    64bit seed, which is once initialized, and then used to produce a stream
    of random numbers. The random routine returns a random number in eax,
    which is between zero and 0x7fffffff, the caller code has to transform it
    into a useable number.
    
    lrand           proc near               ; CODE XREF: sub_0_47E7E0+49
      push    ebx
      push    esi
      mov     ebx, ds:coreseed0    ; coreseed0 (lower 32bits)
      mov     esi, ds:coreseed1    ; coreseed1 (upper 32bits)
      mov     eax, ebx
      mov     ecx, 15A4h
      mov     ebx, 4E35h
      test    eax, eax
      jz      short cs0zero
      mul     ebx
    cs0zero:                                ; CODE XREF: lrand+1C
      xchg    eax, ecx        ; eax = 0x15a4, ecx = res
      mul     esi             ; edx:eax = cs1 * 0x15a4
      add     eax, ecx        ; eax += cs0
      xchg    eax, esi        ; eax = cs1
      mul     ebx             ; = cs1 * (ebx)4e35
      add     edx, esi        ; edx:eax += s0 << 32
      add     eax, 1          ; edx:eax += 1
      adc     edx, 0          ; edx:eax += carry << 32
      mov     ebx, eax
      mov     esi, edx
      mov     ds:coreseed1, ebx ; eax
      mov     ds:coreseed0, esi ; edx
      mov     eax, esi
      and     eax, 7FFFFFFFh
      pop     esi
      pop     ebx
      retn
    lrand           endp
    
    Sorry, I don't want to annoy you, so here is a short explanation of what
    this code does, it can be rewritten as:
    
      new_cs0 = (cs1 * 0x15a4) + ((cs1 * 0x4c35) >> 32) + cs0
      new_cs1 = (cs1 * 0x4e35) + 1
      cs1 = new_cs1
      cs0 = new_cs0
    
    The routine is very well optimized, and I think it is a library routine
    of Borland C Builder, but I cannot verify, since I do not own this
    programm.
    Notice the random routine has just one reference call, meaning
    that this
    is the only time this routine is being used in mIRC, this is the location.
    
      call    lrand
      movzx   edx, [ebp+arg_4]
      movzx   ecx, [ebp+arg_0]
      sub     edx, ecx
      mov     ecx, edx
      cdq               ; eax -> edx:eax
      idiv    ecx       ; mod 0xf88 (3976 possible ports)
      ..
      add     dx, [ebp+arg_0]   ; +0x400 (= 1024) --> 1024 - 5000
      mov     [ebx], dx         ; save ephemeral port into sockaddr !
    
    So for everyone who read until this point, here is the conclusion:
    Since you only get a very tiny number compared to the 64bit seed used,
    and you cannot simplify the above formulas, it is impossible to make
    practicable guesses for ports. My approximation is that you need at least
    60 consecutive port numbers to get the number of possible ports below
    100, which is still too much to hijack without any problems.
    I wasted 2 hours with this algorithm and trying to find a prediction
    algorithm, which I did, but you cannot use it in practice.
    
    So, thanks Khaled, your client is safe ! :) *stamping*
    
    cu,
    scut
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:25:56 PDT