[8803] in bugtraq
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