Legitimate backdoor in distributing enterprise Windows Store apps

    Hello, Habr! In this article, we share our experience in distributing an enterprise application for Windows Store.

    We have a client. An excellent client for whom we have created, implemented and continue to develop a large portal solution for remote agent servicing. About a year ago, it was decided to create a mobile workplace for an employee based on Windows 8 tablets.
    But creating an application is only one task. It was necessary to think over the next step: it should be installed on the tablets of the customer company and dispersed throughout Russia, because end users are representatives of the company in various regions. At the same time, there should be a mechanism for updating applications, since without this, you yourself understand, nowhere.

    At the testing stage, you can use the application for one month by installing a developer license, which we did ( link ). But once the time comes to launch the application. We examined various options:

    1. Distribution through the app store.
      The method seems tempting: we release an application in which the “for our own” functionality is password protected, and only employees can use the application for its intended purpose. But this distribution violates the rules of publishing in the application store. There is a high probability of receiving a review in response (as has already happened with iOS applications):
      2.12 We found that your app is intended for a very limited, or niche, set of users - your company.
    2. Use of computer management programs of the organization , such as Windows Intune ( link ), Air-Watch ( link ).
      These are serious solutions that require additional costs for their purchase and configuration; in addition, they must be taken into use by the company's IT services. The use of these systems, no doubt, solves almost all the problems of remote control and monitoring of devices, but at the moment the customer was not ready to configure and use these systems.
    3. As in many cases there is a way, just have to look a little ...

    Update installer


    We decided to try to cope with the task on our own and invent a bicycle to create a program that helps to configure OC before installing the application, directly install and update our application with a Modern UI interface.
    The fact is that the corporate tablets that the company uses were x86 with Windows 8 Professional installed. This architecture allows you to run not only applications from the store, but also the "good old" programs.

    So, the algorithm would seem to be standard:
    1. The user receives the installer and installs the classic update program.
    2. The program checks the availability of the new version of the application, and if there is one, it downloads the finished package.
    3. The program deploys the package and runs the installation script.
    4. And now the application is installed / updated.


    Sideloading


    But, as usual, not everything is so smooth - there are nuances. There is one more difficulty that Microsoft created for us and which had to be circumvented: application installation is generally blocked on some system configurations. Applications cannot be installed if Group Policy settings are not set to "Allow trusted apps to install." However, the setting itself is not available for some platforms. Details of the sideloading mechanism ( here ).

    Installing applications is available if:

    For the operating system Windows 8 Enterprise, Windows 8 Professional:
    • The computer must be in a domain.
    • Group Policy settings are set to "Allow trusted apps to install".

    For operating systems Windows 8 Enterprise, Windows 8 Professional, Windows RT:
    • A special key (sideloading key) must be activated on the computer. Sideloading key is a 25-character key (similar to an activation key for Windows).
    • Group Policy settings are set to "Allow trusted apps to install".

    In the version with the addition of computers to the domain, we were denied, but the key to activate sideloading was provided.
    What does setting up a key and setting up a policy look like for a user? Maybe the sent installation instructions along with the key solve the problem?
    1. To get started, install the sideloading key. Open a command prompt as administrator and enter the commands:
      slmgr / ipk
      slmgr / ato ec67814b-30e6-4a50-bf7b-d55daf729d1e
    2. Open the local group policy editor (Start -> gpedit.msc). Find folder N and change the value of X.
    3. ...

    In general, the process for an inexperienced user looks nontrivial, something needs to be done with this. Therefore, we will try to use our installer and automate the process.

    Putting it all together


    So, the proposed solution — the installer — works as follows: it is distributed as a .msi file (by mail among employees), it is installed on the system and works according to the following algorithm:



    After installation, the program is minimized to tray and immediately starts the automatic update check. If the application is not installed, the following message appears in the tray:



    Click on it, the form itself appears, on which there is a brief description of the application, an information window, progress bar and buttons. In the information window there may be inscriptions like: “Update available ...”, “Installing the application ...”, etc.





    After installation, the application is in the tray and periodically (several times a day) requests the server for updates. If updates are available, the application notifies the user about this.

    It makes sense to focus a little on the technical implementation of some parts of the program.

    Code examples


    Group Policy Setting
    public static void SetGroupPolicy()
    {
        var key = Registry.LocalMachine.CreateSubKey(@"Software\Policies\Microsoft\Windows\Appx");
        //…проверки…
        key.SetValue("AllowAllTrustedApps", 1, Microsoft.Win32.RegistryValueKind.DWord);
    }
    


    Install Sideloading Key
    public static void InstallSideloadingKey()
    {
        // Проверить, установлен или нет sideloading key
        if (IsSideloadKeyInstalled())
            return;
        Process p = new Process() {
            StartInfo = new ProcessStartInfo() {
                FileName = @"C:\Windows\System32\slmgr.vbs",
            },
        };                        
        // Установить ключ
        p.StartInfo.Arguments = "/ipk " + _sideloadingKey;
        p.Start();
        p.SuppressPopups();
        p.Close();
        // Активировать ключ
        p.StartInfo.Arguments = "/ato ec67814b-30e6-4a50-bf7b-d55daf729d1e";
        p.Start();
        p.SuppressPopups();
        p.Close();            
    }
    


    Verify that the key is installed
    private static bool IsSideloadKeyInstalled()
    {
        // Проверяем, какие ключи установлены в системе и есть ли среди них
        // наш sideloading key.
        bool result = false;
        Process p = new Process() {
            StartInfo = new ProcessStartInfo() {
                        FileName = @"C:\Windows\System32\slmgr.vbs",
            },
        };
    p.StartInfo.Arguments = "/dlv";
    // Команда выводит список всех ключей в системе в отдельном окне.
    p.Start();
    for (int i = 0; (i < 10) && (!p.HasExited); i++)
    {
        p.Refresh();
        if (p.MainWindowHandle.ToInt32() != 0)
        {
            var list = WindowsHelper.GetChildWindows(p.MainWindowHandle);
            foreach(var ptr in list)
            {
                string windowText = WindowsHelper.GetText(ptr);
                if(windowText.Contains("APPXLOB") && windowText.Contains(_sideloadingKeyPart))
                {
                    result = true;
                }
            }
    	 // Закрываем окно с информацией о ключах 
            WindowsHelper.CloseWindow(p.MainWindowHandle);
            Thread.Sleep(1000);
        }
        p.Close();
        return result;
    }
    


    Install application package
    public static void UpdateApp(string appxPath)
    {
        if (String.IsNullOrEmpty(appxPath))
        {
            // Не найден файл .appxbundle"
            return;
        }
        //
        // Сформировать команду
        string command = @"/C powershell Add-AppxPackage ";
        command += appxPath;
        // Обновить приложение или установить с нуля?
        var package = PackageHelper.GetPackage();
        if (package != null) {
            // Приложение уже установлено - надо обновлять
            command += " -Update";
        }
        Process p = new Process() {
            StartInfo = new ProcessStartInfo() {
                WorkingDirectory = @"C:\",
                FileName = "cmd.exe",
                Arguments = command,
                RedirectStandardOutput = true,
                UseShellExecute = false,
            },
            EnableRaisingEvents = true,
        };
        p.Exited += (s, e) =>
        {                
             // Проверить результат процесса установки
            var pr = s as Process;
            string text = pr.StandardOutput.ReadToEnd();
            if (String.IsNullOrEmpty(text)) {
                // Приложение установлено успешно. Уведомить об этом пользователя.
            else
                // В процессе установки произошла ошибка.
        }; 
        p.Start(); // Start process
        p.WaitForExit();                     
    }
    



    Conclusion


    The described distribution method is, of course, very confusing. There are methods for distributing Windows 8 applications that are much more correct and convenient. But the conditions in which we were set forced us to solve the problem in this way. With this decision, you and the customer will not have to buy and configure any third-party systems; You will not load the user with complex application installation algorithms; You will have no reason to fear that the application will not pass certification.

    Also popular now: