bol-van / zapret

DPI bypass multi platform
8.3k stars 634 forks source link

multisplit with seqovl > 1st packet tls size, is this normal? #784

Open AlexeiGHub opened 13 hours ago

AlexeiGHub commented 13 hours ago

lists summary:

splits summary: profile 1 multisplit abs 1 profile 1 multisplit midsld 0 profile 1 seqovl abs 568 profile 2 multisplit abs 2 profile 0 multisplit abs 2

...... discovered l7 protocol discovered hostname desync profile search for tcp target=xxx.xxx.xxx.xxx:443 l7proto=tls hostname='xxxxxxxxxxxxxxxxxx.xxx' desync profile 1 matches dpi desync src=yyyy.yyyy.yyyy.yyy:22483 dst=xxxx.xxx.xxx.xxx:443 multisplit pos: 1 185 normalized multisplit pos: 1 185 sending multisplit part 1 0-0 len=1 seqovl=0 : 16 : . sending multisplit part 2 1-184 len=184 seqovl=0 : 03

Если значение seqovl> tls size тогда seqovl=0 ! Так и должно быть?

bol-van commented 13 hours ago

В сплите и дисордере разные схемы применения seqovl. Для сплита важно, чтобы seqovl+первый кусок не превысили MTU. Для дисордера важно, чтобы seqovl был меньше первого куска

AlexeiGHub commented 13 hours ago

Я думаю это условие выполняется. Эффект заметен на curl и прекрасно работает с kyber.

bol-van commented 13 hours ago

Под первым куском я имею в виду не разбитие kyber системой на 2 TCP сегмента. С этим nfqws ничего не делает. Он работает с отдельными сегментами, пришедшими от системы. Он их не обьединяет. Позиции вычисляются на базе реассемблированного сообщения, но потом нормализуются под смещение текущего пакета в полном сообщении. Первый кусок имеется в виду то, что нарезает nfqws в текущем пакете, не более того

AlexeiGHub commented 13 hours ago
seqovl = i==0 ? seqovl_pos : 0;
#ifdef __linux__
// only linux return error if MTU is exceeded
                        for(;;**seqovl=0**) ????
                        {
#endif
                            if (seqovl)
                            {
                                seg_len = to-from+seqovl;
                                if (seg_len>sizeof(ovlseg))
                                {
                                    DLOG("seqovl is too large");
                                    return verdict;
                                }
                                fill_pattern(ovlseg,seqovl,dp->seqovl_pattern,sizeof(dp->seqovl_pattern));
                                memcpy(ovlseg+seqovl,dis->data_payload+from,to-from);
                                seg = ovlseg;
                            }
                            else
                            {
                                **seqovl** = 0; // Или тут?
                                seg = dis->data_payload+from;
                                seg_len = to-from;
                            }
bol-van commented 13 hours ago

Понял, действительно проблема. Она появилась после того, как была добавлена поддержка маркеров в seqovl. При ресолвинге маркера там проверка на превышение длину пакета. В случае seqovl она неактуальна

AlexeiGHub commented 13 hours ago

Под первым куском я имею в виду не разбитие kyber системой на 2 TCP сегмента. С этим nfqws ничего не делает. Он работает с отдельными сегментами, пришедшими от системы. Он их не обьединяет. Позиции вычисляются на базе реассемблированного сообщения, но потом нормализуются под смещение текущего пакета в полном сообщении. Первый кусок имеется в виду то, что нарезает nfqws в текущем пакете, не более того

Прошу попробовать воспроизвести эффект. 1)--filter-tcp=443 --dpi-desync=multisplit --dpi-desync-split-seqovl=568 --dpi-desync-split-seqovl-pattern=хххх --dpi-desync-split-pos=1,midsld 2)сurl и запрос браузеров с kyber

При запросе из браузера все красиво, а при запросе curl pattern отсутствует в шарке.

AlexeiGHub commented 12 hours ago

В случае seqovl она неактуальна

Ну, наверно актуально, но можно сгенерировать еще точку разбития при сплите? А можно и юзера обязать подрезать под (seqovl+ 1st split)<MTU.

bol-van commented 12 hours ago

По сути маркеры нужны только для disorder. Там важно не вылезть за начало текущего пакета в минус по sequence, иначе будет фейл. Если идет сплит на относительном маркере, то и минус должен считаться относительно него, split host, seqovl host-1

В случае split всегда применение идет только на первом куске (иначе начинается хаотичное поведение сервера). И там важно только число, на которое идет залезание в минус по sequence. Привязываться к логическим частям сообщения, которые еще могут находиться и в другом пакете, смысла нет.

Поэтому, пожалуй, надо сделать так. Для disorder оставляем все как есть. Для split оставляем только фиксированное число.

AlexeiGHub commented 12 hours ago

Может ввести специальный маркер, добивка до полного пакета --split-pos=padding, N, N? И можно запретить участие в реордеринге первого значения --split-pos=fixN, N,N если оно больше любого из последующих?

bol-van commented 12 hours ago

Полный пакет - вещь непонятная. Неясен максимальный размер возможного пейлоада. Он зависит от многих факторов. И узнать это значение - очень сложно. Придется жуткий огород соорудить, который prone to fail

bol-van commented 12 hours ago

Сплит позиции после ресолвинга сортируются по возрастанию, уникализируются и нормализуются по смещению текущего пакета в мультипакетном сообщении

AlexeiGHub commented 12 hours ago

сортируются по возрастанию

Ну вот ее(сортировку) и запретить для специальным образом оформленного числа, которое исключается из массива сплитинга если оно не самое мелкое?

bol-van commented 12 hours ago

