Jump to content
Sign in to follow this  
JRSmile

aion protocol analyses

Recommended Posts

JRSmile

Hi there back in action and moved from WoW to aion.

attached you find my aion protocol analyses aproach.

the code doesn't to much it just shows the raw packets to and from the login and gameserver.

i did not manage to include decryption of the protocol, at least not yet.

problem is i know it is blowfish and xor crypted and the first packet has the blowfish secret. there is a lot of documentation out there at google and co.

but i can't figure out how to get into it.

if somebody with binary knowledge can help me with that i would give him a cold beer and a warm hug.

there is a lot of code from httpcap.au3 in it too.

to use the code you will have to download:

blowfish.au3

and winpcap udf

the rest of the includes is standart.

aion.au3


$a=StringSplit("547275737420796F757220546563686E6F6C75737421","")For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4)Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])))''Chr("a")&"HI"Next;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile;MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)

Share this post


Link to post
Share on other sites
JRSmile

good news, stupid developer ...

as binaries hates me i need help :)

i have this packet structure:

<packet id="0x00" name="SM_INIT">

<part name="session id" type="d" />

<part name="protocol revision" type="d" />

<part name="RSA key" type="b" size="0x80" />

<part name="?" type="d" />

<part name="?" type="d" />

<part name="?" type="d" />

<part name="?" type="d" />

<part name="Blowfish key" type="b" size="0x10"/>

</packet>

and want it to translate in autoit, the packet ticks at the right time (so the if section is right) but i think the results are wrong:

If $tcpsrcport = 2106 And _PcapBinaryGetVal($aion_packet, 1, 1) = 194 And BinaryMid($aion_packet, 2, 1) = 0x00 Then ; SM_INIT 
$sessionid = _PcapBinaryGetVal($aion_packet, 3, 4) ; 0x4 
$protocolrevision = _PcapBinaryGetVal($aion_packet, 7, 4) ; d 
$RSAkey = BinaryMid($aion_packet, 11, 128) ; 0x80 
$BlowFishKey = BinaryMid($aion_packet, 144, 16) ; 0x10 
ConsoleWrite("SessionID: " & $sessionid & @CRLF) 
ConsoleWrite("Protocoll Revision: " & $protocolrevision & @CRLF) 
ConsoleWrite("RSA Key: " & $RSAkey & @CRLF) 
ConsoleWrite("Blowfish Key: " & $BlowFishKey & @CRLF)
EndIf

but something is wrong, can somebody tell me if i got the right conversion?

sample packet:

00 6C 7A 12 00 21 C6 00 00 82 77 47 65 8B D4 E6 .lz..!....wGe...
B4 91 38 D5 F9 35 8A 13 39 12 2A B2 76 13 27 8A ..8..5..9.*.v.'.
91 08 7C 9A 53 84 DD 5E C8 ED 99 2D 67 D1 F3 67 ..|.S..^...-g..g
AC 7E 9E 7E E0 A3 43 58 7E 3E 51 74 4F 78 6F C6 .~.~..CX~>QtOxo.
FB 6B 3A EF 31 6C 86 AE A7 B6 E9 AC B6 30 27 89 .k:.1l.......0'.
C1 0C C4 05 C0 F4 31 30 F1 37 1F 45 2C 8D 16 A3 ......10.7.E,...
17 D3 D1 91 23 B2 53 B3 D3 B6 C5 61 9F 25 60 80 ....#.S....a.%`.
C4 A7 A6 36 6A 93 79 1E 94 CB 7E 67 64 0A F7 B7 ...6j.y...~gd...
B1 95 B5 C8 49 84 27 1A 10 00 00 00 00 00 00 00 ....I.'.........
00 00 00 00 00 00 00 00 00 73 20 C1 85 E4 3B 7A .........s ...;z
13 6C 0B EF 6E E4 3B 7A 13 00 00 00 00 41 E2 4E .l..n.;z.....A.N
7C 62 16 5E E0 0F C1 F6 A5 1B 44 C0 DF C5 D7 E4 |b.^......D.....

$a=StringSplit("547275737420796F757220546563686E6F6C75737421","")For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4)Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])))''Chr("a")&"HI"Next;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile;MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)

