From 45dcbff86f447862f3744d0b309c8b56db62a783 Mon Sep 17 00:00:00 2001 From: z3APA3A <3APA3A@3proxy.ru> Date: Wed, 18 Nov 2020 02:21:06 +0300 Subject: [PATCH] Add heuristics for SOCKSv5 UDPASSOC client request behavior --- src/socks.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/socks.c b/src/socks.c index a6d04c2..682eda2 100644 --- a/src/socks.c +++ b/src/socks.c @@ -33,6 +33,7 @@ void * sockschild(struct clientparam* param) { struct sockaddr_in sin = {AF_INET}; #endif int len; + int heur = 0; param->service = S_SOCKS; @@ -123,6 +124,15 @@ void * sockschild(struct clientparam* param) { RETURN(431); } myinet_ntop(*SAFAMILY(¶m->sinsr), SAADDR(¶m->sinsr), buf, 64); + if(command == 3){ + if(*SAFAMILY(¶m->req) == *SAFAMILY(¶m->sincr) && !memcmp(SAADDR(¶m->req),SAADDR(¶m->sincr), SAADDRLEN(¶m->req))){ + heur = 1; + } + else if (!SAISNULL(¶m->req)){ + heur = 2; + } + } + break; case 3: if ((size = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(451);} /* nmethods */ @@ -330,7 +340,7 @@ fflush(stderr); param->sinsr = param->req; myfree(buf); if(!(buf = myalloc(LARGEBUFSIZE))) {RETURN(21);} - sin = param->sincr; + sin = (heur == 1)?param->req:param->sincr; fds[2].events = fds[1].events = fds[0].events = 0; fds[0].fd = param->remsock; @@ -346,11 +356,20 @@ fflush(stderr); if(len < 10) continue; sasize = sizeof(sin); - if((len = so._recvfrom(param->clisock, (char *)buf, 65535, 0, (struct sockaddr *)&sin, &sasize)) <= 10) { + if(len <= 10) { param->res = 464; break; } - if(SAADDRLEN(&sin) != SAADDRLEN(¶m->sincr) || memcmp(SAADDR(&sin), SAADDR(¶m->sincr), SAADDRLEN(&sin))){ + if(SAADDRLEN(&sin) != SAADDRLEN(¶m->sincr) || memcmp(SAADDR(&sin), SAADDR(¶m->sincr), SAADDRLEN(&sin)) || (heur == 1 && *SAPORT(¶m->sincr)!=*SAPORT(&sin))){ + if(heur == 1){ +#if SOCKSTRACE > 0 +fprintf(stderr, "internal UDP packet ignored\n"); +fflush(stderr); +#endif + sin = param->req; + continue; + } + param->res = 465; break; } @@ -422,6 +441,13 @@ fflush(stderr); fds[0].events = fds[0].revents = 0; param->statssrv64+=len; param->nreads++; + if(heur == 2 && (*SAFAMILY(¶m->sinsr) != *SAFAMILY(¶m->req) || memcmp(SAADDR(¶m->sinsr),SAADDR(¶m->req), SAADDRLEN(¶m->req)))){ +#if SOCKSTRACE > 0 +fprintf(stderr, "external UDP packet ignored\n"); +fflush(stderr); +#endif + continue; + } memcpy(buf+4, SAADDR(¶m->sinsr), SAADDRLEN(¶m->sinsr)); memcpy(buf+4+SAADDRLEN(¶m->sinsr), SAPORT(¶m->sinsr), 2); sasize = sizeof(sin);