Legacy V3 | Bot + Encryption bypass |

Wrote new code? Fixed a bug? Want to discuss technical stuff? Feel free to post it here.

Moderator: Moderators

Message
Author
sli
Perl Monk
Perl Monk
Posts: 810
Joined: 04 Apr 2008, 17:26
Noob?: No

Re: Legacy V3 | Bot + Encryption bypass |

#41 Post by sli »

Code: Select all

use XSLoader;

XSLoader::load 'harmony'

Code: Select all

import ctypes

h = windll.harmony
In short: proxy server. It'd be simple since it's only tunneling packets around, not doing any protocol stuff.

http://aspn.activestate.com/ASPN/Cookbo ... ipe/181063
http://search.cpan.org/~saper/XSLoader-0.08/XSLoader.pm
cs : ee : realist

Barracks
Human
Human
Posts: 23
Joined: 19 Apr 2008, 13:00

Re: Legacy V3 | Bot + Encryption bypass |

#42 Post by Barracks »

Hmm, will try.

Barracks
Human
Human
Posts: 23
Joined: 19 Apr 2008, 13:00

Re: Legacy V3 | Bot + Encryption bypass |

#43 Post by Barracks »

its hard QQ

sli
Perl Monk
Perl Monk
Posts: 810
Joined: 04 Apr 2008, 17:26
Noob?: No

Re: Legacy V3 | Bot + Encryption bypass |

#44 Post by sli »

Do you have an export table? What function is being exported and sticking itself into the client to encrypt packets?
cs : ee : realist

hal9000
Noob
Noob
Posts: 9
Joined: 04 Apr 2008, 10:20

Re: Legacy V3 | Bot + Encryption bypass |

#45 Post by hal9000 »

there aren't exported functions, all the weird things are done in DllMain() called apon dll init.
There is only an useless function:

Code: Select all

public _dummyfunc
_dummyfunc proc near
push    ebp
mov     ebp, esp
pop     ebp
retn
_dummyfunc endp
that's DllMain:

Code: Select all

BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
  DWORD v4; // [sp+0h] [bp-Ch]@1
 
  v4 = fdwReason;
  if ( fdwReason == 1 )
  {
    sub_10001E50((LPVOID)0x6B9274, (int)sub_10001950, 4u);
    sub_10001E50((LPVOID)0x6B9444, (int)sub_100019A0, 4u);
  }
  return 1;
}
0x6B9274, 0x6B9444 these seems to be a moleboxed address, but the real important thing is:
the function sub_10001E50:

Code: Select all

signed int __stdcall sub_10001E50(LPVOID lpAddress, int a2, DWORD dwSize)
{
  signed int result; // eax@4
  DWORD flOldProtect; // [sp+0h] [bp-8h]@5
  signed int v5; // [sp+4h] [bp-4h]@5
 
  if ( lpAddress && a2 && (signed int)dwSize >= 4 )
  {
    VirtualProtect(lpAddress, dwSize, 0x40u, &flOldProtect);
    *(_DWORD *)lpAddress = a2;
    v5 = 4;
    while ( v5 < (signed int)dwSize )
      *((_BYTE *)lpAddress + v5++) = -112;
    result = 0;
  }
  else
  {
    result = -1;
  }
  return result;
}
as fa as i can understand (from disassembled sources and that c conversion) this is the function that does the weird hooking job on sakexe.
(int)sub_100019A0 and (int)sub_10001950 should be a pointer to the evil dll encryption function

darkfate
Super Moderators
Super Moderators
Posts: 61
Joined: 22 Apr 2008, 02:22
Noob?: No
Location: Zurich, Switzerland

Re: Legacy V3 | Bot + Encryption bypass |

#46 Post by darkfate »

sub_10001000 => blowfish

It probably wont take long to finish reversing this, not sure I have time next week.
This is the new send function of harmony.dll (some names are just assumptions by me)

Code: Select all

