mirror of
https://github.com/Waujito/youtubeUnblock.git
synced 2026-02-01 07:00:36 +03:00
Add Timestamp faking strategy
This commit is contained in:
10
README.md
10
README.md
@@ -198,6 +198,11 @@ It should return low speed without **youtubeUnblock** and faster with it. With *
|
||||
curl -o/dev/null -k --connect-to ::google.com -k -L -H Host:\ mirror.gcr.io https://mirror.gcr.io/v2/cimg/android/blobs/sha256:6fd8bdac3da660bde7bd0b6f2b6a46e1b686afb74b9a4614def32532b73f5eaa
|
||||
```
|
||||
|
||||
For ECH check it comes out to be more complicated, since it is still an experimental feature in CURL. If you want to test it, first of all, you should compile curl with ECH support. You can follow [this guide](https://github.com/curl/curl/blob/master/docs/ECH.md). Next, you can check it with
|
||||
```sh
|
||||
LD_LIBRARY_PATH=$HOME/code/openssl $HOME/code/curl/src/curl --ech hard --doh-url https://one.one.one.one/dns-query https://www.opengl.org --ipv4
|
||||
```
|
||||
|
||||
## Flags
|
||||
|
||||
Put flags to the **BINARY**, not an init script. If you are on OpenWRT you should put the flags inside the script: open `/etc/init.d/youtubeUnblock` with any text editor, like vi or nano and put your flags after `procd_set_param command /usr/bin/youtubeUnblock` line.
|
||||
@@ -248,17 +253,20 @@ Flags that do not scoped to a specific section, used over all the youtubeUnblock
|
||||
|
||||
- `--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`
|
||||
- `--faking-strategy={randseq|ttl|tcp_check|pastseq|md5sum|timestamp}` This flag determines the strategy of fake packets invalidation. The user can specify multiple faking options, so multiple techniques will be applied to the fake packet. Defaults to `tcp_check,timestamp`.
|
||||
- `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.
|
||||
- `pastseq` is like `randseq` but sequence number is not random but references the packet sent in the past (before current).
|
||||
- `tcp_check` will invalidate faking packet with invalid checksum. May be handled and dropped by some providers/TSPUs.
|
||||
- `md5sum` will invalidate faking packet with invalid TCP md5sum. md5sum is a TCP option which is handled by the destination server but may be skipped by TSPU.
|
||||
- `timestamp` utilizes TCP Timestamp option. Timestamp TSVal is decreased by `--faking-timestamp-decrease=n` parameter, so it is being rejected by the server.
|
||||
|
||||
- `--faking-ttl=<ttl>` Tunes the time to live (TTL) of fake SNI messages. TTL is specified like that the packet will go through the DPI system and captured by it, but will not reach the destination server. Defaults to **8**.
|
||||
|
||||
- `--fake-seq-offset` Tunes the offset from original sequence number for fake packets. Used by randseq faking strategy. Defaults to 10000. If 0, random sequence number will be set.
|
||||
|
||||
- `--faking-timestamp-decrease=<val>` Decreases TSVal parameter of Timestamp option in fake packet by this value. The default is 600000. According to research made in zapret project, this parameter may work in range between 100 and 0x80000000.
|
||||
|
||||
- `--frag={tcp,ip,none}` Specifies the fragmentation strategy for the packet. tcp is used by default. Ip fragmentation may be blocked by DPI system. None specifies no fragmentation. Probably this won't work, but may be will work for some fake sni strategies.
|
||||
|
||||
- `--frag-sni-reverse={0|1}` Specifies **youtubeUnblock** to send *ClientHello* fragments in the reverse order. Defaults to **1**.
|
||||
|
||||
164
src/args.c
164
src/args.c
@@ -159,6 +159,62 @@ static long parse_numeric_option(const char* value) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static int parse_faking_strategy(char *optarg, int *faking_strategy) {
|
||||
|
||||
*faking_strategy = 0;
|
||||
char *p = optarg;
|
||||
char *ep = p;
|
||||
while (1) {
|
||||
if (*ep == '\0' || *ep == ',') {
|
||||
if (ep == p) {
|
||||
if (*ep == '\0')
|
||||
break;
|
||||
|
||||
p++, ep++;
|
||||
continue;
|
||||
}
|
||||
|
||||
char ep_endsym = *ep;
|
||||
*ep = '\0';
|
||||
|
||||
if (strcmp(p, "randseq") == 0) {
|
||||
*faking_strategy |= FAKE_STRAT_RAND_SEQ;
|
||||
} else if (strcmp(p, "ttl") == 0) {
|
||||
*faking_strategy |= FAKE_STRAT_TTL;
|
||||
} else if (strcmp(p, "tcp_check") == 0) {
|
||||
*faking_strategy |= FAKE_STRAT_TCP_CHECK;
|
||||
} else if (strcmp(p, "pastseq") == 0) {
|
||||
*faking_strategy |= FAKE_STRAT_PAST_SEQ;
|
||||
} else if (strcmp(p, "md5sum") == 0) {
|
||||
*faking_strategy |= FAKE_STRAT_TCP_MD5SUM;
|
||||
} else if (strcmp(p, "timestamp") == 0) {
|
||||
*faking_strategy |= FAKE_STRAT_TCP_TS;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*ep = ep_endsym;
|
||||
|
||||
if (*ep == '\0') {
|
||||
break;
|
||||
} else {
|
||||
p = ep + 1;
|
||||
ep = p;
|
||||
}
|
||||
} else {
|
||||
ep++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( CHECK_BITFIELD(*faking_strategy, FAKE_STRAT_PAST_SEQ) &&
|
||||
CHECK_BITFIELD(*faking_strategy, FAKE_STRAT_RAND_SEQ)) {
|
||||
lgerr("Strategies pastseq and randseq are incompatible\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_udp_dport_range(char *str, struct udp_dport_range **udpr, int *udpr_len) {
|
||||
int seclen = 1;
|
||||
const char *p = str;
|
||||
@@ -297,6 +353,7 @@ enum {
|
||||
OPT_FAKE_SNI,
|
||||
OPT_FAKING_TTL,
|
||||
OPT_FAKING_STRATEGY,
|
||||
OPT_FAKING_TIMESTAMP_DECREASE,
|
||||
OPT_FAKE_SNI_SEQ_LEN,
|
||||
OPT_FAKE_SNI_TYPE,
|
||||
OPT_FAKE_CUSTOM_PAYLOAD,
|
||||
@@ -360,6 +417,7 @@ static struct option long_opt[] = {
|
||||
{"faking-strategy", 1, 0, OPT_FAKING_STRATEGY},
|
||||
{"fake-seq-offset", 1, 0, OPT_FAKE_SEQ_OFFSET},
|
||||
{"faking-ttl", 1, 0, OPT_FAKING_TTL},
|
||||
{"faking-timestamp-decrease", 1, 0, OPT_FAKING_TIMESTAMP_DECREASE},
|
||||
{"frag", 1, 0, OPT_FRAG},
|
||||
{"frag-sni-reverse", 1, 0, OPT_FRAG_SNI_REVERSE},
|
||||
{"frag-sni-faked", 1, 0, OPT_FRAG_SNI_FAKED},
|
||||
@@ -425,7 +483,8 @@ void print_usage(const char *argv0) {
|
||||
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");
|
||||
printf("\t--faking-timestamp-decrease=<val>\n");
|
||||
printf("\t--faking-strategy={randseq|ttl|tcp_check|pastseq|md5sum|timestamp}\n");
|
||||
printf("\t--synfake={1|0}\n");
|
||||
printf("\t--synfake-len=<len>\n");
|
||||
printf("\t--frag={tcp,ip,none}\n");
|
||||
@@ -730,21 +789,11 @@ int yparse_args(struct config_t *config, int argc, char *argv[]) {
|
||||
sect_config->frag_sni_pos = num;
|
||||
break;
|
||||
case OPT_FAKING_STRATEGY:
|
||||
if (strcmp(optarg, "randseq") == 0) {
|
||||
sect_config->faking_strategy = FAKE_STRAT_RAND_SEQ;
|
||||
} else if (strcmp(optarg, "ttl") == 0) {
|
||||
sect_config->faking_strategy = FAKE_STRAT_TTL;
|
||||
} else if (strcmp(optarg, "tcp_check") == 0) {
|
||||
sect_config->faking_strategy = FAKE_STRAT_TCP_CHECK;
|
||||
} else if (strcmp(optarg, "pastseq") == 0) {
|
||||
sect_config->faking_strategy = FAKE_STRAT_PAST_SEQ;
|
||||
} else if (strcmp(optarg, "md5sum") == 0) {
|
||||
sect_config->faking_strategy = FAKE_STRAT_TCP_MD5SUM;
|
||||
} else {
|
||||
if (parse_faking_strategy(
|
||||
optarg, §_config->faking_strategy) < 0) {
|
||||
goto invalid_opt;
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
case OPT_FAKING_TTL:
|
||||
num = parse_numeric_option(optarg);
|
||||
if (errno != 0 || num < 0 || num > 255) {
|
||||
@@ -753,6 +802,14 @@ int yparse_args(struct config_t *config, int argc, char *argv[]) {
|
||||
|
||||
sect_config->faking_ttl = num;
|
||||
break;
|
||||
case OPT_FAKING_TIMESTAMP_DECREASE:
|
||||
num = parse_numeric_option(optarg);
|
||||
if (errno != 0) {
|
||||
goto invalid_opt;
|
||||
}
|
||||
|
||||
sect_config->faking_timestamp_decrease = num;
|
||||
break;
|
||||
case OPT_FAKE_SEQ_OFFSET:
|
||||
num = parse_numeric_option(optarg);
|
||||
if (errno != 0) {
|
||||
@@ -1033,33 +1090,66 @@ static size_t print_config_section(const struct section_config_t *section, char
|
||||
case FAKE_PAYLOAD_DEFAULT:
|
||||
print_cnf_buf("--fake-sni-type=default");
|
||||
break;
|
||||
}
|
||||
|
||||
switch(section->faking_strategy) {
|
||||
case FAKE_STRAT_TTL:
|
||||
print_cnf_buf("--faking-strategy=ttl");
|
||||
print_cnf_buf("--faking-ttl=%d", section->faking_ttl);
|
||||
break;
|
||||
case FAKE_STRAT_RAND_SEQ:
|
||||
print_cnf_buf("--faking-strategy=randseq");
|
||||
break;
|
||||
case FAKE_STRAT_TCP_CHECK:
|
||||
print_cnf_buf("--faking-strategy=tcp_check");
|
||||
break;
|
||||
case FAKE_STRAT_TCP_MD5SUM:
|
||||
print_cnf_buf("--faking-strategy=md5sum");
|
||||
break;
|
||||
case FAKE_STRAT_PAST_SEQ:
|
||||
print_cnf_buf("--faking-strategy=pastseq");
|
||||
print_cnf_buf("--fake-seq-offset=%d", section->fakeseq_offset);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
print_cnf_buf("--seg2delay=%d", section->seg2_delay);
|
||||
} else {
|
||||
print_cnf_buf("--fake-sni=0");
|
||||
}
|
||||
|
||||
if (section->fake_sni && section->faking_strategy) {
|
||||
int show_ttl = 0;
|
||||
int show_seq_offset = 0;
|
||||
int show_faking_ts_decr = 0;
|
||||
|
||||
print_cnf_raw("--faking-strategy=");
|
||||
if (CHECK_BITFIELD(section->faking_strategy, FAKE_STRAT_TTL)) {
|
||||
print_cnf_raw("ttl");
|
||||
print_cnf_raw(",");
|
||||
show_ttl = 1;
|
||||
}
|
||||
|
||||
if (CHECK_BITFIELD(section->faking_strategy, FAKE_STRAT_RAND_SEQ)) {
|
||||
print_cnf_raw("randseq");
|
||||
print_cnf_raw(",");
|
||||
show_ttl = 1;
|
||||
}
|
||||
|
||||
if (CHECK_BITFIELD(section->faking_strategy, FAKE_STRAT_TCP_CHECK)) {
|
||||
print_cnf_raw("tcp_check");
|
||||
print_cnf_raw(",");
|
||||
}
|
||||
|
||||
if (CHECK_BITFIELD(section->faking_strategy, FAKE_STRAT_TCP_MD5SUM)) {
|
||||
print_cnf_raw("md5sum");
|
||||
print_cnf_raw(",");
|
||||
}
|
||||
|
||||
if (CHECK_BITFIELD(section->faking_strategy, FAKE_STRAT_TCP_TS)) {
|
||||
print_cnf_raw("timestamp");
|
||||
print_cnf_raw(",");
|
||||
show_faking_ts_decr = 1;
|
||||
}
|
||||
|
||||
if (CHECK_BITFIELD(section->faking_strategy, FAKE_STRAT_PAST_SEQ)) {
|
||||
print_cnf_raw("pastseq");
|
||||
print_cnf_raw(",");
|
||||
}
|
||||
// delete comma and write space
|
||||
print_cnf_raw("\b ");
|
||||
|
||||
if (show_ttl) {
|
||||
print_cnf_buf("--faking-ttl=%d", section->faking_ttl);
|
||||
}
|
||||
|
||||
if (show_seq_offset) {
|
||||
print_cnf_buf("--fake-seq-offset=%d", section->fakeseq_offset);
|
||||
}
|
||||
if (show_faking_ts_decr) {
|
||||
print_cnf_buf("--faking-timestamp-decrease=%d",
|
||||
section->faking_timestamp_decrease);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
print_cnf_buf("--tls=disabled");
|
||||
}
|
||||
@@ -1247,8 +1337,8 @@ int init_section_config(struct section_config_t **section, struct section_config
|
||||
return ret;
|
||||
}
|
||||
|
||||
def_section->fake_sni_pkt = fake_sni_old;
|
||||
def_section->fake_sni_pkt_sz = sizeof(fake_sni_old) - 1;
|
||||
def_section->fake_sni_pkt = fake_sni;
|
||||
def_section->fake_sni_pkt_sz = sizeof(fake_sni) - 1;
|
||||
|
||||
*section = def_section;
|
||||
return 0;
|
||||
|
||||
@@ -71,6 +71,7 @@ struct section_config_t {
|
||||
int frag_middle_sni;
|
||||
int frag_sni_pos;
|
||||
unsigned char faking_ttl;
|
||||
unsigned int faking_timestamp_decrease;
|
||||
int fake_sni;
|
||||
unsigned int fake_sni_seq_len;
|
||||
|
||||
@@ -176,6 +177,7 @@ for (struct section_config_t *section = (config)->last_section; section != NULL;
|
||||
#endif
|
||||
|
||||
#define FAKE_TTL 8
|
||||
#define FAKING_TIMESTAMP_DECREASE_TTL 600000
|
||||
|
||||
#define FAKE_STRAT_NONE 0
|
||||
// Will invalidate fake packets by out-of-ack_seq out-of-seq request
|
||||
@@ -187,6 +189,7 @@ for (struct section_config_t *section = (config)->last_section; section != NULL;
|
||||
#define FAKE_STRAT_TCP_CHECK (1 << 3)
|
||||
#define FAKE_STRAT_TCP_MD5SUM (1 << 4)
|
||||
#define FAKE_STRAT_UDP_CHECK (1 << 5)
|
||||
#define FAKE_STRAT_TCP_TS (1 << 6)
|
||||
|
||||
#define FAKE_STRAT_COUNT 6
|
||||
|
||||
@@ -199,7 +202,7 @@ for (int strategy = 1; strategy <= (1 << FAKE_STRAT_COUNT); strategy <<= 1) \
|
||||
if ((fake_bitmask) & strategy)
|
||||
|
||||
#ifndef FAKING_STRATEGY
|
||||
#define FAKING_STRATEGY FAKE_STRAT_PAST_SEQ
|
||||
#define FAKING_STRATEGY FAKE_STRAT_TCP_CHECK | FAKE_STRAT_TCP_TS
|
||||
#endif
|
||||
|
||||
#define MAX_FAKE_SIZE 1300
|
||||
@@ -241,7 +244,8 @@ enum {
|
||||
.fragmentation_strategy = FRAGMENTATION_STRATEGY, \
|
||||
.faking_strategy = FAKING_STRATEGY, \
|
||||
.faking_ttl = FAKE_TTL, \
|
||||
.fake_sni = 0, \
|
||||
.faking_timestamp_decrease = FAKING_TIMESTAMP_DECREASE_TTL, \
|
||||
.fake_sni = 1, \
|
||||
.fake_sni_seq_len = 1, \
|
||||
.fake_sni_type = FAKE_PAYLOAD_DEFAULT, \
|
||||
.fake_custom_pkt = NULL, \
|
||||
|
||||
141
src/mangle.c
141
src/mangle.c
@@ -315,7 +315,6 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
|
||||
set_tcp_checksum(tcph, iph, iph_len);
|
||||
}
|
||||
|
||||
/*
|
||||
if (0) {
|
||||
int delta = 2;
|
||||
ret = seqovl_packet(payload, &payload_len, delta);
|
||||
@@ -326,14 +325,28 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
|
||||
lgerror(ret, "seqovl_packet delta %d", delta);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (dlen > AVAILABLE_MTU) {
|
||||
lgdebug("WARNING! Client Hello packet is too big and may cause issues!");
|
||||
}
|
||||
|
||||
if (section->fake_sni) {
|
||||
post_fake_sni(args_default_fake_type(section), iph, iph_len, tcph, tcph_len);
|
||||
struct fake_type f_type = args_default_fake_type(section);
|
||||
|
||||
// f_type.strategy.strategy = FAKE_STRAT_RAND_SEQ;
|
||||
// f_type.strategy.randseq_offset = f_type.fake_len - 1;
|
||||
// f_type.fake_data = "\x16";
|
||||
// f_type.fake_len = 1;
|
||||
//
|
||||
// post_fake_sni(f_type, iph, iph_len, tcph, tcph_len);
|
||||
//
|
||||
// f_type = args_default_fake_type(section);
|
||||
// // f_type.strategy.strategy = FAKE_STRAT_RAND_SEQ;
|
||||
// // f_type.strategy.randseq_offset = 0;
|
||||
// f_type.fake_data += 1;
|
||||
// f_type.fake_len -= 1;
|
||||
|
||||
post_fake_sni(f_type, iph, iph_len, tcph, tcph_len);
|
||||
}
|
||||
|
||||
size_t ipd_offset;
|
||||
@@ -653,6 +666,7 @@ send_fake:
|
||||
struct tcphdr *tcph;
|
||||
ret = tcp_payload_split(frag2, f2len, &iph, &iphfl, &tcph, &tcphfl, NULL, NULL);
|
||||
struct fake_type f_type = args_default_fake_type(section);
|
||||
|
||||
if ((f_type.strategy.strategy & FAKE_STRAT_PAST_SEQ) == FAKE_STRAT_PAST_SEQ) {
|
||||
f_type.strategy.strategy ^= FAKE_STRAT_PAST_SEQ;
|
||||
f_type.strategy.strategy |= FAKE_STRAT_RAND_SEQ;
|
||||
@@ -704,71 +718,68 @@ int post_fake_sni(struct fake_type f_type,
|
||||
void *fsiph = (void *)rfsiph;
|
||||
struct tcphdr *fstcph = (void *)rfstcph;
|
||||
|
||||
ITER_FAKE_STRAT(f_type.strategy.strategy, strategy) {
|
||||
struct fake_type fake_seq_type = f_type;
|
||||
fake_seq_type.strategy.strategy = strategy;
|
||||
struct fake_type fake_seq_type = f_type;
|
||||
|
||||
// one goes for default fake
|
||||
for (int i = 0; i < fake_seq_type.sequence_len; i++) {
|
||||
uint8_t *fake_sni;
|
||||
size_t fake_sni_len;
|
||||
|
||||
ret = gen_fake_sni(
|
||||
fake_seq_type,
|
||||
fsiph, iph_len, fstcph, tcph_len,
|
||||
&fake_sni, &fake_sni_len);
|
||||
if (ret < 0) {
|
||||
lgerror(ret, "gen_fake_sni");
|
||||
return ret;
|
||||
}
|
||||
|
||||
lgtrace_addp("post fake sni #%d", i + 1);
|
||||
|
||||
if (f_type.seg2delay) {
|
||||
ret = instance_config.send_delayed_packet(fake_sni, fake_sni_len, f_type.seg2delay);
|
||||
} else {
|
||||
ret = instance_config.send_raw_packet(fake_sni, fake_sni_len);
|
||||
}
|
||||
if (ret < 0) {
|
||||
lgerror(ret, "send fake sni");
|
||||
goto erret_lc;
|
||||
}
|
||||
size_t iph_len;
|
||||
size_t tcph_len;
|
||||
size_t plen;
|
||||
ret = tcp_payload_split(
|
||||
fake_sni, fake_sni_len,
|
||||
&fsiph, &iph_len,
|
||||
&fstcph, &tcph_len,
|
||||
NULL, &plen);
|
||||
|
||||
if (ret < 0) {
|
||||
lgtrace_addp("continue fake seq");
|
||||
goto erret_lc;
|
||||
}
|
||||
|
||||
|
||||
if (!(strategy == FAKE_STRAT_PAST_SEQ ||
|
||||
strategy == FAKE_STRAT_RAND_SEQ)) {
|
||||
fstcph->seq = htonl(ntohl(fstcph->seq) + plen);
|
||||
}
|
||||
|
||||
if (ipxv == IP4VERSION) {
|
||||
((struct iphdr *)fsiph)->id = htons(ntohs(((struct iphdr *)fsiph)->id) + 1);
|
||||
}
|
||||
|
||||
memcpy(rfsiph, fsiph, iph_len);
|
||||
|
||||
memcpy(rfstcph, fstcph, tcph_len);
|
||||
fsiph = (void *)rfsiph;
|
||||
fstcph = (void *)rfstcph;
|
||||
|
||||
free(fake_sni);
|
||||
continue;
|
||||
erret_lc:
|
||||
free(fake_sni);
|
||||
// one goes for default fake
|
||||
for (int i = 0; i < fake_seq_type.sequence_len; i++) {
|
||||
uint8_t *fake_sni;
|
||||
size_t fake_sni_len;
|
||||
|
||||
ret = gen_fake_sni(
|
||||
fake_seq_type,
|
||||
fsiph, iph_len, fstcph, tcph_len,
|
||||
&fake_sni, &fake_sni_len);
|
||||
if (ret < 0) {
|
||||
lgerror(ret, "gen_fake_sni");
|
||||
return ret;
|
||||
}
|
||||
|
||||
lgtrace_addp("post fake sni #%d", i + 1);
|
||||
|
||||
if (f_type.seg2delay) {
|
||||
ret = instance_config.send_delayed_packet(fake_sni, fake_sni_len, f_type.seg2delay);
|
||||
} else {
|
||||
ret = instance_config.send_raw_packet(fake_sni, fake_sni_len);
|
||||
}
|
||||
if (ret < 0) {
|
||||
lgerror(ret, "send fake sni");
|
||||
goto erret_lc;
|
||||
}
|
||||
size_t iph_len;
|
||||
size_t tcph_len;
|
||||
size_t plen;
|
||||
ret = tcp_payload_split(
|
||||
fake_sni, fake_sni_len,
|
||||
&fsiph, &iph_len,
|
||||
&fstcph, &tcph_len,
|
||||
NULL, &plen);
|
||||
|
||||
if (ret < 0) {
|
||||
lgtrace_addp("continue fake seq");
|
||||
goto erret_lc;
|
||||
}
|
||||
|
||||
|
||||
if (!(CHECK_BITFIELD(f_type.strategy.strategy, FAKE_STRAT_PAST_SEQ) ||
|
||||
CHECK_BITFIELD(f_type.strategy.strategy, FAKE_STRAT_RAND_SEQ))) {
|
||||
fstcph->seq = htonl(ntohl(fstcph->seq) + plen);
|
||||
}
|
||||
|
||||
if (ipxv == IP4VERSION) {
|
||||
((struct iphdr *)fsiph)->id = htons(ntohs(((struct iphdr *)fsiph)->id) + 1);
|
||||
}
|
||||
|
||||
memcpy(rfsiph, fsiph, iph_len);
|
||||
|
||||
memcpy(rfstcph, fstcph, tcph_len);
|
||||
fsiph = (void *)rfsiph;
|
||||
fstcph = (void *)rfstcph;
|
||||
|
||||
free(fake_sni);
|
||||
continue;
|
||||
erret_lc:
|
||||
free(fake_sni);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -5,6 +5,5 @@
|
||||
|
||||
static const char fake_sni[] = "\026\003\001\002\000\001\000\001\374\003\003\323[\345\201f\362\200:B\356Uq\355X\315i\235*\021\367\331\272\a>\233\254\355\307/\342\372\265 \275\2459l&r\222\313\361\3729`\376\256\233\333O\001\373\33050\r\260f,\231\035 \324^\000>\023\002\023\003\023\001\300,\3000\000\237\314\251\314\250\314\252\300+\300/\000\236\300$\300(\000k\300#\300'\000g\300\n\300\024\0009\300\t\300\023\0003\000\235\000\234\000=\000<\0005\000/\000\377\001\000\001u\000\000\000\023\000\021\000\000\016www.google.com\000\v\000\004\003\000\001\002\000\n\000\026\000\024\000\035\000\027\000\036\000\031\000\030\001\000\001\001\001\002\001\003\001\004\000\020\000\016\000\f\002h2\bhttp/1.1\000\026\000\000\000\027\000\000\0001\000\000\000\r\0000\000.\004\003\005\003\006\003\b\a\b\b\b\032\b\033\b\034\b\t\b\n\b\v\b\004\b\005\b\006\004\001\005\001\006\001\003\003\003\001\003\002\004\002\005\002\006\002\000+\000\005\004\003\004\003\003\000-\000\002\001\001\0003\000&\000$\000\035\000 \004\224\206\021\256\f\222\266\3435\216\202\342\2573\341\3503\2107\341\023\016\240r|6\000^K\310s\000\025\000\255\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000";
|
||||
|
||||
static const char fake_sni_old[] = "\026\003\001\004\316\001\000\004\312\003\003K+\272\314\340\306\374>dw%\f\223\346\225\270\270~\335\027\f\264\341H\267\357\303\216T\322[\371 \245\320\212V6\374\3706\232\0216B\325\273P\b\300>\0332>\362\323\033\322\301\204\022f8\223\214\000\"\023\001\023\003\023\002\300+\300/\314\251\314\250\300,\3000\300\n\300\t\300\023\300\024\000\234\000\235\000/\0005\001\000\004_\000\000\000\023\000\021\000\000\016www.google.com\000\027\000\000\377\001\000\001\000\000\n\000\016\000\f\000\035\000\027\000\030\000\031\001\000\001\001\000\v\000\002\001\000\000\020\000\v\000\t\bhttp/1.1\000\005\000\005\001\000\000\000\000\000\"\000\n\000\b\004\003\005\003\006\003\002\003\0003\000k\000i\000\035\000 \333C\212\234-\t\237#\202\\\231\311\022]\333\341t(\t\276U\373u\234\316J~,^|*Z\000\027\000A\004k\n\255\254\376X\226t\001;n~\033\034.\245\027\024\3762_\352$\374\346^f\fF,\201\275\263\336O\231\001\032\200\357dI\266y\031\323\311vR\232\004\r\366FT\004\335\326\356\256\230B\t\313\000*\000\000\000+\000\005\004\003\004\003\003\000\r\000\030\000\026\004\003\005\003\006\003\b\004\b\005\b\006\004\001\005\001\006\001\002\003\002\001\000-\000\002\001\001\000\034\000\002@\001\376\r\0029\000\000\001\000\003\344\000 \337\306\243\332Y\033\a\252\352\025\365Z\035\223\226\304\255\363\215G\356g\344%}7\217\033n\211^\201\002\017g\267\334\326OD}\336\341ZC\230\226'\225\313\357\211\\\242\273\030k\216\377U\315\206\2410\200\203\332Z\223\005\370\b\304\370f\017\200\023\241\223~?\270{\037b\312\001\270\227\366\356\352\002\314\351\006\237\241q\226\300\314\321o\247{\201\317\230}B\005T\3660\335\320\332r?S\217\tq\036\031\326I|\237]\311 c\f\024r\031\310W\373\257\314q)q\030\237\261\227\217Kd?\257'G\320\020\340\256ND\247\005\341\324\024OP>\370\350\270b\311wAj\t\311\213\365i\203\230x\207\354\245<\274\202\230c\v0Y\263\364\022\303a\200\022\031\314\271rl=\327\336\001\327\264\267\342\353\352=\354[u\224\260\257\034\004\232\023\226}\227\030e\221\"\350\207\027dId\324\305\362N:\035\307`\204\337\201;\221\320\266b\362hrH\345e\206\246%\006\020a4\3430\036\225\215\274\275\360Q&\271\237)\222uK\362\017o\220\226W\357\267#\357\v\023\354\213\2629\331\ad\005/~6k\000[\247\301\270\310qJ\004\303|m5\363\376Y\002\243}6\251x\024\331)GH\335\205rI\032\f\210\a\212\347]\271\030\347.\021\213\365\026\030\340/Ny\r\332\3577\3203\026iX}>\2507\327&XRXU!\017\270I\313\352\350^?\352Uss\017\266pF\222NI\245\307_\305#\361\352\243+-\266\317Q\036s\243\277\355{S&\023>\275\360\215\032V\237XOY\345u>\002\305\252T\354\035\327v{P\352M\233\366\221\270\377\251\261f+rF\201wL2W\266X\252\242X\2536I\337c\205uZ\254Fe\305h\t\371\376\216r\336Y\327h\347*\331\257-ZQ{(\336\226\206\017\037\036\021\341\027z\033\254\235\252\227\224\004?p\243\351\\\263\352\205\327#W\345\255\256\375\267bP\3047\363!*K\003t\212(\306\214P\215\3506j\025\375\213e\254s\000)\001\034\000\367\000\361\002\276W%\232?\326\223\277\211v\017\a\361\347\312N\226\024L\260v\210\271j\324[|\270\344\3773\321-\313b>~\310\253XIR\324)&;\033{g;)\344\255\226\370\347I\\y\020\324\360\211vC\310\226s\267|\273$\341\332\2045qh\245w\2255\214\316\030\255\301\326C\343\304=\245\231h`yd\000#s\002\370\374Z\0336\245\361\226\222\306\032k\2457\016h\314(R;\326T~EHH\352\307\023^\247\363\321`V\340\253Z\233\357\227I\373\337z\177\nv\261\252\371\017\226\223\345\005\315y4\b\236N0\2630\017\215c\305&L\260\346J\237\203Q(\335W\027|>\3553\275j\307?W5\3463kc\350\262C\361 \037w!\371}\214\"I\377|\331@a;\342\3566\312\272Z\327u7\204'\215YBLL\235\236\242\345\215\245T\211a\312\263\342\000! \221\202X$\302\317\203\246\207c{\231\330\264\324\\k\271\272\336\356\002|\261O\207\030+\367P\317\356";
|
||||
|
||||
#endif /*RAW_REPLACEMENTS_H*/
|
||||
|
||||
@@ -111,6 +111,9 @@ free((item)); \
|
||||
|
||||
#ifndef KERNEL_SPACE
|
||||
|
||||
|
||||
#define CHECK_BITFIELD(value, field) (((value) & (field)) == (field))
|
||||
|
||||
#define max(a,b)__extension__\
|
||||
({ \
|
||||
__typeof__ (a) _a = (a); \
|
||||
|
||||
78
src/utils.c
78
src/utils.c
@@ -616,6 +616,15 @@ struct tcp_md5sig_opt {
|
||||
// Real length of the option, with NOOP fillers
|
||||
#define TCP_MD5SIG_OPT_RLEN 20
|
||||
|
||||
#define TCP_TS_OPT_KIND 0x08
|
||||
struct tcp_ts_opt {
|
||||
uint8_t kind;
|
||||
uint8_t len;
|
||||
uint32_t ts_val;
|
||||
uint32_t ts_echo;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
int fail_packet(struct failing_strategy strategy, uint8_t *payload, size_t *plen, size_t avail_buflen) {
|
||||
void *iph;
|
||||
size_t iph_len;
|
||||
@@ -636,18 +645,22 @@ int fail_packet(struct failing_strategy strategy, uint8_t *payload, size_t *plen
|
||||
}
|
||||
|
||||
|
||||
if (strategy.strategy == FAKE_STRAT_RAND_SEQ) {
|
||||
if (CHECK_BITFIELD(strategy.strategy, FAKE_STRAT_RAND_SEQ)) {
|
||||
lgtrace_wr("fake seq: %u -> ", ntohl(tcph->seq));
|
||||
|
||||
tcph->seq = htonl(ntohl(tcph->seq) - (strategy.randseq_offset + dlen));
|
||||
|
||||
lgtrace_addp("%u", ntohl(tcph->seq));
|
||||
} else if (strategy.strategy == FAKE_STRAT_PAST_SEQ) {
|
||||
}
|
||||
|
||||
if (CHECK_BITFIELD(strategy.strategy, FAKE_STRAT_PAST_SEQ)) {
|
||||
lgtrace_wr("fake seq: %u -> ", ntohl(tcph->seq));
|
||||
tcph->seq = htonl(ntohl(tcph->seq) - dlen);
|
||||
lgtrace_addp("%u", ntohl(tcph->seq));
|
||||
|
||||
} else if (strategy.strategy == FAKE_STRAT_TTL) {
|
||||
}
|
||||
|
||||
if (CHECK_BITFIELD(strategy.strategy, FAKE_STRAT_TTL)) {
|
||||
lgtrace_addp("set fake ttl to %d", strategy.faking_ttl);
|
||||
|
||||
if (ipxv == IP4VERSION) {
|
||||
@@ -658,7 +671,9 @@ int fail_packet(struct failing_strategy strategy, uint8_t *payload, size_t *plen
|
||||
lgerror(-EINVAL, "fail_packet: IP version is unsupported");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (strategy.strategy == FAKE_STRAT_TCP_MD5SUM) {
|
||||
}
|
||||
|
||||
if (CHECK_BITFIELD(strategy.strategy, FAKE_STRAT_TCP_MD5SUM)) {
|
||||
int optp_len = tcph_len - sizeof(struct tcphdr);
|
||||
int delta = TCP_MD5SIG_OPT_RLEN - optp_len;
|
||||
lgtrace_addp("Incr delta %d: %d -> %d", delta, optp_len, optp_len + delta);
|
||||
@@ -673,9 +688,11 @@ int fail_packet(struct failing_strategy strategy, uint8_t *payload, size_t *plen
|
||||
tcph_len = tcph_len + delta;
|
||||
tcph->doff = tcph_len >> 2;
|
||||
if (ipxv == IP4VERSION) {
|
||||
((struct iphdr *)iph)->tot_len = htons(ntohs(((struct iphdr *)iph)->tot_len) + delta);
|
||||
((struct iphdr *)iph)->tot_len =
|
||||
htons(ntohs(((struct iphdr *)iph)->tot_len) + delta);
|
||||
} else if (ipxv == IP6VERSION) {
|
||||
((struct ip6_hdr *)iph)->ip6_plen = htons(ntohs(((struct ip6_hdr *)iph)->ip6_plen) + delta);
|
||||
((struct ip6_hdr *)iph)->ip6_plen =
|
||||
htons(ntohs(((struct ip6_hdr *)iph)->ip6_plen) + delta);
|
||||
} else {
|
||||
lgerror(-EINVAL, "fail_packet: IP version is unsupported");
|
||||
return -EINVAL;
|
||||
@@ -697,6 +714,53 @@ int fail_packet(struct failing_strategy strategy, uint8_t *payload, size_t *plen
|
||||
}
|
||||
}
|
||||
|
||||
if (CHECK_BITFIELD(strategy.strategy, FAKE_STRAT_TCP_TS)) {
|
||||
int optp_len = tcph_len - sizeof(struct tcphdr);
|
||||
uint8_t *optp = (uint8_t *)tcph + sizeof(struct tcphdr);
|
||||
|
||||
uint8_t *tcp_ts = NULL;
|
||||
|
||||
while (optp_len && *optp != 0x00) {
|
||||
if (*optp == 0x01) {
|
||||
optp_len--;
|
||||
optp++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (optp_len < 2) {
|
||||
lgerr("Tcp option parsing failed");
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t len = optp[1];
|
||||
if (len > optp_len) {
|
||||
lgerr("Tcp option parsing failed");
|
||||
break;
|
||||
}
|
||||
|
||||
if (*optp == 0x08) {
|
||||
tcp_ts = optp;
|
||||
break;
|
||||
}
|
||||
|
||||
optp_len -= len;
|
||||
optp += len;
|
||||
}
|
||||
|
||||
if (tcp_ts) {
|
||||
struct tcp_ts_opt *ts_opt = (void *)tcp_ts;
|
||||
uint32_t old_ts = ntohl(ts_opt->ts_val);
|
||||
ts_opt->ts_val = htonl(ntohl(ts_opt->ts_val) -
|
||||
strategy.faking_timestamp_decrease);
|
||||
uint32_t new_ts = ntohl(ts_opt->ts_val);
|
||||
|
||||
lgtrace_addp( "Fake TCP TimeStamp %u -> %u", old_ts, new_ts);
|
||||
} else {
|
||||
lgtrace_addp( "Fake TCP TimeStamp was not fullfilled: "
|
||||
"the option does not present");
|
||||
}
|
||||
}
|
||||
|
||||
if (ipxv == IP4VERSION) {
|
||||
((struct iphdr *)iph)->frag_off = 0;
|
||||
}
|
||||
@@ -705,7 +769,7 @@ int fail_packet(struct failing_strategy strategy, uint8_t *payload, size_t *plen
|
||||
set_ip_checksum(iph, iph_len);
|
||||
set_tcp_checksum(tcph, iph, iph_len);
|
||||
|
||||
if (strategy.strategy == FAKE_STRAT_TCP_CHECK) {
|
||||
if (CHECK_BITFIELD(strategy.strategy, FAKE_STRAT_TCP_CHECK)) {
|
||||
lgtrace_addp("break fake tcp checksum");
|
||||
tcph->check += 1;
|
||||
}
|
||||
|
||||
@@ -133,6 +133,7 @@ void shift_data(uint8_t *data, size_t dlen, size_t delta);
|
||||
struct failing_strategy {
|
||||
unsigned int strategy;
|
||||
uint8_t faking_ttl;
|
||||
uint32_t faking_timestamp_decrease;
|
||||
size_t randseq_offset;
|
||||
};
|
||||
|
||||
@@ -197,7 +198,8 @@ static inline struct failing_strategy args_default_failing_strategy(const struct
|
||||
struct failing_strategy fl_strat = {
|
||||
.strategy = (unsigned int)section->faking_strategy,
|
||||
.faking_ttl = section->faking_ttl,
|
||||
.randseq_offset = (size_t)section->fakeseq_offset
|
||||
.faking_timestamp_decrease = section->faking_timestamp_decrease,
|
||||
.randseq_offset = (size_t)section->fakeseq_offset,
|
||||
};
|
||||
return fl_strat;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user