Improve security with PowerShell’s constrained language mode

History has conclusively demonstrated that cyberattackers will take advantage of any perceived weakness in a system in order to gain access to a system. Although some have downplayed the idea that PowerShell can be used as a tool for attacking a system, there have been quite a few documented instances of attackers doing just that. Since PowerShell can sometimes be of interest to those who have bad intent, it is a good idea to harden PowerShell whenever possible in an effort to prevent it from being exploited. One option for doing so is to enable constrained language mode within your PowerShell sessions.

What is constrained language mode?

So what is the constrained language mode? Simply put, the mode is a tool that can be used to limit the types of commands that can be executed within a PowerShell session. Let me give you a really simple example.

If you look at the figure below, you can see that I have opened two separate PowerShell windows. The top window is completely normal. As you can see, I entered a mathematical expression into this window. This expression asks for the square root of 64. PowerShell returned a value of 8, which is the correct answer. The figure’s lower PowerShell window has the constrained language mode enabled. I entered exactly the same mathematical expression into this window, but received an error message telling me that PowerShell was unable to invoke the method.


OK, so what’s really going on here? How come the command failed in one window, but succeeded in another? The simple explanation is that constrained language mode allows you to continue using basic PowerShell cmdlets but blocks commands that can be used to interact with various APIs. The reason why the mathematical expression shown in the previous figure produced an error is because I was attempting to use .NET. Had I entered a simpler expression such as 2+2, the operation would have been allowed.

There is a long list of items that PowerShell either limits or blocks when constrained language mode is enabled. I won’t bore you with the full list, but some of the more noteworthy items include:

• COM objects
• Unapproved .NET types
• XAML based workflows
• PowerShell classes

Setting PowerShell’s constrained language mode

If you want to determine which language mode PowerShell is currently using, enter this command:

$ExecutionContext.SessionState.LanguageMode

As you can see in the screenshot below, PowerShell is set to use full language mode, which means that constrained language mode is not enabled.


If you decide that you want to enable constrained delegation, you can do so by using a variation of the command shown above. Simply enter the command as before, but append =”ConstrainedLanguage”. The full command looks like this:

$ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage"

You can see what a switch from full language to constrained language looks like in the screenshot below.

PowerShell’s Achilles’ heel

The problem with using constrained delegation as a security feature is that depending on how it is implemented, it can be relatively easy for an attacker to get around it. The reason for this is that PowerShell’s language mode is session specific. Let me show you what I mean.

If you look at the screenshot below, you can see that I have two PowerShell windows open. I set the language mode of the window on the left to Constrained Language. I then verified the language mode to make sure that PowerShell really had been properly set to use constrained language. Next, I opened up the window on the right and checked PowerShell’s language mode. The PowerShell session running in that window is using full language, even though the session within the window on the left remains limited to using constrained language. In other words, if an attacker wants to gain access to the full language, then they need only to open another PowerShell session.

Two problems

Although constrained language mode can improve security, its use presents two big problems. First, as previously noted, constrained language mode is easy to circumvent because it is session specific. If an attacker wants to avoid constrained language mode, they can simply launch a new PowerShell session.

The second problem with using constrained language mode is that it can break your existing PowerShell scripts. I showed you an example earlier of a mathematical expression that could not be evaluated because doing so required the use of .NET. Just imagine if that expression had been a part of a script.

The trick to making the use of constrained language practical is to accept the idea that constrained language mode is not designed to be used by itself. Instead, constrained language mode is designed to be used in conjunction with Device Guard User Mode Code Integrity (UMCI).

For those who might not be familiar with UMCI, it is a tool that allows administrators to set policies describing the code that is allowed to run on the system. Because Device Guard runs on a system wide basis, it is ideal for enforcing the use of constrained language mode. An attacker will not be able to circumvent constrained language mode by opening a new PowerShell session, because Device Guard policies apply to the system as a whole, not solely to the current PowerShell session.

A powerful tool

Constrained language mode can be a very powerful tool for locking down PowerShell in an effort to prevent it from being used for nefarious purposes. Even so, it is completely ineffective by itself, because an attacker could bypass it by launching another PowerShell session, or simply disable it by entering a single command. In spite of its weaknesses however, constrained language mode can greatly enhance PowerShell’s security when it is used in conjunction with Device Guard User Mode Code Integrity.

Featured image: Shutterstock

Brien Posey

Brien Posey is a freelance technology author and speaker with over two decades of IT experience. Prior to going freelance, Brien was a CIO for a national chain of hospitals and healthcare facilities. He has also served as a network engineer for the United States Department of Defense at Fort Knox. In addition, Brien has worked as a network administrator for some of the largest insurance companies in America. To date, Brien has received Microsoft’s MVP award numerous times in categories including Windows Server, IIS, Exchange Server, and File Systems / Storage. You can visit Brien’s Website at: www.brienposey.com.

Share
Published by
Brien Posey
Tags Powershell

Recent Posts

Losing your edge? 7 free tools to keep you focused at work

Staying focused at work in an always-connected world is hard! Here’s how to use tech — and some free tools…

15 hours ago

What’s next in the evolution of biometrics and facial recognition technology?

Facial recognition technology has matured to the point of being reliable — for better or for worse. What does the…

19 hours ago

Locking down your Exchange server with cipher suites

Cipher suites are a set of algorithms you need to secure your environment, either by using SSL and TLS. Here’s…

22 hours ago

AI cyber risks: What to look out for when deploying AI technology

Artificial intelligence has greatly improved modern life. But businesses must recognize that AI cyber risks exist and take appropriate measures.

2 days ago

Review: Office 365 synchronizing and administration tool CiraSync

CiraSync offers an enterprise solution for syncing global address list contacts and calendars to smartphones and other mobile devices. Here’s…

2 days ago

HIPAA IT compliance: Privacy and security rules you must know

HIPAA is the mandatory health regulation that must be followed strictly. But if you’re an IT pro in the health-care…

2 days ago