mirror of
https://github.com/bol-van/zapret.git
synced 2025-05-24 22:32:58 +03:00
nfqws: tls mod set sni
This commit is contained in:
@@ -609,7 +609,7 @@ 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, uint8_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)
|
||||
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
|
||||
@@ -630,6 +630,7 @@ static bool runtime_tls_mod(int fake_n,const struct fake_tls_mod_cache *modcache
|
||||
phton16(fake_mod+modcache->extlen_offset,(uint16_t)sz_ext);
|
||||
phton16(fake_mod+modcache->padlen_offset,(uint16_t)sz_pad);
|
||||
b=true;
|
||||
DLOG("fake[%d] applied padencap tls mod. sizes increased by %zu bytes.\n", fake_n, payload_len);
|
||||
}
|
||||
}
|
||||
if (fake_tls_mod & FAKE_TLS_MOD_RND)
|
||||
@@ -638,6 +639,7 @@ static bool runtime_tls_mod(int fake_n,const struct fake_tls_mod_cache *modcache
|
||||
fill_random_bytes(fake_mod+11,32); // random
|
||||
fill_random_bytes(fake_mod+44,fake_mod[43]); // session id
|
||||
b=true;
|
||||
DLOG("fake[%d] applied rnd tls mod\n", fake_n);
|
||||
}
|
||||
if (fake_tls_mod & FAKE_TLS_MOD_DUP_SID)
|
||||
{
|
||||
@@ -650,6 +652,7 @@ static bool runtime_tls_mod(int fake_n,const struct fake_tls_mod_cache *modcache
|
||||
if (!b) memcpy(fake_mod,fake_data,fake_data_size);
|
||||
memcpy(fake_mod+44,payload+44,fake_mod[43]); // session id
|
||||
b=true;
|
||||
DLOG("fake[%d] applied dupsid tls mod\n", fake_n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
170
nfq/nfqws.c
170
nfq/nfqws.c
@@ -950,35 +950,57 @@ static bool parse_ip_list(char *opt, ipset *pp)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_tlsmod_list(char *opt, uint8_t *mod)
|
||||
static bool parse_tlsmod_list(char *opt, uint32_t *mod, char *sni, size_t sni_buf_len)
|
||||
{
|
||||
char *e,*p,c;
|
||||
char *e,*e2,*p,c,c2;
|
||||
|
||||
*mod &= FAKE_TLS_MOD_SAVE_MASK;
|
||||
*mod |= FAKE_TLS_MOD_SET;
|
||||
for (p=opt ; p ; )
|
||||
{
|
||||
if ((e = strchr(p,',')))
|
||||
for (e2=p ; *e2 && *e2!=',' && *e2!='=' ; e2++);
|
||||
|
||||
if ((e = strchr(e2,',')))
|
||||
{
|
||||
c=*e;
|
||||
*e=0;
|
||||
}
|
||||
|
||||
if (*e2=='=')
|
||||
{
|
||||
c2=*e2;
|
||||
*e2=0;
|
||||
}
|
||||
else
|
||||
e2=NULL;
|
||||
|
||||
if (!strcmp(p,"rnd"))
|
||||
*mod |= FAKE_TLS_MOD_RND;
|
||||
else if (!strcmp(p,"rndsni"))
|
||||
*mod |= FAKE_TLS_MOD_RND_SNI;
|
||||
else if (!strcmp(p,"sni"))
|
||||
{
|
||||
*mod |= FAKE_TLS_MOD_SNI;
|
||||
if (!e2 || !e2[1] || e2[1]==',') goto err;
|
||||
strncpy(sni,e2+1,sni_buf_len-1);
|
||||
sni[sni_buf_len-1]=0;
|
||||
}
|
||||
else if (!strcmp(p,"padencap"))
|
||||
*mod |= FAKE_TLS_MOD_PADENCAP;
|
||||
else if (!strcmp(p,"dupsid"))
|
||||
*mod |= FAKE_TLS_MOD_DUP_SID;
|
||||
else if (strcmp(p,"none"))
|
||||
return false;
|
||||
goto err;
|
||||
|
||||
if (e2) *e2=c2;
|
||||
if (e) *e++=c;
|
||||
p = e;
|
||||
}
|
||||
return true;
|
||||
err:
|
||||
if (e2) *e2=c2;
|
||||
if (e) *e++=c;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1012,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, uint8_t fake_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, slen;
|
||||
size_t extlen;
|
||||
|
||||
modcache->extlen_offset = modcache->padlen_offset = 0;
|
||||
if (fake_tls_mod & FAKE_TLS_MOD_PADENCAP)
|
||||
if (fake_tls_mod & (FAKE_TLS_MOD_PADENCAP|FAKE_TLS_MOD_SNI))
|
||||
{
|
||||
if (!TLSFindExtLen(fake_tls,*fake_tls_size,&modcache->extlen_offset))
|
||||
{
|
||||
@@ -1026,6 +1048,84 @@ static bool onetime_tls_mod_blob(int profile_n, int fake_n, uint8_t fake_tls_mod
|
||||
return false;
|
||||
}
|
||||
DLOG("profile %d fake[%d] tls extensions length offset : %zu\n", profile_n, fake_n, modcache->extlen_offset);
|
||||
size_t slen;
|
||||
if (!TLSFindExt(fake_tls,*fake_tls_size,0,&ext,&extlen,false))
|
||||
{
|
||||
DLOG_ERR("profile %d fake[%d] sni mod is set but tls fake does not have SNI\n", profile_n, fake_n);
|
||||
return false;
|
||||
}
|
||||
uint8_t *sniext = fake_tls + (ext - fake_tls);
|
||||
if (!TLSAdvanceToHostInSNI(&ext,&extlen,&slen))
|
||||
{
|
||||
DLOG_ERR("profile %d fake[%d] sni set but tls fake has invalid SNI structure\n", profile_n, fake_n);
|
||||
return false;
|
||||
}
|
||||
uint8_t *sni = fake_tls + (ext - fake_tls);
|
||||
|
||||
if (fake_tls_mod & FAKE_TLS_MOD_SNI)
|
||||
{
|
||||
size_t slen_new = strlen(fake_tls_sni);
|
||||
ssize_t slen_delta = slen_new-slen;
|
||||
if (slen_delta)
|
||||
{
|
||||
if ((*fake_tls_size+slen_delta)>fake_tls_buf_size)
|
||||
{
|
||||
DLOG_ERR("profile %d fake[%d] not enough space for new SNI\n", profile_n, fake_n);
|
||||
return false;
|
||||
}
|
||||
memmove(sni+slen_new,sni+slen,fake_tls+*fake_tls_size-(sni+slen));
|
||||
phton16(fake_tls+3,(uint16_t)(pntoh16(fake_tls+3)+slen_delta));
|
||||
phton24(fake_tls+6,(uint32_t)(pntoh24(fake_tls+6)+slen_delta));
|
||||
phton16(fake_tls+modcache->extlen_offset,(uint16_t)(pntoh16(fake_tls+modcache->extlen_offset)+slen_delta));
|
||||
phton16(sniext-2,(uint16_t)(pntoh16(sniext-2)+slen_delta));
|
||||
phton16(sniext,(uint16_t)(pntoh16(sniext)+slen_delta));
|
||||
phton16(sni-2,(uint16_t)(pntoh16(sni-2)+slen_delta));
|
||||
*fake_tls_size+=slen_delta;
|
||||
}
|
||||
DLOG_ERR("profile %d fake[%d] change sni to %s size_delta=%zd\n", profile_n, fake_n, fake_tls_sni,slen_delta);
|
||||
memcpy(sni,fake_tls_sni,slen_new);
|
||||
slen = slen_new;
|
||||
}
|
||||
if (fake_tls_mod & FAKE_TLS_MOD_RND_SNI)
|
||||
{
|
||||
if (!slen)
|
||||
{
|
||||
DLOG_ERR("profile %d fake[%d] rndsni set but tls fake has zero sized SNI\n", profile_n, fake_n);
|
||||
return false;
|
||||
}
|
||||
|
||||
char *s1=NULL, *s2=NULL;
|
||||
if (params.debug)
|
||||
{
|
||||
if ((s1 = malloc(slen+1)))
|
||||
{
|
||||
memcpy(s1,sni,slen); s1[slen]=0;
|
||||
}
|
||||
}
|
||||
|
||||
fill_random_az(sni,1);
|
||||
if (slen>=7) // domain name in SNI must be at least 3 chars long to enable xxx.tls randomization
|
||||
{
|
||||
fill_random_az09(sni+1,slen-5);
|
||||
sni[slen-4] = '.';
|
||||
memcpy(sni+slen-3,tld[random()%(sizeof(tld)/sizeof(*tld))],3);
|
||||
}
|
||||
else
|
||||
fill_random_az09(sni+1,slen-1);
|
||||
|
||||
if (params.debug)
|
||||
{
|
||||
if (s1 && (s2 = malloc(slen+1)))
|
||||
{
|
||||
memcpy(s2,sni,slen); s2[slen]=0;
|
||||
DLOG("profile %d fake[%d] generated random SNI : %s -> %s\n",profile_n,fake_n,s1,s2);
|
||||
}
|
||||
free(s1); free(s2);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fake_tls_mod & FAKE_TLS_MOD_PADENCAP)
|
||||
{
|
||||
if (TLSFindExt(fake_tls,*fake_tls_size,21,&ext,&extlen,false))
|
||||
{
|
||||
if ((ext-fake_tls+extlen)!=*fake_tls_size)
|
||||
@@ -1054,54 +1154,6 @@ static bool onetime_tls_mod_blob(int profile_n, int fake_n, uint8_t fake_tls_mod
|
||||
DLOG("profile %d fake[%d] tls padding is absent. added. padding length offset %zu\n", profile_n, fake_n, modcache->padlen_offset);
|
||||
}
|
||||
}
|
||||
if (fake_tls_mod & FAKE_TLS_MOD_RND_SNI)
|
||||
{
|
||||
if (!TLSFindExt(fake_tls,*fake_tls_size,0,&ext,&extlen,false))
|
||||
{
|
||||
DLOG_ERR("profile %d fake[%d] rndsni set but tls fake does not have SNI\n", profile_n, fake_n);
|
||||
return false;
|
||||
}
|
||||
if (!TLSAdvanceToHostInSNI(&ext,&extlen,&slen))
|
||||
{
|
||||
DLOG_ERR("profile %d fake[%d] rndsni set but tls fake has invalid SNI structure\n", profile_n, fake_n);
|
||||
return false;
|
||||
}
|
||||
if (!slen)
|
||||
{
|
||||
DLOG_ERR("profile %d fake[%d] rndsni set but tls fake has zero sized SNI\n", profile_n, fake_n);
|
||||
return false;
|
||||
}
|
||||
uint8_t *sni = fake_tls + (ext - fake_tls);
|
||||
|
||||
char *s1=NULL, *s2=NULL;
|
||||
if (params.debug)
|
||||
{
|
||||
if ((s1 = malloc(slen+1)))
|
||||
{
|
||||
memcpy(s1,sni,slen); s1[slen]=0;
|
||||
}
|
||||
}
|
||||
|
||||
fill_random_az(sni,1);
|
||||
if (slen>=7) // domain name in SNI must be at least 3 chars long to enable xxx.tls randomization
|
||||
{
|
||||
fill_random_az09(sni+1,slen-5);
|
||||
sni[slen-4] = '.';
|
||||
memcpy(sni+slen-3,tld[random()%(sizeof(tld)/sizeof(*tld))],3);
|
||||
}
|
||||
else
|
||||
fill_random_az09(sni+1,slen-1);
|
||||
|
||||
if (params.debug)
|
||||
{
|
||||
if (s1 && (s2 = malloc(slen+1)))
|
||||
{
|
||||
memcpy(s2,sni,slen); s2[slen]=0;
|
||||
DLOG("profile %d fake[%d] generated random SNI : %s -> %s\n",profile_n,fake_n,s1,s2);
|
||||
}
|
||||
free(s1); free(s2);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static bool onetime_tls_mod(struct desync_profile *dp)
|
||||
@@ -1130,7 +1182,7 @@ static bool onetime_tls_mod(struct desync_profile *dp)
|
||||
fake_tls->extra = malloc(sizeof(struct fake_tls_mod_cache));
|
||||
if (!fake_tls->extra) return false;
|
||||
}
|
||||
if (!onetime_tls_mod_blob(dp->n,n,dp->fake_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;
|
||||
}
|
||||
if (!bMod)
|
||||
@@ -1378,7 +1430,7 @@ static void exithelp(void)
|
||||
" --dpi-desync-any-protocol=0|1\t\t\t; 0(default)=desync only http and tls 1=desync any nonempty data packet\n"
|
||||
" --dpi-desync-fake-http=<filename>|0xHEX\t; file containing fake http request\n"
|
||||
" --dpi-desync-fake-tls=<filename>|0xHEX\t\t; file containing fake TLS ClientHello (for https)\n"
|
||||
" --dpi-desync-fake-tls-mod=mod[,mod]\t\t; comma separated list of TLS fake mods. available mods : none,rnd,rndsni,dupsid,padencap\n"
|
||||
" --dpi-desync-fake-tls-mod=mod[,mod]\t\t; comma separated list of TLS fake mods. available mods : none,rnd,rndsni,sni=<sni>,dupsid,padencap\n"
|
||||
" --dpi-desync-fake-unknown=<filename>|0xHEX\t; file containing unknown protocol fake payload\n"
|
||||
" --dpi-desync-fake-syndata=<filename>|0xHEX\t; file containing SYN data payload\n"
|
||||
" --dpi-desync-fake-quic=<filename>|0xHEX\t; file containing fake QUIC Initial\n"
|
||||
@@ -2051,11 +2103,11 @@ 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 */
|
||||
load_blob_to_collection(optarg, &dp->fake_tls, FAKE_MAX_TCP,4);
|
||||
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->fake_tls_mod))
|
||||
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);
|
||||
|
38
nfq/params.c
38
nfq/params.c
@@ -206,7 +206,7 @@ bool dp_fake_defaults(struct desync_profile *dp)
|
||||
return false;
|
||||
if (blob_collection_empty(&dp->fake_tls))
|
||||
{
|
||||
if (!blob_collection_add_blob(&dp->fake_tls,fake_tls_clienthello_default,sizeof(fake_tls_clienthello_default),4))
|
||||
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 (blob_collection_empty(&dp->fake_unknown))
|
||||
@@ -222,35 +222,15 @@ bool dp_fake_defaults(struct desync_profile *dp)
|
||||
memset(item->data,0,item->size);
|
||||
item->data[0] = 0x40;
|
||||
}
|
||||
if (blob_collection_empty(&dp->fake_wg))
|
||||
struct blob_collection_head **fake,*fakes_z64[] = {&dp->fake_wg, &dp->fake_dht, &dp->fake_discord, &dp->fake_stun, &dp->fake_unknown_udp,NULL};
|
||||
for(fake=fakes_z64;*fake;fake++)
|
||||
{
|
||||
if (!(item=blob_collection_add_blob(&dp->fake_wg,NULL,64,0)))
|
||||
return false;
|
||||
memset(item->data,0,item->size);
|
||||
}
|
||||
if (blob_collection_empty(&dp->fake_dht))
|
||||
{
|
||||
if (!(item=blob_collection_add_blob(&dp->fake_dht,NULL,64,0)))
|
||||
return false;
|
||||
memset(item->data,0,item->size);
|
||||
}
|
||||
if (blob_collection_empty(&dp->fake_discord))
|
||||
{
|
||||
if (!(item=blob_collection_add_blob(&dp->fake_discord,NULL,64,0)))
|
||||
return false;
|
||||
memset(item->data,0,item->size);
|
||||
}
|
||||
if (blob_collection_empty(&dp->fake_stun))
|
||||
{
|
||||
if (!(item=blob_collection_add_blob(&dp->fake_stun,NULL,64,0)))
|
||||
return false;
|
||||
memset(item->data,0,item->size);
|
||||
}
|
||||
if (blob_collection_empty(&dp->fake_unknown_udp))
|
||||
{
|
||||
if (!(item=blob_collection_add_blob(&dp->fake_unknown_udp,NULL,64,0)))
|
||||
return false;
|
||||
memset(item->data,0,item->size);
|
||||
if (blob_collection_empty(*fake))
|
||||
{
|
||||
if (!(item=blob_collection_add_blob(*fake,NULL,64,0)))
|
||||
return false;
|
||||
memset(item->data,0,item->size);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@@ -44,7 +44,8 @@
|
||||
#define FAKE_TLS_MOD_RND 0x10
|
||||
#define FAKE_TLS_MOD_DUP_SID 0x20
|
||||
#define FAKE_TLS_MOD_RND_SNI 0x40
|
||||
#define FAKE_TLS_MOD_PADENCAP 0x80
|
||||
#define FAKE_TLS_MOD_SNI 0x80
|
||||
#define FAKE_TLS_MOD_PADENCAP 0x100
|
||||
|
||||
#define FAKE_MAX_TCP 1460
|
||||
#define FAKE_MAX_UDP 1472
|
||||
@@ -87,7 +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;
|
||||
|
||||
uint8_t fake_tls_mod;
|
||||
uint32_t fake_tls_mod;
|
||||
char fake_tls_sni[64];
|
||||
|
||||
int udplen_increment;
|
||||
|
||||
|
Reference in New Issue
Block a user