Microsoft has asked system administrators to patch PowerShell 7 against two vulnerabilities allowing attackers to bypass Windows Defender Application Control (WDAC) enforcements and gain access to plain text credentials.
PowerShell is a cross-platform solution that provides a command-line shell, a framework, and a scripting language focused on automation for processing PowerShell cmdlets.
Redmond released PowerShell 7.0.8 and PowerShell 7.1.5 to address these security flaws in the PowerShell 7 and PowerShell 7.1 branches in September and October.
Leaked passwords and WDAC bypass
WDAC is designed to protect Windows devices against potentially malicious software by ensuring that only trusted apps and drivers can run, thus blocking malware and unwanted software from launching.
When the software-based WDAC security layer is enabled in Windows, PowerShell automatically goes into constrained language mode, restricting access to only a limited set of Windows APIs.
By exploiting the Windows Defender Application Control security feature bypass vulnerability tracked as CVE-2020-0951, threat actors can circumvent WDAC’s allowlist, which allows them to execute PowerShell commands that would otherwise be blocked when WDAC is enabled.
«To exploit the vulnerability, an attacker need administrator access on a local machine where PowerShell is running. The attacker could then connect to a PowerShell session and send commands to execute arbitrary code,» Microsoft explains.
The second flaw, tracked as CVE-2021-41355, is an information disclosure vulnerability in .NET Core where credentials could be leaked in clear text on devices running non-Windows platforms.
«An Information Disclosure vulnerability exists in .NET where System.DirectoryServices.Protocols.LdapConnection may send credentials in plain text on non-Windows Operating systems,» Microsoft said.
How to tell if you are affected
The CVE-2020-0951 vulnerability affects both PowerShell 7 and PowerShell 7.1 versions, while CVE-2021-41355 only impacts users of PowerShell 7.1.
To check the PowerShell version you are running and determine if you are vulnerable to attacks exploiting these two bugs, you can execute the
command from a Command Prompt.
Microsoft says no mitigation measures are currently available to block the exploitation of these security flaws.
Admins are advised to install the updated PowerShell 7.0.8 and 7.1.5 versions as soon as possible to protect systems from potential attacks.
«System administrators are advised to update PowerShell 7 to an unaffected version,» Microsoft added. Details on what PowerShell versions are affected and the fixed versions can be found here and here.
In July, Microsoft warned of another high severity .NET Core remote code execution vulnerability in PowerShell 7.
Microsoft recently announced that it would be making it easier to update PowerShell for Windows 10 and Windows Server customers by releasing future updates via the Microsoft Update service.
Redis is an in-memory data structure store that is used to store data in the form of key-values and can be used as a database, serialized/session storage, cache, and job queue.
For example in Framework Django and Flask, Redis can be used as the session instance or in Gitlab using Redis as the Job queue.
Redis uses a
Text Based line protocol
so it can be accessed using
without the need for special software to access Redis instances, but Redis has an official client software called
Redis Support 2 types of command :
1. Non—RESP (REdis Serialization Protocol) format by using Space as a separator.
2. RESP format, this format is more recommended (because it is standard for Redis Request/Response ), besides that using this format will avoid syntax errors if there are special characters such as quotation marks ( “ ) in Redis request.
Redis stores data in memory, so when the server is restarted the data will be lost because RAM is volatile storage, to avoid this problem Redis has a Persistence feature, which will save data to the hard disk.
Redis provides two types of persistence :
RDB (Redis Database Backup) which will save data to the hard disk every time the “
” command is executed, and
AOF (Append Only File) will save data to the hard disk every time it performs an operation (basically its function just like Bash Shell which saved command history to
every time the command is executed successfully).
Redis configuration parameters for persistence
AOF is not a good option to do file writing (In the context of SSRF in this blog post), because Redis does not allow AOF filename changes (by default: appendonly.aof) using the
command (during Runtime), but must be done directly by editing the file
The last exploit to impact Redis was the Redis EVAL Lua Sandbox Escape — CVE-2015–4335 discovered by Ben Murphy. However, this issue has been fixed from Redis version 2.8.21 and 3.0.2.
At the time of writing this blog post, there is no Exploit to directly get RCE on Redis instances, but attackers can take advantage of the “persistence” feature or maybe take advantage of Unsafe Serialization from the related application so that it can be used as a technique to get RCE. Also, there is “Redis post-exploitation” discovered Pavel Toporkov to get RCE on Redis Instance.
Redis Vs HTTP
Redis and HTTP are both Text-Based Protocols, so HTTP can be used to access Redis, but because it has the potential to cause security issues, since the release of Redis 3.2.7 which makes HTTP Header
as aliases for the QUIT command and then logs with messages “Possible SECURITY ATTACK detected. It looks like somebody is sending POST or Host: commands to Redis. This is likely due to an attacker attempting to use Cross Protocol Scripting to compromise your Redis instance. Connection aborted.” is generated to Redis log.
If you want to force HTTP to communicate with Redis ≥ 3.2.7, you need SSRF (GET Method) + CRLF Injection in the GET parameter section. In order to avoid the POST, and CRLF Injection keywords, the HOST Header will be in a position after the Redis command.
Trivia: Alias POST to QUIT was created based on a suggestion from a member of the news.ycombinator.com forum, geocar.
Every Payload generated by payload_redis.py in this blog post, will be input as a URL in the SSRF Lab Web, so there is no need for screenshots of the attack process to the Lab. This information is given so that there is no confusion about how to attack.
By default, Redis runs with the low privilege of being the user ‘redis’. In the Lab, we used root privileges to be able to write crontab and authorized_key ssh, because the user ‘redis’ does not have permission to write to both files.
Redis And SSRF
Redis — Cron
Cron is a task scheduler on Linux, cron will execute the command that is set using the
command periodically according to the set time.
Cron stores crontab files in
(Ubuntu) and System Wide crontabs are in
The lab will use 2 different OS because there is a slight difference in behavior between cron on Centos and Ubuntu.
$ python payload_redis.py cron
Reverse IP >
Centos/Ubuntu (Default Centos)
Redis will write the file with 0644 permission, while the crontab file on ubuntu is expected to have 0600 permission so it will give a warning in the system log.
In addition, there are dummy data in the Redis RDB file which causes cron to ignore the crontab file because there is invalid syntax, so even if the crontab file has 0600 permissions it will not be executed.
Writing crontab files with Redis through SSRF will not work properly in Ubuntu , because crontab files in Ubuntu are expected to have 0600 permission to be executable and clean of dummy data that cause syntax errors.
On Centos even though the crontab file has permissions 0644 and there is dummy data, cron will still be executed so that it can get a reverse shell.
Redis — SSH Public Key
Authorized_keys is used to store a list of SSH public keys so that users log in using the SSH private-public key pair instead of a password. Authorized_keys are located in
is writable, this can be used to store the attacker’s SSH keys.
Both Ubuntu and Centos Lab ssh can be accessed even though dummy data is present.
Redis As Session Storage
Backend servers often time use Redis as Session Storage, in the Redis web lab session storage will focus on exploiting Unsafe Serialialization, because Sessions are usually in the form of objects, and so that these objects can be stored to Redis, Session objects must be converted into strings. The process of converting objects into strings is called “Serialization” and the process of converting strings into objects is called “Deserialization”.
The lab implements Redis as Session Storage using sample snippets from Server-side Sessions with Redis and Pickle is used as Serializer, pickle is known to be insecure and can be exploited to get RCE.
The attack flow is quite simple, we only need to change the session value with the Payload Pickle through SSRF. According to the logic in the source code, the session will be serialized and base64 encoded.
To be able to change the session value stored in Redis, you need a Key name, in this lab, the session will be stored with the name
We can see the Session-Id using the default web browser features called developer tools
Trivia: Flask Internal
When the request is about to end or when the views return, Flask will internally call the
method, then in the
method there is another call to the
method which calls
method will save the value of the session (in the context of this blog post, the session value will be saved to Redis).
Why is this information important? because when we try to change the value of the flask session in Redis through SSRF, the value we managed to change through SSRF earlier will be overwritten back with the original value.
There are at least 3 scenarios that can be done to archive RCE at the Pickle-Redis Lab :
When the SSRF payload is executed, we simultaneously access other endpoints, eg
(this method can use multithreading/multiprocessing) because when accessing other endpoints, Flask will call the
method of the
class, then retrieve the session value (so avoid
Change the value of the Session-Id, then write the Payload Pickle to the Modified Session-Id, for example the Session Id is AAAA-AAAA-AAAA-AAAA, we can change it to AAAA-AAAA-AAAA-AAAB for example, then set AAAA-AAAA- AAAA-AAAB as Key, later just use AAAA-AAAA-AAAA-AAAB on the client side so that Flask reads the value of the Session Id.
Using the Master-Slave Redis feature (trigger through SSRF with the
command), then change the value directly through the Master, because any changes that occur in the Master will be automatically synced to the Slave.
Note : Original Session-Id session:8ac1cb48–5064–4067–9e43-ed0df6856426 changed to session:8ac1cb48–5064–4067–9e43-ed0df6856425
Redis Master-Slave RCE
This post-exploit technique is introduced by Pavel Toporkov.
Info: I will write a separate blog post to explain more about this post-exploit technique.
Redis As Job Queue
An example of using Redis as a Job Queue to get RCE can refer to LiveOverFlow Video.https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FLrLJuyAdoAg%3Ffeature%3Doembed&display_name=YouTube&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DLrLJuyAdoAg&image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FLrLJuyAdoAg%2Fhqdefault.jpg&key=a19fcc184b9711e1b4764040d3dc5c07&type=text%2Fhtml&schema=youtubeGitLab 11.4.7 Remote Code Execution — Real World CTF 2018
Trivia : Redis Protected Mode
If Redis is not in Protected Mode, the Redis instance will be exposed on the outside network/internet, which is even worse if the Redis instance does not use authentication, causing people to arbitrarily access the Redis instance.