PowerShell, Security Kieran Jacobsen PowerShell, Security Kieran Jacobsen

Mitigating IE Zero-Day (CVE-2020-0674/ADV200001) with PowerShell and Intune

Microsoft published a security advisory (ADV200001) containing mitigations against an actively exploited zero-day remote code execution (RCE) vulnerability in Internet Explorer. At time of writing, there is no patch for the vulnerability. Microsoft is expecting to release a patch as part of the usual Patch Tuesday (Wednesday for some of us) cycle.

Microsoft has provided some mitigation steps that can be applied; however, they only recommend taking these steps if there is an indication you are under elevated risk. One of the problems with the mitigation steps is that you MUST revert the changes before you can install any future updated.

The mitigations also come with some side-effects; their impact might be too much for some organisations. Side-effects include:

  • Printing to HP printers and other USB printers mail fail.
  • Windows Media Player is reported to break on playing MP4 files.
  • Sfc.exe will break.
  • Printing to "Microsoft Print to PDF" is reported to break.
  • Proxy automatic configuration scripts (PAC scripts) may not work. For me, I couldn’t imagine managing some enterprise environments without PAC scripts. That alone would be a good reason to not deploy these fixes.

If after all of this, you want to still apply these mitigations. I put together some quick guidance for their implementation with Intune.

Enabling the mitigations

  1. Get a copy of the Enable-ADV200001.ps1 script from my GitHub repository.
  2. Sign-in to the Microsoft Endpoint Manager Admin Center.
  3. Select Devices > PowerShell scripts > Add.
  4. In Basics, enter the Name: Enable IE Mitigations for ADV200001, and select Next:
  5. In Script settings, browse to where you downloaded the Enable-ADV200001.ps1 script, leave everything else at their default settings, and select Next:
  6. Select Scope tags. Scope tags are optional, if you don’t use this feature, select Next.
  7. Select Assignments > Select groups to include. Select with groups this script should be applied to, select Next.
  8. In Review + add, a summary is shown of the settings you configured. Select Add to save the script. When you select Add, the policy is deployed to the groups you chose.

Disabling the mitigations

  1. Get a copy of the Disable-ADV200001.ps1 script from my GitHub repository.
  2. Sign-in to the Microsoft Endpoint Manager Admin Center.
  3. Select Devices > PowerShell scripts > Add.
  4. In Basics, enter the Name: Disable IE Mitigations for ADV200001, and select Next:
  5. In Script settings, browse to where you downloaded the Disable-ADV200001.ps1 script, leave everything else at their default settings, and select Next:
  6. Select Scope tags. Scope tags are optional, if you don’t use this feature, select Next.
  7. Select Assignments > Select groups to include. Select with groups this script should be applied to, select Next.
  8. In Review + add, a summary is shown of the settings you configured. Select Add to save the script. When you select Add, the policy is deployed to the groups you chose.

More guidance can be found here Use PowerShell scripts on Windows 10 devices in Intune

Just remember that before your next patch cycle, you need to disable the mitigations, otherwise the updates will fail.

Read More
Azure, Security Kieran Jacobsen Azure, Security Kieran Jacobsen

DNS Squatting with Azure App Services

Several days ago, a post titled: Microsoft Resnet - DNS Configuration Web Vulnerabilitygrabbed my interest. It has an innocuous title, and I hadn’t recalled anyone else talking about a Microsoft DNS Vulnerability. The post wasn't that long, the description and the proof-of-concept are only a few paragraphs in length; however what I did discover was an interesting vulnerability, one that, I feel, is going to become more and more prevalent with the use of Platform As A Service (PaaS) technologies like Azure App Services.

TL DR

  • SaifAllah benMassaoud from Vulnerability Lab discovered that resnet.microsoft.com was resolving to resnetportal-prod.azurewebsites.net, however there was no Azure App Service at this address.
  • Anyone could have established an App Service with this DNS name, and thus squat on a microsoft.com subdomain.
  • This vulnerability has the potential to affect any organisation that is using App Services (or similar PaaS services) and custom domain names where they do not have appropriate controls in place.

Like many involved in the InfoSec industry, I monitor a bunch of vulnerability disclosure feeds. They can be a valuable source of knowledge: new techniques, new bugs, new breaches or just interesting tools and technology.

Several days ago, a post titled: Microsoft Resnet - DNS Configuration Web Vulnerability grabbed my interest. It has an innocuous title, and I hadn’t recalled anyone else talking about a Microsoft DNS Vulnerability. The post wasn't that long, the description and the proof-of-concept are only a few paragraphs in length; however what I did discover was an interesting vulnerability, one that, I feel, is going to become more and more prevalent with the use of Platform As A Service (PaaS) technologies like Azure App Services.

Simply put, in this situation, someone had created a CNAME entry within Microsoft’s DNS to point resnet.microsoft.com to resnetportal-prod.azurewebsites.net, unfortunately, resnetportal-prod.azurewebsites.net didn’t exist. This doesn’t sound that bad? Right?

