mirror of
https://github.com/hufrea/byedpi.git
synced 2025-06-29 18:21:14 +00:00
Dynamic fake
This commit is contained in:
parent
c1bef73d42
commit
9eb9432af9
115
desync.c
115
desync.c
@ -95,14 +95,26 @@ static bool sock_has_notsent(int sfd)
|
||||
}
|
||||
return tcpi.tcpi_notsent_bytes != 0;
|
||||
}
|
||||
|
||||
|
||||
static char *alloc_pktd(size_t n)
|
||||
{
|
||||
char *p = mmap(0, n, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
||||
return p == MAP_FAILED ? 0 : p;
|
||||
}
|
||||
#define free_pktd(p, n) munmap(p, n)
|
||||
#else
|
||||
#define sock_has_notsent(sfd) 0
|
||||
|
||||
#define alloc_pktd(n) malloc(n)
|
||||
#define free_pktd(p, n) free(p)
|
||||
#endif
|
||||
|
||||
static struct packet get_tcp_fake(const char *buffer, size_t n,
|
||||
|
||||
static struct packet get_tcp_fake(const char *buffer, ssize_t n,
|
||||
struct proto_info *info, const struct desync_params *opt)
|
||||
{
|
||||
struct packet pkt;
|
||||
struct packet pkt = { 0 };
|
||||
if (opt->fake_data.data) {
|
||||
pkt = opt->fake_data;
|
||||
}
|
||||
@ -113,12 +125,50 @@ static struct packet get_tcp_fake(const char *buffer, size_t n,
|
||||
}
|
||||
pkt = info->type == IS_HTTP ? fake_http : fake_tls;
|
||||
}
|
||||
if (opt->fake_offset) {
|
||||
if (pkt.size > opt->fake_offset) {
|
||||
pkt.size -= opt->fake_offset;
|
||||
pkt.data += opt->fake_offset;
|
||||
if (info->type != IS_HTTP
|
||||
&& (opt->fake_mod || opt->fake_sni_count)) do {
|
||||
ssize_t ps = n > pkt.size ? n : pkt.size;
|
||||
char *p = alloc_pktd(ps);
|
||||
if (!p) {
|
||||
uniperror("malloc/mmap");
|
||||
break;
|
||||
}
|
||||
const char *sni = 0;
|
||||
if (opt->fake_sni_count) {
|
||||
sni = opt->fake_sni_list[rand() % opt->fake_sni_count];
|
||||
}
|
||||
do {
|
||||
if ((opt->fake_mod & FM_ORIG) && info->type == IS_HTTPS) {
|
||||
memcpy(p, buffer, n);
|
||||
|
||||
if (!sni || !change_tls_sni(sni, p, n, n)) {
|
||||
break;
|
||||
}
|
||||
LOG(LOG_E, "change sni error\n");
|
||||
}
|
||||
memcpy(p, pkt.data, pkt.size);
|
||||
if (sni && change_tls_sni(sni, p, pkt.size, n) < 0) {
|
||||
free_pktd(p, ps);
|
||||
p = 0;
|
||||
break;
|
||||
}
|
||||
} while(0);
|
||||
if (p) {
|
||||
if (opt->fake_mod & FM_RAND) {
|
||||
randomize_tls(p, ps);
|
||||
}
|
||||
pkt.data = p;
|
||||
pkt.size = ps;
|
||||
pkt.dynamic = 1;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (opt->fake_offset.m) {
|
||||
pkt.off = gen_offset(opt->fake_offset.pos,
|
||||
opt->fake_offset.flag, buffer, n, 0, info);
|
||||
if (pkt.off > pkt.size || pkt.off < 0) {
|
||||
pkt.off = 0;
|
||||
}
|
||||
else pkt.size = 0;
|
||||
}
|
||||
return pkt;
|
||||
}
|
||||
@ -155,24 +205,30 @@ static ssize_t send_fake(int sfd, const char *buffer,
|
||||
return -1;
|
||||
}
|
||||
char *p = 0;
|
||||
size_t ms = pos > pkt.size ? pos : pkt.size;
|
||||
ssize_t ret = -1;
|
||||
|
||||
while (1) {
|
||||
p = mmap(0, pos, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
||||
if (p == MAP_FAILED) {
|
||||
uniperror("mmap");
|
||||
p = 0;
|
||||
break;
|
||||
if (pkt.dynamic) {
|
||||
p = pkt.data;
|
||||
}
|
||||
else {
|
||||
p = mmap(0, ms,
|
||||
PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
||||
if (p == MAP_FAILED) {
|
||||
uniperror("mmap");
|
||||
p = 0;
|
||||
break;
|
||||
}
|
||||
memcpy(p, pkt.data, pkt.size);
|
||||
}
|
||||
memcpy(p, pkt.data, pkt.size < pos ? pkt.size : pos);
|
||||
|
||||
if (setttl(sfd, opt->ttl ? opt->ttl : DEFAULT_TTL) < 0) {
|
||||
break;
|
||||
}
|
||||
if (opt->md5sig && set_md5sig(sfd, 5)) {
|
||||
break;
|
||||
}
|
||||
struct iovec vec = { .iov_base = p, .iov_len = pos };
|
||||
struct iovec vec = { .iov_base = p + pkt.off, .iov_len = pos };
|
||||
|
||||
ssize_t len = vmsplice(fds[1], &vec, 1, SPLICE_F_GIFT);
|
||||
if (len < 0) {
|
||||
@ -184,7 +240,7 @@ static ssize_t send_fake(int sfd, const char *buffer,
|
||||
uniperror("splice");
|
||||
break;
|
||||
}
|
||||
memcpy(p, buffer, pos);
|
||||
memcpy(p + pkt.off, buffer, pos);
|
||||
|
||||
if (setttl(sfd, params.def_ttl) < 0) {
|
||||
break;
|
||||
@ -195,7 +251,9 @@ static ssize_t send_fake(int sfd, const char *buffer,
|
||||
ret = len;
|
||||
break;
|
||||
}
|
||||
if (p) munmap(p, pos);
|
||||
if (!pkt.dynamic && p) {
|
||||
munmap(p, ms);
|
||||
}
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
return ret;
|
||||
@ -273,15 +331,15 @@ static ssize_t send_fake(int sfd, const char *buffer,
|
||||
return -1;
|
||||
}
|
||||
s->tfile = hfile;
|
||||
ssize_t len = -1;
|
||||
ssize_t len = -1, ps = pkt.size - pkt.off;
|
||||
|
||||
while (1) {
|
||||
DWORD wrtcnt = 0;
|
||||
if (!WriteFile(hfile, pkt.data, pkt.size < pos ? pkt.size : pos, &wrtcnt, 0)) {
|
||||
if (!WriteFile(hfile, pkt.data + pkt.off, ps < pos ? ps : pos, &wrtcnt, 0)) {
|
||||
uniperror("WriteFile");
|
||||
break;
|
||||
}
|
||||
if (pkt.size < pos) {
|
||||
if (ps < pos) {
|
||||
if (SetFilePointer(hfile, pos, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
|
||||
uniperror("SetFilePointer");
|
||||
break;
|
||||
@ -562,9 +620,14 @@ ssize_t desync(struct poolhd *pool,
|
||||
}
|
||||
else switch (part.m) {
|
||||
#ifdef FAKE_SUPPORT
|
||||
case DESYNC_FAKE:
|
||||
case DESYNC_FAKE:;
|
||||
struct packet pkt = get_tcp_fake(buffer, n, &info, &dp);
|
||||
|
||||
if (pos != lp) s = send_fake(sfd,
|
||||
buffer + lp, pos - lp, &dp, get_tcp_fake(buffer, n, &info, &dp));
|
||||
buffer + lp, pos - lp, &dp, pkt);
|
||||
|
||||
if (pkt.dynamic)
|
||||
free_pktd(pkt.data, pkt.size);
|
||||
break;
|
||||
#endif
|
||||
case DESYNC_DISORDER:
|
||||
@ -680,10 +743,10 @@ ssize_t desync_udp(int sfd, char *buffer,
|
||||
else {
|
||||
pkt = fake_udp;
|
||||
}
|
||||
if (dp->fake_offset) {
|
||||
if (pkt.size > dp->fake_offset) {
|
||||
pkt.size -= dp->fake_offset;
|
||||
pkt.data += dp->fake_offset;
|
||||
if (dp->fake_offset.m) {
|
||||
if (pkt.size > dp->fake_offset.pos) {
|
||||
pkt.size -= dp->fake_offset.pos;
|
||||
pkt.data += dp->fake_offset.pos;
|
||||
}
|
||||
else pkt.size = 0;
|
||||
}
|
||||
|
3
desync.h
3
desync.h
@ -26,4 +26,7 @@ struct proto_info {
|
||||
char init, type;
|
||||
int host_len, host_pos;
|
||||
};
|
||||
|
||||
static long gen_offset(long pos, int flag,
|
||||
const char *buffer, size_t n, long lp, struct proto_info *info);
|
||||
#endif
|
||||
|
58
main.c
58
main.c
@ -32,13 +32,13 @@ ASSERT(sizeof(struct in6_addr) == 16)
|
||||
|
||||
|
||||
struct packet fake_tls = {
|
||||
sizeof(tls_data), tls_data
|
||||
sizeof(tls_data), tls_data, 0, 0
|
||||
},
|
||||
fake_http = {
|
||||
sizeof(http_data), http_data
|
||||
sizeof(http_data), http_data, 0, 0
|
||||
},
|
||||
fake_udp = {
|
||||
sizeof(udp_data), udp_data
|
||||
sizeof(udp_data), udp_data, 0, 0
|
||||
};
|
||||
|
||||
|
||||
@ -106,11 +106,13 @@ static const char help_text[] = {
|
||||
#ifdef __linux__
|
||||
" -S, --md5sig Add MD5 Signature option for fake packets\n"
|
||||
#endif
|
||||
" -n, --tls-sni <str> Change SNI in fake ClientHello\n"
|
||||
" -n, --fake-sni <str> Change SNI in fake\n"
|
||||
" Replaced: ? - rand let, # - rand num, * - rand let/num\n"
|
||||
#endif
|
||||
" -t, --ttl <num> TTL of fake packets, default 8\n"
|
||||
" -O, --fake-offset <n> Fake data start offset\n"
|
||||
" -O, --fake-offset <pos_t> Fake data start offset\n"
|
||||
" -l, --fake-data <f|:str> Set custom fake packet\n"
|
||||
" -Q, --fake-tls-mod <r,o> Modify fake TLS CH: rand,orig\n"
|
||||
" -e, --oob-data <char> Set custom OOB data\n"
|
||||
" -M, --mod-http <h,d,r> Modify HTTP: hcsmix,dcsmix,rmspace\n"
|
||||
" -r, --tlsrec <pos_t> Make TLS record at position\n"
|
||||
@ -164,11 +166,12 @@ const struct option options[] = {
|
||||
#ifdef __linux__
|
||||
{"md5sig", 0, 0, 'S'},
|
||||
#endif
|
||||
{"tls-sni", 1, 0, 'n'},
|
||||
{"fake-sni", 1, 0, 'n'},
|
||||
#endif
|
||||
{"ttl", 1, 0, 't'},
|
||||
{"fake-data", 1, 0, 'l'},
|
||||
{"fake-offset", 1, 0, 'O'},
|
||||
{"fake-tls-mod", 1, 0, 'Q'},
|
||||
{"oob-data", 1, 0, 'e'},
|
||||
{"mod-http", 1, 0, 'M'},
|
||||
{"tlsrec", 1, 0, 'r'},
|
||||
@ -602,6 +605,10 @@ void clear_params(void)
|
||||
mem_destroy(s.ipset);
|
||||
s.hosts = 0;
|
||||
}
|
||||
if (s.fake_sni_list != 0) {
|
||||
free(s.fake_sni_list);
|
||||
s.fake_sni_list = 0;
|
||||
}
|
||||
}
|
||||
free(params.dp);
|
||||
params.dp = 0;
|
||||
@ -916,20 +923,39 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
val = strtol(optarg, &end, 0);
|
||||
if (val <= 0 || *end)
|
||||
if (parse_offset(&dp->fake_offset, optarg)) {
|
||||
invalid = 1;
|
||||
else
|
||||
dp->fake_offset = val;
|
||||
break;
|
||||
} else dp->fake_offset.m = 1;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
if (change_tls_sni(optarg, fake_tls.data, fake_tls.size)) {
|
||||
fprintf(stderr, "error chsni\n");
|
||||
clear_params();
|
||||
return -1;
|
||||
case 'Q':
|
||||
end = optarg;
|
||||
while (end && !invalid) {
|
||||
switch (*end) {
|
||||
case 'r':
|
||||
dp->fake_mod |= FM_RAND;
|
||||
break;
|
||||
case 'o':
|
||||
dp->fake_mod |= FM_ORIG;
|
||||
break;
|
||||
default:
|
||||
invalid = 1;
|
||||
continue;
|
||||
}
|
||||
end = strchr(end, ',');
|
||||
if (end) end++;
|
||||
}
|
||||
printf("sni: %s\n", optarg);
|
||||
break;
|
||||
|
||||
case 'n':;
|
||||
const char **p = add((void *)&dp->fake_sni_list,
|
||||
&dp->fake_sni_count, sizeof(optarg));
|
||||
if (!p) {
|
||||
invalid = 1;
|
||||
continue;
|
||||
}
|
||||
*p = optarg;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
|
238
packets.c
238
packets.c
@ -102,7 +102,7 @@ static size_t find_tls_ext_offset(uint16_t type,
|
||||
}
|
||||
|
||||
|
||||
static size_t chello_ext_offset(uint16_t type, const char *data, size_t size)
|
||||
static size_t find_ext_block(const char *data, size_t size)
|
||||
{
|
||||
if (size < 44) {
|
||||
return 0;
|
||||
@ -114,43 +114,184 @@ static size_t chello_ext_offset(uint16_t type, const char *data, size_t size)
|
||||
uint16_t cip_len = ANTOHS(data, 44 + sid_len);
|
||||
|
||||
size_t skip = 44 + sid_len + 2 + cip_len + 2;
|
||||
return find_tls_ext_offset(type, data, size, skip);
|
||||
return skip > size ? 0 : skip;
|
||||
}
|
||||
|
||||
|
||||
int change_tls_sni(const char *host, char *buffer, size_t bsize)
|
||||
static int merge_tls_records(char *buffer, ssize_t n)
|
||||
{
|
||||
size_t sni_offs, pad_offs;
|
||||
if (n < 5) {
|
||||
return 0;
|
||||
}
|
||||
uint16_t full_sz = 0;
|
||||
uint16_t r_sz = ANTOHS(buffer, 3);
|
||||
int i = 0;
|
||||
|
||||
if (!(sni_offs = chello_ext_offset(0x00, buffer, bsize))) {
|
||||
while (1) {
|
||||
full_sz += r_sz;
|
||||
if (5 + full_sz > n - 5
|
||||
|| buffer[5 + full_sz] != *buffer) {
|
||||
break;
|
||||
}
|
||||
r_sz = ANTOHS(buffer, 5 + full_sz + 3);
|
||||
|
||||
if (full_sz + 10 + r_sz > n) {
|
||||
break;
|
||||
}
|
||||
memmove(buffer + 5 + full_sz,
|
||||
buffer + 10 + full_sz, n - (10 + full_sz));
|
||||
i++;
|
||||
}
|
||||
SHTONA(buffer, 3, full_sz);
|
||||
SHTONA(buffer, 7, full_sz - 4);
|
||||
return i * 5;
|
||||
}
|
||||
|
||||
|
||||
static void copy_name(char *out, const char *name, size_t out_len)
|
||||
{
|
||||
for (size_t i = 0; i < out_len; i++) {
|
||||
switch (name[i]) {
|
||||
case '*':;
|
||||
int r = rand() % (10 + 'z' - 'a' + 1);
|
||||
out[i] = (r < 10 ? '0' : ('a' - 10)) + r;
|
||||
break;
|
||||
case '?':
|
||||
out[i] = 'a' + (rand() % ('z' - 'a' + 1));
|
||||
break;
|
||||
case '#':
|
||||
out[i] = '0' + (rand() % 10);
|
||||
break;
|
||||
default:
|
||||
out[i] = name[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int remove_tls_ext(char *buffer,
|
||||
ssize_t n, size_t skip, uint16_t type)
|
||||
{
|
||||
ssize_t ext_offs = find_tls_ext_offset(type, buffer, n, skip);
|
||||
if (!ext_offs) {
|
||||
return 0;
|
||||
}
|
||||
uint16_t ext_sz = ANTOHS(buffer, ext_offs + 2);
|
||||
ssize_t ext_end = ext_offs + 4 + ext_sz;
|
||||
if (ext_end > n) {
|
||||
return 0;
|
||||
}
|
||||
memmove(buffer + ext_offs, buffer + ext_end, n - ext_end);
|
||||
return ext_sz + 4;
|
||||
}
|
||||
|
||||
|
||||
static int resize_ech_ext(char *buffer,
|
||||
ssize_t n, size_t skip, int inc)
|
||||
{
|
||||
ssize_t ech_offs = find_tls_ext_offset(0xfe0d, buffer, n, skip);
|
||||
if (!ech_offs) {
|
||||
return 0;
|
||||
}
|
||||
uint16_t ech_sz = ANTOHS(buffer, ech_offs + 2);
|
||||
ssize_t ech_end = ech_offs + 4 + ech_sz;
|
||||
|
||||
if (ech_sz < 12 || ech_end > n) {
|
||||
return 0;
|
||||
}
|
||||
uint16_t enc_sz = ANTOHS(buffer, ech_offs + 4 + 6);
|
||||
ssize_t pay_offs = ech_offs + 4 + 8 + enc_sz;
|
||||
uint16_t pay_sz = ech_sz - (8 + enc_sz + 2);
|
||||
|
||||
if (pay_offs + 2 > n || pay_sz < -inc) {
|
||||
return 0;
|
||||
}
|
||||
SHTONA(buffer, ech_offs + 2, ech_sz + inc);
|
||||
SHTONA(buffer, pay_offs, pay_sz + inc);
|
||||
|
||||
memmove(buffer + ech_end + inc, buffer + ech_end, n - ech_end);
|
||||
return inc;
|
||||
}
|
||||
|
||||
|
||||
static void resize_sni(char *buffer, ssize_t n,
|
||||
ssize_t sni_offs, ssize_t sni_sz, ssize_t new_sz)
|
||||
{
|
||||
SHTONA(buffer, sni_offs + 2, new_sz + 5);
|
||||
SHTONA(buffer, sni_offs + 4, new_sz + 3);
|
||||
SHTONA(buffer, sni_offs + 7, new_sz);
|
||||
|
||||
ssize_t sni_end = sni_offs + 4 + sni_sz;
|
||||
memmove(buffer + sni_end + new_sz - (sni_sz - 5), buffer + sni_end, n - sni_end);
|
||||
}
|
||||
|
||||
|
||||
int change_tls_sni(const char *host, char *buffer, ssize_t n, ssize_t nn)
|
||||
{
|
||||
int avail = merge_tls_records(buffer, n);
|
||||
avail += (nn - n);
|
||||
|
||||
uint16_t r_sz = ANTOHS(buffer, 3);
|
||||
r_sz += avail;
|
||||
|
||||
size_t skip = find_ext_block(buffer, n);
|
||||
if (!skip) {
|
||||
return -1;
|
||||
}
|
||||
if (!(pad_offs = chello_ext_offset(0x15, buffer, bsize))) {
|
||||
ssize_t sni_offs = find_tls_ext_offset(0x00, buffer, n, skip);
|
||||
if (!sni_offs) {
|
||||
return -1;
|
||||
}
|
||||
char *sni = &buffer[sni_offs];
|
||||
char *pad = &buffer[pad_offs];
|
||||
|
||||
uint16_t old_sz = ANTOHS(buffer, sni_offs + 2) - 5;
|
||||
uint16_t free_sz = ANTOHS(buffer, pad_offs + 2);
|
||||
uint16_t new_sz = strlen(host);
|
||||
uint16_t sni_sz = ANTOHS(buffer, sni_offs + 2);
|
||||
|
||||
ssize_t diff = new_sz - old_sz;
|
||||
|
||||
if ((free_sz != (bsize - pad_offs - 4))
|
||||
|| free_sz < diff) {
|
||||
if (sni_offs + 4 + sni_sz > n) {
|
||||
return -1;
|
||||
}
|
||||
SHTONA(sni, 2, old_sz + diff + 5);
|
||||
SHTONA(sni, 4, old_sz + diff + 3);
|
||||
SHTONA(sni, 7, old_sz + diff);
|
||||
SHTONA(pad, 2, free_sz - diff);
|
||||
int diff = (int )new_sz - (sni_sz - 5);
|
||||
avail -= diff;
|
||||
|
||||
char *host_end = sni + 9 + old_sz;
|
||||
int oth_sz = bsize - (sni_offs + 9 + old_sz);
|
||||
if (diff < 0 && avail > 0) {
|
||||
resize_sni(buffer, n, sni_offs, sni_sz, new_sz);
|
||||
diff = 0;
|
||||
}
|
||||
if (avail) {
|
||||
avail -= resize_ech_ext(buffer, n, skip, avail);
|
||||
}
|
||||
uint16_t exts[] = {
|
||||
0x0015, // padding
|
||||
0x0031, // post_handshake_auth
|
||||
0x0010, // ALPN
|
||||
0x001c, // record_size_limit
|
||||
0x0023, // session_ticket
|
||||
0x0005, // status_request
|
||||
0x0022, // delegated_credentials
|
||||
0x0012, // signed_certificate_timestamp
|
||||
0x001b, // compress_certificate
|
||||
0
|
||||
};
|
||||
for (uint16_t *e = exts; avail && avail < 4; e++) {
|
||||
if (!*e) {
|
||||
return -1;
|
||||
}
|
||||
avail += remove_tls_ext(buffer, n, skip, *e);
|
||||
}
|
||||
if (!(sni_offs = find_tls_ext_offset(0x00, buffer, n, skip))) {
|
||||
return -1;
|
||||
}
|
||||
if (diff) {
|
||||
resize_sni(buffer, n, sni_offs, sni_sz, new_sz);
|
||||
}
|
||||
copy_name(buffer + sni_offs + 9, host, new_sz);
|
||||
|
||||
memmove(host_end + diff, host_end, oth_sz);
|
||||
memcpy(sni + 9, host, new_sz);
|
||||
if (avail >= 4) {
|
||||
SHTONA(buffer, 5 + r_sz - avail, 0x0015);
|
||||
SHTONA(buffer, 5 + r_sz - avail + 2, avail - 4);
|
||||
memset(buffer + 5 + r_sz - avail + 4, 0, avail - 4);
|
||||
}
|
||||
SHTONA(buffer, 3, r_sz);
|
||||
SHTONA(buffer, 7, r_sz - 4);
|
||||
SHTONA(buffer, skip, 5 + r_sz - skip - 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -168,7 +309,11 @@ int parse_tls(const char *buffer, size_t bsize, char **hs)
|
||||
if (!is_tls_chello(buffer, bsize)) {
|
||||
return 0;
|
||||
}
|
||||
size_t sni_offs = chello_ext_offset(0x00, buffer, bsize);
|
||||
size_t skip = find_ext_block(buffer, bsize);
|
||||
if (!skip) {
|
||||
return 0;
|
||||
}
|
||||
size_t sni_offs = find_tls_ext_offset(0x00, buffer, bsize, skip);
|
||||
|
||||
if (!sni_offs || (sni_offs + 12) >= bsize) {
|
||||
return 0;
|
||||
@ -394,3 +539,48 @@ int part_tls(char *buffer, size_t bsize, ssize_t n, long pos)
|
||||
SHTONA(buffer, 5 + pos + 3, r_sz - pos);
|
||||
return 5;
|
||||
}
|
||||
|
||||
|
||||
static void gen_rand_array(char *out, size_t len)
|
||||
{
|
||||
for (; len; len--, out++) {
|
||||
uint8_t c = rand() % 256;
|
||||
*((uint8_t *)out) = c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void randomize_tls(char *buffer, ssize_t n)
|
||||
{
|
||||
if (n < 44) {
|
||||
return;
|
||||
}
|
||||
uint8_t sid_len = buffer[43];
|
||||
if (n < (44l + sid_len + 2)) {
|
||||
return;
|
||||
}
|
||||
gen_rand_array(buffer + 11, 32);
|
||||
gen_rand_array(buffer + 44, sid_len);
|
||||
|
||||
size_t skip = find_ext_block(buffer, n);
|
||||
if (!skip) {
|
||||
return;
|
||||
}
|
||||
ssize_t ks_offs = find_tls_ext_offset(0x0033, buffer, n, skip);
|
||||
if (!ks_offs || ks_offs + 6 >= n) {
|
||||
return;
|
||||
}
|
||||
int ks_sz = ANTOHS(buffer, ks_offs + 2);
|
||||
if (ks_offs + 4 + ks_sz > n) {
|
||||
return;
|
||||
}
|
||||
ssize_t g_offs = ks_offs + 4 + 2;
|
||||
while (g_offs + 4 < ks_offs + 4 + ks_sz) {
|
||||
uint16_t g_sz = ANTOHS(buffer, g_offs + 2);
|
||||
if (ks_offs + 4 + g_sz > n) {
|
||||
return;
|
||||
}
|
||||
gen_rand_array(buffer + g_offs + 4, g_sz);
|
||||
g_offs += 4 + g_sz;
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ extern char tls_data[517];
|
||||
extern char http_data[43];
|
||||
extern char udp_data[64];
|
||||
|
||||
int change_tls_sni(const char *host, char *buffer, size_t bsize);
|
||||
int change_tls_sni(const char *host, char *buffer, ssize_t bsize, ssize_t nn);
|
||||
|
||||
bool is_tls_chello(const char *buffer, size_t bsize);
|
||||
|
||||
@ -42,6 +42,8 @@ bool is_tls_shello(const char *buffer, size_t bsize);
|
||||
|
||||
int part_tls(char *buffer, size_t bsize, ssize_t n, long pos);
|
||||
|
||||
void randomize_tls(char *buffer, ssize_t n);
|
||||
|
||||
//bool is_dns_req(char *buffer, size_t n);
|
||||
|
||||
//bool is_quic_initial(char *buffer, size_t bsize);
|
||||
|
10
params.h
10
params.h
@ -37,6 +37,9 @@
|
||||
#define AUTO_NOBUFF -1
|
||||
#define AUTO_NOSAVE 0
|
||||
|
||||
#define FM_RAND 1
|
||||
#define FM_ORIG 2
|
||||
|
||||
enum demode {
|
||||
DESYNC_NONE,
|
||||
DESYNC_SPLIT,
|
||||
@ -67,6 +70,8 @@ struct part {
|
||||
struct packet {
|
||||
ssize_t size;
|
||||
char *data;
|
||||
ssize_t off;
|
||||
bool dynamic;
|
||||
};
|
||||
|
||||
struct desync_params {
|
||||
@ -74,7 +79,10 @@ struct desync_params {
|
||||
bool md5sig;
|
||||
struct packet fake_data;
|
||||
int udp_fake_count;
|
||||
int fake_offset;
|
||||
struct part fake_offset;
|
||||
int fake_sni_count;
|
||||
const char **fake_sni_list;
|
||||
int fake_mod;
|
||||
bool drop_sack;
|
||||
char oob_char[2];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user