Add --fake-custom-sni-file option

Allows to specify fake as a binary file
This commit is contained in:
Vadim Vetrov
2025-01-27 19:51:28 +03:00
parent 49de2cad6a
commit ef78f5e185
2 changed files with 45 additions and 2 deletions

View File

@@ -229,8 +229,11 @@ Flags that do not scoped to a specific section, used over all the youtubeUnblock
- `--fake-sni-seq-len=<length>` This flag specifies **youtubeUnblock** to build a complicated construction of fake client hello packets. length determines how much fakes will be sent. Defaults to **1**.
- `--fake-sni-type={default|custom|random}` This flag specifies which faking message type should be used for fake packets. For `random`, the message of random length and with random payload will be sent. For `default` the default payload (sni=www.google.com) is used. And for the `custom` option, the payload from `--fake-custom-payload` section utilized. Defaults to `default`.
- `--fake-custom-payload=<payload>` Useful with `--fake-sni-type=custom`. You should specify the payload for fake message manually. Use hex format: `--fake-custom-payload=0001020304` mean that 5 bytes sequence: `0x00`, `0x01`, `0x02`, `0x03`, `0x04` used as fake.
- `--fake-custom-payload-file=<binary file containing TLS message>` Same as `--fake-custom-payload` but binary file instead of hex. The file should contain raw binary TLS message (TCP payload).
- `--faking-strategy={randseq|ttl|tcp_check|pastseq|md5sum}` This flag determines the strategy of fake packets invalidation. Defaults to `randseq`
- `randseq` specifies that random sequence/acknowledgment random will be set. This option may be handled by provider which uses *conntrack* with drop on invalid *conntrack* state firewall rule enabled.
- `ttl` specifies that packet will be invalidated after `--faking-ttl=n` hops. `ttl` is better but may cause issues if unconfigured.

View File

@@ -309,6 +309,7 @@ enum {
OPT_FAKE_SNI_SEQ_LEN,
OPT_FAKE_SNI_TYPE,
OPT_FAKE_CUSTOM_PAYLOAD,
OPT_FAKE_CUSTOM_PAYLOAD_FILE,
OPT_START_SECTION,
OPT_END_SECTION,
OPT_DAEMONIZE,
@@ -363,6 +364,7 @@ static struct option long_opt[] = {
{"fake-sni-seq-len", 1, 0, OPT_FAKE_SNI_SEQ_LEN},
{"fake-sni-type", 1, 0, OPT_FAKE_SNI_TYPE},
{"fake-custom-payload", 1, 0, OPT_FAKE_CUSTOM_PAYLOAD},
{"fake-custom-payload-file", 1, 0, OPT_FAKE_CUSTOM_PAYLOAD_FILE},
{"faking-strategy", 1, 0, OPT_FAKING_STRATEGY},
{"fake-seq-offset", 1, 0, OPT_FAKE_SEQ_OFFSET},
{"faking-ttl", 1, 0, OPT_FAKING_TTL},
@@ -427,6 +429,7 @@ void print_usage(const char *argv0) {
printf("\t--fake-sni-seq-len=<length>\n");
printf("\t--fake-sni-type={default|random|custom}\n");
printf("\t--fake-custom-payload=<hex payload>\n");
printf("\t--fake-custom-payload-file=<binary file containing TLS message>\n");
printf("\t--fake-seq-offset=<offset>\n");
printf("\t--faking-ttl=<ttl>\n");
printf("\t--faking-strategy={randseq|ttl|tcp_check|pastseq|md5sum}\n");
@@ -796,6 +799,7 @@ int yparse_args(struct config_t *config, int argc, char *argv[]) {
break;
case OPT_FAKE_CUSTOM_PAYLOAD:
SFREE(sect_config->fake_custom_pkt);
sect_config->fake_custom_pkt_sz = 0;
ret = parse_fake_custom_payload(optarg, &sect_config->fake_custom_pkt, &sect_config->fake_custom_pkt_sz);
if (ret == -EINVAL) {
@@ -805,6 +809,36 @@ int yparse_args(struct config_t *config, int argc, char *argv[]) {
}
break;
case OPT_FAKE_CUSTOM_PAYLOAD_FILE:
#ifdef KERNEL_SPACE
lgerr("--fake-custom-payload-file is not allowed in kernel space. Use --fake-custom-payload argument instead");
goto error;
#else
{
SFREE(sect_config->fake_custom_pkt);
sect_config->fake_custom_pkt_sz = 0;
ret = read_file(optarg);
if (ret < 0) {
goto error;
}
if (glob_file_size > MAX_FAKE_SIZE) {
goto invalid_opt;
}
sect_config->fake_custom_pkt = malloc(glob_file_size);
if (sect_config->fake_custom_pkt != NULL) {
memcpy(sect_config->fake_custom_pkt, glob_file_buffer, glob_file_size);
sect_config->fake_custom_pkt_sz = glob_file_size;
} else {
goto error;
}
break;
}
#endif
case OPT_FK_WINSIZE:
num = parse_numeric_option(optarg);
if (errno != 0 || num < 0) {
@@ -931,7 +965,8 @@ stop_exec:
#endif
invalid_opt:
printf("Invalid option %s\n", long_opt[optIdx].name);
if (optind > 0 && optind <= argc)
lgerr("Invalid option %s\n", argv[optind - 1]);
ret = -EINVAL;
error:
#ifndef KERNEL_SPACE
@@ -939,7 +974,11 @@ error:
#endif
if (errno) ret = -errno;
if (ret != -EINVAL) {
lgerror(ret, "argparse: error thrown in %s", long_opt[optIdx].name);
if (optind > 0 && optind <= argc)
lgerror(
ret == 0 ? EINVAL : -ret,
"argparse: error thrown in %s", argv[optind - 1]
);
ret = -EINVAL;
}
@@ -1030,6 +1069,7 @@ static size_t print_config_section(const struct section_config_t *section, char
print_cnf_buf("--sni-domains=all");
} else if (section->sni_domains != NULL) {
print_cnf_raw("--sni-domains=");
for (struct domains_list *sne = section->sni_domains; sne != NULL; sne = sne->next) {
print_cnf_raw("%s,", sne->domain_name);
}