ihaveabadfeeling-luke.gif

For those who are not familiar with the azurewebsites.net domain, this is the domain used by Azure App Services to host services. When you create an App Service, you specify a name, like myawesomewebapp.azurewebsites.net, you can then deploy your application to that App Service. You can pick whatever you want as the applications name, as long as no one else has taken it before you.

You can optionally specify a custom domain name for your App Service, like myawesomewebapp.com, and use a CNAME entry to map your custom domain to your azurewebsites.net domain (you can now also use an A record).

You should now be able to see the problem; resnetportal-prod.azurewebsites.net didn’t exist yet the name resnet.microsoft.com was pointed to this App service. What does exist is a great squatting/hijacking opportunity. Anyone could have signed up for an Azure Subscription, created an App Service with the name resnetportal-prod.azurewebsites.net and then hijacked resnet.microsoft.com. Vulnerability Lab maanged to discover a pretty significant issue.

What could one do with a subdomain of microsoft.com? Phishing, credential theft, and ransomware comes to mind pretty quickly. I am sure an APT crew would love to have a domain or subdomain like this. There are probably only a few domain names in the world where the average user and even the average system administrator are extremely trusting, and microsoft.com would have to be one.

It isn't just the big organisations like Microsoft at risk. Any company that makes use of PaaS services like Azure App Services and CNAME entries could potentially become the next victim. Attackers might use your domain name to attack others or perhaps create more effective attacks against your own users.

Let’s consider our friends Contoso Limited; they deployed an application for their users to contosoapp.azurewebsites.net, they also established a custom domain name, home.contoso.com. The app was used for some time, and eventually they decide to decommission it. A developer, maybe a sysadmin deletes the Azure App Service, but in their haste, they forget about the DNS entries. More time goes by, and now Bob from an APT group finds the entry for home.contoso.com pointing to contosoapp.azurewebsites.net, he then goes and sets up his own App Service and hijacks home.contoso.com.

Bob the sends out this email to some Contoso email addresses:

Subject: New Employee Experience
From: Contoso Marketing
Body:
    Hi Team,

    We have launched a new employee portal, it is great and has a bunch of awesome features. The site can be found at http://home.contoso.com. 

    From,

    The Contoso Marketing Team

Bob doesn’t even need to hide the links in the email, he doesn’t need any of the usual masking techniques, he can simply display the company’s domain name. If the email structure, text and links are well crafted, how would Fred from Accounting determine if this was a legitimate email?

When a user navigates to the page, perhaps it prompts for credentials, maybe it tries to run a browser exploit? I have no doubt that a campaign against an organisation like this would be extremely successful.

Now the details of how SaifAllah benMassaoud from Vulnerability Lab initially discovered the misconfiguration are not described in the release. I am going to guess that he probably used an automated DNS enumeration tool like DNSRecon and DNSNinja. These make the discovery of DNS records easy, and it would be easy to automate additional checks based upon their results to find vulnerable configurations.

In terms of defending against these issues, there are two methods, both of which need to be implemented by organisations:

  1. Appropriate change control processes: If an App Service or similar PaaS solution is being decommissioned, processes should be in place to ensure that any associated DNS records are removed;
  2. Monitor your DNS zones for configuration issues: Have automated scripts that check and send alerts if configuration issues are found.

If you haven’t looked at a DNS management tool like DNSControl, do so now! DNSControl was originally developed by Stack Overflow, and you don’t need to have hundreds of domain names and records to gain value from a tool that allows you to manage DNS as code.

DNSControl uses a Domain Specific Language for defining domains and their records, independently of your provider. You can use macros and variables to simplify your configuration. My favorite features is the ability to configure multiple DNS providers, this is great for migrations and for fault tolerance. The CloudFlare provider still allows for control over their proxy as well, ensuring that all of our configuration remains in source control.

Defending against this vulnerability is fairly simple, practice good change control processes and monitor your DNS zones. DNS enumeration tools like DNSRecon and DNSNinja can also assist in determining your organisations risk, whilst DNS as code tools like DNSControl will give us better control over our DNS change processes.

Kieran Jacobsen

Read More
PowerShell Kieran Jacobsen PowerShell Kieran Jacobsen

Microsoft Releases PowerShell to Linux and OS X!

The Announcement

On Friday I woke to the remarkable news that PowerShell has been open sourced, and made available on Linux and Mac. You should read the PowerShell Team’s Announcement, and Jeffrey Snover’s announcement. There is an excellent video on Channel 9, PowerShell on Linux and Open Source.


I want to first start by congratulating everyone over at Microsoft, in particular the PowerShell Team and Jeffrey Snover.  I have been an avid user of PowerShell since the codename Monad days and it has been one of the few technology constants in my 10 years in the industry (the other being Active Directory).

