PDA

Просмотр полной версии : Вопросы по дешифрации.


Активист
18.09.2016, 02:07
Хроники infinite odyssey.
1. Настроил phx. Выполнено.

1) Не дешифровать трафик
2) Обход смены XOR ключа

1 - поставить, 2 - убрать

Добавлено через 11 минут
Nickers, для разбора алгоритма нужен "нефильтрованый" траффик, который можно получить, как я уже отписался выше
http://storage9.static.itmages.ru/i/16/0917/s_1474143721_7587543_ef57fde407.jpeg (http://itmages.ru/image/view/4899062/ef57fde4)http://storage9.static.itmages.ru/i/16/0917/s_1474143721_8594538_730feeb118.jpeg (http://itmages.ru/image/view/4899061/730feeb1)http://storage1.static.itmages.ru/i/16/0917/s_1474143722_8882232_6d17b1f129.jpeg (http://itmages.ru/image/view/4899063/6d17b1f1)


2. И началось.
Завел перса, усадил на 5ю точку, выставил на панельку скилл(id=30514).
Умение маятник _l2central.info/wiki/Маятник_-_Боец_Сайхи Выполнено.

5D 93 8D CE 5D E7 13 45 85 00
30 A7 30 76 63 B1 C3 CF 61 6C
6A D3 4A 13 0F B3 5C CC 79 7F
A7 6C AE D2 79 5D E9 A5 1D 9C
15 65 B4 11 18 D3 CD F5 1D E7
0F 12 B7 72 45 F4 46 31 B5 68
66 20 9F F3 6E 5D 7C 3B 77 EF
9B 87 0F 47 F3 13 C0 20 70 04
CE 36 12 EE 5B CD 75 36 74 F1
AD 80 BD 14 48 BA B2 67 A4 F3
01 9A C1 1F A5 07 66 99 F5 DE
84 2F D7 1E 68 A4 D5 07 EA ED
32 A4 BC A5 64 B7 16 9E 66 AF
E9 BF 7E 06 4A A2 F0 22 8B 28
94 BD 33 5E 30 98 BA FF CE EC
6D 6B E7 F0 BC F7 28 D5 04 46
9E 20 43 D0 E1 B4 3D 9A AF A6
40 CF 5B C7 57 54 C2 6F E3 D6
45 CA 80 9A D0 2A F3 68 BA 0A
В RAW логе почему то в отличие от отображаемого в пнх, тип пакета можно различить по начальным 0C00 как попытка на использование умения

0:06:09 C>GS
0C004C3DA512672AE65BB41E
0:06:09 C>GS
0C005D938DCE5DE713458500
0:06:09 C>GS
0C0030A7307663B1C3CF616C
0:06:09 C>GS
0C006AD34A130FB35CCC797F
0:06:09 C>GS
0C00A76CAED2795DE9A51D9C
0:06:09 C>GS
0C001565B41118D3CDF51DE7
0:06:09 C>GS
0C000F12B77245F44631B568
0:06:09 C>GS
0C0066209FF36E5D7C3B77EF
0:06:09 C>GS
0C009B870F47F313C0207004
0:06:09 C>GS
0C00CE3612EE5BCD753674F1
0:06:09 C>GS
0C00AD80BD1448BAB267A4F3
0:06:09 C>GS
0C00019AC11FA5076699F5DE
0:06:09 C>GS
0C00842FD71E68A4D507EAED
0:06:09 C>GS
0C0032A4BCA564B7169E66AF
0:06:09 C>GS
0C00E9BF7E064AA2F0228B28
0:06:09 C>GS
0C0094BD335E3098BAFFCEEC
0:06:09 C>GS
0C006D6BE7F0BCF728D50446
0:06:09 C>GS
0C009E2043D0E1B43D9AAFA6
0:06:09 C>GS
0C0040CF5BC75754C26FE3D6
0:06:09 C>GS
0C0045CA809AD02AF368BA0A


3. И тут я начал сомневаться в своих действиях,
Нашел стандартное строение нужного мне пакета под GOD в файлах пнх. Выполнено преобразование.
39=RequestMagicSkillUse:d(skillID:Get.Skill)d(Ctrl Pressed)c(ShiftPressed)