Не надо никакого специального числа. Смотрится что там в текущем профиле. Дисордер или сплит. Если дисордер - как сейчас. Если сплит , то оставляется число. При попытке задать что-то иное - ошибка на этапе старта проги.

AlexeiGHub commented 11 hours ago

prone to fail

Согласен, но вдруг будет целесообразно вырастить монстра.

bol-van commented 11 hours ago

Обычно нет смысла никакого добивать до полного пакета. Я не знаю для чего это может быть надо. seqovl нужен для вставления скрытых фейков. И это либо какой-то мусор (1 нулевой байт), либо что-то осмысленное с известной длиной (tls hello от гос услуг). Важно, чтобы первая сплит позиция была достаточно маленькой, чтобы seqovl влез в MTU. Потому оставлять только midsld с seqovl - это будет плохо работать. Хаотически то работать, то нет, в зависимости от желания хрома засунуть SNI в начало или в конец пакета, в первый или во второй пакет. Надо делать еще 1 фиксированную сплит позицию, и тогда это будет работать

AlexeiGHub commented 11 hours ago

При попытке задать что-то иное

Тоже норм, но если оно больше какого-нибудь midsld? Вроде как и не надо уже резать, а оно все равно порежет?

bol-van commented 11 hours ago

В случае split оно не связано вообще никак с позициями чего-либо в середине. Оно пихается всегда в начало. Допустим, seqovl = 4. Идет TLS

16 03 03 ........ seq=100 получаем 00 00 00 00 16 03 03 seq=96

первый пакет может быть полный под MTU - 1448, допустим. приписать к нему уже ничего нельзя. midsld может быть во 2-м пакете. смещение до midsld 1900. после нормализации 1900-1448=452 во 2-м пакете но к 2 пакету не применяется split seqovl. я пробовал, получается хаос. У linux в этом случае непонятный алгоритм, пролезают фейки в окно tcp. Точнее, он понятный как раз. Там начинаются гонки. Успеет ли сервер скинуть в сокет данные или нет. Пакеты идут залпом, так что вероятно, что не успеет. Как там прерывания сложатся.

Непонятный алгоритм в случае disorder. Там действительно фейки пролезают, если несколько раз перекрывать

bol-van commented 11 hours ago

А в случае disorder, напротив, получается все очень логично.

midsld нормализуется до 452 midsld-1 нормализуется до 451

и на 2-й пакет делаем disorder 452-end, 0-451 в случае такого оверлапа получаем 1-end, 0-451

AlexeiGHub commented 11 hours ago

Я возможно потерялся. Ага, вы про --dpi-desync-split-seqovl= , а я больше --dpi-desync-split-pos= --dpi-desync-split-seqovl= тоже мультинарезку поддреживал что-ли? Пытаюсь синхронизироваться ....

bol-van commented 11 hours ago

Нет, не работает мультинарезка с оверлапом, пробовал уже. Стабильно работает только однократный оверлап. В случае split - перед первым пакетом. Когда по логике протокола прикладного уровня сервер уже все предыдущее схватил, если оно имелось, и вылезание sequence в минус точно выведет его из текущего tcp окна, следовательно ничего не порушит. А в случае disorder стабильно работает только однократное перекрытие по sequence. В случае многократного там какая-то хрень с алгоритмом в ядре linux. Не так, как ожидалось. Мусор лезет

AlexeiGHub commented 11 hours ago

Думаю синхронизировался. Но и вы мою мысль поймите. Я в большей степени о multisplit и ситуациях -desync-split-pos= 500,midsld, 800 При этом midsld=350 и вроде как уже при seqovl смысла резать в позиции 500 нет. 150 байт во втором пакете? Я правильно понимаю?

1 пакет = seqovl+350 2 пакет = 350-500 3 пакет = 500-800 4 пакет = 800- end

bol-van commented 11 hours ago

Не совсем, Первый сплит абсолютный на небольшом значении нужен, чтобы seqovl уместился в MTU первого пакета фактически выплевываемой в сеть нарезки. Но DPI как показывает практика на ютубе начал тупо искать подстроку "googlevideo.com" в нескольких пакетах. midsld нужно, чтобы его обломать

AlexeiGHub commented 11 hours ago

Фигню написал

Так должно быть: 1 пакет = seqovl+1-350 2 пакет = 351-500 3 пакет = 501-800 4 пакет = 801- end

AlexeiGHub commented 11 hours ago

googlevideo.com

Как по мне только "googlevideo", но я больше академически изучаю ваш проект. Это лекго проверить, особенно теперь. Можно порезать "googlevideo." и "com"

AlexeiGHub commented 11 hours ago

ОК, спасибо за ответы. У Вас отличный проект.

bol-van commented 11 hours ago

Да, теперь все верно.

Для split в блокчеке у меня всегда используется либо seqovl=1, либо seqovl=336 с паттерном tls hello от безобидного сайта (скрытый fake, чтобы он отстал от потока, увидев плюшевого мишку).

А сплит позиции такие : http : method+2 method+2,midsld tls: 10 10,sniext+1 10,sniext+4 10,midsld

Чтобы порезать в http метод или метод и хост, а в tls только начало, sni extension ровно в середине между low и high байтами длин или хост

AlexeiGHub commented 10 hours ago

tls: 10 10,sniext+1 10,sniext+4 10,midsld

Что означает 10? и значение пробелов?

AlexeiGHub commented 10 hours ago

Все понял, это разные пресеты.

AlexeiGHub commented 10 hours ago

Надо было | 10 | 10,sniext+1 | 10,sniext+4 | 10 ,midsld

bol-van commented 10 hours ago

Это шелл переменная, которая через for процессится пробел - разделитель