Remove pos sorting, support offset flag

This commit is contained in:
ruti 2024-03-05 23:22:12 +03:00
parent ff472f6448
commit eb3f28b25f
4 changed files with 104 additions and 112 deletions

View File

@ -25,6 +25,7 @@
#define memfd_create(name, flags) fileno(tmpfile()) #define memfd_create(name, flags) fileno(tmpfile())
#endif #endif
#else #else
#include <windows.h>
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#endif #endif
@ -67,15 +68,15 @@ int setttl(int fd, int ttl, int family) {
} }
#ifndef _WIN32 #ifndef _WIN32
static inline void delay(long mk) static inline void delay(long ms)
{ {
struct timespec time = { struct timespec time = {
.tv_nsec = mk * 1000 .tv_nsec = ms * 1000000
}; };
nanosleep(&time, 0); nanosleep(&time, 0);
} }
#else #else
#define delay(mk) {} #define delay(ms) Sleep(ms)
#endif #endif
#ifndef _WIN32 #ifndef _WIN32
@ -204,27 +205,30 @@ int desync(int sfd, char *buffer, size_t bfsize,
return -1; return -1;
} }
} }
else if (type == IS_HTTPS && params.tlsrec) { else if (type == IS_HTTPS && params.tlsrec_n) {
struct part *part = params.tlsrec;
int i = 0;
long lp = 0; long lp = 0;
while (part) { for (int i = 0; i < params.tlsrec_n; i++) {
long pos = part->pos + i * 5; struct part part = params.tlsrec[i];
if (params.tlsrec_sni) {
long pos = part.pos + i * 5;
if (part.flag == OFFSET_SNI) {
pos += (host - buffer - 5); pos += (host - buffer - 5);
} }
else if (pos < 0) { else if (pos < 0) {
pos += n; pos += n;
} }
LOG(LOG_S, "tlsrec: pos=%ld, n=%ld\n", pos, n); if (pos < lp) {
if (!part_tls(buffer + lp, LOG(LOG_E, "tlsrec cancel: %ld < %ld\n", pos, lp);
bfsize - lp, n - lp, pos - lp)) {
break; break;
} }
if (!part_tls(buffer + lp,
bfsize - lp, n - lp, pos - lp)) {
LOG(LOG_E, "tlsrec error: pos=%ld, n=%ld\n", pos, n);
break;
}
LOG(LOG_S, "tlsrec: pos=%ld, n=%ld\n", pos, n);
n += 5; n += 5;
lp = pos + 5; lp = pos + 5;
i++;
part = part->next;
} }
} }
@ -233,30 +237,37 @@ int desync(int sfd, char *buffer, size_t bfsize,
return -1; return -1;
} }
} }
struct part *part = params.parts;
long lp = 0; long lp = 0;
if ((!type && params.de_known)) { if ((!type && params.de_known)) {
part = 0;
} }
while (part) { else for (int i = 0; i < params.parts_n; i++) {
long pos = part->pos; struct part part = params.parts[i];
if (params.split_host) {
if (host) long pos = part.pos;
pos += (host - buffer); if (part.flag == OFFSET_SNI) {
if (type != IS_HTTPS)
break;
else else
pos = 0; pos += (host - buffer);
}
else if (part.flag == OFFSET_HOST) {
if (type != IS_HTTP)
break;
else
pos += (host - buffer);
} }
else if (pos < 0) { else if (pos < 0) {
pos += n; pos += n;
} }
if (pos <= 0 || pos >= n || pos <= lp) { if (pos <= 0 || pos >= n || pos <= lp) {
LOG(LOG_E, "split cancel: pos=%ld-%ld, n=%ld\n", lp, pos, n);
break; break;
} }
LOG(LOG_S, "split: pos=%ld-%ld, m=%d\n", lp, pos, part->m); LOG(LOG_S, "split: pos=%ld-%ld, m=%d\n", lp, pos, part.m);
int s = 0; int s = 0;
switch (part->m) { switch (part.m) {
#ifndef _WIN32 #ifndef _WIN32
case DESYNC_FAKE: case DESYNC_FAKE:
s = send_fake(sfd, s = send_fake(sfd,
@ -284,7 +295,6 @@ int desync(int sfd, char *buffer, size_t bfsize,
return -1; return -1;
} }
lp = pos; lp = pos;
part = part->next;
} }
if (lp < n) { if (lp < n) {
LOG(LOG_S, "send: pos=%ld-%ld\n", lp, n); LOG(LOG_S, "send: pos=%ld-%ld\n", lp, n);

110
main.c
View File

@ -40,14 +40,14 @@ oob_data = {
struct params params = { struct params params = {
.ttl = 8, .ttl = 8,
.parts_n = 0,
.parts = 0, .parts = 0,
.sfdelay = 3000, .sfdelay = 3,
.split_host = 0,
.def_ttl = 0, .def_ttl = 0,
.custom_ttl = 0, .custom_ttl = 0,
.mod_http = 0, .mod_http = 0,
.tlsrec = 0, .tlsrec = 0,
.tlsrec_sni = 0, .tlsrec_n = 0,
.de_known = 0, .de_known = 0,
.ipv6 = 1, .ipv6 = 1,
@ -72,12 +72,11 @@ const char help_text[] = {
" -g, --def-ttl <num> TTL for all outgoing connections\n" " -g, --def-ttl <num> TTL for all outgoing connections\n"
// desync options // desync options
" -K, --desync-known Desync only HTTP and TLS with SNI\n" " -K, --desync-known Desync only HTTP and TLS with SNI\n"
" -H, --split-at-host Add Host/SNI offset to split position\n" " -s, --split <n[+s]> Split packet at n, +s to add SNI offset\n"
" -s, --split <offset> Split packet at spec position\n" " -s, --disorder <n[+s]> Split and send reverse order\n"
" -s, --disorder <offset> Split and send reverse order\n" " -o, --oob <n[+s]> Split and send as OOB data\n"
" -o, --oob <offset> Split and send as OOB data\n"
#ifdef FAKE_SUPPORT #ifdef FAKE_SUPPORT
" -f, --fake <offset> Split and send fake packet\n" " -f, --fake <n[+s]> Split and send fake packet\n"
" -t, --ttl <num> TTL of fake packets, default 8\n" " -t, --ttl <num> TTL of fake packets, default 8\n"
" -l, --fake-tls <file>\n" " -l, --fake-tls <file>\n"
" -j, --fake-http <file> Set custom fake packet\n" " -j, --fake-http <file> Set custom fake packet\n"
@ -85,8 +84,7 @@ const char help_text[] = {
#endif #endif
" -e, --oob-data <file> Set custom OOB data\n" " -e, --oob-data <file> Set custom OOB data\n"
" -M, --mod-http <h,d,r> Modify http: hcsmix,dcsmix,rmspace\n" " -M, --mod-http <h,d,r> Modify http: hcsmix,dcsmix,rmspace\n"
" -r, --tlsrec <offset> Make TLS record at offset\n" " -r, --tlsrec <n[+s]> Make TLS record at offset\n"
" -L, --tlsrec-at-sni Add SNI offset to tlsrec position\n"
}; };
@ -103,13 +101,12 @@ const struct option options[] = {
{"debug", 1, 0, 'x'}, {"debug", 1, 0, 'x'},
{"desync-known ", 0, 0, 'K'}, {"desync-known ", 0, 0, 'K'},
{"split-at-host", 0, 0, 'H'},
{"split", 1, 0, 's'}, {"split", 1, 0, 's'},
{"disorder", 1, 0, 'd'}, {"disorder", 1, 0, 'd'},
{"oob", 1, 0, 'o'}, {"oob", 1, 0, 'o'},
#ifdef FAKE_SUPPORT
{"fake", 1, 0, 'f'}, {"fake", 1, 0, 'f'},
{"ttl", 1, 0, 't'}, {"ttl", 1, 0, 't'},
#ifdef FAKE_SUPPORT
{"fake-tls", 1, 0, 'l'}, {"fake-tls", 1, 0, 'l'},
{"fake-http", 1, 0, 'j'}, {"fake-http", 1, 0, 'j'},
{"tls-sni", 1, 0, 'n'}, {"tls-sni", 1, 0, 'n'},
@ -117,7 +114,6 @@ const struct option options[] = {
{"oob-data", 1, 0, 'e'}, {"oob-data", 1, 0, 'e'},
{"mod-http", 1, 0, 'M'}, {"mod-http", 1, 0, 'M'},
{"tlsrec", 1, 0, 'r'}, {"tlsrec", 1, 0, 'r'},
{"tlsrec-at-sni", 0, 0, 'L'},
{"def-ttl", 1, 0, 'g'}, {"def-ttl", 1, 0, 'g'},
{"delay", 1, 0, 'w'}, // {"delay", 1, 0, 'w'}, //
@ -195,41 +191,39 @@ int get_default_ttl()
} }
struct part *add_part(struct part **root, long val) struct part *add_part(struct part **root, int *n)
{ {
struct part *part = malloc(sizeof(struct part)); struct part *p = realloc(
if (!part) { *root, sizeof(struct part) * (*n + 1));
uniperror("malloc"); if (!p) {
uniperror("realloc");
return 0; return 0;
} }
part->pos = val; *root = p;
*n = *n + 1;
return &((*root)[(*n) - 1]);
}
struct part *p = *root, *v = 0;
if (!p) { int parse_offset(struct part *part, const char *str)
*root = part; {
return part; char *end = 0;
} long val = strtol(str, &end, 0);
while (p) { if (*end == '+') switch (*(end + 1)) {
if (val < p->pos) { case 's':
if (v) { part->flag = OFFSET_SNI;
part->next = p;
v->next = part;
}
else {
part->next = *root;
*root = part;
}
break; break;
} case 'h':
if (!p->next) { part->flag = OFFSET_HOST;
p->next = part;
part->next = 0;
break; break;
default:
return -1;
} }
v = p; else if (*end) {
p = p->next; return -1;
} }
return part; part->pos = val;
return 0;
} }
@ -265,9 +259,6 @@ int main(int argc, char **argv)
} }
} }
char daemon = 0;
char *pidfile = 0;
int rez; int rez;
int invalid = 0; int invalid = 0;
@ -340,23 +331,20 @@ int main(int argc, char **argv)
params.de_known = 1; params.de_known = 1;
break; break;
case 'H':
params.split_host = 1;
break;
case 's': case 's':
case 'd': case 'd':
case 'o': case 'o':
case 'f': case 'f':
val = strtol(optarg, &end, 0); ;
if (*end) { struct part *part = add_part(
invalid = 1; &params.parts, &params.parts_n);
break;
}
struct part *part = add_part(&params.parts, val);
if (!part) { if (!part) {
return -1; return -1;
} }
if (parse_offset(part, optarg)) {
invalid = 1;
break;
}
switch (rez) { switch (rez) {
case 's': part->m = DESYNC_SPLIT; case 's': part->m = DESYNC_SPLIT;
break; break;
@ -431,19 +419,15 @@ int main(int argc, char **argv)
break; break;
case 'r': case 'r':
val = strtol(optarg, &end, 0); part = add_part(&params.tlsrec, &params.tlsrec_n);
if (val > 0xffff || *end) {
invalid = 1;
break;
}
part = add_part(&params.tlsrec, val);
if (!part) { if (!part) {
return -1; return -1;
} }
if (parse_offset(part, optarg)
|| part->pos > 0xffff) {
invalid = 1;
break; break;
}
case 'L':
params.tlsrec_sni = 1;
break; break;
case 'g': case 'g':
@ -459,7 +443,7 @@ int main(int argc, char **argv)
case 'w': // case 'w': //
params.sfdelay = strtol(optarg, &end, 0); params.sfdelay = strtol(optarg, &end, 0);
if (params.sfdelay < 0 || optarg == end if (params.sfdelay < 0 || optarg == end
|| params.sfdelay >= 1000000 || *end) || params.sfdelay >= 1000 || *end)
invalid = 1; invalid = 1;
break; break;

View File

@ -6,6 +6,9 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#endif #endif
#define OFFSET_SNI 1
#define OFFSET_HOST 2
enum demode { enum demode {
DESYNC_NONE, DESYNC_NONE,
DESYNC_SPLIT, DESYNC_SPLIT,
@ -16,21 +19,21 @@ enum demode {
struct part { struct part {
int m; int m;
int flag;
long pos; long pos;
struct part *next;
}; };
struct params { struct params {
char de_known; char de_known;
int ttl; int ttl;
int parts_n;
struct part *parts; struct part *parts;
char split_host;
long sfdelay; long sfdelay;
int def_ttl; int def_ttl;
char custom_ttl; char custom_ttl;
int mod_http; int mod_http;
int tlsrec_n;
struct part *tlsrec; struct part *tlsrec;
char tlsrec_sni;
char ipv6; char ipv6;
char resolve; char resolve;

View File

@ -3,7 +3,7 @@
-------------- --------------
Использование: Использование:
$ ./ciadpi --split 3 --disorder 10 $ ./ciadpi --disorder 3+sni
Описание аргументов: Описание аргументов:
-i, --ip <ip> -i, --ip <ip>
@ -35,26 +35,25 @@ $ ./ciadpi --split 3 --disorder 10
Отключить запутывание для нераспознанных протоколов Отключить запутывание для нераспознанных протоколов
Распознаваемые протоколы: HTTP и TLS с SNI Распознаваемые протоколы: HTTP и TLS с SNI
-s, --split <offset> -s, --split <n[+s]>
Разбить запрос по указанному смещению Разбить запрос по указанному смещению
После числа можно добавить флаг:
+s: добавить смещение SNI
+h: добавить смещение Host
Можно указывать несколько раз, чтобы разбить запрос по нескольким позициям Можно указывать несколько раз, чтобы разбить запрос по нескольким позициям
При указании отрицательного значения к нему прибавляется размер пакета При указании отрицательного значения к нему прибавляется размер пакета
-d, --disorder <offset> -d, --disorder <n[+s]>
Подобен --split, но части отправляются в обратном порядке Подобен --split, но части отправляются в обратном порядке
! Поведение в Windows отлично: сначала отправляется лишь часть, но затем целый запрос ! Поведение в Windows отлично: сначала отправляется лишь часть, но затем целый запрос
-f, --fake <offset> -o, --oob <n[+s]>
Подобен --split, но после offset отсылается один или несколько байт OOB данных
-f, --fake <n[+s]>
Подобен --disorder, только перед отправкой первого куска отправляется часть поддельного Подобен --disorder, только перед отправкой первого куска отправляется часть поддельного
Количество байт отправляемого из фейка равно рамеру разбиваемой части Количество байт отправляемого из фейка равно рамеру разбиваемой части
-o, --oob <offset>
Подобен --split, но после offset отсылается несколько байт OOB данных
-H, --split-at-host
Если найден SNI или Host, то считать смещение относительно позиции домена
При offset=0 запрос будет разбит прямо перед именем хоста
-t, --ttl <num> -t, --ttl <num>
TTL для поддельного пакета, по умолчанию 8 TTL для поддельного пакета, по умолчанию 8
Необходимо подобрать такое значение, чтобы пакет не дошел до сервера, но был обработан DPI Необходимо подобрать такое значение, чтобы пакет не дошел до сервера, но был обработан DPI
@ -79,14 +78,10 @@ $ ./ciadpi --split 3 --disorder 10
rmspace: rmspace:
"Host: name" -> "Host:name\t" "Host: name" -> "Host:name\t"
-r, --tlsrec <offset> -r, --tlsrec <n[+s]>
Разделить ClientHello на отдельные записи по указанному смещению Разделить ClientHello на отдельные записи по указанному смещению
Также возможен отсчет от конца при указании отрицательного значения
Можно указывать несколько раз Можно указывать несколько раз
-L, --tlsrec-at-sni
Отсчитывать позицию tlsrec относительно SNI
------- -------
Сборка: Сборка:
Для сборки понадобится: Для сборки понадобится: