Browse Source

Merge pull request #4 from vemneyy/copilot/update-random-dpi-desync-increment

Add per-fake random range support for `--dpi-desync-ts-increment`
pull/2093/head
vemneyy 4 months ago
committed by GitHub
parent
commit
f29955b606
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      docs/readme.en.md
  2. 2
      docs/readme.md
  3. 34
      nfq/desync.c
  4. 49
      nfq/nfqws.c
  5. 2
      nfq/params.h

2
docs/readme.en.md

@ -209,7 +209,7 @@ nfqws takes the following parameters:
--dpi-desync-hostfakesplit-mod=mod[,mod] ; can be none, host=<hostname>, altorder=0|1
--dpi-desync-ipfrag-pos-tcp=<8..9216> ; ip frag position starting from the transport header. multiple of 8, default 32.
--dpi-desync-ipfrag-pos-udp=<8..9216> ; ip frag position starting from the transport header. multiple of 8, default 8.
--dpi-desync-ts-increment=<int|0xHEX> ; ts fooling TSval signed increment. default -600000
--dpi-desync-ts-increment=<int|0xHEX|[+|-](N-M)|N-M> ; ts fooling TSval signed increment or per-fake random value from range. default -600000
--dpi-desync-badseq-increment=<int|0xHEX> ; badseq fooling seq signed increment. default -10000
--dpi-desync-badack-increment=<int|0xHEX> ; badseq fooling ackseq signed increment. default -66000
--dpi-desync-any-protocol=0|1 ; 0(default)=desync only http and tls 1=desync any nonempty data packet

2
docs/readme.md

