From b434ef4b7f6fcd63e7443572e1fa2b822d88706f Mon Sep 17 00:00:00 2001 From: Vadim Vetrov Date: Sat, 17 Aug 2024 12:51:53 +0300 Subject: [PATCH] Add compatibility with v0.2.2 --- README.md | 4 ++++ args.c | 32 +++++++++++++++++++++++++++++--- config.h | 2 ++ mangle.c | 41 +++++++++++++++++++++++++++++++++++++---- raw_replacements.h | 2 ++ 5 files changed, 74 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 8472cba..7753890 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,10 @@ Available flags: - `--frag-sni-faked={0|1}` Specifies **youtubeUnblock** to send fake packets near *ClientHello* (fills payload with zeroes). Defaults to **0**. +- `--frag-middle-sni={0|1}` With this options **youtubeUnblock** will split the packet in the middle of SNI data. Defaults to 1. + +- `--frag-sni-pos=` With this option **youtubeUnblock** will split the packet at the position pos. Defaults to 2. + - `--quic-drop` Drop all QUIC packets which goes to youtubeUnblock. Won't affect any other UDP packets. Suitable for some TVs. Note, that for this option to work you should also add proxy udp to youtubeUnblock in firewall. `connbytes` may also be used with udp. - `--fk-winsize=` Specifies window size for the fragmented TCP packet. Applicable if you want for response to be fragmented. May slowdown connection initialization. diff --git a/args.c b/args.c index 9876cae..b69e0ce 100644 --- a/args.c +++ b/args.c @@ -18,6 +18,8 @@ struct config_t config = { .faking_ttl = FAKE_TTL, .fake_sni = 1, .fake_sni_seq_len = 1, + .frag_middle_sni = 1, + .frag_sni_pos = 2, .sni_detection = SNI_DETECTION_PARSE, @@ -43,8 +45,8 @@ struct config_t config = { .domains_strlen = sizeof(defaul_snistr), .queue_start_num = DEFAULT_QUEUE_NUM, - .fake_sni_pkt = fake_sni, - .fake_sni_pkt_sz = sizeof(fake_sni) - 1, // - 1 for null-terminator + .fake_sni_pkt = fake_sni_old, + .fake_sni_pkt_sz = sizeof(fake_sni_old) - 1, // - 1 for null-terminator }; #define OPT_SNI_DOMAINS 1 @@ -55,6 +57,8 @@ struct config_t config = { #define OPT_FRAG 4 #define OPT_FRAG_SNI_REVERSE 12 #define OPT_FRAG_SNI_FAKED 13 +#define OPT_FRAG_MIDDLE_SNI 18 +#define OPT_FRAG_SNI_POS 19 #define OPT_FK_WINSIZE 14 #define OPT_TRACE 15 #define OPT_QUIC_DROP 16 @@ -65,7 +69,7 @@ struct config_t config = { #define OPT_NO_GSO 8 #define OPT_QUEUE_NUM 9 -#define OPT_MAX OPT_QUIC_DROP +#define OPT_MAX OPT_FRAG_SNI_POS static struct option long_opt[] = { {"help", 0, 0, 'h'}, @@ -78,6 +82,8 @@ static struct option long_opt[] = { {"frag", 1, 0, OPT_FRAG}, {"frag-sni-reverse", 1, 0, OPT_FRAG_SNI_REVERSE}, {"frag-sni-faked", 1, 0, OPT_FRAG_SNI_FAKED}, + {"frag-middle-sni", 1, 0, OPT_FRAG_MIDDLE_SNI}, + {"frag-sni-pos", 1, 0, OPT_FRAG_SNI_POS}, {"fk-winsize", 1, 0, OPT_FK_WINSIZE}, {"quic-drop", 0, 0, OPT_QUIC_DROP}, {"sni-detection", 1, 0, OPT_SNI_DETECTION}, @@ -128,6 +134,8 @@ void print_usage(const char *argv0) { printf("\t--frag={tcp,ip,none}\n"); printf("\t--frag-sni-reverse={0|1}\n"); printf("\t--frag-sni-faked={0|1}\n"); + printf("\t--frag-middle-sni={0|1}\n"); + printf("\t--frag-sni-pos=\n"); printf("\t--fk-winsize=\n"); printf("\t--quic-drop\n"); printf("\t--sni-detection={parse|brute}\n"); @@ -213,6 +221,24 @@ int parse_args(int argc, char *argv[]) { goto invalid_opt; } + break; + case OPT_FRAG_MIDDLE_SNI: + if (strcmp(optarg, "1") == 0) { + config.frag_middle_sni = 1; + } else if (strcmp(optarg, "0") == 0) { + config.frag_middle_sni = 0; + } else { + goto invalid_opt; + } + + break; + case OPT_FRAG_SNI_POS: + num = parse_numeric_option(optarg); + if (errno != 0 || num < 0) { + goto invalid_opt; + } + + config.frag_sni_pos = num; break; case OPT_FAKING_STRATEGY: if (strcmp(optarg, "randseq") == 0) { diff --git a/config.h b/config.h index b3e6a42..beb08f4 100644 --- a/config.h +++ b/config.h @@ -22,6 +22,8 @@ struct config_t { int frag_sni_reverse; int frag_sni_faked; int faking_strategy; + int frag_middle_sni; + int frag_sni_pos; unsigned char faking_ttl; int fake_sni; unsigned int fake_sni_seq_len; diff --git a/mangle.c b/mangle.c index bac5561..bfb1932 100644 --- a/mangle.c +++ b/mangle.c @@ -106,9 +106,24 @@ int process_tcp4_packet(const uint8_t *raw_payload, uint32_t raw_payload_len) { ipd_offset = vrd.sni_offset; mid_offset = ipd_offset + vrd.sni_len / 2; - uint32_t poses[] = { 2, mid_offset }; + uint32_t poses[2]; + int cnt = 0; - ret = send_tcp4_frags(payload, payload_len, poses, 2, 0); + if (config.frag_sni_pos && dlen > config.frag_sni_pos) { + poses[cnt++] = config.frag_sni_pos; + } + + if (config.frag_middle_sni) { + poses[cnt++] = mid_offset; + } + + if (cnt > 1 && poses[0] > poses[1]) { + uint32_t tmp = poses[0]; + poses[0] = poses[1]; + poses[1] = tmp; + } + + ret = send_tcp4_frags(payload, payload_len, poses, cnt, 0); if (ret < 0) { lgerror("tcp4 send frags", ret); goto accept; @@ -122,8 +137,26 @@ int process_tcp4_packet(const uint8_t *raw_payload, uint32_t raw_payload_len) { mid_offset = ipd_offset + vrd.sni_len / 2; mid_offset += 8 - mid_offset % 8; - uint32_t poses[] = { mid_offset }; - ret = send_ip4_frags(payload, payload_len, poses, 1, 0); + uint32_t poses[2]; + int cnt = 0; + + if (config.frag_sni_pos && dlen > config.frag_sni_pos) { + poses[cnt] = config.frag_sni_pos + ((char *)data - (char *)tcph); + poses[cnt] += 8 - poses[cnt] % 8; + cnt++; + } + + if (config.frag_middle_sni) { + poses[cnt++] = mid_offset; + } + + if (cnt > 1 && poses[0] > poses[1]) { + uint32_t tmp = poses[0]; + poses[0] = poses[1]; + poses[1] = tmp; + } + + ret = send_ip4_frags(payload, payload_len, poses, cnt, 0); if (ret < 0) { lgerror("ip4 send frags", ret); goto accept; diff --git a/raw_replacements.h b/raw_replacements.h index 5bc5a08..4123bd8 100644 --- a/raw_replacements.h +++ b/raw_replacements.h @@ -5,4 +5,6 @@ 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*/