int __stdcall send_new(SOCKET socket, const char *old_packet, int old_len, int old_flags)
{
  int v5; // eax@7
  int v6; // eax@12
  DWORD tickCount1; // eax@2
  DWORD tickCount2; // esi@2
  int v9; // eax@2
  signed int tmp_rand; // eax@2
  int tmp_rand2; // eax@2
  char v12; // bl@4
  int v13; // eax@7
  DWORD v14; // eax@12
  unsigned __int8 v15; // al@14
  int v16; // eax@23
  int v17; // eax@28
  int key_seed; // [sp+24h] [bp-10h]@2
  __int16 input; // [sp+28h] [bp-Ch]@2
  int unused_var; // [sp+2Ah] [bp-Ah]@2
  __int16 v21; // [sp+2Eh] [bp-6h]@2
  int Size; // [sp+20h] [bp-14h]@2
  int v23; // [sp+14h] [bp-20h]@4
  int v24; // [sp+30h] [bp-4h]@4
  unsigned __int8 *v25; // [sp+18h] [bp-1Ch]@7
  int v26; // [sp+10h] [bp-24h]@7
  int v27; // [sp+Ch] [bp-28h]@10
  int v28; // [sp+8h] [bp-2Ch]@14
  int v29; // [sp+1Ch] [bp-18h]@23

  if ( !dword_1000A2EC )
  {
    tickCount1 = GetTickCount();
    srand(tickCount1);
    key_seed = rand() + 78319;
    invert_flag();
    fill_random_key(key_seed);
    invert_flag();
    buf[0] = 0x89;                                              // key packet
    key_seed_cpy = key_seed;
    Sleep(10u);
    tickCount2 = GetTickCount();
    v9 = rand();
    srand(v9 ^ tickCount2);
    tmp_rand = rand() + 42564;
    key_seed = tmp_rand;
    input = (unsigned __int16)((signed int)(unsigned __int8)rand() >> 5) | (unsigned __int16)(8
                                                                                            * (unsigned __int16)(tmp_rand >> 3));
    srand(key_seed);
    tmp_rand2 = rand();
    key_seed = tmp_rand2;
    unused_var = tmp_rand2;
    srand(8 * *(__int16 *)((char *)&input + 1));
    v21 = rand();
    blowfish_encrypt((unsigned __int8 *)&input, &output, 8, (unsigned __int8)ptr_keypacket1, 256);
    invert_flag();
    Size = 0;
    while ( Size < 56 )
    {
      v23 = Size % 8;
      v12 = (unsigned __int8)((signed int)*((_BYTE *)&input + Size / 8 + 1) >> (8 - Size % 8)) | (unsigned __int8)(*((_BYTE *)&input + Size / 8) << Size % 8);
      v24 = (unsigned __int8)v12;
      sub_100018B0(v12);
      ++Size;
    }
    invert_flag();
    if ( send(socket, (const char *)buf, 13, 0) != 13 )
      return -1;
  }
  v25 = buf;
  buf[0] = (unsigned __int8)(8 * (dword_1000A2EC % 8u & 7)) | (unsigned __int8)(buf[0] & 0xC7);
  v13 = rand();
  v26 = v13;
  v5 = v13 & 0x80000003;
  if ( v5 < 0 )
    v5 = ((v5 - 1) | 0xFFFFFFFC) + 1;
  *v25 = v5 & 3 | (unsigned __int8)(*v25 & 0xFC);
  if ( old_len % 4 )
    v27 = 4 - old_len % 4;
  else
    v27 = 0;
  *v25 = (unsigned __int8)((v27 & 3) << 6) | *v25 & 0x3F;
  v14 = GetTickCount();
  srand(v14);
  v6 = rand() & 0x800000FF;
  if ( v6 < 0 )
    v6 = ((v6 - 1) | 0xFFFFFF00) + 1;
  LOBYTE(key_seed_cpy) = (unsigned __int8)((unsigned __int8)*old_packet ^ 0x36) ^ (_BYTE)v6;
  v15 = *v25 & 3;
  v28 = v15;
  if ( v15 <= 3u )
  {
    switch ( v28 )
    {
      case 0:
        sub_100018B0(key_seed_cpy);
        break;
      case 1:
        sub_100018B0(key_seed_cpy);
        break;
      case 2:
        sub_100018B0((_BYTE)key_seed_cpy ^ 0x2D);
        break;
      case 3:
        sub_100018B0((unsigned __int8)((signed int)buf[0] >> 4) | (unsigned __int8)(16 * (_BYTE)key_seed_cpy));
        break;
    }
  }
  *v25 = (unsigned __int8)(4 * (byte_1000A504 & 1)) | (unsigned __int8)(*v25 & 0xFB);
  *(int *)((char *)&key_seed_cpy + 1) = dword_1000A2EC;
  word_1009A746 = (_WORD)old_len + ((*v25 >> 6) & 3) + 12;
  blowfish_encrypt(
    (unsigned __int8 *)old_packet,
    &byte_1009A748,
    old_len + ((*v25 >> 6) & 3) + 4,
    (unsigned int)&ptr_keypacket1[256 * (unsigned __int8)byte_1000A504],
    256);
  if ( 262144 - len < (unsigned int)(unsigned __int16)word_1009A746 )
    return -1;
  Size = (unsigned __int16)word_1009A746;
  blowfish_encrypt(buf, buf, 8, (unsigned __int8)ptr_blowfish_stdkey, 256);
  if ( len )
  {
    memcpy(&new_packet[len], buf, Size);
    len += Size;
    v17 = send(socket, new_packet, len, 0);
    v29 = v17;
    if ( v17 < 0 )
      return v29;
    len -= Size;
  }
  else
  {
    v16 = send(socket, (const char *)buf, Size, 0);
    v29 = v16;
    if ( v16 != Size )
    {
      if ( v29 < 0 )
        return v29;
      memcpy(&new_packet[len], &buf[v29], Size - v29);
      len += Size - v29;
    }
  }
  ++dword_1000A2EC;
  return old_len;
}
You can't make people smarter. You can expose them to information, but your responsibility stops there.
- Mark Rippetoe

sli
Perl Monk
Perl Monk
Posts: 810
Joined: 04 Apr 2008, 17:26
Noob?: No

Re: Legacy V3 | Bot + Encryption bypass |

#47 Post by sli »

All you need to do is find the hard coded key. That's gonna be a bitch, sure, but there are kajillions of blowfish implementations. There shouldn't be any reversing outside finding the key, which might be susceptible to a memory search. Then again, I'm no reverse engineer.
cs : ee : realist

zoiaum
Noob
Noob
Posts: 1
Joined: 21 May 2008, 13:48
Noob?: No

Re: Legacy V3 | Bot + Encryption bypass |

#48 Post by zoiaum »

Looks like tsuki rPE don't work anymore.
I think the harmony.dll got update again.

sli
Perl Monk
Perl Monk
Posts: 810
Joined: 04 Apr 2008, 17:26
Noob?: No

Re: Legacy V3 | Bot + Encryption bypass |

#49 Post by sli »

Speaking of rPE, someone wanna post a download link up here? Only ones I found were on boards that required registration, and fuck that noise.
cs : ee : realist

autior
Noob
Noob
Posts: 6
Joined: 09 May 2008, 07:01
Noob?: No

Re: Legacy V3 | Bot + Encryption bypass |

#50 Post by autior »

sli wrote:Speaking of rPE, someone wanna post a download link up here? Only ones I found were on boards that required registration, and fuck that noise.
I uploaded rPE v1.0, if u still need it.

Locked