@ -239,7 +239,7 @@ dvtws, собираемый из тех же исходников (см. [док
--dpi-desync-hostfakesplit-mod=mod[,mod] ; может быть none, host=<hostname>, altorder=0|1
--dpi-desync-ipfrag-pos-tcp=<8..9216> ; позиция ip фрагментации tcp, начиная с транспортного заголовка. должно быть кратно 8, по умолчанию - 32.
--dpi-desync-ipfrag-pos-udp=<8..9216> ; позиция ip фрагментации udp, начиная с транспортного заголовка. должно быть кратно 8, по умолчанию - 8.
--dpi-desync-ts-increment=<int|0xHEX> ; инкремент TSval для ts. по умолчанию -600000
--dpi-desync-ts-increment=<int|0xHEX|[+|-](N-M)|N-M> ; инкремент TSval для ts или случайное значение из диапазона для каждого фейка. по умолчанию -600000
--dpi-desync-badseq-increment=<int|0xHEX> ; инкремент sequence number для badseq. по умолчанию -10000
--dpi-desync-badack-increment=<int|0xHEX> ; инкремент ack sequence number для badseq. по умолчанию -66000
--dpi-desync-any-protocol=0|1 ; 0(default)=работать только по http request и tls clienthello 1=по всем непустым пакетам данных

34
nfq/desync.c

@ -876,6 +876,16 @@ static uint16_t IP4_IP_ID_ADD(uint16_t ip_id, uint16_t inc, t_ip_id_mode mode)
#define IP4_IP_ID_NEXT(ip_id,mode) IP4_IP_ID_ADD(ip_id,+1,mode)
#define IP4_IP_ID_PREV(ip_id,mode) IP4_IP_ID_ADD(ip_id,-1,mode)
static uint32_t desync_ts_increment(const struct desync_profile *dp)
{
if (!dp->desync_ts_increment_random)
return dp->desync_ts_increment;
int64_t span = (int64_t)dp->desync_ts_increment_max - dp->desync_ts_increment_min + 1;
int32_t value = dp->desync_ts_increment_min + (int32_t)(random() % span);
return (uint32_t)value;
}
// fake_mod buffer must at least sizeof(desync_profile->fake_tls)
// return : true - altered, false - not altered
@ -1531,7 +1541,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
pkt1_len = sizeof(pkt1);
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, TH_SYN | TH_ACK, false, 0, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
DF, ttl_fake, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
dp->desync_fooling_mode, dp->desync_ts_increment, dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
dp->desync_fooling_mode, desync_ts_increment(dp), dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
NULL, 0, pkt1, &pkt1_len))
{
goto send_orig;
@ -2085,7 +2095,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
pkt1_len = sizeof(pkt1);
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_fake, false, 0, htonl(sequence), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
DF, ttl_fake, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
dp->desync_fooling_mode, dp->desync_ts_increment, dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
dp->desync_fooling_mode, desync_ts_increment(dp), dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
fake_data, fake_size, pkt1, &pkt1_len))
{
reasm_orig_cancel(ctrack);
@ -2110,7 +2120,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
pkt1_len = sizeof(pkt1);
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, TH_RST | (dp->desync_mode == DESYNC_RSTACK ? TH_ACK : 0), false, 0, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
DF, ttl_fake, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
dp->desync_fooling_mode, dp->desync_ts_increment, dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
dp->desync_fooling_mode, desync_ts_increment(dp), dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
NULL, 0, pkt1, &pkt1_len))
{
reasm_orig_cancel(ctrack);
@ -2244,7 +2254,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_fake, false, 0,
net32_add(dis->tcp->th_seq, pos_host), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
DF, ttl_fake, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
dp->desync_fooling_mode, dp->desync_ts_increment, dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
dp->desync_fooling_mode, desync_ts_increment(dp), dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
fakehost, host_size, pkt2, &pkt2_len))
goto send_orig_clean;
if (dp->ip_id_mode!=IPID_SEQ_GROUP) ip_id = IP4_IP_ID_NEXT(ip_id,dp->ip_id_mode);
@ -2538,7 +2548,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
fakeseg2_len = sizeof(fakeseg2);
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_fake, false, 0, net32_add(dis->tcp->th_seq, split_pos), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
DF, ttl_fake, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
dp->desync_fooling_mode, dp->desync_ts_increment, dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
dp->desync_fooling_mode, desync_ts_increment(dp), dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
pat + split_pos, dis->len_payload - split_pos, fakeseg2, &fakeseg2_len))
goto send_orig;
@ -2554,7 +2564,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
pkt1_len = sizeof(pkt1);
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, false, 0, net32_add(dis->tcp->th_seq, split_pos - seqovl), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
DF, ttl_orig, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
fooling_orig, dp->desync_ts_increment, dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
fooling_orig, desync_ts_increment(dp), dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
seg, seg_len, pkt1, &pkt1_len))
goto send_orig;
ip_id = IP4_IP_ID_NEXT(ip_id,dp->ip_id_mode);
@ -2581,7 +2591,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
seg_len = sizeof(fakeseg);
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_fake, false, 0, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
DF, ttl_fake, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
dp->desync_fooling_mode, dp->desync_ts_increment, dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
dp->desync_fooling_mode, desync_ts_increment(dp), dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
pat, split_pos, fakeseg, &seg_len))
goto send_orig;
if (dp->ip_id_mode!=IPID_SEQ_GROUP) ip_id = IP4_IP_ID_NEXT(ip_id,dp->ip_id_mode);
@ -2593,7 +2603,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
pkt1_len = sizeof(pkt1);
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, false, 0, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
DF, ttl_orig, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
fooling_orig, dp->desync_ts_increment, dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
fooling_orig, desync_ts_increment(dp), dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
dis->data_payload, split_pos, pkt1, &pkt1_len))
goto send_orig;
ip_id = IP4_IP_ID_NEXT(ip_id,dp->ip_id_mode);
@ -2650,7 +2660,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
fakeseg_len = sizeof(fakeseg);
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_fake, false, 0, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
DF, ttl_fake, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
dp->desync_fooling_mode, dp->desync_ts_increment, dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
dp->desync_fooling_mode, desync_ts_increment(dp), dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
pat, split_pos, fakeseg, &fakeseg_len))
goto send_orig;
@ -2690,7 +2700,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
pkt1_len = sizeof(pkt1);
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, false, 0, net32_add(dis->tcp->th_seq, -seqovl), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
DF, ttl_orig, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
fooling_orig, dp->desync_ts_increment, dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
fooling_orig, desync_ts_increment(dp), dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
seg, seg_len, pkt1, &pkt1_len))
goto send_orig;
ip_id = IP4_IP_ID_NEXT(ip_id,dp->ip_id_mode);
@ -2729,7 +2739,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
fakeseg_len = sizeof(fakeseg);
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_fake, false, 0, net32_add(dis->tcp->th_seq, split_pos), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
DF, ttl_fake, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
dp->desync_fooling_mode, dp->desync_ts_increment, dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
dp->desync_fooling_mode, desync_ts_increment(dp), dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
pat + split_pos, dis->len_payload - split_pos, fakeseg, &fakeseg_len))
goto send_orig;
if (dp->ip_id_mode!=IPID_SEQ_GROUP) ip_id = IP4_IP_ID_NEXT(ip_id,dp->ip_id_mode);
@ -2741,7 +2751,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
pkt1_len = sizeof(pkt1);
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, false, 0, net32_add(dis->tcp->th_seq, split_pos), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
DF, ttl_orig, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
fooling_orig, dp->desync_ts_increment, dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
fooling_orig, desync_ts_increment(dp), dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
dis->data_payload + split_pos, dis->len_payload - split_pos, pkt1, &pkt1_len))
goto send_orig;
ip_id = IP4_IP_ID_NEXT(ip_id,dp->ip_id_mode);

