diff --git a/desync.c b/desync.c index d305d86..7a1749d 100644 --- a/desync.c +++ b/desync.c @@ -365,13 +365,10 @@ ssize_t send_fake(int sfd, char *buffer, #endif ssize_t send_oob(int sfd, char *buffer, - ssize_t n, long pos) + ssize_t n, long pos, char *c) { - ssize_t size = oob_data.size - 1; - char *data = oob_data.data + 1; - char rchar = buffer[pos]; - buffer[pos] = oob_data.data[0]; + buffer[pos] = c[1] ? c[0] : 'a'; ssize_t len = send(sfd, buffer, pos + 1, MSG_OOB); buffer[pos] = rchar; @@ -380,24 +377,12 @@ ssize_t send_oob(int sfd, char *buffer, uniperror("send"); return -1; } + wait_send_if_support(sfd); + len--; if (len != pos) { return len; } - if (size) { - wait_send(sfd); - } - for (long i = 0; i < size; i++) { - if (send(sfd, data + i, 1, MSG_OOB) < 0) { - uniperror("send"); - if (get_e() == EAGAIN) { - return len; - } - } - if (size != 1) { - wait_send(sfd); - } - } return len; } @@ -414,7 +399,7 @@ ssize_t send_disorder(int sfd, if (len < 0) { uniperror("send"); } - wait_send_if_support(sfd); + else wait_send_if_support(sfd); if (setttl(sfd, params.def_ttl, fa) < 0) { return -1; @@ -424,19 +409,17 @@ ssize_t send_disorder(int sfd, ssize_t send_late_oob(int sfd, char *buffer, - ssize_t n, long pos, int fa) + ssize_t n, long pos, int fa, char *c) { int bttl = 1; if (setttl(sfd, bttl, fa) < 0) { return -1; } - ssize_t len = send_oob(sfd, buffer, n, pos); + ssize_t len = send_oob(sfd, buffer, n, pos, c); if (len < 0) { uniperror("send"); } - wait_send_if_support(sfd); - if (setttl(sfd, params.def_ttl, fa) < 0) { return -1; } @@ -529,7 +512,7 @@ ssize_t desync(int sfd, char *buffer, size_t bfsize, if (offset && pos <= offset) { continue; } - else if (pos <= 0 || pos >= n || pos <= lp) { + else if (pos < 0 || pos > n || pos < lp) { LOG(LOG_E, "split cancel: pos=%ld-%ld, n=%zd\n", lp, pos, n); break; } @@ -538,7 +521,7 @@ ssize_t desync(int sfd, char *buffer, size_t bfsize, switch (part.m) { #ifdef FAKE_SUPPORT case DESYNC_FAKE: - s = send_fake(sfd, + if (pos != lp) s = send_fake(sfd, buffer + lp, type, pos - lp, fa, &dp); break; #endif @@ -549,14 +532,12 @@ ssize_t desync(int sfd, char *buffer, size_t bfsize, case DESYNC_OOB: s = send_oob(sfd, - buffer + lp, n - lp, pos - lp); - wait_send_if_support(sfd); + buffer + lp, n - lp, pos - lp, dp.oob_char); break; - case DESYNC_OOB2: + case DESYNC_DISOOB: s = send_late_oob(sfd, - buffer + lp, n - lp, pos - lp, fa); - //wait_send_if_support(sfd); + buffer + lp, n - lp, pos - lp, fa, dp.oob_char); break; case DESYNC_SPLIT: @@ -628,7 +609,13 @@ ssize_t desync_udp(int sfd, char *buffer, size_t bfsize, else { pkt = fake_udp; } - + if (dp->fake_offset) { + if (pkt.size > dp->fake_offset) { + pkt.size -= dp->fake_offset; + pkt.data += dp->fake_offset; + } + else pkt.size = 0; + } int bttl = dp->ttl ? dp->ttl : 8; if (setttl(sfd, bttl, fa) < 0) { return -1; diff --git a/main.c b/main.c index 8a26e3f..c2fb784 100644 --- a/main.c +++ b/main.c @@ -25,7 +25,6 @@ #define VERSION "12" -char oob_char[1] = "a"; char ip_option[1] = "\0"; struct packet fake_tls = { @@ -34,9 +33,6 @@ struct packet fake_tls = { fake_http = { sizeof(http_data), http_data }, -oob_data = { - sizeof(oob_char), oob_char -}, fake_udp = { sizeof(udp_data), udp_data }; @@ -90,7 +86,7 @@ const char help_text[] = { " +h - add HTTP Host offset\n" " -d, --disorder Split and send reverse order\n" " -o, --oob Split and send as OOB data\n" - " -O, --oob2 Insert OOB data\n" + " -q, --disoob Split and send reverse order as OOB data\n" #ifdef FAKE_SUPPORT " -f, --fake Split and send fake packet\n" " -t, --ttl TTL of fake packets, default 8\n" @@ -98,11 +94,11 @@ const char help_text[] = { " -k, --ip-opt[=f|:str] IP options of fake packets\n" " -S, --md5sig Add MD5 Signature option for fake packets\n" #endif - " -R, --fake-offset Fake data start offset\n" + " -O, --fake-offset Fake data start offset\n" " -l, --fake-data Set custom fake packet\n" " -n, --tls-sni Change SNI in fake ClientHello\n" #endif - " -e, --oob-data Set custom OOB data, filename or :string\n" + " -e, --oob-data Set custom OOB data\n" " -M, --mod-http Modify HTTP: hcsmix,dcsmix,rmspace\n" " -r, --tlsrec Make TLS record at position\n" " -a, --udp-fake UDP fakes count, default 0\n" @@ -139,7 +135,7 @@ const struct option options[] = { {"split", 1, 0, 's'}, {"disorder", 1, 0, 'd'}, {"oob", 1, 0, 'o'}, - {"oob2", 1, 0, 'O'}, + {"disoob", 1, 0, 'q'}, #ifdef FAKE_SUPPORT {"fake", 1, 0, 'f'}, {"ttl", 1, 0, 't'}, @@ -149,7 +145,7 @@ const struct option options[] = { #endif {"fake-data", 1, 0, 'l'}, {"tls-sni", 1, 0, 'n'}, - {"fake-offset", 1, 0, 'R'}, + {"fake-offset", 1, 0, 'O'}, #endif {"oob-data", 1, 0, 'e'}, {"mod-http", 1, 0, 'M'}, @@ -166,28 +162,24 @@ const struct option options[] = { }; -char *parse_cform(const char *str, ssize_t *size) +size_t parse_cform(char *buffer, size_t blen, + const char *str, size_t slen) { - ssize_t len = strlen(str); - char *d = malloc(len); - if (!d) { - return 0; - } static char esca[] = { 'r','\r','n','\n','t','\t','\\','\\', 'f','\f','b','\b','v','\v','a','\a', 0 }; ssize_t i = 0, p = 0; - for (; p < len; ++p && ++i) { + for (; p < slen && i < blen; ++p && ++i) { if (str[p] != '\\') { - d[i] = str[p]; + buffer[i] = str[p]; continue; } p++; char *e = esca; for (; *e; e += 2) { if (*e == str[p]) { - d[i] = *(e + 1); + buffer[i] = *(e + 1); break; } } @@ -195,14 +187,30 @@ char *parse_cform(const char *str, ssize_t *size) continue; } int n = 0; - if (sscanf(&str[p], "x%2hhx%n", &d[i], &n) == 1 - || sscanf(&str[p], "%3hho%n", &d[i], &n) == 1) { + if (sscanf(&str[p], "x%2hhx%n", &buffer[i], &n) == 1 + || sscanf(&str[p], "%3hho%n", &buffer[i], &n) == 1) { p += (n - 1); continue; } i--; p--; } - char *m = realloc(d, i); + return i; +} + + +char *data_from_str(const char *str, ssize_t *size) +{ + ssize_t len = strlen(str); + if (len == 0) { + return 0; + } + char *d = malloc(len); + if (!d) { + return 0; + } + size_t i = parse_cform(d, len, str, len); + + char *m = len != i ? realloc(d, i) : 0; if (i == 0) { return 0; } @@ -214,7 +222,7 @@ char *parse_cform(const char *str, ssize_t *size) char *ftob(const char *str, ssize_t *sl) { if (*str == ':') { - return parse_cform(str + 1, sl); + return data_from_str(str + 1, sl); } char *buffer = 0; long size; @@ -424,10 +432,6 @@ void clear_params(void) free(params.dp); params.dp = 0; } - if (oob_data.data != oob_char) { - free(oob_data.data); - oob_data.data = oob_char; - } } @@ -641,7 +645,7 @@ int main(int argc, char **argv) case 's': case 'd': case 'o': - case 'O': + case 'q': case 'f': ; struct part *part = add((void *)&dp->parts, @@ -661,7 +665,7 @@ int main(int argc, char **argv) break; case 'o': part->m = DESYNC_OOB; break; - case 'O': part->m = DESYNC_OOB2; + case 'q': part->m = DESYNC_DISOOB; break; case 'f': part->m = DESYNC_FAKE; } @@ -695,7 +699,7 @@ int main(int argc, char **argv) dp->md5sig = 1; break; - case 'R': + case 'O': val = strtol(optarg, &end, 0); if (val <= 0 || *end) invalid = 1; @@ -724,14 +728,11 @@ int main(int argc, char **argv) break; case 'e': - if (oob_data.data != oob_char) { - continue; - } - oob_data.data = ftob(optarg, &oob_data.size); - if (!oob_data.data) { - uniperror("read/parse"); + val = parse_cform(dp->oob_char, 1, optarg, strlen(optarg)); + if (val != 1) { invalid = 1; } + else dp->oob_char[1] = 1; break; case 'M': diff --git a/params.h b/params.h index 173ae1f..d7b03e1 100644 --- a/params.h +++ b/params.h @@ -33,7 +33,7 @@ enum demode { DESYNC_SPLIT, DESYNC_DISORDER, DESYNC_OOB, - DESYNC_OOB2, + DESYNC_DISOOB, DESYNC_FAKE }; @@ -43,7 +43,7 @@ char *demode_str[] = { "DESYNC_SPLIT", "DESYNC_DISORDER", "DESYNC_OOB", - "DESYNC_OOB2", + "DESYNC_DISOOB", "DESYNC_FAKE" }; #endif @@ -68,6 +68,7 @@ struct desync_params { int udp_fake_count; int fake_offset; char drop_sack; + char oob_char[2]; int parts_n; struct part *parts; @@ -113,9 +114,7 @@ extern struct params params; extern struct packet fake_tls; extern struct packet fake_http; -extern struct packet oob_data; extern struct packet fake_udp; extern char ip_option[1]; - #endif