mirror of
https://github.com/wavestone-cdt/EDRSandblast.git
synced 2026-06-09 00:47:16 +00:00
D3FC0N 30 release: Obj callbacks, firewalling, symbols w/ internet, and more
Co-authored-by: Maxime Meignan <maxime.meignan@wavestone.com>
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
#include <windef.h>
|
||||
#include <winhttp.h>
|
||||
|
||||
#include "../EDRSandblast.h"
|
||||
#include "HttpClient.h"
|
||||
|
||||
|
||||
BOOL HttpsDownloadFullFile(LPCWSTR domain, LPCWSTR uri, PBYTE* output, SIZE_T* output_size) {
|
||||
wprintf_or_not(L"Downloading https://%s%s...\n", domain, uri);
|
||||
// Get proxy configuration
|
||||
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig;
|
||||
WinHttpGetIEProxyConfigForCurrentUser(&proxyConfig);
|
||||
BOOL proxySet = !(proxyConfig.fAutoDetect || proxyConfig.lpszAutoConfigUrl != NULL);
|
||||
DWORD proxyAccessType = proxySet ? ((proxyConfig.lpszProxy == NULL) ?
|
||||
WINHTTP_ACCESS_TYPE_NO_PROXY : WINHTTP_ACCESS_TYPE_NAMED_PROXY) : WINHTTP_ACCESS_TYPE_NO_PROXY;
|
||||
LPCWSTR proxyName = proxySet ? proxyConfig.lpszProxy : WINHTTP_NO_PROXY_NAME;
|
||||
LPCWSTR proxyBypass = proxySet ? proxyConfig.lpszProxyBypass : WINHTTP_NO_PROXY_BYPASS;
|
||||
|
||||
// Initialize HTTP session and request
|
||||
HINTERNET hSession = WinHttpOpen(L"WinHTTP/1.0", proxyAccessType, proxyName, proxyBypass, 0);
|
||||
if (hSession == NULL) {
|
||||
printf_or_not("WinHttpOpen failed with error : 0x%x\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
HINTERNET hConnect = WinHttpConnect(hSession, domain, INTERNET_DEFAULT_HTTPS_PORT, 0);
|
||||
if (!hConnect) {
|
||||
printf_or_not("WinHttpConnect failed with error : 0x%x\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"GET", uri, NULL,
|
||||
WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
|
||||
if (!hRequest) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Configure proxy manually
|
||||
if (!proxySet)
|
||||
{
|
||||
WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions;
|
||||
autoProxyOptions.dwFlags = proxyConfig.lpszAutoConfigUrl != NULL ? WINHTTP_AUTOPROXY_CONFIG_URL : WINHTTP_AUTOPROXY_AUTO_DETECT;
|
||||
autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
|
||||
autoProxyOptions.fAutoLogonIfChallenged = TRUE;
|
||||
|
||||
if (proxyConfig.lpszAutoConfigUrl != NULL)
|
||||
autoProxyOptions.lpszAutoConfigUrl = proxyConfig.lpszAutoConfigUrl;
|
||||
|
||||
WCHAR szUrl[MAX_PATH] = { 0 };
|
||||
swprintf_s(szUrl, _countof(szUrl), L"https://%ws%ws", domain, uri);
|
||||
|
||||
WINHTTP_PROXY_INFO proxyInfo;
|
||||
WinHttpGetProxyForUrl(
|
||||
hSession,
|
||||
szUrl,
|
||||
&autoProxyOptions,
|
||||
&proxyInfo);
|
||||
|
||||
WinHttpSetOption(hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo));
|
||||
DWORD logonPolicy = WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW;
|
||||
WinHttpSetOption(hRequest, WINHTTP_OPTION_AUTOLOGON_POLICY, &logonPolicy, sizeof(logonPolicy));
|
||||
}
|
||||
|
||||
// Perform request
|
||||
BOOL bRequestSent;
|
||||
do {
|
||||
bRequestSent = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
|
||||
} while (!bRequestSent && GetLastError() == ERROR_WINHTTP_RESEND_REQUEST);
|
||||
if (!bRequestSent) {
|
||||
return FALSE;
|
||||
}
|
||||
BOOL bResponseReceived = WinHttpReceiveResponse(hRequest, NULL);
|
||||
if (!bResponseReceived) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Read response
|
||||
DWORD dwAvailableSize = 0;
|
||||
DWORD dwDownloadedSize = 0;
|
||||
SIZE_T allocatedSize = 4096;
|
||||
if (!WinHttpQueryDataAvailable(hRequest, &dwAvailableSize))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*output = (PBYTE) malloc(allocatedSize);
|
||||
*output_size = 0;
|
||||
while (dwAvailableSize)
|
||||
{
|
||||
while (*output_size + dwAvailableSize > allocatedSize) {
|
||||
allocatedSize *= 2;
|
||||
PBYTE new_output = (PBYTE)realloc(*output, allocatedSize);
|
||||
if (new_output == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*output = new_output;
|
||||
}
|
||||
if (!WinHttpReadData(hRequest, *output + *output_size, dwAvailableSize, &dwDownloadedSize))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*output_size += dwDownloadedSize;
|
||||
|
||||
WinHttpQueryDataAvailable(hRequest, &dwAvailableSize);
|
||||
}
|
||||
PBYTE new_output = (PBYTE)realloc(*output, *output_size);
|
||||
if (new_output == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*output = new_output;
|
||||
WinHttpCloseHandle(hRequest);
|
||||
WinHttpCloseHandle(hConnect);
|
||||
WinHttpCloseHandle(hSession);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user