49
nfq/nfqws.c

@ -25,6 +25,7 @@
#include <signal.h>
#include <errno.h>
#include <time.h>
#include <limits.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/stat.h>
@ -866,6 +867,48 @@ static bool parse_net32_signed(const char *opt, uint32_t *value)
return sscanf(opt, "%d", (int32_t*)value) > 0;
}
}
static bool parse_desync_ts_increment(const char *opt, struct desync_profile *dp)
{
int sign = 1;
const char *s = opt;
if (*s == '+' || *s == '-')
{
sign = (*s == '-') ? -1 : 1;
s++;
}
bool with_brackets = *s == '(';
if (with_brackets) s++;
const char *dash = strchr(s, '-');
if (dash && dash > s && dash[1])
{
char *e;
long long v0 = strtoll(s, &e, 10);
if (e != dash) return false;
long long v1 = strtoll(dash + 1, &e, 10);
if (with_brackets)
{
if (*e != ')') return false;
e++;
}
if (*e || v0 < 0 || v1 < 0 || v0 > v1 || v1 > INT_MAX) return false;
dp->desync_ts_increment_random = true;
dp->desync_ts_increment_min = (int32_t)(sign * v0);
dp->desync_ts_increment_max = (int32_t)(sign * v1);
if (dp->desync_ts_increment_min > dp->desync_ts_increment_max)
{
int32_t t = dp->desync_ts_increment_min;
dp->desync_ts_increment_min = dp->desync_ts_increment_max;
dp->desync_ts_increment_max = t;
}
return true;
}
if (with_brackets) return false;
dp->desync_ts_increment_random = false;
return parse_net32_signed(opt, &dp->desync_ts_increment);
}
static void load_file_or_exit(const char *filename, void *buf, size_t *size, size_t *offset)
{
size_t ofs;
@ -2016,7 +2059,7 @@ static void exithelp(void)
" --dpi-desync-hostfakesplit-mod=mod[,mod]\t\t; mods can be none,host=<hostname>,altorder=0|1\n"
" --dpi-desync-ipfrag-pos-udp=<8..%u>\t\t\t; ip frag position starting from the transport header. multiple of 8, default %u.\n"
" --dpi-desync-ipfrag-pos-tcp=<8..%u>\t\t\t; ip frag position starting from the transport header. multiple of 8, default %u.\n"
" --dpi-desync-ts-increment=<int|0xHEX>\t\t\t; ts fooling TSval signed increment. default %d\n"
" --dpi-desync-ts-increment=<int|0xHEX|[+|-](N-M)|N-M>\t; ts fooling TSval signed increment or random range per fake. default %d\n"
" --dpi-desync-badseq-increment=<int|0xHEX>\t\t; badseq fooling seq signed increment. default %d\n"
" --dpi-desync-badack-increment=<int|0xHEX>\t\t; badseq fooling ackseq signed increment. default %d\n"
" --dpi-desync-any-protocol=0|1\t\t\t\t; 0(default)=desync only http and tls 1=desync any nonempty data packet\n"
@ -3117,9 +3160,9 @@ int main(int argc, char **argv)
}
break;
case IDX_DPI_DESYNC_TS_INCREMENT:
if (!parse_net32_signed(optarg, &dp->desync_ts_increment))
if (!parse_desync_ts_increment(optarg, dp))
{
DLOG_ERR("dpi-desync-ts-increment should be signed decimal or signed 0xHEX\n");
DLOG_ERR("dpi-desync-ts-increment should be signed decimal, signed 0xHEX, [+-](N-M) or N-M\n");
exit_clean(1);
}
break;

2
nfq/params.h

@ -156,6 +156,8 @@ struct desync_profile
autottl desync_autottl, desync_autottl6;
uint32_t desync_fooling_mode;
uint32_t desync_ts_increment, desync_badseq_increment, desync_badseq_ack_increment;
bool desync_ts_increment_random;
int32_t desync_ts_increment_min, desync_ts_increment_max;
uint16_t desync_tcp_flags_set, desync_tcp_flags_unset;
struct blob_collection_head fake_http,fake_tls,fake_unknown,fake_unknown_udp,fake_quic,fake_wg,fake_dht,fake_discord,fake_stun;

Loading…
Cancel
Save