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