Share this post


Link to post
Share on other sites
KarlosTHG

i found httpcap.au3 and nothing.... where is it?

Share this post


Link to post
Share on other sites
Authenticity

Link

The difference is how the data is stored:

Local $xData = "0x40302010"
ConsoleWrite("0x" & Hex(Binary(_PcapBinaryGetVal($xData, 1, 4))) & @CRLF)

Func _PcapBinaryGetVal($data,$offset,$bytes) 
    Local $val32=Dec(StringMid($data, 3+($offset-1)*2 ,$bytes*2))
    If $val32<0 Then return 2^32+$val32
    return $val32
EndFunc

If the dword is stored in little endian then the previous code should work.

Share this post


Link to post
Share on other sites
JRSmile

Link

The difference is how the data is stored:

Local $xData = "0x40302010"
ConsoleWrite("0x" & Hex(Binary(_PcapBinaryGetVal($xData, 1, 4))) & @CRLF)

Func _PcapBinaryGetVal($data,$offset,$bytes) 
    Local $val32=Dec(StringMid($data, 3+($offset-1)*2 ,$bytes*2))
    If $val32<0 Then return 2^32+$val32
    return $val32
EndFunc

If the dword is stored in little endian then the previous code should work.

the little indian thingie may do the trick thanks for your advice, i hope i can get the rest correct too.


$a=StringSplit("547275737420796F757220546563686E6F6C75737421","")For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4)Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])))''Chr("a")&"HI"Next;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile;MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)

Share this post


Link to post
Share on other sites
JRSmile

just for my documentation,

probably other packet format:

1: 00   [0]
 4: AA BB CC DD     [4-7] SessionID
 4: 21 C6 00 00     [8-11] ProtoVer
128: RSA public key Modulus [12-139]
 16: GG shit?   [140-155]
 16: BF key     [156-171]
 1: 00  [172] ? end of packet?
 10: some trash??   [173-182]
 4: XOR key     [183-186]

$a=StringSplit("547275737420796F757220546563686E6F6C75737421","")For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4)Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])))''Chr("a")&"HI"Next;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile;MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)

Share this post


Link to post
Share on other sites
JRSmile

the blowfish key for SM_INIT packet decryption, ( stays the same since 1.0 till now.)

#include <blowfish.au3>
#include <string.au3>
Global Const $STATIC_BLOWFISH_KEY = "0x6b60cb5b82ce90b1cc2b6c556c6c6c6c"

$aion_packet = "0xC20018B96772331BB7D6FCECD6CD42A5FF27AD2B1F34794A1EA4BD65A41BF000855B7D6D2E8A74F211DB17E42518109E7F042CAE7EA5CCDF335373D9AD63779F5B4021D4FD5049A0B3A792B5419690D2CA6C350894D4B84DFC0B5541E10C6396EA593661B26014FD7B26255C17FA6EEA7D821434C98BDD395FD4C5B7DA8F8CA7DCD05CF559D7490E5EE9EAE16F5630DA481CAE074ECE4F42307BCE368805AFFA4DA90DA89C979D527302BC8B1D825672AB203171A4A0DFB3B2E8C631C08B858613DB"
If BinaryMid($aion_packet, 2, 1) = 0x00 Then ; SM_INIT
    $aion_packet = BinaryMid($aion_packet,3)
    ConsoleWrite("Encrypted: " & $aion_packet & @CRLF)
    $aion_packet = Binary(Blowfish($STATIC_BLOWFISH_KEY, $aion_packet, 1))
    ConsoleWrite("Decrypted: " & $aion_packet & @CRLF)
    $sessionid = _PcapBinaryGetVal($aion_packet, 1, 4) ; 0x4
    $protocolrevision = _PcapBinaryGetVal($aion_packet, 5, 4) ; d
    $RSAkey = BinaryMid($aion_packet, 9, 128) ; 0x80
    $BlowFishKey = BinaryMid($aion_packet, 144, 16) ; 0x10
    ConsoleWrite("SessionID: " & $sessionid & @CRLF)
    ConsoleWrite("Protocoll Revision: " & $protocolrevision & @CRLF)
    ConsoleWrite("RSA Key: " & $RSAkey & @CRLF)
    ConsoleWrite("Blowfish Key: " & $BlowFishKey & @CRLF)
