Снова релиз. Снова нашей команды. На этот раз мы представляем вам свой сокс-сервер. Основные характеристики: -Протокол Socks5 -Написан на Си -Компилируется в Unix и Windows системах (я тестировал программу в различных дистрибутивах Linux и FreeBSD, а так же в Windows XP. Нет причин, по которым программа не должна собираться в других операционках) -Не требует root-привелегий -Размер бинарника в формате PE: 2,5 Кб. В формате ELF может меняться в зависимости от ОС, я получал бинарники размером от 9 до 16 Кб -Поддерживается аудентификация по логину:паролю -Клиент может передавать адрес сервера как в виде D/N, так и в виде IPv4 (IPv6 не поддерживается) -Поддерживается только метод connect. Это объясняется тем, что я просто не знаю софт, использующий другие методы простокола Socks5. -Исходник занимает 1 файл размером менее 10Кб - при необходимости 500 строк кода можно скопи-пастить через stdin. Скачать Обсудить на оффсайте
ооо, какую старую темку я поднял 0_о Строго не судите, но на момент поста темы, я даже не знал о существовании данного ресурса. В общем огромная просьба, быть может он у кого-нить сохранился, выложите плз, у них сейчас новая версия, но она на перле, ибо си не особо переносим на юниксоиды, а мне-то как-раз на си и нужен. Выручайте, мужики=)
Code: /******************************************************************************* Satanic Socks Server v0.66.170506 Powered by drmist\STNC Compilation: Win32: Visual C++ Unix: gcc -lpthread sss.c -o sss v0.66.170506 + IPv4 + Domain names + Connect method + Login:Password authorization (c) 2006 www.security-teams.net crew *******************************************************************************/ #define UNIX 1 // #define WIN32 1 // #define AUTH_ON 1 #define PORT 3003 #define BUFF_SIZE 1024 #ifdef AUTH_ON const char AuthLogin[] = "login"; const char AuthPass[] = "pass"; #define SOCKS5_METHOD 0x02 #else #define SOCKS5_METHOD 0x00 #endif #ifdef UNIX #include "sys/types.h" #include "sys/socket.h" #include "netinet/in.h" #include "netdb.h" typedef int SOCKET; typedef int bool; typedef int __stdcall; #define SOCKET_ERROR -1 #define INVALID_SOCKET -1 #define false 0 #define true 1 #define SD_BOTH SHUT_RDWR #define _malloc malloc #define closesocket close void create_thread(void* func, void* param) { int ThrId; pthread_create(&ThrId, 0, func, param); } #endif #ifdef WIN32 #include "winsock2.h" #pragma comment(linker, "/SUBSYSTEM:WINDOWS") #pragma comment(linker, "/ENTRY:main /ALIGN:0x200 /BASE:0x400000") #pragma comment(linker, "/MERGE:.rdata=.text /SECTION:.text, EWR") typedef UINT in_addr_t; #define strcmp lstrcmp #define free GlobalFree void create_thread(void* func, void* param) { CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func, param, 0, NULL); } char* _malloc(int BuffSize) { return (char*)GlobalAlloc(GMEM_FIXED, BuffSize); } void bzero(void* lpBuff, int BuffSize) { _asm { xor eax, eax mov ecx, BuffSize mov edi, lpBuff cld rep stosb } } #endif #define SOCKS_VERSION 0x05 #define SOCKS_SUCCESS 0x00 #define SOCKS_FAILURE 0x01 #define SOCKS_CONNECTION_REFUSED 0x05 #define SOCKS_CMD_NOT_SUPPORTED 0x07 typedef struct { char* _ConnectStruct; SOCKET From; SOCKET To; char Buff[BUFF_SIZE]; char* Error; } SOCKSPIPE; typedef SOCKSPIPE* LPSOCKSPIPE; typedef struct _CONNECTSTRUCT { SOCKSPIPE FromStruct; SOCKSPIPE ToStruct; char Error; } CONNECTSTRUCT; typedef CONNECTSTRUCT* LPCONNECTSTRUCT; LPCONNECTSTRUCT CreateConnectStruct(SOCKET From, SOCKET To) { LPCONNECTSTRUCT Result = (LPCONNECTSTRUCT)_malloc(sizeof(CONNECTSTRUCT)); Result->FromStruct._ConnectStruct = (char*)Result; Result->FromStruct.From = From; Result->FromStruct.To = To; Result->FromStruct.Error = &(Result->Error); Result->ToStruct._ConnectStruct = (char*)Result; Result->ToStruct.From = To; Result->ToStruct.To = From; Result->ToStruct.Error = &(Result->Error); Result->Error = 0x00; return Result; } bool swrite(SOCKET s, char* Buff, int buff_size) { int bytes; while(buff_size > 0) { bytes = send(s, Buff, buff_size, 0); if((bytes == 0)||(bytes == SOCKET_ERROR)) return false; buff_size -= bytes; Buff += bytes; } return true; } bool sread(SOCKET s, char* Buff, int buff_size) { int bytes; while(buff_size > 0) { bytes = recv(s, Buff, buff_size, 0); if((bytes == 0)||(bytes == SOCKET_ERROR)) return false; buff_size -= bytes; Buff += bytes; } return true; } __stdcall SocksPipe(LPSOCKSPIPE PipeStruct) { int bytes; do { bytes = recv(PipeStruct->From, PipeStruct->Buff, BUFF_SIZE, 0); if((bytes == 0) || (bytes == SOCKET_ERROR)) break; if(*(PipeStruct->Error) & 0x01) { *(PipeStruct->Error) |= 0x02; return 0; } if(!swrite(PipeStruct->To, PipeStruct->Buff, bytes)) { *(PipeStruct->Error) |= 0x02; return 0; } } while(!(*(PipeStruct->Error) & 0x01)); if(*(PipeStruct->Error) & 0x01) *(PipeStruct->Error) |= 0x02; else { *(PipeStruct->Error) |= 0x01; shutdown(PipeStruct->From, SD_BOTH); shutdown(PipeStruct->To, SD_BOTH); closesocket(PipeStruct->From); closesocket(PipeStruct->To); while(!(*(PipeStruct->Error) & 0x02)) { #ifdef UNIX sleep(1); #endif #ifdef WIN32 Sleep(1000); #endif } free(PipeStruct->_ConnectStruct); } return 0; } bool Socks5SendCode(SOCKET s, char Code, char* TempBuff, char* ip, char* port) { *(int*)TempBuff = 0x1000000 | (Code << 8) | SOCKS_VERSION; *(int*)(TempBuff + 4) = *(int*)ip; *(short*)(TempBuff + 8) = *(short*)port; return swrite(s, TempBuff, 10); } SOCKET Socks5ServConnect(SOCKET s, char* TempBuff, char* ip, u_short port) { struct sockaddr_in saddr; SOCKET Redir = socket(AF_INET, SOCK_STREAM, 0); if(Redir == INVALID_SOCKET) Socks5SendCode(s, SOCKS_FAILURE, TempBuff, ip, (char*)&port); else { bzero(&saddr, sizeof(struct sockaddr_in)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = *(in_addr_t*)ip; saddr.sin_port = port; if(connect(Redir, (struct sockaddr*)&saddr, sizeof(struct sockaddr_in)) == -1) { Socks5SendCode(s, SOCKS_CONNECTION_REFUSED, TempBuff, ip, (char*)&port); closesocket(Redir); Redir = INVALID_SOCKET; } } return Redir; } bool Socks5CmdIsSupported(SOCKET s, char cmd, char* TempBuff, char* ip, char* port) { if(cmd != 0x01) // 0x02 - bind; 0x03 - udp associate { Socks5SendCode(s, SOCKS_CMD_NOT_SUPPORTED, TempBuff, ip, port); return false; } return true; } bool Socks5GetCmd(SOCKET s, char* TempBuff, char* cmd, char* ip, char* port) { struct hostent* hp; char DnLen; char AddrType; char Tmp[5]; if(!sread(s, TempBuff, 4)) return false; if((TempBuff[0] != SOCKS_VERSION)||(TempBuff[2] != 0x00)) return false; *cmd = TempBuff[1]; AddrType = TempBuff[3]; switch(AddrType) { case 0x01: // ip v4 if(!sread(s, ip, 4)) return false; break; case 0x03: // domain name if(!sread(s, &DnLen, 1)) return false; if(DnLen == 0) return false; if(!sread(s, TempBuff, DnLen)) return false; TempBuff[DnLen] = 0x00; hp = gethostbyname(TempBuff); if(((int)hp == -1)||((int)hp == 0)) { if(!sread(s, port, 2)) return false; *(int*)(&Tmp) = 0x03000405; *(char*)(&Tmp + 4) = DnLen; if(swrite(s, Tmp, 5)) if(swrite(s, TempBuff, DnLen)) swrite(s, port, 2); return false; } else *(int*)ip = *(int*)hp->h_addr; break; case 0x04: // ip v6, not supported *(int*)(&Tmp) = 0x04000805; if(sread(s, TempBuff, 16)) if(sread(s, port, 2)) if(swrite(s, Tmp, 4)) if(swrite(s, TempBuff, 16)) swrite(s, port, 2); return false; default: return false; } return sread(s, port, 2); } #ifdef AUTH_ON bool Socks5Auth(SOCKET s, char* TempBuff) { char Login[256]; char LoginLen; char PassLen; char Status = '\xFF'; if(!sread(s, TempBuff, 2)) return false; LoginLen = TempBuff[1]; if((TempBuff[0] != 0x01)||(LoginLen == 0)) return false; if(!sread(s, Login, LoginLen+1)) return false; PassLen = Login[LoginLen]; if(!PassLen) return false; Login[LoginLen] = 0x00; if(!sread(s, TempBuff, PassLen)) return false; TempBuff[PassLen] = 0x00; if((strcmp(AuthLogin, Login) == 0)&&(strcmp(AuthPass, TempBuff) == 0)) Status = 0x00; *(short*)TempBuff = (Status << 8) | 0x01; if(!swrite(s, TempBuff, 2)) return false; return (Status == 0x00); } #endif bool Socks5Accept(SOCKET s, char* TempBuff) { char MethodsCount; char Cmd = '\xFF'; if(!sread(s, TempBuff, 2)) return false; MethodsCount = TempBuff[1]; if((TempBuff[0] != SOCKS_VERSION)||(MethodsCount == 0)) return false; if(!sread(s, TempBuff, MethodsCount)) return false; do { MethodsCount--; if(TempBuff[MethodsCount] == SOCKS5_METHOD) { Cmd = TempBuff[MethodsCount]; break; } } while(MethodsCount > 0); *(short*)TempBuff = (Cmd << 8) | SOCKS_VERSION; if(!swrite(s, TempBuff, 2)) return false; #ifdef AUTH_ON return (Cmd == 0xFF) ? false : Socks5Auth(s, TempBuff); #else return (Cmd != 0xFF); #endif } __stdcall AcceptThread(SOCKET s) { SOCKET Redir; LPCONNECTSTRUCT ConnectStruct; char TempBuff[256]; char cmd; char ip[4]; u_short port; if(Socks5Accept(s, TempBuff)) if(Socks5GetCmd(s, TempBuff, &cmd, ip, (char*)&port)) if(Socks5CmdIsSupported(s, cmd, TempBuff, ip, (char*)&port)) { Redir = Socks5ServConnect(s, TempBuff, ip, port); if(Redir != INVALID_SOCKET) { if(Socks5SendCode(s, SOCKS_SUCCESS, TempBuff, ip, (char*)&port)) { ConnectStruct = CreateConnectStruct(s, Redir); create_thread(&SocksPipe, &(ConnectStruct->ToStruct)); SocksPipe(&(ConnectStruct->FromStruct)); return 0; } closesocket(Redir); } } closesocket(s); return 0; } int main(int argc, char* argv[]) { SOCKET s, accepted; struct sockaddr_in saddr; int saddr_size = sizeof(struct sockaddr_in); #ifdef WIN32 WSADATA WSA; if(WSAStartup(MAKEWORD(2, 2), &WSA) != 0) return 0; #endif s = socket(AF_INET, SOCK_STREAM, 0); if(s != INVALID_SOCKET) { bzero(&saddr, sizeof(struct sockaddr_in)); saddr.sin_family = AF_INET; saddr.sin_port = htons(PORT); if(bind(s, (struct sockaddr*)&saddr, sizeof(struct sockaddr_in)) != SOCKET_ERROR) if(listen(s, 0) != SOCKET_ERROR) for(;;) { accepted = accept(s, (struct sockaddr*)&saddr, &saddr_size); if(accepted != INVALID_SOCKET) create_thread(&AcceptThread, (void*)accepted); } closesocket(s); } #ifdef WIN32 WSACleanup(); ExitProcess(0); #endif return 0; }