It has been a long road since the original Monad Manifesto to reach this milestone, and it could not have been accomplished without Jeffrey’s amazing efforts. Don Jones posted up an excellent article on just why this is such an important accomplishment, you should also read the PowerShell Team's post: Windows PowerShell is now “PowerShell”: An Open Source Project with Linux support – How did we do it?.

This wasn’t an unexpected announcement, in fact, it was quite expected. I never doubted that this accouncement would never occur, to me it wasn't a matter of IF PowerShell would become open source, but WHEN.

Like almost everyone I was in the dark that this was happening, but I had a gut feeling things were close. There were plenty of clues and signs that this was about to happen: .Net Core, Nano Server, Bash on Windows and even the inclusion of Pester in Windows 10. Still, I wasn’t quite expecting to wake up on Friday to the news.

What Was Announced

Microsoft announced that from PowerShell would be run as an open source project, and that an intial alpha release would be made available. This release is version 6.0 and is currently available PowerShell Core, for Windows, Ubuntu, Centos and Mac OS X, with more platforms expected in the future.

So what is PowerShell Core? Core is a cut down version of PowerShell, designed to run on top of the .Net Framework Core edition. We have already seen PowerShell Core in releases of Windows Nano Server. Core edition does not support all of the functionality that the Desktop version will contain.

It is worth noting that this is an alpha release, and as such, you should treat it, and have suitable expectations. This isn’t a production ready release, and likely isn’t going to be for a while yet.

Changes to Remoting

One of the big items in the announcement is the changes to the PowerShell Remoting Protocol (MS-PSRP). Currently the MS-PSRP only supports WinRM, however with PowerShell 6.0, support for SSH will be introduced.

This isn't executing commands over SSH, what is actually occuring is that the objects forming our request are serialized into XML, transmitted over SSH, and then de-serialized. SSH is used as a transport layer for the remoting protocol, mush like WinRM is currently used. SSH is not replacing WinRM, just providing another option for administrators to use.

What this does mean is that you will start to be able to manage your Windows servers from your Macbook, and your Linux servers from your Windows 10 machine. 

I had a significant number of issues with WinRM. From its poor performance to its insecure defaults, and I am hoping that the inclusion of SSH support should start to make a difference. If nothing else, it provides a number of new and interesting ways to design and manage our environments.

What’s Missing?

This is a PowerShell Core release, it is based upon the .Net Core, and as such, some things are just simply not going to be there. It should also be obvious that things like WIM and CIM are not supported and will not be available. Get-EventLog isn't there either, as it doesn't fit with the Linux log file model.

Security Impacts!

Security teams should begin to familiarise themselves with not only PowerShell 6.0 and its remoting changes now, but also with Nano Server prior to their release. With a cross pollination of administration teams, that is, Windows and Linux administrators managing each other's eco systems, we are going to see changes in our network architecture and security requirements. SSH connections from a Windows system will begin to move from the abnormal to the normal.

PowerShell is already a highly desirable target for attackers, with more instances of attacks using PowerShell on a daily basis. With the move to include PowerShell on Linux systems, especially servers, the attraction of PowerShell to attacks is likely to increase. The ability to move from a Windows client to that lovely Red Hat farm makes PowerShell an awesome attacker and Red Team tool. Some in the security industry are already calling PowerShell the next Flash or Java for cross platform hacking.

I guess the other thing we need to consider is that a significant number of people are probably pouring over the PowerShell source code with the intention of finding vulnerabilities. Whilst the chances are probably small that someone might find a significant issue, there is still the possibility.

Other Investments to Watch

Looking through the known issues document, and also the PowerShell Teams announcement, two items stood out to me:

  • The ability to write CMDLets in Python and other languages
  • Unix-style wildcard expansion

Getting Started

The best place to start is the PowerShell Home Page, after that, the PowerShell GitHub repository is your next stop.

Windows

It is worth noting that installing PowerShell 6.0 will not replace your existing PowerShell version, it is installed side-by-side. It is also worth noting that this installs Core edition and not Desktop edition.

Simply grab the right MSI, and run the installer

Linux

There are official guides for Centos 7, Ubuntu 14.04 and Ubuntu 16.04. The Centos guide should also work for Red Hat.

There are also two great guides:

Mac OS X

You can find Microsoft's instructions for installing here, for more detail check out The IT Hollow's guide, Install PowerShell on Mac.

Other Install Options

There are a bunch of other ways you can get started with PowerShell 6.0:

Once you have PowerShell installed, take a look at some of the demos available.

If you are new to PowerShell and are coming from a Linux or Unix background, check out: A Unix Persons Guide to PowerShell.

Contributing

The great part of any open source project is that we can all play our own part and contribute. You don’t need to be a developer to contribute either, I often contribute to projects by helping out with documentation, or cleaning up simple default configuration files and example usage.