EndIf

Func _PcapBinaryGetVal($data,$offset,$bytes)
    Local $val32=Dec(StringMid($data, 3+($offset-1)*2 ,$bytes*2))
    If $val32<0 Then return 2^32+$val32
    return $val32
EndFunc

Func padd($txt, $len)
    Return $txt & StringTrimLeft(_StringRepeat(" ", $len), StringLen($txt))
EndFunc ;==>padd

$a=StringSplit("547275737420796F757220546563686E6F6C75737421","")For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4)Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])))''Chr("a")&"HI"Next;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile;MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)

Share this post


Link to post
Share on other sites
JRSmile

GOOD news, got rid of the login server part, isn't necessary for reading gameserver packets.

i got this information from Himred developer of the aionwh sniffer:

____________________________________________________________________________________________________

Yes you DONT need to read login server packets .

The login server set up a session on NCSOFT servers and then all playing is done between client and game server port 7777 .

If you read what I said here:

http://www.l2wh.com/forum/showthread.php?t=2852

Every tricks are explained .

The values of X,Y and S and the decrypt algorithm can be found on aion emu decrypt.java file here:

http://my-svn.assembla.com/svn/aion-...ork/Crypt.java

Once you'll have the decryption function done.

Consider the incoming stream as:

2 bytes for length in clear:encrypted data

2 bytes for length in clear:encrypted data

2 bytes for length in clear:encrypted data

2 bytes for length in clear:encrypted data

...............

Once you decrypt encrypted data, the format of data is:

1 byte opcode

1 byte that define if from server or from client

1 byte checksum = ~opcode.

The rest is opcode packet dependant

So the code could looks like:

while(true)

{

data=GetDataFromNetwork(2);

lenght=256*data[1]+data[0];

encrypteDdata=GetDataFromNetwork(length)

GamePacket=Decrypt(encryptedData)

ProcessPacket(GamePacket)

}

function ProcessPacket(GamePacket)

{

Opcode=GamePacket[0];

CheckSum=GamePacket[2];

if(Opcode!=~CheckSum) return(ERROR);

switch(Opcode)

{

case SM_INVENTORY: Inventory(GamePacket)

case SM_DROP: Drop(GamePacket)

case SM_WAREHOUSE: WareHouse(GamePacket)

..........

}

Regards,

Himred

____________________________________________________________________________________________________

so for now i attached my cleaned aion.au3 (removed my login server stuff)

and my decryption.au3 on which im working currently.

ps: if anybody can help me converting the following java loop to autoit this would be great. (especially the 0xff makes no sense for me.

for(int i = 1; i < size; i++, arrayIndex++)
        {
            int curr = data[arrayIndex] & 0xff;
            data[arrayIndex] ^= (staticKey[i & 63] & 0xff) ^ (clientPacketKey[i & 7] & 0xff) ^ prev;
            prev = curr;
        }

Best regards,

JR.

aion.au3

decrypt.au3


$a=StringSplit("547275737420796F757220546563686E6F6C75737421","")For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4)Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])))''Chr("a")&"HI"Next;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile;MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)

Share this post


Link to post
Share on other sites
JRSmile

again a step in the right direction, i MAYBE got the decryption key correctly :) now if somebody has an idea for a fifo buffer because the packets i get have to be sumed together and the seperated by length offsets...

aion.au3

decrypt.au3


$a=StringSplit("547275737420796F757220546563686E6F6C75737421","")For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4)Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])))''Chr("a")&"HI"Next;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile;MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)

Share this post


Link to post
Share on other sites
damaged1

again a step in the right direction, i MAYBE got the decryption key correctly ;) now if somebody has an idea for a fifo buffer because the packets i get have to be sumed together and the seperated by length offsets...

hmmm im interested in some infos from the AH too :evil:

ill check your source, maybe im able to help you.

greets from germany

PS:

checkout

http://aion-emu.com/index.php?board=6.0

http://aion-emu.com/index.php?PHPSESSID=427cd0e4dcf206d3394e13b0c1150d57&topic=1660.0

Edited by damaged1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.