UDP desync: fake

This commit is contained in:
ruti 2023-07-07 22:07:27 +02:00
parent 3ede6651f4
commit 922ed35310
7 changed files with 91 additions and 22 deletions

View File

@ -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; int pos = params.split;
char *host = 0; char *host = 0;
int len = 0, type = 0; int len = 0, type = 0;
int fa = dst->sa_family;
struct sockaddr sa;
socklen_t alen = sizeof(sa);
if (getsockname(sfd, &sa, &alen)) {
perror("getsockname");
return -1;
}
int fa = sa.sa_family;
if ((len = parse_tls(buffer, n, &host))) { if ((len = parse_tls(buffer, n, &host))) {
type = IS_HTTPS; type = IS_HTTPS;
@ -185,3 +178,35 @@ int desync(int sfd, char *buffer, ssize_t n)
} }
return 0; 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;
}

View File

@ -1 +1,2 @@
int desync(int sfd, char *buffer, ssize_t n); 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);

40
main.c
View File

@ -20,14 +20,19 @@ struct packet fake_tls = {
}, },
fake_http = { fake_http = {
sizeof(http_data), http_data sizeof(http_data), http_data
},
fake_udp = {
sizeof(udp_data), udp_data
}; };
struct params params = { struct params params = {
.ttl = 8, .ttl = 8,
.split = 3, .split = 3,
.sfdelay = 3000, .sfdelay = 3000,
.attack = DESYNC_NONE, .attack = DESYNC_NONE,
.desync_udp = 0,
.split_host = 0, .split_host = 0,
.def_ttl = 0, .def_ttl = 0,
.mod_http = 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; char *buffer = 0;
long size;
FILE *file = fopen(name, "rb"); FILE *file = fopen(name, "rb");
if (!file) if (!file)
@ -55,7 +61,7 @@ char *ftob(char *name)
if (fseek(file, 0, SEEK_END)) { if (fseek(file, 0, SEEK_END)) {
break; break;
} }
long size = ftell(file); size = ftell(file);
if (!size || fseek(file, 0, SEEK_SET)) { if (!size || fseek(file, 0, SEEK_SET)) {
break; break;
} }
@ -67,6 +73,9 @@ char *ftob(char *name)
buffer = 0; buffer = 0;
} }
} while (0); } while (0);
if (buffer) {
*sl = size;
}
fclose(file); fclose(file);
return buffer; return buffer;
} }
@ -122,9 +131,11 @@ int main(int argc, char **argv)
" -H, --split-at-host Add Host/SNI offset to split position\n" " -H, --split-at-host Add Host/SNI offset to split position\n"
" -t, --ttl <num> TTL of fake packets, default 8\n" " -t, --ttl <num> TTL of fake packets, default 8\n"
" -l, --fake-tls <file>\n" " -l, --fake-tls <file>\n"
" -o, --fake-http <file> Set custom fake packet\n" " -o, --fake-http <file>\n"
" -e, --fake-udp <file> Set custom fake packet\n"
" -n, --tls-sni <str> Change SNI in fake CH\n" " -n, --tls-sni <str> Change SNI in fake CH\n"
" -M, --mod-http <h,d,r> Modify http: hcsmix,dcsmix,rmspace\n" " -M, --mod-http <h,d,r> Modify http: hcsmix,dcsmix,rmspace\n"
" -u, --desync-udp <f> UDP desync method: fake\n"
}; };
const struct option options[] = { const struct option options[] = {
@ -147,8 +158,10 @@ int main(int argc, char **argv)
{"ttl", 1, 0, 't'}, {"ttl", 1, 0, 't'},
{"fake-tls", 1, 0, 'l'}, {"fake-tls", 1, 0, 'l'},
{"fake-http", 1, 0, 'o'}, {"fake-http", 1, 0, 'o'},
{"fake-udp", 1, 0, 'e'},
{"tls-sni", 1, 0, 'n'}, {"tls-sni", 1, 0, 'n'},
{"mod-http", 1, 0, 'M'}, {"mod-http", 1, 0, 'M'},
{"desync-udp", 1, 0, 'u'},
{"global-ttl", 1, 0, 'g'}, // {"global-ttl", 1, 0, 'g'}, //
{"delay", 1, 0, 'w'}, // {"delay", 1, 0, 'w'}, //
{"debug", 1, 0, 'x'}, // {"debug", 1, 0, 'x'}, //
@ -162,7 +175,7 @@ int main(int argc, char **argv)
char *end = 0; char *end = 0;
while (!invalid && (rez = getopt_long_only(argc, argv, 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) { switch (rez) {
case 'D': case 'D':
@ -283,7 +296,7 @@ int main(int argc, char **argv)
break; break;
case 'l': case 'l':
fake_tls.data = ftob(optarg); fake_tls.data = ftob(optarg, &fake_tls.size);
if (!fake_tls.data) { if (!fake_tls.data) {
perror("read file"); perror("read file");
return -1; return -1;
@ -291,13 +304,21 @@ int main(int argc, char **argv)
break; break;
case 'o': case 'o':
fake_http.data = ftob(optarg); fake_http.data = ftob(optarg, &fake_http.size);
if (!fake_http.data) { if (!fake_http.data) {
perror("read file"); perror("read file");
return -1; return -1;
} }
break; break;
case 'e':
fake_udp.data = ftob(optarg, &fake_udp.size);
if (!fake_udp.data) {
perror("read file");
return -1;
}
break;
case 'M': case 'M':
end = optarg; end = optarg;
while (end && !invalid) { while (end && !invalid) {
@ -320,6 +341,13 @@ int main(int argc, char **argv)
} }
break; break;
case 'u':
if (*optarg != 'f')
invalid = 1;
else
params.desync_udp = DESYNC_UDP_FAKE;
break;
case 'g': // case 'g': //
val = strtol(optarg, &end, 0); val = strtol(optarg, &end, 0);
if (val <= 0 || val > 255 || *end) if (val <= 0 || val > 255 || *end)

View File

@ -47,6 +47,8 @@ char http_data[43] = {
"Host: www.wikipedia.org\r\n\r\n" "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) int find_tls_ext_offset(uint16_t type, char *data, size_t size)
{ {

View File

@ -11,6 +11,7 @@
extern char tls_data[517]; extern char tls_data[517];
extern char http_data[43]; extern char http_data[43];
extern char udp_data[64];
int change_tls_sni(char *host, char *buffer, size_t bsize); int change_tls_sni(char *host, char *buffer, size_t bsize);

View File

@ -7,11 +7,14 @@ enum demode {
DESYNC_FAKE DESYNC_FAKE
}; };
#define DESYNC_UDP_FAKE 1
struct params { struct params {
int ttl; int ttl;
int split; int split;
size_t sfdelay; size_t sfdelay;
enum demode attack; enum demode attack;
int desync_udp;
char split_host; char split_host;
int def_ttl; int def_ttl;
int mod_http; int mod_http;
@ -30,11 +33,12 @@ struct params {
extern struct params params; extern struct params params;
struct packet { struct packet {
size_t size; ssize_t size;
char *data; char *data;
}; };
extern struct packet fake_tls; extern struct packet fake_tls;
extern struct packet fake_http; extern struct packet fake_http;
extern struct packet fake_udp;
#define LOG_S 1 #define LOG_S 1
#define LOG_L 2 #define LOG_L 2

12
proxy.c
View File

@ -502,7 +502,8 @@ static inline int on_data(struct eval *val, char *buffer, size_t bfsize)
if (n) perror("recv data"); if (n) perror("recv data");
return -1; return -1;
} }
if (desync(val->pair->fd, buffer, n)) { if (desync(val->pair->fd, buffer,
n, (struct sockaddr *)&val->in6)) {
return -1; return -1;
} }
val->type = EV_TUNNEL; val->type = EV_TUNNEL;
@ -633,8 +634,15 @@ int on_udp_tunnel(struct eval *val, char *buffer, size_t bfsize)
return -1; return -1;
} }
map_fix(&addr, 6); map_fix(&addr, 6);
if ((val->flag & FLAG_CONN))
ns = sendto(val->fd, ns = sendto(val->fd,
buffer + skip + offs, n - offs, 0, &addr.sa, asz); 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 { } else {
map_fix(&addr, 0); map_fix(&addr, 0);
offs = s_set_addr(buffer + skip, skip, &addr, 1); 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, ns = sendto(val->fd, buffer + skip - offs,
n + offs, 0, (struct sockaddr *)&val->in6, sizeof(val->in6)); n + offs, 0, (struct sockaddr *)&val->in6, sizeof(val->in6));
} }
if (ns <= 0) { if (ns < 0) {
perror("sendto"); perror("sendto");
return -1; return -1;
} }