If you feel like contributing, start by reading the contribution guidelines. I also recommend you take a look at the governance process. The Governance process includes how to raise issues, make contributions, and participate in the design process via RFCs. The documents also provide information on the roles and responsibilities of everyone involved in the project.

I recently spent some time working on some issues with the documentation of the PSScriptAnalyzer. The contribution process is similar to that of PowerShell, and it was super simple and easy to create a pull request and work with the PowerShell Team. I would like to point out that if your pull request is large, you may need to sign the Contribution License Agreement, don’t worry, it isn’t difficult and only takes a few seconds to complete. The agreement just covers that the work you are completing is yours and not of anyone else.

Tool Updates

Update your development tools! Virtual Studio Code (and the PowerShell extension), PSScriptAnalyzer and the ISE Steroids have all been updated to include support for PowerShell 6.0.

More Information

With all of this you should be well on your way to working with PowerShell on Linux and Mac OS X! Good luck and don't forget to share your experiences!

Kieran Jacobsen

Read More
Security Kieran Jacobsen Security Kieran Jacobsen

How the Skype team failed at PowerShell

The Skype for Business team recently sent out an email to preview customers with guidance around the Skype Meeting Broadcast feature. As I was away, Readify’s CIO, Tatham Oddie was the one who actioned it. The guidance in this email has a number of issues, leading him to post his thoughts up on Twitter, needless to say, he didn't like their advice!

The instructions were pretty simple, as you can see:

A full copy of the email can be found here.

I was shocked when I saw the guidance, from requiring elevation, to changing the execution policy without informing the user, and then a Lync reference to top it all off. I felt that some things needed a discussion.

Unneeded Elevation

The user is asked to run an elevated PowerShell session on two occasions. This is two too many.

For the first instance, the user is asked to run an elevated PowerShell simply to execute Get-Host. GET-HOST! There is no conceivable reason why you would ever need to be elevated to run this CMDLet. I think Get-Host is probably one of the simplest CMDLets in existence, yet the Skype for Business team felt like it needed to be elevated.

Open PowerShell as an administrator (Right click on icon and click run as administrator)

Now the second elevation attempt is almost legitimate. During the step titled “Connect to your Office 365 tenant through remote PowerShell”, we will be executing Set-ExecutionPolicy. Unfortunately, I will discuss later why this command shouldn’t be here, and hence there is no reason for elevation.

Open PowerShell as an administrator (Right click on icon and click run as administrator) and issue the following cmdlets:

Any time you elevate, you need to be more aware of what you are doing. In most cases, elevation is only required if you are making changes to the local system. Instructions to configure a cloud based service requiring elevation should be ring big honking alarm bells, maybe even giant ones. Why on Earth would I be making changes locally, when configuring a cloud service?

I don’t run as local administrator; my every day account is not a member of the local administrators group. This has the unfortunate side-effect of breaking much of Windows 10 (thanks Gabe), however it dramatically improves your security posture. Even if UAC was bypassed, my account isn’t a member of the group, it doesn’t have the privileges you seek. When I need to elevate, it’s a conscious decision on my part, do I want this app to do this, do I want to make this change? I very much believe that all users, be they home users, developers, or system administrators, should run in this model. As a side note, its painfully obvious that most of the Microsoft development team runs with local admin.

Changing The Execution Policy

Set-ExecutionPolicy Unrestricted

I always get a bit upset when someone or something changes the execution policy and in the guidance, that is exactly what the Skype for Business team want to do. Not only have they decided to make this change for me, but they have picked one of the least secure settings, unrestricted. They haven’t even made an attempt to switch it back and the end of the execution process.

The first thing I want to point out is that the Skype for Business CMDLets will work perfectly on execution policy of AllSigned and RemoteSigned. They are after all signed with a code signing certificate issued to Microsoft. After going through all of the effort to get their modules signed, the Skype team simple went YOLO, let’s set the policy to Unrestricted.

They could have of course gotten the user to run simply that PowerShell session as unrestricted, or they could have recorded what the policy was before they changed it, and switched it back. Like this:

There has also been no attempt at even checking what the execution policy was previously, perhaps all would have been OK? Why not have this as a prerequisite step?

Finally, they have made the assumption that the user receiving this guidance can change the policy. I have worked in a few environments where group policy would step in and prevent setting the execution policy to unrestricted.

What is an Admin with MFA to do?

It would have been great to see a mention of what an admin with MFA enabled, should do to run these commands. Thankfully the Skype for Business team allow the use of App Passwords, unlike their poorly informed and aggravatingly annoying peers in the SharePoint and Exchange online teams who reject app passwords.

Is that a Lync reference?

$LyncSession = New-CsOnlineSession -Credential $credential

I know Tatham and I are being pedantic, but a Lync reference, seriously? Microsoft announced that Lync would be replaced by the Skype for Business branding a year ago!

What the email should have looked like

I don’t like tearing things apart without helping to fix them, so how could the Skype team have done things better?

