mirror of
https://github.com/bol-van/zapret.git
synced 2025-04-20 22:12:58 +03:00
Compare commits
No commits in common. "6e1e7e43bce542e06d8ee6e029bdebde9bb3784f" and "7272b243cbc2cd8c15cd5775be9f352500cbc7b0" have entirely different histories.
6e1e7e43bc
...
7272b243cb
@ -478,6 +478,5 @@ nfqws: detect Discord Voice IP discovery packets
|
||||
nfqws: detect STUN message packets
|
||||
nfqws: change SNI to specified value tls mod : --dpi-desync-fake-tls-mod sni=<sni>
|
||||
nfqws: update default TLS ClientHello fake. firefox 136.0.4 finger, no kyber, SNI=microsoft.com
|
||||
nfqws: multiple mods for multiple TLS fakes
|
||||
init.d: remove 50-discord
|
||||
blockcheck: use tpws --fix-seg on linux for multiple splits
|
||||
|
@ -291,13 +291,9 @@ It's possible to use TLS Client Hello with any fingerprint and any SNI.
|
||||
By default if custom fake is not defined `rnd,rndsni,dupsid` mods are applied. If defined - `none`.
|
||||
This behaviour is compatible with previous versions with addition of `dupsid`.
|
||||
|
||||
If multiple TLS fakes are present each one takes the last mod.
|
||||
If a mod is specified after fake it replaces previous mod.
|
||||
This way it's possible to use different mods for every TLS fake.
|
||||
If TLS mod is enabled and there're multiple TLS fakes, all valid TLS Client Hello fakes are modified.
|
||||
If there's no TLS Client Hello program exits with error.
|
||||
|
||||
If a mod is set to non-TLS fake it causes error. Use `--dpi-desync-fake-tls-mod=none'.
|
||||
|
||||
Example : `--dpi-desync-fake-tls=iana_org.bin --dpi-desync-fake-tls-mod=rndsni --dpi-desync-fake-tls=0xaabbccdd --dpi-desync-fake-tls-mod=none'
|
||||
|
||||
### TCP segmentation
|
||||
|
||||
|
@ -346,15 +346,8 @@ dvtws, собираемый из тех же исходников (см. [док
|
||||
По умолчанию если не задан собственный фейк для TLS используются модификации `rnd,rndsni,dupsid`. Если фейк задан, используется `none`.
|
||||
Это соответствует поведению программы более старых версий с добавлением функции `dupsid`.
|
||||
|
||||
Если задан режим модификации и имеется множество TLS фейков, к каждому из них применяется последний режим модификации.
|
||||
Если режим модификации задан после фейка, то он замещает предыдущий режим.
|
||||
Таким образом можно использовать разные режимы модификации для разных фейков.
|
||||
При невозможности модифицировать фейк на этапе запуска программа завершается с ошибкой.
|
||||
|
||||
Если сначала идет TLS фейк, для него задан режим однократной модификации, затем идет не TLS фейк, то будет ошибка.
|
||||
Нужно использовать `--dpi-desync-fake-tls-mod=none'.
|
||||
|
||||
Пример : `--dpi-desync-fake-tls=iana_org.bin --dpi-desync-fake-tls-mod=rndsni --dpi-desync-fake-tls=0xaabbccdd --dpi-desync-fake-tls-mod=none'
|
||||
Если задан режим модификации и имеется множество TLS фейков, модифицируются все фейки, являющиеся TLS Client Hello.
|
||||
Если нет ни одного TLS Client Hello фейка, программа завершается с ошибкой.
|
||||
|
||||
### TCP СЕГМЕНТАЦИЯ
|
||||
|
||||
|
14
nfq/desync.c
14
nfq/desync.c
@ -623,12 +623,12 @@ static uint16_t IP4_IP_ID_FIX(const struct ip *ip)
|
||||
// fake_mod buffer must at least sizeof(desync_profile->fake_tls)
|
||||
// size does not change
|
||||
// return : true - altered, false - not altered
|
||||
static bool runtime_tls_mod(int fake_n,const struct fake_tls_mod_cache *modcache, const struct fake_tls_mod *tls_mod, const uint8_t *fake_data, size_t fake_data_size, const uint8_t *payload, size_t payload_len, uint8_t *fake_mod)
|
||||
static bool runtime_tls_mod(int fake_n,const struct fake_tls_mod_cache *modcache, uint32_t fake_tls_mod, const uint8_t *fake_data, size_t fake_data_size, const uint8_t *payload, size_t payload_len, uint8_t *fake_mod)
|
||||
{
|
||||
bool b=false;
|
||||
if (modcache) // it's filled only if it's TLS
|
||||
{
|
||||
if (tls_mod->mod & FAKE_TLS_MOD_PADENCAP)
|
||||
if (fake_tls_mod & FAKE_TLS_MOD_PADENCAP)
|
||||
{
|
||||
size_t sz_rec = pntoh16(fake_data+3) + payload_len;
|
||||
size_t sz_handshake = pntoh24(fake_data+6) + payload_len;
|
||||
@ -647,7 +647,7 @@ static bool runtime_tls_mod(int fake_n,const struct fake_tls_mod_cache *modcache
|
||||
DLOG("fake[%d] applied padencap tls mod. sizes increased by %zu bytes.\n", fake_n, payload_len);
|
||||
}
|
||||
}
|
||||
if (tls_mod->mod & FAKE_TLS_MOD_RND)
|
||||
if (fake_tls_mod & FAKE_TLS_MOD_RND)
|
||||
{
|
||||
if (!b) memcpy(fake_mod,fake_data,fake_data_size);
|
||||
fill_random_bytes(fake_mod+11,32); // random
|
||||
@ -655,11 +655,9 @@ static bool runtime_tls_mod(int fake_n,const struct fake_tls_mod_cache *modcache
|
||||
b=true;
|
||||
DLOG("fake[%d] applied rnd tls mod\n", fake_n);
|
||||
}
|
||||
if (tls_mod->mod & FAKE_TLS_MOD_DUP_SID)
|
||||
if (fake_tls_mod & FAKE_TLS_MOD_DUP_SID)
|
||||
{
|
||||
if (payload_len<44)
|
||||
DLOG("fake[%d] cannot apply dupsid tls mod. data payload is too short.\n",fake_n);
|
||||
else if (fake_data[43]!=payload[43])
|
||||
if (fake_data[43]!=payload[43])
|
||||
DLOG("fake[%d] cannot apply dupsid tls mod. fake and orig session id length mismatch.\n",fake_n);
|
||||
else if (payload_len<(44+payload[43]))
|
||||
DLOG("fake[%d] cannot apply dupsid tls mod. data payload is not valid.\n",fake_n);
|
||||
@ -1323,7 +1321,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
{
|
||||
case TLS:
|
||||
if ((fake_item->size <= sizeof(fake_data_buf)) &&
|
||||
runtime_tls_mod(n,(struct fake_tls_mod_cache *)fake_item->extra,(struct fake_tls_mod *)fake_item->extra2, fake_item->data, fake_item->size, rdata_payload, rlen_payload, fake_data_buf))
|
||||
runtime_tls_mod(n,(struct fake_tls_mod_cache *)fake_item->extra, dp->fake_tls_mod, fake_item->data, fake_item->size, rdata_payload, rlen_payload, fake_data_buf))
|
||||
{
|
||||
fake_data = fake_data_buf;
|
||||
break;
|
||||
|
84
nfq/nfqws.c
84
nfq/nfqws.c
@ -950,12 +950,12 @@ static bool parse_ip_list(char *opt, ipset *pp)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_tlsmod_list(char *opt, struct fake_tls_mod *tls_mod)
|
||||
static bool parse_tlsmod_list(char *opt, uint32_t *mod, char *sni, size_t sni_buf_len)
|
||||
{
|
||||
char *e,*e2,*p,c,c2;
|
||||
|
||||
tls_mod->mod &= FAKE_TLS_MOD_SAVE_MASK;
|
||||
tls_mod->mod |= FAKE_TLS_MOD_SET;
|
||||
*mod &= FAKE_TLS_MOD_SAVE_MASK;
|
||||
*mod |= FAKE_TLS_MOD_SET;
|
||||
for (p=opt ; p ; )
|
||||
{
|
||||
for (e2=p ; *e2 && *e2!=',' && *e2!='=' ; e2++);
|
||||
@ -975,20 +975,20 @@ static bool parse_tlsmod_list(char *opt, struct fake_tls_mod *tls_mod)
|
||||
e2=NULL;
|
||||
|
||||
if (!strcmp(p,"rnd"))
|
||||
tls_mod->mod |= FAKE_TLS_MOD_RND;
|
||||
*mod |= FAKE_TLS_MOD_RND;
|
||||
else if (!strcmp(p,"rndsni"))
|
||||
tls_mod->mod |= FAKE_TLS_MOD_RND_SNI;
|
||||
*mod |= FAKE_TLS_MOD_RND_SNI;
|
||||
else if (!strcmp(p,"sni"))
|
||||
{
|
||||
tls_mod->mod |= FAKE_TLS_MOD_SNI;
|
||||
*mod |= FAKE_TLS_MOD_SNI;
|
||||
if (!e2 || !e2[1] || e2[1]==',') goto err;
|
||||
strncpy(tls_mod->sni,e2+1,sizeof(tls_mod->sni)-1);
|
||||
tls_mod->sni[sizeof(tls_mod->sni)-1-1]=0;
|
||||
strncpy(sni,e2+1,sni_buf_len-1);
|
||||
sni[sni_buf_len-1]=0;
|
||||
}
|
||||
else if (!strcmp(p,"padencap"))
|
||||
tls_mod->mod |= FAKE_TLS_MOD_PADENCAP;
|
||||
*mod |= FAKE_TLS_MOD_PADENCAP;
|
||||
else if (!strcmp(p,"dupsid"))
|
||||
tls_mod->mod |= FAKE_TLS_MOD_DUP_SID;
|
||||
*mod |= FAKE_TLS_MOD_DUP_SID;
|
||||
else if (strcmp(p,"none"))
|
||||
goto err;
|
||||
|
||||
@ -1034,13 +1034,13 @@ static void SplitDebug(void)
|
||||
|
||||
static const char * tld[]={"com","org","net","edu","gov","biz"};
|
||||
|
||||
static bool onetime_tls_mod_blob(int profile_n, int fake_n, const struct fake_tls_mod *tls_mod, uint8_t *fake_tls, size_t *fake_tls_size, size_t fake_tls_buf_size, struct fake_tls_mod_cache *modcache)
|
||||
static bool onetime_tls_mod_blob(int profile_n, int fake_n, uint32_t fake_tls_mod, const char *fake_tls_sni, uint8_t *fake_tls, size_t *fake_tls_size, size_t fake_tls_buf_size, struct fake_tls_mod_cache *modcache)
|
||||
{
|
||||
const uint8_t *ext;
|
||||
size_t extlen;
|
||||
|
||||
modcache->extlen_offset = modcache->padlen_offset = 0;
|
||||
if (tls_mod->mod & (FAKE_TLS_MOD_RND_SNI|FAKE_TLS_MOD_SNI|FAKE_TLS_MOD_PADENCAP))
|
||||
if (fake_tls_mod & (FAKE_TLS_MOD_RND_SNI|FAKE_TLS_MOD_SNI|FAKE_TLS_MOD_PADENCAP))
|
||||
{
|
||||
if (!TLSFindExtLen(fake_tls,*fake_tls_size,&modcache->extlen_offset))
|
||||
{
|
||||
@ -1048,7 +1048,7 @@ static bool onetime_tls_mod_blob(int profile_n, int fake_n, const struct fake_tl
|
||||
return false;
|
||||
}
|
||||
DLOG("profile %d fake[%d] tls extensions length offset : %zu\n", profile_n, fake_n, modcache->extlen_offset);
|
||||
if (tls_mod->mod & (FAKE_TLS_MOD_RND_SNI|FAKE_TLS_MOD_SNI))
|
||||
if (fake_tls_mod & (FAKE_TLS_MOD_RND_SNI|FAKE_TLS_MOD_SNI))
|
||||
{
|
||||
size_t slen;
|
||||
if (!TLSFindExt(fake_tls,*fake_tls_size,0,&ext,&extlen,false))
|
||||
@ -1063,9 +1063,9 @@ static bool onetime_tls_mod_blob(int profile_n, int fake_n, const struct fake_tl
|
||||
return false;
|
||||
}
|
||||
uint8_t *sni = fake_tls + (ext - fake_tls);
|
||||
if (tls_mod->mod & FAKE_TLS_MOD_SNI)
|
||||
if (fake_tls_mod & FAKE_TLS_MOD_SNI)
|
||||
{
|
||||
size_t slen_new = strlen(tls_mod->sni);
|
||||
size_t slen_new = strlen(fake_tls_sni);
|
||||
ssize_t slen_delta = slen_new-slen;
|
||||
char *s1=NULL;
|
||||
if (params.debug)
|
||||
@ -1093,12 +1093,12 @@ static bool onetime_tls_mod_blob(int profile_n, int fake_n, const struct fake_tl
|
||||
*fake_tls_size+=slen_delta;
|
||||
slen = slen_new;
|
||||
}
|
||||
DLOG("profile %d fake[%d] change SNI : %s => %s size_delta=%zd\n", profile_n, fake_n, s1, tls_mod->sni, slen_delta);
|
||||
DLOG("profile %d fake[%d] change SNI : %s => %s size_delta=%zd\n", profile_n, fake_n, s1, fake_tls_sni, slen_delta);
|
||||
free(s1);
|
||||
|
||||
memcpy(sni,tls_mod->sni,slen_new);
|
||||
memcpy(sni,fake_tls_sni,slen_new);
|
||||
}
|
||||
if (tls_mod->mod & FAKE_TLS_MOD_RND_SNI)
|
||||
if (fake_tls_mod & FAKE_TLS_MOD_RND_SNI)
|
||||
{
|
||||
if (!slen)
|
||||
{
|
||||
@ -1136,7 +1136,7 @@ static bool onetime_tls_mod_blob(int profile_n, int fake_n, const struct fake_tl
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tls_mod->mod & FAKE_TLS_MOD_PADENCAP)
|
||||
if (fake_tls_mod & FAKE_TLS_MOD_PADENCAP)
|
||||
{
|
||||
if (TLSFindExt(fake_tls,*fake_tls_size,21,&ext,&extlen,false))
|
||||
{
|
||||
@ -1171,37 +1171,39 @@ static bool onetime_tls_mod_blob(int profile_n, int fake_n, const struct fake_tl
|
||||
}
|
||||
static bool onetime_tls_mod(struct desync_profile *dp)
|
||||
{
|
||||
if (dp->n && !(dp->fake_tls_mod & (FAKE_TLS_MOD_SET|FAKE_TLS_MOD_CUSTOM_FAKE)))
|
||||
dp->fake_tls_mod |= FAKE_TLS_MOD_RND|FAKE_TLS_MOD_RND_SNI|FAKE_TLS_MOD_DUP_SID; // old behavior compat + dup_sid
|
||||
if (!(dp->fake_tls_mod & ~FAKE_TLS_MOD_SAVE_MASK))
|
||||
return true; // nothing to do
|
||||
|
||||
struct blob_item *fake_tls;
|
||||
struct fake_tls_mod *tls_mod;
|
||||
int n=0;
|
||||
bool bMod=false;
|
||||
|
||||
LIST_FOREACH(fake_tls, &dp->fake_tls, next)
|
||||
{
|
||||
++n;
|
||||
tls_mod = (struct fake_tls_mod *)fake_tls->extra2;
|
||||
if (!tls_mod) continue;
|
||||
if (dp->n && !(tls_mod->mod & (FAKE_TLS_MOD_SET|FAKE_TLS_MOD_CUSTOM_FAKE)))
|
||||
tls_mod->mod |= FAKE_TLS_MOD_RND|FAKE_TLS_MOD_RND_SNI|FAKE_TLS_MOD_DUP_SID; // old behavior compat + dup_sid
|
||||
if (!(tls_mod->mod & ~FAKE_TLS_MOD_SAVE_MASK))
|
||||
continue;
|
||||
|
||||
if (!IsTLSClientHello(fake_tls->data,fake_tls->size,false) || (fake_tls->size < (44+fake_tls->data[43]))) // has session id ?
|
||||
{
|
||||
DLOG("profile %d fake[%d] tls mod set but tls fake structure invalid.\n", dp->n, n);
|
||||
return false;
|
||||
DLOG("profile %d fake[%d] tls mod set but tls fake structure invalid. mod skipped.\n", dp->n, n);
|
||||
continue;
|
||||
|
||||
}
|
||||
bMod = true;
|
||||
if (!fake_tls->extra)
|
||||
{
|
||||
fake_tls->extra = malloc(sizeof(struct fake_tls_mod_cache));
|
||||
if (!fake_tls->extra) return false;
|
||||
}
|
||||
if (!onetime_tls_mod_blob(dp->n,n,tls_mod,fake_tls->data,&fake_tls->size,fake_tls->size_buf,(struct fake_tls_mod_cache*)fake_tls->extra))
|
||||
if (!onetime_tls_mod_blob(dp->n,n,dp->fake_tls_mod,dp->fake_tls_sni,fake_tls->data,&fake_tls->size,fake_tls->size_buf,(struct fake_tls_mod_cache*)fake_tls->extra))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (!bMod)
|
||||
DLOG_ERR("profile %d tls fake list does not have any valid TLS ClientHello\n", dp->n);
|
||||
return bMod;
|
||||
}
|
||||
|
||||
static struct blob_item *load_blob_to_collection(const char *filename, struct blob_collection_head *blobs, size_t max_size, size_t size_reserve)
|
||||
static void load_blob_to_collection(const char *filename, struct blob_collection_head *blobs, size_t max_size, size_t size_reserve)
|
||||
{
|
||||
struct blob_item *blob = blob_collection_add(blobs);
|
||||
uint8_t *p;
|
||||
@ -1220,7 +1222,6 @@ static struct blob_item *load_blob_to_collection(const char *filename, struct bl
|
||||
}
|
||||
blob->data = p;
|
||||
blob->size_buf = blob->size+size_reserve;
|
||||
return blob;
|
||||
}
|
||||
|
||||
|
||||
@ -2115,26 +2116,15 @@ int main(int argc, char **argv)
|
||||
load_blob_to_collection(optarg, &dp->fake_http, FAKE_MAX_TCP,0);
|
||||
break;
|
||||
case 39: /* dpi-desync-fake-tls */
|
||||
{
|
||||
dp->tls_fake_last = load_blob_to_collection(optarg, &dp->fake_tls, FAKE_MAX_TCP,4+sizeof(dp->tls_mod_last.sni));
|
||||
if (!(dp->tls_fake_last->extra2 = malloc(sizeof(struct fake_tls_mod))))
|
||||
{
|
||||
DLOG_ERR("out of memory\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
struct fake_tls_mod *tls_mod = (struct fake_tls_mod*)dp->tls_fake_last->extra2;
|
||||
*tls_mod = dp->tls_mod_last;
|
||||
tls_mod->mod |= FAKE_TLS_MOD_CUSTOM_FAKE;
|
||||
}
|
||||
load_blob_to_collection(optarg, &dp->fake_tls, FAKE_MAX_TCP,4+sizeof(dp->fake_tls_sni));
|
||||
dp->fake_tls_mod |= FAKE_TLS_MOD_CUSTOM_FAKE;
|
||||
break;
|
||||
case 40: /* dpi-desync-fake-tls-mod */
|
||||
if (!parse_tlsmod_list(optarg,&dp->tls_mod_last))
|
||||
if (!parse_tlsmod_list(optarg,&dp->fake_tls_mod,dp->fake_tls_sni,sizeof(dp->fake_tls_sni)))
|
||||
{
|
||||
DLOG_ERR("Invalid tls mod : %s\n",optarg);
|
||||
exit_clean(1);
|
||||
}
|
||||
if (dp->tls_fake_last)
|
||||
*(struct fake_tls_mod*)dp->tls_fake_last->extra2 = dp->tls_mod_last;
|
||||
break;
|
||||
case 41: /* dpi-desync-fake-unknown */
|
||||
load_blob_to_collection(optarg, &dp->fake_unknown, FAKE_MAX_TCP, 0);
|
||||
|
@ -185,6 +185,7 @@ void dp_init(struct desync_profile *dp)
|
||||
dp->desync_ipfrag_pos_udp = IPFRAG_UDP_DEFAULT;
|
||||
dp->desync_ipfrag_pos_tcp = IPFRAG_TCP_DEFAULT;
|
||||
dp->desync_repeats = 1;
|
||||
dp->fake_tls_mod = 0;
|
||||
dp->fake_syndata_size = 16;
|
||||
dp->wscale=-1; // default - dont change scale factor (client)
|
||||
dp->desync_ttl6 = 0xFF; // unused
|
||||
@ -205,11 +206,8 @@ bool dp_fake_defaults(struct desync_profile *dp)
|
||||
return false;
|
||||
if (blob_collection_empty(&dp->fake_tls))
|
||||
{
|
||||
if (!(item=blob_collection_add_blob(&dp->fake_tls,fake_tls_clienthello_default,sizeof(fake_tls_clienthello_default),4+sizeof(((struct fake_tls_mod*)0)->sni))))
|
||||
if (!blob_collection_add_blob(&dp->fake_tls,fake_tls_clienthello_default,sizeof(fake_tls_clienthello_default),4+sizeof(dp->fake_tls_sni)))
|
||||
return false;
|
||||
if (!(item->extra2 = malloc(sizeof(struct fake_tls_mod))))
|
||||
return false;
|
||||
*(struct fake_tls_mod*)item->extra2 = dp->tls_mod_last;
|
||||
}
|
||||
if (blob_collection_empty(&dp->fake_unknown))
|
||||
{
|
||||
|
@ -56,11 +56,6 @@ struct fake_tls_mod_cache
|
||||
{
|
||||
size_t extlen_offset, padlen_offset;
|
||||
};
|
||||
struct fake_tls_mod
|
||||
{
|
||||
char sni[64];
|
||||
uint32_t mod;
|
||||
};
|
||||
|
||||
struct desync_profile
|
||||
{
|
||||
@ -93,8 +88,8 @@ struct desync_profile
|
||||
uint8_t fake_syndata[FAKE_MAX_TCP],seqovl_pattern[FAKE_MAX_TCP],fsplit_pattern[FAKE_MAX_TCP],udplen_pattern[FAKE_MAX_UDP];
|
||||
size_t fake_syndata_size;
|
||||
|
||||
struct fake_tls_mod tls_mod_last;
|
||||
struct blob_item *tls_fake_last;
|
||||
uint32_t fake_tls_mod;
|
||||
char fake_tls_sni[64];
|
||||
|
||||
int udplen_increment;
|
||||
|
||||
|
@ -570,7 +570,6 @@ void blob_collection_destroy(struct blob_collection_head *head)
|
||||
{
|
||||
LIST_REMOVE(entry, next);
|
||||
free(entry->extra);
|
||||
free(entry->extra2);
|
||||
free(entry->data);
|
||||
free(entry);
|
||||
}
|
||||
|
@ -153,7 +153,6 @@ struct blob_item {
|
||||
size_t size; // main data blob size
|
||||
size_t size_buf;// main data blob allocated size
|
||||
void *extra; // any data without size
|
||||
void *extra2; // any data without size
|
||||
LIST_ENTRY(blob_item) next;
|
||||
};
|
||||
LIST_HEAD(blob_collection_head, blob_item);
|
||||
|
Loading…
x
Reference in New Issue
Block a user