Hello Everyone,
I have a variety of projects to share in the short term but I wanted to talk about one in particular because it is more than a bit annoying.
Like many firms, my employer is rolling out Microsoft Teams as the preferred communication platform. While I do not have any real complaints about the functionality of the actual product, I have been dismayed at the realization that Microsoft’s patching strategy with this product seems entirely user-centric without any formal ways for Information Technology teams to force the issue. If you refer to their documentation here, they make it very clear that the intention is for this mechanism to simply work automatically.
Teams does not give admins the ability to deploy updates through any delivery mechanism.
Unfortunately, things do not always work as intended and there are user patterns and vulnerability implications that are simply not accounted for in this model. If someone downloads and installs Microsoft Teams but only uses it once or twice, the vulnerable bits will remain (Albeit at rest). This is the problem within my environment that needed to be addressed because the vulnerabilities are detected and perceived as actionable by our Information Security team.
So in summation:
- Microsoft Teams does not officially have an administrator-driven model for forcing updates to occur
- Users do silly thing sometimes like download software, run it once, and never revisit or remove it again.
- I refuse to accept that there is nothing that we can do about this.
The solution to this problem combines a number of different tools.
- Tanium Core package
- PowerShell Application Deployment Toolkit
- winget package manager
- Weaponized obstinance
The first rabbit I chased with this process was to attempt to invoke the Update.exe application that is embedded with every installation of Teams. A passing glance at the switches of that executable made it seem viable at first but attempting to leverage them for our task led nowhere. In my frustration, I recalled seeing that Microsoft Teams was available via the winget package manager that is currently in the pre-release stages. I had hoped to find an example of a call to Update.exe via that mechanism but instead found that the package manager was using the Teams CDN to pull down and invoke a separate executable. At that point, I abandoned the idea of leveraging the Update.exe mechanism with the assumption that Microsoft would have used it themselves if it were viable.
So…downloading content using PowerShell isn’t particularly difficult. There are several different ways to do that but I generally fall back to Start-BitsTransfer out of habit. The next piece of the puzzle was finding a way to easily gather the current Teams CDN location. Microsoft’s URLs in this regard are version-specific rather than something like /latest so I decided to just use winget again and came up with a simple one-liner for the task.
$cdnURL = $(& winget show Microsoft.Teams | Select-String -Pattern "https://statics.teams.cdn.office").ToString().Replace("Download Url: ",'').Replace(' ','')
Now we know the targeting URL and, as all kids of the late 80’s/early 90’s understand, knowing is half the battle. Having this URL is good but we now need a delivery apparatus that can eventually invoke it within userspace. One might be tempted to do this via Tanium Deploy but I did not like the idea of that; this URL is going to change frequently and I don’t want to constantly maintain an application for this purpose. There is a better way.
Instead, a parameterized Core Package that leverages key functionality of the PowerShell Application Toolkit is called for…which presented another challenge. The traditional structure of the toolkit does not lend itself to this delivery apparatus; all of the constituent components of the toolkit dynamically reference each other based on their positioning within a fixed directory structure and Core Packages do not currently support directory structure. Fortunately, I only need the core components which are all located within a single directory. There have been instances where I needed the entire toolkit and for those I just used the bootstrapper script that the Core package invokes to self-assemble the proper directory structure; that’s a story for another post.
Now that we have covered the basic makeup of the Core package, let’s discuss the script that it is calling. This script is very basic.
As you can see, the sequence of events is relatively straightforward.
- Parameters passed through the Tanium Core Package are encoded and must be unescaped in order to be usable.
- A simple validation is done to ensure that the URL is structured appropriately.
- A folder is created (If one does not already exist) under c:\softwareCache\Teams to serve as a staging point for further operations.
- Start-BitsTransfer is invoked to download the content.
- The PowerShell App Deployment Toolkit functions are dot-sourced after the Teams executable is validated.
- The Execute-ProcessAsUser cmdlet from the Toolkit is called to invoke the Teams executable under the user’s context.
- The executable is deleted.
This solution has eliminated many thousands of vulnerabilities that were caused due to the Teams installation sitting unused or the automated updater not running as expected. The best part? The URL structure is predictable and one could conceivably use TanREST to ask Get Installed Application Version[Microsoft Teams] from all machines, parse the highest version, generate the URL, and kick off an action to deploy that parameterized package on a fully-automated basis. I’ll throw that one on the list for later.
Disclaimer: Any code made available on this site is free to use at your own discretion but it is provided without any explicit or implied guarantees of support, reliability, or functionality. I accept no responsibility in the event that the code, in its original form or any derivative versions thereafter, malfunctions or causes problems . Anything from this site that you decide to work with should be tested thoroughly in development environments in collaboration with your Technical Account Manager (TAM) until such time that you, the responsible party, decides that you are satisfied with its outcomes.