When looking for methods of execution in controlled environments, software components are an essential area of review. With the implementation of controls such as AppLocker, running arbitrary executables becomes more difficult. In most environments we test, AppLocker is now a common configuration implementation which serves to reduce the attack surface by defining the permitted locations an executable is allowed to run from. Whilst it is sometimes possible to find gaps in policy configurations that allow execution of executable payloads, generally, the implementation is often effective with default and common rules. It is less common to find that the Dynamic Link Library (DLL) protections available in AppLocker are implemented. Microsoft even display a stark warning about knowing the implications of DLL controls before you enable this feature. This allows attackers to profile software in use and determine if there is an available attack surface to introduce a malicious DLL. If an opportunity is discovered, this brings the benefits that the trusted process is loading the attacker’s payload.
Whilst delivering testing, Cyberis profiled a SonicWall Global VPN client that was in use and determined that the software versions listed below were looking for a missing DLL in user-writeable locations (AppData). This presented the opportunity to introduce a payload that would be executed by the trusted process. VPN clients tend to be used by several users and in this case, present an opportunity for an attacker to gain execution in the context of a user if they hold the ability to introduce a DLL. The benefit of these types of attacks is that they tend to be transparent to a user, and from a detection perspective are more difficult to spot due to the trusted process tree.
- SonicWall Global Client VPN – 22.214.171.1244
- SonicWall Global Client VPN – 4.10.6.0913
- Windows 10 Enterprise – Build 19043
- Windows 10 Pro – Build 19042
When the software starts up, it searches for a DLL, "EPASpoof.dll" in several locations in both protected system paths such as "Program Files" and then continues through user writeable locations within the user directory inside "AppData". My initial testing showed that searching was taking place in my local python scripts directory on a Windows 10 Pro machine, so I initially used this location which was successful. Testing on the Windows 10 Enterprise device showed that "c:\users\<User>\AppData\Local\Microsoft\WindowsApps\" was also a search location. By placing "EPASpoof.dll" in this location I was also successful in getting the application to load the DLL. This is more significant as this is a universal location and therefore an attacker would not need to know the specific local paths and could gain execution by placing the "EPASpoof.dll" here as a predictable path. This path worked on both operating system versions.
To demonstrate this issue, I have used a simple 64Bit DLL with a MessageBox function that upon invocation of the program, gets executed. This could obviously be replaced with a range of payloads that would execute in the context of the user when the program starts.
The following screenshot shows that the DLL is found by the process and is loaded as a module.
Attack Detection And Mitigation
SonicWall has issued a fix for this vulnerability in release 4.10.7.
The detection metric for this type of attack would be a file disk write for "EPASpoof.dll" in a user-writeable location. If you have AppLocker DLL rules enabled that control permitted DLL source locations, then testing has showed that this process will not run as the DLL is not sourced from the program locations. It is strongly recommended to review all implemented rules before making any changes or enabling additional protection mechanisms.
Cyberis would like to thank the SonicWall PSIRT team for the handling of this disclosure process.
- Monday, September 20, 2021: Reported issue to The SonicWall Product Security Incident Response Team (PSIRT)
- Monday September 20, 2021: PSIRT acknowledged report submission
- Thursday 4th November 2021: Request for updates from PSIRT
- Thursday 4th November 2021: PSIRT accepted issue and moved to remediation
- Thursday 4th November 2021: Testing latest version 4.10.6. showed issue still in current release version
- Thursday 4th November 2021: PSIRT confirmed fix in next release
- Monday 6th December, 2021: Request for updated from PSIRT
- Monday 6th December, 2021: PSIRT confirmed fix in release 4.10.7 and assigned CVE-2021-20047