Well here is one that I prepared:

To get started with Meeting Broadcast please follow these steps:

Setup PowerShell
Open PowerShell

To check your PowerShell version, enter this cmdlet:

Get-Host

You must have version 3 or higher. If you have a lower version, install PowerShell version 4: http://www.microsoft.com/en-us/download/details.aspx?id=40855

To check you have the Skype for Business module installed, enter this command:

Get-Module -ListAvailable -Name SkypeOnlineConnector

If there is no results listed, Install the Skype for Business module: http://www.microsoft.com/en-us/download/details.aspx?id=39366

To check you have the correct execution policy level, enter this command:

Get-ExecutionPolicy

If the output is undefined or restricted, please view our guidance on setting the execution policy to RemoteSigned: http://www.microsoft.com/some-guidance-here

Restart your computer (as it may not be prompted to do so).


Connect to your Office 365 tenant through remote PowerShell
Open PowerShell and issue the following cmdlets:

$Credential = get-credential
$Skype4BusinessSession = New-CsOnlineSession -Credential $credential
Import-PSSession $Skype4BusinessSession

Note: If your account has Multi-Factor Authentication enabled, please ensure you use your username and an app password.

As you can see, there are a number of changes.

  • There are no elevation requests in the instructions. We check the prerequisites with no elevation, and the connection instructions no longer require elevation either.
  • There are now appropriate checks to ensure the Skype for Business Online Connector is installed. This is a simple touch, but makes the process much easier for users.
  • Checking what the Execution Policy is, and we link to Microsoft guidance on what the appropriate policy is, and how to change the policy.
  • I removed the Lync reference.
  • Changed the restart wording. Sometimes when you install the module, it doesn’t correctly prompt for a restart, but it does indeed need a restart.
  • Added a note around what to do if MFA is enabled.

None of these changes were very difficult, nor where they very time consuming. I really don’t understand why no one at Microsoft picked up any of these issues prior to the email being sent off. I can’t see any excuses for missing this issues, they were painfully obvious.

Kieran Jacobsen

Read More
Security, PowerShell Kieran Jacobsen Security, PowerShell Kieran Jacobsen

Why isn't Remoting Disabled by Default on Windows Server?

I was recently involved in a brief and quite lively Twitter discussion with Don Jones and Jeffery Snover about PowerShell Remoting and why it is enabled by default. I have been involved in a number of discussions about this topic, but never with such a distinguished crowd such as this one. My opinion, and my original comments, where along of the line of  “I believe Remoting should be off by default”, “Well, RDP is disabled by default, why not Remoting”, and “SSH has been off by default for years”, whilst the counter arguments were of the form “Because Nano Server” or “You could always customise your environment to be off by default”. 

Don Jones posted a follow up to this discussion on PowerShell.org titled “Why is Remoting Enabled by Default on Windows Server?” and asked me to put together a post on why I felt it should be off by default. This was difficult for me to put together, so here goes!

It has long been an industry practice, to disable/stop services which are not in use on your clients and servers. The argument is quite simple, enabled services are vulnerable servers, they expose your devices to potential risks. Simply having Remoting off, unless explicitly required, will reduce the attack surface area and increase the security of our systems.

Even Microsoft has followed an off by default methodology for the past 10 to 15 years. Services like POP3 and IMAP are off by default in Exchange, SQL servers do not listen for IP addresses by default, we need to install roles and features individually. Microsoft learnt from a number of major security blunders in the early days (Code Red, Slammer and even Blaster), and focused on a more secure development and deployment model. Why should there be an exception to this posture that has worked extremely well since Windows 2003?

Linux administrators, and developers of Linux distributions have been in a similar situation in the past. For a significantly long period of time, SSHD has been off by default, and administrators have still be able to manage their server fleets. One of the early reasons for an off by default approach in Linux, was that it ensured that administrators were aware of the risks prior to enabling SSHD. Now it can be argued, that this has been a failure, and I think most would agree. I do, however, believe that the failure is not in the off by default configuration, but is in the lack of documentation covering the secure configuration of SSHD. People in glass houses shouldn’t throw stones, as Remoting can be just as poorly deployed.

Remote Desktop is a great example where Microsoft followed these methodologies. RDP is off for a number of reasons with security being only one of them. Ironically, one of the obvious reasons to have RDP off by default is to encourage the move from on server management to remote management. Whilst adoption has not been as high as was expected (due to issues with third party vendors, administrators and to a big extent Microsoft), it is clearly a sign of how ahead of the curve Microsoft has been.

It has become increasingly dangerous to expose management services, be they SSH or RDP on the Internet. If you have ever been responsible to auditing the log files of a server where SSH or RDP is exposed to the Internet, you will be well aware of the automated scan attempts that are performed. Brian Kreb’s has posted on Internet criminals selling access to Linux and Windows servers whose credentials they have brute forced. What happens when the criminals discover Remoting? Bruteforcing credentials via Remoting should be even easier and have written about just such a thing on previous occasions. Should we be enabling these criminals and providing them with even more machines that they can take over?

