diff --git a/desync.c b/desync.c index fde50b3..a239bc9 100644 --- a/desync.c +++ b/desync.c @@ -417,14 +417,44 @@ ssize_t send_late_oob(int sfd, char *buffer, } +static long gen_offset(long pos, int flag, + ssize_t n, long lp, int type, int hp, int len) +{ + if (flag & (OFFSET_SNI | OFFSET_HOST)) { + if (!hp || ((flag & OFFSET_SNI) && type != IS_HTTPS)) { + return -1; + } + pos += hp; + + if (flag & OFFSET_END) + pos += len; + else if (flag & OFFSET_MID) + pos += (len / 2); + else if (flag & OFFSET_RAND) + pos += (rand() % len); + } + else if (flag & OFFSET_RAND) { + pos += lp + (rand() % (n - lp)); + } + else if (flag & OFFSET_MID) { + pos += (n / 2); + } + else if (pos < 0 || (flag & OFFSET_END)) { + pos += n; + } + return pos; +} + + ssize_t desync(int sfd, char *buffer, size_t bfsize, ssize_t n, ssize_t offset, struct sockaddr *dst, int dp_c) { struct desync_params dp = params.dp[dp_c]; char *host = 0; - int len = 0, type = 0; + int len = 0, type = 0, host_pos = 0; int fa = get_family(dst); + // parse packet if ((len = parse_tls(buffer, n, &host))) { type = IS_HTTPS; @@ -435,7 +465,9 @@ ssize_t desync(int sfd, char *buffer, size_t bfsize, if (len && host) { LOG(LOG_S, "host: %.*s (%zd)\n", len, host, host - buffer); + host_pos = host - buffer; } + // modify packet if (type == IS_HTTP && dp.mod_http) { LOG(LOG_S, "modify HTTP: n=%zd\n", n); @@ -450,12 +482,12 @@ ssize_t desync(int sfd, char *buffer, size_t bfsize, struct part part = dp.tlsrec[i]; long pos = part.pos + i * 5; - if (part.flag == OFFSET_SNI) { - pos += (host - buffer - 5); - } - else if (pos < 0) { - pos += n; + if (pos < 0 || part.flag) { + pos -= 5; } + pos = gen_offset(pos, + part.flag, n, lp, type, host_pos, len); + if (pos < lp) { LOG(LOG_E, "tlsrec cancel: %ld < %ld\n", pos, lp); break; @@ -481,30 +513,16 @@ ssize_t desync(int sfd, char *buffer, size_t bfsize, for (int i = 0; i < dp.parts_n; i++) { struct part part = dp.parts[i]; - // change pos - long pos = part.pos; - if (part.flag == OFFSET_SNI) { - if (type != IS_HTTPS) - continue; - else - pos += (host - buffer); - } - else if (part.flag == OFFSET_HOST) { - if (type != IS_HTTP) - continue; - else - pos += (host - buffer); - } - else if (pos < 0 || part.flag == OFFSET_END) { - pos += n; - } + long pos = gen_offset(part.pos, + part.flag, n, lp, type, host_pos, len); + // after EAGAIN if (offset && pos <= offset) { continue; } else if (pos < 0 || pos > n || pos < lp) { LOG(LOG_E, "split cancel: pos=%ld-%ld, n=%zd\n", lp, pos, n); - break; + continue; } // send part ssize_t s = 0; diff --git a/main.c b/main.c index dc16943..00b74b7 100644 --- a/main.c +++ b/main.c @@ -376,21 +376,34 @@ int parse_offset(struct part *part, const char *str) { char *end = 0; long val = strtol(str, &end, 0); - if (*end == '+') switch (*(end + 1)) { - case 's': - part->flag = OFFSET_SNI; - break; - case 'h': - part->flag = OFFSET_HOST; - break; - case 'e': - part->flag = OFFSET_END; - break; - default: - return -1; - } - else if (*end) { - return -1; + if (*end == '+') { + switch (*(end + 1)) { + case 's': + part->flag = OFFSET_SNI; + break; + case 'h': + part->flag = OFFSET_HOST; + break; + case 'e': // + part->flag = OFFSET_END; + break; + case 'n': + break; + default: + return -1; + } + switch (*(end + 2)) { + case 'e': + part->flag |= OFFSET_END; + break; + case 'm': + part->flag |= OFFSET_MID; + break; + case 'r': + part->flag |= OFFSET_RAND; + break; + case 's':; + } } part->pos = val; return 0; @@ -908,7 +921,8 @@ int main(int argc, char **argv) clear_params(); return -1; } - + srand((unsigned int)time(0)); + int status = run((struct sockaddr_ina *)¶ms.laddr); clear_params(); return status; diff --git a/params.h b/params.h index b4f4ba0..7f93c0a 100644 --- a/params.h +++ b/params.h @@ -20,10 +20,12 @@ #define FAKE_SUPPORT 1 #define TIMEOUT_SUPPORT 1 #endif - -#define OFFSET_SNI 1 -#define OFFSET_HOST 2 -#define OFFSET_END 3 + +#define OFFSET_END 1 +#define OFFSET_MID 2 +#define OFFSET_RAND 4 +#define OFFSET_SNI 8 +#define OFFSET_HOST 16 #define DETECT_HTTP_LOCAT 1 #define DETECT_TLS_ERR 2