Во что нужно id скила преобразовывать?
преобразовал в DWord и получилось
39 32 77 00 00 00 00 00 00 00 Правильный формат.
преобразовал в Byte и получилось
39 32 00 00 00 00 00 00 00 00 Не правильный
Если во чтото другое преобразовывать то по длине пакета не сходится.

Пакет под интерлюд подсмотрел получается преобразуется под DWord
тогда длина пакета не совпадает, в пакете же еще должен тип присутствовать как в самом примере.

RequestMagicSkillUse
Назначение: использовать магический скилл
Формат:
2F
XX XX XX XX // ID скилла
XX XX XX XX // состояние CTRL : 00 - отпущен, 01 - нажат
XX XX XX XX // состояние SHIFT: 00 - отпущен, 01 - нажат

_http://coderx.ru/showpost.php?p=23931&postcount=1

c(ShiftPressed занимает 1 байт, а не 4, т.е
Формат:
2F
XX XX XX XX // ID скилла
XX XX XX XX // состояние CTRL : 00 - отпущен, 01 - нажат
XX // состояние SHIFT: 00 - отпущен, 01 - нажат



4. Следующее действие, набор логов для сравнения.
Решил со скилом немного повременить и взять за пример пакет разрыва пати.
В interlud-е он
2B=RequestWithDrawalParty:

В моем случае должен быть
44=RequestWithDrawalParty:

Александр Шестаков
18.09.2016, 08:00
c(ShiftPressed занимает 1 байт, а не 4, т.е
Формат:
2F
XX XX XX XX // ID скилла
XX XX XX XX // состояние CTRL : 00 - отпущен, 01 - нажат
XX // состояние SHIFT: 00 - отпущен, 01 - нажат

Активист
18.09.2016, 12:49
RAW логи без разрывов
Почему RAW лог идет по типу 0300 E2 сам пакет
Так должен выглядеть пакет
030044 68 Разница
-----------------------------
0300E2 226 +158
0300CE 206 +138
030025 37 -31
030001 1 -67
03002A 42 -26
0300EB 235 +167
030023 35 -33
030016 22 -46
03001A 26 -42
0300B3 179 +111
0300D6 214 +146
030077 119 +51
0300DD 221 +153
03000D 13 -55
0300C1 193 +125
030052 82 +14
0300D0 208 +140
030077 119 +51
03009C 156 +88
03009C 156 +88
030054 84 +16
030072 114 +46
030021 33 -35
03000E 14 -54
030090 144 +76
030065 101 +33
030063 99 +31
030015 21 -47
03005A 90 +22
0300E6 230 +162
030041 65 -3
030006 6 -62
0300D1 209 +141
030092 146 +78
030025 37 -31
03000E 14 -54
030028 40 -28
030010 16 -52
0300C7 199 +131
030033 51 -17
030038 56 -12
030072 114 +46
0300A3 163 +95
03008D 141 +73
030021 33 -35
030098 152 +84
0300D2 210 +142
030007 7 -61
0300EC 236 +168
030040 64 -4
0300F8 248 +180
0300A8 168 +100
030079 121 +53
0300C5 197 +129
030054 84 +16
030020 32 -36
030005 5 -63
0300B4 180 +112
0300A2 162 +94
030074 116 +48
03007E 124 +54
030068 104 +36
0300E3 227 +159
030095 149 +81
0300DB 219 +151
03005E 94 +26
030052 82 +14
030031 49 -19
03004B 75 +7


0300E6
0300B4
030066
0300CF
03006C
0300E9
0300CB
030000
03001A
030074
0300DC
0300FE
0300BB
03008A
0300A8
030010
03001D
0300D4
0300B4
0300F8
0300B3
03006C
030091
030040
030002
0300E3
030056
030070
030094
0300A5
0300F0
030079
0300DE
0300EB
0300E2
03003D
0300B9
030068
030083
030013
030010
030086
03002B
0300A7
030092
030038
0300BC
0300B3
0300DE
030094
03006E
0300B7
03002C
0300FE
03004E
0300B1
030035
0300B5
0300A8
03008B
030038
0300A9
03002F
030051
030055
03005E
0300FF
030009
0300F3
0300F0
0300D0
030026
0300C4
0300B4
0300AE
03006A
030086
0300EA
030059
03006E
030027
03001D
0300BB
03003C
0300AC
03007C
030090
03001F
03004A
0300E0
030065
030053
030036
0300A9
030012
0300F8
030038
030045
03001A
030091
03009B
0300D9
03005A
03008F
030023
030071
030065
0300B2
0300D3
030040
0300CA
0300E9
0300E1
0300C2
03005A
03009C
0300C9
0300D0
0300A2
030029
030045
030066
0300E7
0300A5
0300A2
0300E8
03002C
03007F
03002E
0300ED
0300D4
0300EC
0300D8
0300A3
0300DF
0300BC
0300CE
030041
03005D
030036
030037
03000A
030074
0300B2
030095
030095
030017
030061
03001A
03009E
0300CA
030044
030067
0300E5
030012
03003E
0300F9
03001B
03004B
030048
030027
030015
030032
030088
03005F
03003C
0300C1
030038
030078
03001B
03008E
0300C8
030043
0300CF
03005F
030008
030098
0300B1
0300A5
0300BF
03002C
03008D
0300DC
030025
03000B
030090
0300F0
030085
0300E8
030047
030073
03007A
030016
030027
030081
03003A
030021
03001C
030081
030089
0300AA
030019
0300FF
030094
030096
030007
030080
030016
0300CD
03008C
0300C3
030095
03005E
0300D2
030024
030006
03008A
0300D2
0300A5
0300AA
030010
030035
0300F0
0300A9
03003C
030097
03006B
03000B
030060
030062
03007D
03004B
03004A
030043
030078
030042
03002C
03002E
0300CC
03005A
0300E9
030072
0300BC
030016
0300E6
0300F8
03003C
0300E6
0300E1
03009B
0300E4
030004
030013
0300A1
030041
03008D
0300BF
030056
0300B8
03004C
0300B2
0300FF
030089
0300F7
030089
030051
030023
03004E
0300FA
03004F
0300A2
03003F
0300D0
0300F9
030045
0300E8
03005A
0300C9
030072
0300FC
0300D3
030090
03004F
03002B
0300A8
0300EE
03007D
030054
0300BD
0300C1
0300B6
0300A2
0300AA
030022
030099
0300DF
030079
030087
030015
03002E
030092
0300C5
0300E1
0300B0
030079
03000E
030053
0300B9
03000D
030066
03004A
0300A8
03004D
0300C9
030094
030075
030009
0300FD
030082
030097
0300AB
0300DD
0300CA
030081
03009F
030006
03004C
030014
0300F3
03003B
0300A9
0300E4
0300A1
030098
030063
0300C1
0300D5
03007B
03006A
0300E5
0300E8
03005E
030065
030070
030044
03000D
03007B
0300C3
0300D1
0300D9
0300B8
0300AE
0300C3
0300C4
030030
030024
03008E
0300D7
0300E7
03003F
0300B0
0300B2
0300DA
0300A9
030098
0300EF
03008A
0300C5
0300EF
03007D
0300CC
0300C4
0300E1
030019
0300D9
030023
0300E1
030080
0300B4
0300C2
0300B1
03003C
030065
03009E
0300A9
0300EF
03008E
03001D
03002E
030011
030092
030051
0300AC
0300FC
030072
0300C2
030098
03008A
0300FA
0300AE
03001E
03006B
030023
03000E
030017
0300C6
030068
03006D
030084
030004
03004C
03006D
03003C
0300DF
03003B
03002C
0300AC
0300C5
0300D7

wimax
19.09.2016, 05:20
Трафик дишыфруеца с 3 пакета

Добавлено через 7 минут

public class Crypt implements ICrypt
{
private final L2GameClient _client;
private final byte[] _inKey = new byte[16];
private final byte[] _outKey = new byte[16];
private boolean _isEnabled;

public Crypt(L2GameClient client)
{
_client = client;
}

public void setKey(byte[] key)
{
System.arraycopy(key, 0, _inKey, 0, 16);
System.arraycopy(key, 0, _outKey, 0, 16);
}

@Override
public void encrypt(ByteBuf buf)
{
if (!_isEnabled)
{
_isEnabled = true;
onPacketSent(buf);
return;
}

onPacketSent(buf);

int a = 0;
while (buf.isReadable())
{
final int b = buf.readByte() & 0xFF;
a = b ^ _outKey[(buf.readerIndex() - 1) & 15] ^ a;
buf.setByte(buf.readerIndex() - 1, a);
}

shiftKey(_outKey, buf.writerIndex());
}

@Override
public void decrypt(ByteBuf buf)
{
if (!_isEnabled)
{
onPacketReceive(buf);
return;
}

int a = 0;
while (buf.isReadable())
{
final int b = buf.readByte() & 0xFF;
buf.setByte(buf.readerIndex() - 1, b ^ _inKey[(buf.readerIndex() - 1) & 15] ^ a);
a = b;
}

shiftKey(_inKey, buf.writerIndex());

onPacketReceive(buf);
}

private void onPacketSent(ByteBuf buf)
{
byte[] data = new byte[buf.writerIndex()];
buf.getBytes(0, data);
EventDispatcher.getInstance().notifyEvent(new OnPacketSent(_client, data));
}

private void onPacketReceive(ByteBuf buf)
{
byte[] data = new byte[buf.writerIndex()];
buf.getBytes(0, data);
EventDispatcher.getInstance().notifyEvent(new OnPacketReceived(_client, data));
}

private void shiftKey(byte[] key, int size)
{
int old = key[8] & 0xff;
old |= (key[9] << 8) & 0xff00;
old |= (key[10] << 0x10) & 0xff0000;
old |= (key[11] << 0x18) & 0xff000000;

old += size;

key[8] = (byte) (old & 0xff);
key[9] = (byte) ((old >> 0x08) & 0xff);
key[10] = (byte) ((old >> 0x10) & 0xff);
key[11] = (byte) ((old >> 0x18) & 0xff);
}
}

Активист
20.09.2016, 01:13
Код не понятен*(
Тему скриптинг гляну, там видел несколько похожих обозначений.

Нашел откуда этот код, теперь нужно его проанализировать*)
С тем, что был раньше.

Добавлено через 8 часов 43 минуты
Думал обойдусь без разбора полностью пакетов если просто пойму по какой формуле шифруется, но не тут то было, формулу не так просто найти, придется полностью весь код разбирать, что к чему, хоть ставь свой сервак и на его примере разбирайся как оно все пашет*(
Буду курить эти фак-и если есть что то по новее в смысле хроник GOD с небольшими изменениями, буду очень признателен.
http://www.la2kings.ru/la2bot/packets.html#PlayOk
http://fursoffers.narod.ru/Packets.htm

wimax
20.09.2016, 02:43
Мб у тебя нету шифрации? ты выдумуеш?)

Активист
20.09.2016, 05:25
Мб у тебя нету шифрации? ты выдумуеш?)

Года 2 назад играючи на этом же сервере чуть ниже хрониками, я пользовался пнх для привязки к местности используя кликер, и так же ловлей 2-х пакетов тыкать лсы.
Раньше эти пакеты создавались 1 раз на сессию и при повторе этих пакетов все работало, а сейчас каждый запуск одного и того же действия пакет изменяется и привязан к предыдущему, так как при повторной отправке этого пакета коннект рушится.

Активист
22.09.2016, 01:47
Скачал с инета не сильно старую ревизию тех же разработчиков.
Порылся в файлах нашел интересненькое incolution.jar а в нем уже
Blowfish.class
Crypt.class
Twofish.class
Теперь посмотрю темки по декомпиляции, надеюсь если и получится, то хотя бы читабельный код.

Добавлено через 2 часа 50 минут
Декодировал эту красоту теперь надо посидеть над кодом и подумать, но время поджимает и некогда сидеть за разбором кода.


Добавлено через 8 минут
Blowfish

package org.inc.nionetcore.util.crypt;

import org.inc.incolution.util.ArrayUtil;

public final class Blowfish
extends Crypt
{
private static final int BLOCK_SIZE = 8;
private static final int[] KP = { 111111111, -1111111111 };//// в этих массивах я убрал кучу переменных
private static final int[] KS1 = { 111111111, -111111111 };//// в этих массивах я убрал кучу переменных
private static final int[] KS2 = { -111111111, 1111111111 };//// в этих массивах я убрал кучу переменных
private static final int[] KS3 = { 111111111, 111111111 };//// в этих массивах я убрал кучу переменных
private static final int P_SZ = 18;
private static final int ROUNDS = 16;
private static final int SBOX_SK = 256;
private final int[] _P;
private final int[] _S0;
private final int[] _S1;
private final int[] _S2;
private final int[] _S3;

public Blowfish(byte[] key)
{
super(key);

this._S0 = new int[256];
this._S1 = new int[256];
this._S2 = new int[256];
this._S3 = new int[256];
this._P = new int[18];

System.arraycopy(KS0, 0, this._S0, 0, 256);
System.arraycopy(KS1, 0, this._S1, 0, 256);
System.arraycopy(KS2, 0, this._S2, 0, 256);
System.arraycopy(KS3, 0, this._S3, 0, 256);
System.arraycopy(KP, 0, this._P, 0, 18);

int keyLength = key.length;
int keyIndex = 0;
for (int i = 0; i < 18; i++)
{
int data = 0;
for (int j = 0; j < 4; j++)
{
data = data << 8 | key[(keyIndex++)] & 0xFF;
if (keyIndex >= keyLength) {
keyIndex = 0;
}
}
this._P ^= data;
}
processTable(0, 0, this._P);
processTable(this._P[16], this._P[17], this._S0);
processTable(this._S0['þ'], this._S0['ÿ'], this._S1);
processTable(this._S1['þ'], this._S1['ÿ'], this._S2);
processTable(this._S2['þ'], this._S2['ÿ'], this._S3);
}

public final void appendChecksum(byte[] raw, int offset, int size)
{
int count = offset + size - 4;
int checksum = 0;
for (; offset < count; offset += 4) {
checksum ^= ArrayUtil.getD(raw, offset);
}
ArrayUtil.putD(raw, offset, checksum);
}

protected final void decryptBlock(byte[] data, int offset)
{
int xl = ArrayUtil.getD(data, offset);
int xr = ArrayUtil.getD(data, offset + 4);
xl ^= this._P[17];
for (int k = 16; k > 0;)
{
xr ^= func(xl) ^ this._P[(k--)];
xl ^= func(xr) ^ this._P[(k--)];
}
xr ^= this._P[0];
ArrayUtil.putD(data, offset, xr);
ArrayUtil.putD(data, offset + 4, xl);
}

protected final void encryptBlock(byte[] data, int offset)
{
int xl = ArrayUtil.getD(data, offset);
int xr = ArrayUtil.getD(data, offset + 4);
xl ^= this._P[0];
for (int k = 1; k < 16;)
{
xr ^= func(xl) ^ this._P[(k++)];
xl ^= func(xr) ^ this._P[(k++)];
}
xr ^= this._P[17];
ArrayUtil.putD(data, offset, xr);
ArrayUtil.putD(data, offset + 4, xl);
}

private final int func(int x)
{
return (this._S0[(x >>> 24)] + this._S1[(x >>> 16 & 0xFF)] ^ this._S2[(x >>> 8 & 0xFF)]) + this._S3[(x & 0xFF)];
}

protected final int getBlockSize()
{
return 8;
}

private final void processTable(int xl, int xr, int[] table)
{
int size = table.length;
for (int s = 0; s < size; s += 2)
{
xl ^= this._P[0];
for (int i = 1; i < 16; i += 2)
{
xr ^= func(xl) ^ this._P[i];
xl ^= func(xr) ^ this._P[(i + 1)];
}
xr ^= this._P[17];
table[s] = xr;
table[(s + 1)] = xl;
xr = xl;
xl = table[s];
}
}

public final boolean verifyChecksum(byte[] raw, int offset, int size)
{
if ((size <= 4) || ((size & 0x3) != 0)) {
return false;
}
int count = offset + size - 4;
int checksum = 0;
for (; offset < count; offset += 4) {
checksum ^= ArrayUtil.getD(raw, offset);
}
return checksum == ArrayUtil.getD(raw, offset);
}

public final int calcDataSize(int size)
{
size += 4;
return size + (8 - size % 8);
}
}


Crypt


package org.inc.nionetcore.util.crypt;

import java.util.Random;
import org.inc.incolution.util.ArrayUtil;

public abstract class Crypt
{
private static final Random rnd = new Random();
public static final int KEY_256_BIT = 32;
public static final int KEY_192_BIT = 24;
public static final int KEY_128_BIT = 16;
public static final int KEY_64_BIT = 8;
private final byte[] _key;

public static void encXORPass(byte[] raw, int key)
{
Blowfish.encXORPass(raw, 0, raw.length, key);
}

public static void encXORPass(byte[] raw, int offset, int size, int key)
{
int stop = size - 8;
int pos = 4 + offset;

int ecx = key;
while (pos < stop)
{
int edx = raw[pos] & 0xFF;
edx |= (raw[(pos + 1)] & 0xFF) << 8;
edx |= (raw[(pos + 2)] & 0xFF) << 16;
edx |= (raw[(pos + 3)] & 0xFF) << 24;

ecx += edx;
edx ^= ecx;

raw[(pos++)] = ((byte)(edx & 0xFF));
raw[(pos++)] = ((byte)(edx >> 8 & 0xFF));
raw[(pos++)] = ((byte)(edx >> 16 & 0xFF));
raw[(pos++)] = ((byte)(edx >> 24 & 0xFF));
}
raw[(pos++)] = ((byte)(ecx & 0xFF));
raw[(pos++)] = ((byte)(ecx >> 8 & 0xFF));
raw[(pos++)] = ((byte)(ecx >> 16 & 0xFF));
raw[pos] = ((byte)(ecx >> 24 & 0xFF));
}

public static void decXORPass(byte[] raw, int offset, int size)
{
size = size + offset - 8;
offset += 4;
int ecx = ArrayUtil.getD(raw, size);
ArrayUtil.putD(raw, size, 0);
while (size > offset)
{
size -= 4;
int edx = ArrayUtil.getD(raw, size);
edx ^= ecx;
ecx -= edx;
ArrayUtil.putD(raw, size, edx);
}
}

protected Crypt(byte[] key)
{
this._key = key;
}

public final byte[] getKey()
{
return this._key;
}

public static final byte[] generateTwofishKey(int keyLenght)
{
checkTwofishKeyLenght(keyLenght);
byte[] key = new byte[keyLenght];
rnd.nextBytes(key);
return key;
}

public static final byte[] generateBlowfishKey(int keyLenght)
{
byte[] key = new byte[keyLenght];
rnd.nextBytes(key);
return key;
}

protected static void checkTwofishKeyLenght(int keyLenght)
{
switch (keyLenght)
{
case 8:
case 16:
case 24:
case 32:
break;
default:
throw new IllegalArgumentException("Incorrect key length");
}
}

public final void decrypt(byte[] data, int offset, int size)
{
int blockSize = getBlockSize();
for (int i = size / blockSize; i-- > 0;) {
decryptBlock(data, offset + i * blockSize);
}
}

public final void encrypt(byte[] data, int offset, int size)
{
int blockSize = getBlockSize();
for (int i = size / blockSize; i-- > 0;) {
encryptBlock(data, offset + i * blockSize);
}
}

protected abstract int getBlockSize();

protected abstract void decryptBlock(byte[] paramArrayOfByte, int paramInt);

protected abstract void encryptBlock(byte[] paramArrayOfByte, int paramInt);

public abstract boolean verifyChecksum(byte[] paramArrayOfByte, int paramInt1, int paramInt2);

public abstract void appendChecksum(byte[] paramArrayOfByte, int paramInt1, int paramInt2);

public abstract int calcDataSize(int paramInt);
}



[I]Добавлено через 7 минут
Последний class ну никак не влазит, он в 2а раза больше размера сообщения.

wimax
23.09.2016, 03:50
мда блоуфиш Это логин сервер помоему ты не осилиш забей)

Активист
24.09.2016, 00:36
мда блоуфиш Это логин сервер помоему ты не осилиш забей)

Ну осилю или нет мы узнаем после 20 числа следующего месяца, а пока мне просто не до игры*(
Но разбором шифрации мне интересней разбираться чем играть :)
Да и код первых 2х типов шифрации не такой уж и большой для разбора.
Я глянул последний там просто мрак да и по вики одним глазом глянул, там будет головная боль ооочень большая из за того, что при разборе кода мне трудно это все представлять, фантазия не ахти.

ScythLab
24.09.2016, 01:41
А кто там что собрался осиливать? Алгоритмы известны, ок. Алгоритмы не самые сложные (хотя самому с нуля написать библиотеку не самая простая задача, но выполнимая, так что лучше взять готовые сырцы), а дальше что? Где ключи, пароли, явки? Какие еще дополнительные проверки есть в протоколе? Это как все будет узнаваться/обходиться?