Well, we are doing this to an extent right now. Users, administrators and developers have all been busy provisioning virtual machines on platforms like Azure and AWS, and whilst in many cases RDP endpoints are on random high ports, the same cannot be said for Remoting. Those who deployed and manage these systems may be well unaware of the risks that they have introduced to their networks. Moving to an off by default model could protect these environments from this sort of configuration error.

As a side note, it is still interesting to me how Microsoft changed Remoting from off to on by default in Windows Server 2012, with very little fanfare. In 2014 when I presented on Lateral Movement with PowerShell, audiences typically responded with a significant amount of surprise, be they from an administration or security background.

In Don’s post, he talks about the fact we could easily create an off by default environment if we so wanted. I really have to disagree with him, and say that he has missed the point to a degree. Whilst it is true, that we could use a customised gold/master image, Group Policy or some other tool to create an environment where Remoting is off by default, it must be highlighted that the inverse, an on by default environment would be just as simple to create with these tools. If you want it on, then turn it on, it isn’t that hard. 

Don also talks about the fact that Remoting is an incredibly controllable, HTTP-based protocol. This introduces the other issue I have with Remoting. Unless you are deploying an Azure Virtual Machine, post install, you will be exposing Remoting over HTTP and not HTTPS. Is this 2015 or 2001? Do we really still need to talk about the virtues of HTTPS? It would be trivial for Microsoft to change the default from HTTP to HTTPS in a manner similar to RDP. 

Now let’s talk about the big elephant in the room, or should I say Nano elephant in the room? What about Nano Server?!?!? Nano Server, whilst it is a new concept for some of us, isn’t a completely new in our industry. Whilst I agree, it is probably easier to have Remoting (and WMI) enabled by default, it isn’t like the deployment of a Nano Server is currently a simple process. Currently Nano Server is coming as a standalone WIM image, we need to manually add packages providing roles, and we currently need to join a domain during installation. How hard would it be to have a step enabling Remoting? It is trivial. 

Having said all of that, perhaps the best middle ground would be to have Remoting enabled on Nano Server, and off for Core and Full installs? Administrators have more option on the latter two than the former. Perhaps a compromise is in order?

Another side note, why doesn’t Microsoft want to enable Remoting on Clients? If Remoting is safe for Internet exposed servers, shouldn’t it be ok for Windows Clients?

So in summary, why should Remoting be off by default?

  • Off by default is an industry standard practice.
  • Off by default has been Microsoft practice for over 10 years.
  • Linux administrators deal with SSHD off, so can we!
  • RDP has been off by default, we lived with that.
  • RDP and SSH are actively brute forced, why open up another attack vector?
  • Off by default reduces administrative misconfiguration/insecure configuration
  • It is just as easy to switch it on, as it is to switch it off.
  • Nano Server isn’t as much of a challenge as we thing, but it could be the exception.

As Don said, whether you agree or not, it is entirely up to you and you are welcome to add your polite, professional comments to this post, or over at the PowerShell.org forums where I have cross-posted. Like Don, I wanted to explain and attempt to justify why I think Microsoft’s approach is not correct. I often believe the discussion is more important than the outcome, and I believe this is definitely the case here.

Kieran Jacobsen

Read More
Security, PowerShell Kieran Jacobsen Security, PowerShell Kieran Jacobsen

MS15-034 Update

I just wanted to let everyone know that over the past few days I updated my MS15-034 code to support HTTPS connections. The work involved was much easier than I expected, so I felt that it was worth including.

Working with HTTPS is pretty simple. I have followed the usual convention and defined the –UseSSL parameter, it should be noted you will need to specify a port with the –Port parameter as well. Typically –Port 443 –UseSSL will perform what you need.

Let’s take a look at a few quick examples.

1)    Testing a Windows 2012 server with HTTPS and determining if it is vulnerable:

2)    Invoking the DOS, this time there is a custom port number in use:

One thing to note, the certificate will be validated, so make sure it is trusted/valid etc.

I am still seeing and hearing of this attack occurring, with a significant number of systems still remaining unpatched. I still haven’t seen any code examples supporting Remote Code Execution (RCE), but I am sure someone has figured that one out and is keeping it very secret.

You can find the updated code at the GitHub repository MS15034, or download the code as a zip file.

Kieran Jacobsen

Read More
Security, PowerShell Kieran Jacobsen Security, PowerShell Kieran Jacobsen

Exploiting MS15-034 with PowerShell

Updates have been made available to this code to support SSL. See the update here.


On Thursday morning, I woke up to an extremely busy Twitter stream; the topic which that was on everyone’s’ lips was Microsoft Security Bulletin MS15-034.

