diff --git a/desync.c b/desync.c index 3196a4e..e7cb780 100644 --- a/desync.c +++ b/desync.c @@ -119,20 +119,13 @@ int disorder_attack(int sfd, char *buffer, ssize_t n, int pos, int fa) } -int desync(int sfd, char *buffer, ssize_t n) +int desync(int sfd, char *buffer, + ssize_t n, struct sockaddr *dst) { int pos = params.split; char *host = 0; int len = 0, type = 0; - - struct sockaddr sa; - socklen_t alen = sizeof(sa); - - if (getsockname(sfd, &sa, &alen)) { - perror("getsockname"); - return -1; - } - int fa = sa.sa_family; + int fa = dst->sa_family; if ((len = parse_tls(buffer, n, &host))) { type = IS_HTTPS; @@ -184,4 +177,36 @@ int desync(int sfd, char *buffer, ssize_t n) } } return 0; +} + + +int desync_udp(int fd, char *buffer, + ssize_t n, struct sockaddr_in6 *dst) +{ + if (params.desync_udp & DESYNC_UDP_FAKE) { + if (setttl(fd, params.ttl, AF_INET) < 0) { + return -1; + } + if (setttl(fd, params.ttl, AF_INET6) < 0) { + return -1; + } + if (sendto(fd, fake_udp.data, fake_udp.size, + 0, (struct sockaddr *)dst, sizeof(*dst)) < 0) { + perror("sendto"); + return -1; + } + if (setttl(fd, params.def_ttl, AF_INET) < 0) { + return -1; + } + if (setttl(fd, params.def_ttl, AF_INET6) < 0) { + return -1; + } + } + ssize_t ns = sendto(fd, + buffer, n, 0, (struct sockaddr *)dst, sizeof(*dst)); + if (ns < 0) { + perror("sendto"); + return -1; + } + return 0; } \ No newline at end of file diff --git a/desync.h b/desync.h index 3da3a27..f7ca096 100644 --- a/desync.h +++ b/desync.h @@ -1 +1,2 @@ -int desync(int sfd, char *buffer, ssize_t n); \ No newline at end of file +int desync(int sfd, char *buffer, ssize_t n, struct sockaddr *dst); +int desync_udp(int fd, char *buffer, ssize_t n, struct sockaddr_in6 *dst); \ No newline at end of file diff --git a/main.c b/main.c index 7d16e35..8f2086a 100644 --- a/main.c +++ b/main.c @@ -20,14 +20,19 @@ struct packet fake_tls = { }, fake_http = { sizeof(http_data), http_data +}, +fake_udp = { + sizeof(udp_data), udp_data }; + struct params params = { .ttl = 8, .split = 3, .sfdelay = 3000, .attack = DESYNC_NONE, + .desync_udp = 0, .split_host = 0, .def_ttl = 0, .mod_http = 0, @@ -44,9 +49,10 @@ struct params params = { }; -char *ftob(char *name) +char *ftob(char *name, ssize_t *sl) { char *buffer = 0; + long size; FILE *file = fopen(name, "rb"); if (!file) @@ -55,7 +61,7 @@ char *ftob(char *name) if (fseek(file, 0, SEEK_END)) { break; } - long size = ftell(file); + size = ftell(file); if (!size || fseek(file, 0, SEEK_SET)) { break; } @@ -67,6 +73,9 @@ char *ftob(char *name) buffer = 0; } } while (0); + if (buffer) { + *sl = size; + } fclose(file); return buffer; } @@ -122,9 +131,11 @@ int main(int argc, char **argv) " -H, --split-at-host Add Host/SNI offset to split position\n" " -t, --ttl TTL of fake packets, default 8\n" " -l, --fake-tls \n" - " -o, --fake-http Set custom fake packet\n" + " -o, --fake-http \n" + " -e, --fake-udp Set custom fake packet\n" " -n, --tls-sni Change SNI in fake CH\n" " -M, --mod-http Modify http: hcsmix,dcsmix,rmspace\n" + " -u, --desync-udp UDP desync method: fake\n" }; const struct option options[] = { @@ -147,8 +158,10 @@ int main(int argc, char **argv) {"ttl", 1, 0, 't'}, {"fake-tls", 1, 0, 'l'}, {"fake-http", 1, 0, 'o'}, + {"fake-udp", 1, 0, 'e'}, {"tls-sni", 1, 0, 'n'}, {"mod-http", 1, 0, 'M'}, + {"desync-udp", 1, 0, 'u'}, {"global-ttl", 1, 0, 'g'}, // {"delay", 1, 0, 'w'}, // {"debug", 1, 0, 'x'}, // @@ -162,7 +175,7 @@ int main(int argc, char **argv) char *end = 0; while (!invalid && (rez = getopt_long_only(argc, argv, - "DNXUKHhvf:i:p:b:B:c:m:s:t:l:o:n:M:g:w:x:", options, 0)) != -1) { + "DNXUKHhvf:i:p:b:B:c:m:s:t:l:o:e:n:M:u:g:w:x:", options, 0)) != -1) { switch (rez) { case 'D': @@ -283,7 +296,7 @@ int main(int argc, char **argv) break; case 'l': - fake_tls.data = ftob(optarg); + fake_tls.data = ftob(optarg, &fake_tls.size); if (!fake_tls.data) { perror("read file"); return -1; @@ -291,13 +304,21 @@ int main(int argc, char **argv) break; case 'o': - fake_http.data = ftob(optarg); + fake_http.data = ftob(optarg, &fake_http.size); if (!fake_http.data) { perror("read file"); return -1; } break; + case 'e': + fake_udp.data = ftob(optarg, &fake_udp.size); + if (!fake_udp.data) { + perror("read file"); + return -1; + } + break; + case 'M': end = optarg; while (end && !invalid) { @@ -320,6 +341,13 @@ int main(int argc, char **argv) } break; + case 'u': + if (*optarg != 'f') + invalid = 1; + else + params.desync_udp = DESYNC_UDP_FAKE; + break; + case 'g': // val = strtol(optarg, &end, 0); if (val <= 0 || val > 255 || *end) diff --git a/packets.c b/packets.c index efda598..6a7ac30 100644 --- a/packets.c +++ b/packets.c @@ -47,6 +47,8 @@ char http_data[43] = { "Host: www.wikipedia.org\r\n\r\n" }; +char udp_data[64] = {0}; + int find_tls_ext_offset(uint16_t type, char *data, size_t size) { diff --git a/packets.h b/packets.h index 8a16c60..9370cac 100644 --- a/packets.h +++ b/packets.h @@ -11,6 +11,7 @@ extern char tls_data[517]; extern char http_data[43]; +extern char udp_data[64]; int change_tls_sni(char *host, char *buffer, size_t bsize); diff --git a/params.h b/params.h index 73f8bc1..a1838ea 100644 --- a/params.h +++ b/params.h @@ -7,11 +7,14 @@ enum demode { DESYNC_FAKE }; +#define DESYNC_UDP_FAKE 1 + struct params { int ttl; int split; size_t sfdelay; enum demode attack; + int desync_udp; char split_host; int def_ttl; int mod_http; @@ -30,11 +33,12 @@ struct params { extern struct params params; struct packet { - size_t size; + ssize_t size; char *data; }; extern struct packet fake_tls; extern struct packet fake_http; +extern struct packet fake_udp; #define LOG_S 1 #define LOG_L 2 diff --git a/proxy.c b/proxy.c index 4f08bb5..0cba2bf 100644 --- a/proxy.c +++ b/proxy.c @@ -502,7 +502,8 @@ static inline int on_data(struct eval *val, char *buffer, size_t bfsize) if (n) perror("recv data"); return -1; } - if (desync(val->pair->fd, buffer, n)) { + if (desync(val->pair->fd, buffer, + n, (struct sockaddr *)&val->in6)) { return -1; } val->type = EV_TUNNEL; @@ -633,8 +634,15 @@ int on_udp_tunnel(struct eval *val, char *buffer, size_t bfsize) return -1; } map_fix(&addr, 6); - ns = sendto(val->fd, - buffer + skip + offs, n - offs, 0, &addr.sa, asz); + + if ((val->flag & FLAG_CONN)) + ns = sendto(val->fd, + buffer + skip + offs, n - offs, 0, &addr.sa, asz); + else { + ns = desync_udp(val->fd, + buffer + skip + offs, n - offs, &addr.in6); + val->flag |= FLAG_CONN; + } } else { map_fix(&addr, 0); offs = s_set_addr(buffer + skip, skip, &addr, 1); @@ -644,7 +652,7 @@ int on_udp_tunnel(struct eval *val, char *buffer, size_t bfsize) ns = sendto(val->fd, buffer + skip - offs, n + offs, 0, (struct sockaddr *)&val->in6, sizeof(val->in6)); } - if (ns <= 0) { + if (ns < 0) { perror("sendto"); return -1; }