[8803] in bugtraq

home help back first fref pref prev next nref lref last post

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

daemon@ATHENA.MIT.EDU (scut)
Wed Dec 23 21:33:50 1998

Date: 	Tue, 22 Dec 1998 22:30:55 +0100
Reply-To: Bugtraq List <BUGTRAQ@NETSPACE.ORG>
From: scut <scut@NB.IN-BERLIN.DE>
To: BUGTRAQ@NETSPACE.ORG

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

home help back first fref pref prev next nref lref last post