MS15-034 is a critical security bulletin impacting HTTP.SYS, which forms a core component of IIS and a number of other Windows roles and features. The vulnerability described in the bulletin is a Remote Code Execution (RCE) however at the time of the publication of this post, only a Denial of Service (DOS) of the system has been achieved. There are a number of claimed RCE pieces of code on sale, yet none have been verified.

Over the days since the original release of the bulletin and its associated fixes, things have moved quite quickly. Simple detection (more) and exploitation code had been developed, as well as more complex pieces and even a Metasploit module. Now it is fine for those of us who have Linux systems, or even maybe those who have Windows ports of perl, python, curl or wget installed to use a number of these scripts/examples that are out there, however I feel it is important that this be presented in a way that is accessible and understandable by the average Windows administrator.

Chris Campbell (@obscuresec), put together some PowerShell code that would allow administrators to determine if a system was vulnerable. Unfortunately, there were some issues with this code that means it isn’t as effective as it could be. Firstly, Chris’ code doesn’t report if any other HTTP errors are generated, for example, if you specify an invalid page, the code wouldn’t alert you to the HTTP 404 that would be returned. The next issue is that a non-vulnerable system returns a HTTP 400 after the patch, something the code doesn’t pick up on. Finally, the range header values specify do not match what has been specified in other pieces of code. I felt we needed not only PowerShell code to test if a server was vulnerable, but that it would be interesting to see if we could also exploit a vulnerable server.

Now it should be noted, that you simply can't use the .Net WebRequest class to specify the appropriate “Range” header values, you need to use the TCPClient class and run at a lower level. This is more of a separate discussion I will leave for a later post.

Over the course of past few days, I developed PowerShell code, heavily inspired by the Metasplout module, to allow for the testing and exploitation of MS15-034. This code is contained in the module, MS15034.psm1 up on the Posh Security GitHub. There are two functions which will be of interest; Test-MS15034, which allows for the testing of servers, and Invoke-MS15034DOS which is capable of performing a denial of service against a specified target.

Testing

The CMDLet Test-MS15034 requires the specification of a computer name or IP address, and optionally a port number, and then 3 different parameter sets:

  1. Specifying the -Windows2008 parameter
  2. Specifying the -Windows2012 parameter  
  3. Specifying a custom HTTP path with the -ServerPath parameter

The first two are simply to simply the testing against lab environments, as they will connect to the URL of the format http://<Computer>/welcome.png and http://<Computer>/IIS-85.png respectively. The third option is to specify your own HTTP path, which is something you are more likely to do in a real world scenario. You can specify any file or structure using -ServerPath, examples could be:

  • /index.html
  • /CompanyLogo.png
  • /images/logo.jpg

Let’s look at some examples (these may not display correctly via RSS)!

1) Testing a Windows 2008 server and determining that it is vulnerable:

2) Testing a Windows 2012 server and determining that it is vulnerable:

3) Testing a Windows 2012 server and determining that it is not vulnerable :

4) Testing a server using a custom server path and determining that it is vulnerable:

5) Testing a server and specifying the wrong operating system (or the default files do not exist):

6) Testing a server using a custom server path, which doesn't exist:

This CMDLet will connect to the URL determined by the parameters, specifying the header Range: bytes=0-18446744073709551615. If the response from the server is a HTTP 416, then it is vulnerable, if the response is HTTP 400, then the server is not vulnerable. Other errors will be displayed and managed accordingly. 

Exploitation

Now let’s take an attack to the next level and take the server down! The CMDLet Invoke-MS15034DOS will do the trick for us. This CMDLet works much like the Metasploit module. The CMDLet accepts the same parameters as Test-MS15034, however it will begin by testing if the server is vulnerable, and if so, will then perform a denial of service.  The denial of service will be performed by specifying the header Range: bytes=0-18446744073709551615. 

 

In the examples that follow, I am simply using the default out-of-the-box images as the addresses, much like in the previous tests.

1) Invoking a denial of service against a Windows 2012 (R2) server:

2) Invoking a denial of service against a Windows 2008 (R2) server:

3) What happens if you try to invoke a denial of service against a patched server:

Next is a video of Invoke-MS15034DOS against an unpatched Windows 2012 R2 server. Note how quickly the server is taken down. I think it makes a nice alternative to Restart-Computer.

It should be noted that my code will only support HTTP and not HTTPS. I could develop support for HTTPS, but I suspect that in most environments, testing if a server is vulnerable via HTTP will be sufficient.

You can download my module from my GitHub repository MS15034, a zip file can be found here.

I really hope people will find this code useful. I will be putting together some follow up posts on this topic, including some observations around the issue and how I developed the code.

Kieran Jacobsen

Read More
PowerShell Kieran Jacobsen PowerShell Kieran Jacobsen

Automating Office 365 deployments in CloudFlare

