Results 1 to 3 of 3
  1. #1
    New User
    Reputation
    1
    Join Date
    May 2009
    Posts
    2
    CoreCoins
    0

    Trade Feedbacks

    Status
    n/a
    Positive
    0 (0%)
    Negative
    0 (0%)

    Understanding WoW communication protocol



    Donate to Remove Ads, Get ShoutBawx - Elite Forum Access
    Hi all, my first post here! Well I have been gathering info's here and there (<3 google) in the past week. I do not have much experience in WoW hacking but I do have experience in other games hacking and programming in general. Lately I have also put myself to the challenge of learning ASM (mostly used within ollydbg).

    Please note this is my first real attempt at reversing a program all by myself, any constructive critism would be greatly appreciated.

    another note: All asm analysis were performed server-client only, but the packet analysis were performed from both sides.

    Everything in this post is related to WoW communication protocol (mostly encryption used). There are a few personal goals I would like to achieve (and could use some help to be honest):

    -Find a way to decrypt packet headers using WoW client (memory reading allowed)
    -Find a way to decrypt packet headers NOT using WoW client (from pure packet reading, I don't know if this can be achieved, see below for more information on missing srp6 rand value when sniffing packets).
    -Understand inner WoW workings from ollydbg analysis.
    -Understand inner WoW workings from mangos analysis.
    -Final goal: Create a packet logger that can find out how to decrypt keys only by analysing packets (If possible).

    There are mostly 2 parts of info I have been able to gather so far: ollydbg and packet sniffing. I think that reversing wow might not be needed, but I would really like to understand how they make it work internally.

    I will start with the ASM part. I have found (I assume I have found, I could be wrong on alot of places) some information reversing WoW listen() routine.

    In short:
    WoW listen for incoming packets the following way: Listen for 2 bytes (len part of the header), decrypt them, find PacketLen, listen for "PacketLen" bytes and then decrypt the first 2 bytes of that payload (the OpCode). Then it handles the OpCode but taht is out of scope for now.
    listen: approx WoW.004611AE (call to WS2_32.#16), I am pretty sure the offset is static, but in case not, putting a bp on WS2_32.#16 works fine).
    decript: WoW.0053FC90 (100% sure about that one)

    In details:
    note that below are dumps from ollydbg, trying to test my skills, I have commented every lines that I think could be interested in first (I ommited a big part of the decryption function because I think it is related to encrypting client packets befor they are sent, I never seen that part being hit yet when checking incoming packets). I would like some feedbacks on the comments, are they good? are they wrong? am I completly out of scope? I didn`t start to analyze how all that works in details yet, I would like to make sure my comments are right befor going further.

    First of all, for the listening part:

    Code:
    004611A9   . 6A 00          PUSH 0                                   ; /Flags = 0
    004611AB   . 57             PUSH EDI                                 ; |Length int len EDI
    004611AC   . 50             PUSH EAX                                 ; |Buffer char *buf EAX
    004611AD   . 51             PUSH ECX                                 ; |Socket
    004611AE   . FF15 88A69700  CALL DWORD PTR DS:[<&WS2_32.#16>]        ; \recv
    004611B4   . 8BD8           MOV EBX,EAX
    004611B6   . 85DB           TEST EBX,EBX
    004611B8   . 895D F4        MOV DWORD PTR SS:[EBP-C],EBX             ;  if ( EBX > 0 ) (not 100% sure)
    004611BB   . 7D 0F          JGE SHORT Wow.004611CC                   ;  { skip the next 4 instructions }
    004611BD   . FF15 F4A69700  CALL DWORD PTR DS:[<&WS2_32.#111>]       ; [WSAGetLastError
    004611C3   . 3D 14270000    CMP EAX,2714                             ;  if eax == 2714 (socks error code)
    004611C8   .^74 D6          JE SHORT Wow.004611A0                    ;  { go back to listen } 2714=WSA_WOULDBLOCK I think
    004611CA   . 85DB           TEST EBX,EBX                             ;  if (!eax)
    004611CC   > 7F 08          JG SHORT Wow.004611D6                    ;  { skip the next 2 instructions }
    004611CE   > 85FF           TEST EDI,EDI                             ;  if (EDI > 0)
    004611D0   . 0F8F 86010000  JG Wow.0046135C                          ;  { that seem to completly exit the listen routine }
    004611D6   > 80BE 74030000 >CMP BYTE PTR DS:[ESI+374],0              ;  if ptr == 0 skip decryption and go directly after
    004611DD   . 74 38          JE SHORT Wow.00461217                    ;  | the instructions marked with "|" might be interesting
    004611DF   . 0FB686 7603000>MOVZX EAX,BYTE PTR DS:[ESI+376]          ;  |
    004611E6   . 8B7E 20        MOV EDI,DWORD PTR DS:[ESI+20]            ;  |
    004611E9   . 2BC7           SUB EAX,EDI                              ;  |
    004611EB   . 0345 FC        ADD EAX,DWORD PTR SS:[EBP-4]             ;  |
    004611EE   . 33D2           XOR EDX,EDX                              ;  |
    004611F0   . 85C0           TEST EAX,EAX                             ;  |
    004611F2   . 0F9EC2         SETLE DL                                 ;  | DL = (bool)EAX ?
    004611F5   . 83EA 01        SUB EDX,1                                ;  |
    004611F8   . 23C2           AND EAX,EDX                              ;  |
    004611FA   . 3BC3           CMP EAX,EBX                              ;  |
    004611FC   . 7C 02          JL SHORT Wow.00461200                    ;  if (EAX < EBX) assumption: this check if len bytes have been decoded (seem to always be false)
    004611FE   . 8BC3           MOV EAX,EBX                              ;  Arg1 = *buf of socket
    00461200   > 8D8E 4A020000  LEA ECX,DWORD PTR DS:[ESI+24A]           ;  Args 3-4 = *key or DWORD key (assumption)
    00461206   . 51             PUSH ECX                                 ; /Arg4
    00461207   . 51             PUSH ECX                                 ; |Arg3
    00461208   . 50             PUSH EAX                                 ; |Arg2
    00461209   . 8B46 1C        MOV EAX,DWORD PTR DS:[ESI+1C]            ; |
    0046120C   . 03C7           ADD EAX,EDI                              ; |
    0046120E   . 50             PUSH EAX                                 ; |Arg1
    0046120F   . E8 7CEA0D00    CALL Wow.0053FC90                        ; \Wow.0053FC90 (ptr to decryption method)
    for the decryption part:

    Code:
    0053FC90  /$ 55             PUSH EBP                                 ;  EBP is saved on the stack
    0053FC91  |. 8BEC           MOV EBP,ESP                              ;  EBP = ESP
    0053FC93  |. 8B45 14        MOV EAX,DWORD PTR SS:[EBP+14]            ;  EAX = stack ptr EBP + 14
    0053FC96  |. 83EC 0C        SUB ESP,0C                               ;  STACK - 0C (3x DWORD) (does this give 3 free DWORD's on the stack?)
    0053FC99  |. 53             PUSH EBX                                 ;  EBX -> STACK
    0053FC9A  |. 56             PUSH ESI                                 ;  ESI -> STACK
    0053FC9B  |. 8B75 10        MOV ESI,DWORD PTR SS:[EBP+10]            ;  ESI = stack ptr EBP + 10
    0053FC9E  |. 3BF0           CMP ESI,EAX                              ;  ESI == EAX?
    0053FCA0  |. 57             PUSH EDI                                 ;  EDI -> STACK
    0053FCA1  |. 74 0B          JE SHORT Wow.0053FCAE                    ;  if ( ESI != EAX)
    0053FCA3  |. B9 40000000    MOV ECX,40                               ;  {   ECX = 40
    0053FCA8  |. 8BF8           MOV EDI,EAX                              ;      EDI = EAX
    0053FCAA  |. F3:A5          REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS>;      REP: Find info on that keyword
    0053FCAC  |. 66:A5          MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI] ;      Store 16bits in ptr ES:[EDI] (need info about that kind of allocation)}
    0053FCAE  |> 8B75 0C        MOV ESI,DWORD PTR SS:[EBP+C]             ;  ESI = stack ptr EBP + C
    0053FCB1  |. 8A90 00010000  MOV DL,BYTE PTR DS:[EAX+100]             ;  DL = memory ptr EAX + 100
    0053FCB7  |. 8A88 01010000  MOV CL,BYTE PTR DS:[EAX+101]             ;  CL = memory ptr EAX + 101
    0053FCBD  |. 83E6 FC        AND ESI,FFFFFFFC                         ;  ESI & FFFFFFFC (ESI (arg2?) seem to be the num bytes to decrypt)
    0053FCC0  |. 8975 F4        MOV DWORD PTR SS:[EBP-C],ESI             ;  ESI -> stack at EBP - C
    0053FCC3  |. BE 00000000    MOV ESI,0                                ;  ESI = 0
    0053FCC8  |. 8975 F8        MOV DWORD PTR SS:[EBP-8],ESI             ;  ESI (0) -> stack at EBP - 8
    0053FCCB  |. 0F86 F2000000  JBE Wow.0053FDC3                         ;  not sure what this compare against, seem like it may be enc for c->s packets, research so far is done s->c only
    0053FCD1  |> 80C2 01        /ADD DL,1                                ;  SKIPPING ANAYLISIS START (assuming client->server 4bytes encryption)
    0053FCD4  |. 0FB6F2         |MOVZX ESI,DL
    0053FCD7  |. 020C06         |ADD CL,BYTE PTR DS:[ESI+EAX]
    0053FCDA  |. 0FB61C06       |MOVZX EBX,BYTE PTR DS:[ESI+EAX]
    0053FCDE  |. 03F0           |ADD ESI,EAX
    0053FCE0  |. 885D 13        |MOV BYTE PTR SS:[EBP+13],BL
    0053FCE3  |. 0FB6F9         |MOVZX EDI,CL
    0053FCE6  |. 0FB61C07       |MOVZX EBX,BYTE PTR DS:[EDI+EAX]
    0053FCEA  |. 881E           |MOV BYTE PTR DS:[ESI],BL
    0053FCEC  |. 0FB65D 13      |MOVZX EBX,BYTE PTR SS:[EBP+13]
    0053FCF0  |. 881C07         |MOV BYTE PTR DS:[EDI+EAX],BL
    0053FCF3  |. 0FB61C07       |MOVZX EBX,BYTE PTR DS:[EDI+EAX]
    0053FCF7  |. 021E           |ADD BL,BYTE PTR DS:[ESI]
    0053FCF9  |. 03F8           |ADD EDI,EAX
    0053FCFB  |. 0FB6F3         |MOVZX ESI,BL
    0053FCFE  |. 0FB63406       |MOVZX ESI,BYTE PTR DS:[ESI+EAX]
    0053FD02  |. 80C2 01        |ADD DL,1
    0053FD05  |. 8975 FC        |MOV DWORD PTR SS:[EBP-4],ESI
    0053FD08  |. 8855 13        |MOV BYTE PTR SS:[EBP+13],DL
    0053FD0B  |. 0FB6D2         |MOVZX EDX,DL
    0053FD0E  |. 020C02         |ADD CL,BYTE PTR DS:[EDX+EAX]
    0053FD11  |. 8D3402         |LEA ESI,DWORD PTR DS:[EDX+EAX]
    0053FD14  |. 0FB6D1         |MOVZX EDX,CL
    0053FD17  |. 0FB61C02       |MOVZX EBX,BYTE PTR DS:[EDX+EAX]
    0053FD1B  |. 897D 14        |MOV DWORD PTR SS:[EBP+14],EDI
    0053FD1E  |. 8D3C02         |LEA EDI,DWORD PTR DS:[EDX+EAX]
    0053FD21  |. 8A16           |MOV DL,BYTE PTR DS:[ESI]
    0053FD23  |. 881E           |MOV BYTE PTR DS:[ESI],BL
    0053FD25  |. 8817           |MOV BYTE PTR DS:[EDI],DL
    0053FD27  |. 0FB61F         |MOVZX EBX,BYTE PTR DS:[EDI]
    0053FD2A  |. 021E           |ADD BL,BYTE PTR DS:[ESI]
    0053FD2C  |. 33D2           |XOR EDX,EDX
    0053FD2E  |. 0FB6F3         |MOVZX ESI,BL
    0053FD31  |. 8A3406         |MOV DH,BYTE PTR DS:[ESI+EAX]
    0053FD34  |. 0955 FC        |OR DWORD PTR SS:[EBP-4],EDX
    0053FD37  |. 8A55 13        |MOV DL,BYTE PTR SS:[EBP+13]
    0053FD3A  |. 80C2 01        |ADD DL,1
    0053FD3D  |. 0FB6F2         |MOVZX ESI,DL
    0053FD40  |. 020C06         |ADD CL,BYTE PTR DS:[ESI+EAX]
    0053FD43  |. 0FB61C06       |MOVZX EBX,BYTE PTR DS:[ESI+EAX]
    0053FD47  |. 03F0           |ADD ESI,EAX
    0053FD49  |. 885D 13        |MOV BYTE PTR SS:[EBP+13],BL
    0053FD4C  |. 0FB6F9         |MOVZX EDI,CL
    0053FD4F  |. 0FB61C07       |MOVZX EBX,BYTE PTR DS:[EDI+EAX]
    0053FD53  |. 881E           |MOV BYTE PTR DS:[ESI],BL
    0053FD55  |. 0FB65D 13      |MOVZX EBX,BYTE PTR SS:[EBP+13]
    0053FD59  |. 03F8           |ADD EDI,EAX
    0053FD5B  |. 881F           |MOV BYTE PTR DS:[EDI],BL
    0053FD5D  |. 0FB61F         |MOVZX EBX,BYTE PTR DS:[EDI]
    0053FD60  |. 021E           |ADD BL,BYTE PTR DS:[ESI]
    0053FD62  |. 80C2 01        |ADD DL,1
    0053FD65  |. 0FB6F3         |MOVZX ESI,BL
    0053FD68  |. 0FB63406       |MOVZX ESI,BYTE PTR DS:[ESI+EAX]
    0053FD6C  |. C1E6 10        |SHL ESI,10
    0053FD6F  |. 0975 FC        |OR DWORD PTR SS:[EBP-4],ESI
    0053FD72  |. 0FB6F2         |MOVZX ESI,DL
    0053FD75  |. 020C06         |ADD CL,BYTE PTR DS:[ESI+EAX]
    0053FD78  |. 0FB61C06       |MOVZX EBX,BYTE PTR DS:[ESI+EAX]
    0053FD7C  |. 03F0           |ADD ESI,EAX
    0053FD7E  |. 897D 14        |MOV DWORD PTR SS:[EBP+14],EDI
    0053FD81  |. 885D 13        |MOV BYTE PTR SS:[EBP+13],BL
    0053FD84  |. 0FB6F9         |MOVZX EDI,CL
    0053FD87  |. 0FB61C07       |MOVZX EBX,BYTE PTR DS:[EDI+EAX]
    0053FD8B  |. 03F8           |ADD EDI,EAX
    0053FD8D  |. 881E           |MOV BYTE PTR DS:[ESI],BL
    0053FD8F  |. 0FB65D 13      |MOVZX EBX,BYTE PTR SS:[EBP+13]
    0053FD93  |. 881F           |MOV BYTE PTR DS:[EDI],BL
    0053FD95  |. 0FB61F         |MOVZX EBX,BYTE PTR DS:[EDI]
    0053FD98  |. 021E           |ADD BL,BYTE PTR DS:[ESI]
    0053FD9A  |. 897D 14        |MOV DWORD PTR SS:[EBP+14],EDI
    0053FD9D  |. 8B7D 08        |MOV EDI,DWORD PTR SS:[EBP+8]
    0053FDA0  |. 0FB6F3         |MOVZX ESI,BL
    0053FDA3  |. 0FB61C06       |MOVZX EBX,BYTE PTR DS:[ESI+EAX]
    0053FDA7  |. 8B75 F8        |MOV ESI,DWORD PTR SS:[EBP-8]
    0053FDAA  |. C1E3 18        |SHL EBX,18
    0053FDAD  |. 0B5D FC        |OR EBX,DWORD PTR SS:[EBP-4]
    0053FDB0  |. 83C6 04        |ADD ESI,4
    0053FDB3  |. 315C3E FC      |XOR DWORD PTR DS:[ESI+EDI-4],EBX
    0053FDB7  |. 3B75 F4        |CMP ESI,DWORD PTR SS:[EBP-C]
    0053FDBA  |. 8975 F8        |MOV DWORD PTR SS:[EBP-8],ESI
    0053FDBD  |.^0F82 0EFFFFFF  \JB Wow.0053FCD1                         ;  SKIPPING ANALYSIS END
    0053FDC3  |> 3B75 0C        CMP ESI,DWORD PTR SS:[EBP+C]             ;  ESI == stack at EBP + C ?
    0053FDC6  |. 73 4D          JNB SHORT Wow.0053FE15                   ;  if NOT (ESI > stack at EBP + C) jump pass next loop
    0053FDC8  |. EB 06          JMP SHORT Wow.0053FDD0                   ;  Skip the next instruction
    0053FDCA  |  8D9B 00000000  LEA EBX,DWORD PTR DS:[EBX]
    0053FDD0  |> 80C2 01        /ADD DL,1                                ;  ++DL
    0053FDD3  |. 0FB6F2         |MOVZX ESI,DL                            ;  ESI = DL
    0053FDD6  |. 020C06         |ADD CL,BYTE PTR DS:[ESI+EAX]            ;  CL += memory ptr ESI + EAX
    0053FDD9  |. 0FB61C06       |MOVZX EBX,BYTE PTR DS:[ESI+EAX]         ;  EBX = (byte) memory ptr at ESI + EAX
    0053FDDD  |. 03F0           |ADD ESI,EAX                             ;  ESI += EAX
    0053FDDF  |. 0FB6F9         |MOVZX EDI,CL                            ;  EDI = CL
    0053FDE2  |. 03F8           |ADD EDI,EAX                             ;  EDI += EAX
    0053FDE4  |. 885D 13        |MOV BYTE PTR SS:[EBP+13],BL             ;  BL -> stack at EBP + 13
    0053FDE7  |. 0FB61F         |MOVZX EBX,BYTE PTR DS:[EDI]             ;  EBX = memory ptr at EDI
    0053FDEA  |. 881E           |MOV BYTE PTR DS:[ESI],BL                ;  BL -> memory ptr at EBP + 13
    0053FDEC  |. 0FB65D 13      |MOVZX EBX,BYTE PTR SS:[EBP+13]          ;  EBX = stack ptr at EBP + 13
    0053FDF0  |. 881F           |MOV BYTE PTR DS:[EDI],BL                ;  BL -> memory ptr at EDI
    0053FDF2  |. 0FB61F         |MOVZX EBX,BYTE PTR DS:[EDI]             ;  EBX = memory ptr at EDI
    0053FDF5  |. 021E           |ADD BL,BYTE PTR DS:[ESI]                ;  BL += memory ptr at ESI
    0053FDF7  |. 897D 14        |MOV DWORD PTR SS:[EBP+14],EDI           ;  EDI -> stack ptr at EBP+14
    0053FDFA  |. 8B7D 08        |MOV EDI,DWORD PTR SS:[EBP+8]            ;  EDI = stack ptr at EBP + 8
    0053FDFD  |. 0FB6F3         |MOVZX ESI,BL                            ;  ESI=BL
    0053FE00  |. 0FB61C06       |MOVZX EBX,BYTE PTR DS:[ESI+EAX]         ;  EBX = memory ptr at ESI+EAX
    0053FE04  |. 8B75 F8        |MOV ESI,DWORD PTR SS:[EBP-8]            ;  ESI = stack ptr at EBP-8
    0053FE07  |. 301C3E         |XOR BYTE PTR DS:[ESI+EDI],BL            ;  PACKET BUFFER IS MODIFIED HERE (data is XOR'd with BL)
    0053FE0A  |. 83C6 01        |ADD ESI,1                               ;  ++ESI
    0053FE0D  |. 3B75 0C        |CMP ESI,DWORD PTR SS:[EBP+C]            ;  ESI <> stack ptr EBP+c ?
    0053FE10  |. 8975 F8        |MOV DWORD PTR SS:[EBP-8],ESI            ;  ESI -> stack ptr EBP -8
    0053FE13  |.^72 BB          \JB SHORT Wow.0053FDD0                   ;  if (ESI > stack ptr at EBP + C) { loop back }
    0053FE15  |> 5F             POP EDI
    0053FE16  |. 5E             POP ESI
    0053FE17  |. 8888 01010000  MOV BYTE PTR DS:[EAX+101],CL             ;  CL-> mem ptr EAX+101
    0053FE1D  |. 8890 00010000  MOV BYTE PTR DS:[EAX+100],DL             ;  DL -> mem ptr EAX + 100
    0053FE23  |. 5B             POP EBX
    0053FE24  |. 8BE5           MOV ESP,EBP                              ;  ESP = EBP (that change the stack ptr?)
    0053FE26  |. 5D             POP EBP
    0053FE27  \. C3             RETN
    Part 2: Packet analysis.

    In short:
    -Analysed packets so far are the 4 logon packets (ommited realmlist packet). Those packets consists of:
    2x client-> server packets (AuthLogonChallenge, AuthLogonProof)
    2x server-> client packets (AuthLogonChallenge, AuthLogonProof)
    in order:
    c->s AuthLogonChallenge
    s->c AuthLogonChallenge
    c->s AuthLogonProof
    s->c AuthLogonProof

    in details:

    c->s AuthLogonChallenge
    I think there ain't much to it about this packet, included is the version, build, os, some localization related stuff, timezon, ip and userName.

    s->c AuthLogonChallenge
    A little more interesting here! This packet contains data related to the SRP6 authentication used to encrypt password (really uninterested here) AND to generate a KEY used in post-logon encryption (I am not 100% sure about this, but I think I am right). The values contained in this packet related to SRP6 encryption are: B, g, N, Salt and crcsalt(we can skil crcsalt for now I dont think it is of interest). Looking at boogiebot and mangos source I think I managed to get close to generating a valid K value (used for encryption). the main problem here is to get the "lowercase" a value. I do not have any experience in encryption, so I am really in an unknown field right now, but I think I could generate K value (assumptions made from looking at boogiebot) using the following method:
    1. Srp6 initialized with N and g from server data
    2. a (lowercase) = BigNumber.Random (that is the line I am stuck in, I might be able to generate a valid value if I would manually connect to the server using a clientless approch, but I dont want to do that)
    3. A (uppercase) = Srp6.GetA(a) (lowercase a as param)
    4. I = Srp6.GetLogonHask(username, password) (I think both must be uppercase, right?)
    5. x = Srp6.Getx(Salt, I)
    6. u = Srp6.getu(A, B)
    7. S = srp.ClientGetS(a, B, x, y) ---> the only value I am missing here to generate the key (K) is the "lowercase" a generated by WoW client
    8. K = Srp6.ShaInterleave(S) --> This is (I am almost certain) the value used in encryption/decryption

    I think that the interesting packets reside in the packet above, but I will still post information I found about the other 2 packets

    c->s AuthLogonProof
    This packet give us several information about server SRP6:
    1.A (Should this be same A value as calculated in AuthLogonChallenge returned by the server, or is it the server version of A, that is kinda confusing me)
    2. M1 (Same question apply as above)
    3. crc_hash (is this of interest?)

    s->c AuthLogonProof
    nothing much here, only a "verification" value "M2", not sure what this is involved here, I think it is only for security check and thus could be ignored.

    so my biggest question right now is: How to get the missing "lowercase" a value to be able to re-create the key (K)? is it even possible? is that value even needed? is there a "hack around"? etc.?

    Thanks everyone, my english is not so great, so I hope it`s ok with everyone.
    Last edited by MikeDotNet; 05-10-2009 at 12:45 AM.

  2. #2
    Private
    Reputation
    1
    Join Date
    Jan 2009
    Posts
    3
    CoreCoins
    0

    Trade Feedbacks

    Status
    n/a
    Positive
    0 (0%)
    Negative
    0 (0%)
    Hi

    Taking your goals:

    -Find a way to decrypt packet headers using WoW client (memory reading allowed)
    -Find a way to decrypt packet headers NOT using WoW client (from pure packet reading, I don't know if this can be achieved, see below for more information on missing srp6 rand value when sniffing packets).
    [..]
    -Final goal: Create a packet logger that can find out how to decrypt keys only by analysing packets (If possible)

    1) You could use this address
    [0x1132F74] + 0x508 = K
    kynox posted here.

    This gets you K, which is the key for the RC4 encryption that WoW uses since 3.1. If you have a look at the mangos 3.1 source afterwards, you should be able to decrypt the packets in no time.

    2) SRP6 itself seems impossible to reverse in realtime. Even with known parameters like the account-password. That is due to use of modular exponentation in SRP6.
    See here.

    Since 3.1 it is impossible to decypher the stream in realtime by only sniffing packets since they changed the encryption method to RC4. Read more about RC4 if you want to know why.
    Before 3.1 it was possible to do a full passive attack on the encryption, because they only XORed the headers using the sessionkey over and over again. Since you knew at least the packet length you had the chance of doing a known-plaintext attack that revealed the sessionkey within the first 40 or 60 packets. But as I said - it is no longer possible.

    3) So: your only way would be to do memory reading and afterwards decrypting the stream.

    Hope that helps

  3. #3
    New User
    Reputation
    3
    Join Date
    Apr 2009
    Posts
    7
    CoreCoins
    0

    Trade Feedbacks

    Status
    n/a
    Positive
    0 (0%)
    Negative
    0 (0%)
    Just to confirm what Boopy said, the a value or even the final K value is not deducible from the packet stream. In theory that is the purpose of shared-key cryptography, to come up with a protocol through which two parties can construct the same key and trust/verify that the other has it as well, without this key being deducible from their communication with each other.

    Now of course, whatever happens with that key after it was produced is up to you and no longer covered by the algorithm guarantees. It turns out that before patch 3.1 they were doing something really stupid with it, that allowed us to guess what it was just after about 50 packets. Nowadays they're using it to generate the key for the RC4 encryption algorithm (not exactly K, but some mangled version of it!). This algorithm is generally pretty safe against attack, so pending some surprising advances in the cracking of RC4, we're stuck.

    However, you're not out in the cold. Supposing you can get the value of K from the WoW client's memory, it's not too hard to build the decryption algorithm. You don't even have to go rummaging through the disassembled client, the fine folks in the Aspire Hearthstone team already did it for us. Just check out their 3_1_0 branch from SVN and look at src/hearthstone-shared/Auth/WowCrypt.cpp as well as SARC4.cpp. It's using the OpenSSL library, which makes things very easy on the coder. A note: yes those are good constants, they're snatched from the client and should work on live servers.


    Now, if you're like me you want to build this so that your bot/tool/whatever doesn't reside on your computer, for safety, otherwise might as well go with memory manipulation. When I realised how naive I was in expecting WoW's cryptography to be easily cracked, I was kinda bummed out about my project. But then I realised that all I needed was to have an app that you run quickly on your client at the right time, it grabs the session key K, sends it to the bot over the network and then quits, thus flying entirely under the Warden's radar. On the bot side, when I get to handle the very last packet before encryption begins, I choke the packet stream (effectively freezing the client at "Connected", I think), listen on a port, and then setup the encryption when I receive the session key on that port. Of course you have to use the key extractor pretty fast otherwise the server drops you, but I think you should have a good 20 seconds.

 

 

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
All times are GMT -4. The time now is 03:01 PM. Powered by vBulletin® Version 4.2.0
Copyright © 2014 vBulletin Solutions, Inc. All rights reserved. Resources saved on this page: MySQL 17.65%
vBulletin Optimisation provided by vB Optimise (Pro) - vBulletin Mods & Addons Copyright © 2014 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search