A few weeks ago, I wrote about Posh-CloudFlare, a PowerShell module I created for managing CloudFlare hosted domains. Since then, I was working on extending an Office 365 deployment, and realized that what was needed was a script which could automate the configuration of new domains. With that in mind, I developed a new PowerShell script,  Posh-Office365CloudFlare.

Let's understand the process for the addition and configuration of a new domain for Office 365.

The process starts with the Office 365 Portal. We navigate to the Domains section, click the "Add Domain" button, and after ignoring the introduction, we proceed to step 1. This step starts with us entering our domain name, let's use our old favorite contoso.com. Now we will be asked to verify that we own this domain, either through the creation of a TXT record or an MX record. The typical method is to use is that of a TXT record, created at the root of our desired domain with a value something like "MS=mx********".

After we create the domain, and the wizard successfully sees the appropriate record, we will be allowed to proceed to the next step. Step 2 isn't one that I usually make use of. I typically don't want to modify my users email domains, nor do I want to add new users at this time. I skip this step and move straight on to step 3.

Step 3 starts with another quick introduction screen, and then we will be asked if we would like the DNS for this domain to be managed by Microsoft. Obviously, we are going to answer no and move on. Finally, we reach an important step, we are asked what we want to do with this domain. First, "Outlook for email, calendar, and contacts", or in other words, email; the second, "Lync for instant messaging and online meetings", which is kind of obvious.

If you select “Outlook for email, calendar, and contacts”, then we will be told to create the following records in contoso.com:

  • MX - @.contoso.com - which points to contoso-com.mail.protection.outlook.com (priority 0)
  • CNAME – autodiscover.contoso.com – which points to autodiscover.outlook.com
  • CNAME – msoid.contoso.com – which points to clientconfig.microsoftonline-p.net
  • TXT – @.contoso.com – which contains a SPF record

If you select “Lync for instant messaging and online meetings”, then we will need to create the following records for contoso.com:

  • CNAME - sip.contoso.com - which points to sipdir.online.lync.com
  • CNAME - lyncdiscover.contoso.com - which points to webdir.online.lync.com
  • CNAME – msoid.contoso.com – which points to clientconfig.microsoftonline-p.net
  • SRV - _sip._tls.contoso.com - with its appropriate port, weight, priority and target
  • SRV - _sipfederationtls._tcp.contoso.com - with its appropriate port, weight, priority and target

Reviewing this list of records, we will notice that the only record that changes for each domain is the MX record. The record consists of the domain name we want to add, with dashes replacing the original dots in the domain name. As you can see in the above example, cotoso.com's MX record points to contoso-com.mail.protection.outlook.com, where as awesomecompany.net would point to awesomecompany-net.mail.protection.com. 

What about some records that could actually help our users? What if I said we could redirect sub domains of our own to the Outlook Web Access page? Wouldn't it be awesome if a user entered https://mail.contoso.com into their browser, and ended up with the Outlook Web Access? This can be achieved by creating a CNAME record that points to mail.office.com. Let's have our script create entries for mail and webmail perform this redirection.

Now back to the script.

This was a simple script, it doesn't have any complex logic, it will need the following information:

  • CloudFlare API Token and email address; this is obvious as we need to talk to the CloudFlare Client API.
  • The domain name.
  • Do we want to create mail records? Lync records or both?

This is a very, very simple script, we just need to have a set of New-CFDNSRecord calls, with various controls depending on what we require.

For example, creating the MX record is as simple as:

This script only took an hour or so for testing and development time, however there was quite a bit of effort directed to changes in the Posh-CloudFlare and the New-CFDNSRecord CMDLet. If you look at the diff's between the last few versions, you will notice the following changes:

  • The CMDLet now accepts input from the pipeline (in this case via property name).
  • Restructure the CMDLet into Begin/Process/End (required for proper handling of pipeline input).
  • Implementation of parameter sets.
  • Cleanup of the validation of parameters.

I added parameter sets to New-CFDNSRecord with the aim to remove the somewhat faulty validation that I had previously. Whilst this sounded, and looked like it was simple, it actually took a few tried to ensure that the CMDLet would function appropriately. This was really interesting and deserves its own post in the future.

Parameter validation was updated in all of the CMDLets to improve email address validation. Previously, validation consisted of testing for an "@" character. Now I am using a regular expression.

Finally, I have spent some time cleaning up the code, not just within New-CFDNSRecord, but across all of the CMDLets. I have been trying, where possible to use ISE Steroids to ensure that everything I right is neat and presentable; it is a fantastic resource.

My final thought on all of this journey is, why couldn't Microsoft have implemented something like this? Microsoft has integrated the process with a bunch of other DNS providers, including the likes of GoDaddy, Network Solutions, 1 and 1 and even Yahoo Small Business. Why can't it also look at CloudFlare?

You can find the finished script over at GitHub, at Posh-Office365CloudFlare, the script is called Register-Office365.ps1. I have included comment based help with examples.

Kieran Jacobsen

Read More