ViscosityService runs as SYSTEM process.
Viscosity.exe contacts with service using named pipe.
Only files digitally signed by
SparkLabs can use this pipe because of usage of
But it’s possible to bypass this by injecting our DLL into
So now we can send any commands to service using DLL.
Inside service there is method
startOpenVPN which is responsible for executing
One of the parameter of this method is
openVPNVer which is used to generate valid path to exe file:
Of course from Viscosity GUI we have limited options for choosing this parameter.
But because we control pipe, we can send anything, for example:
Now we control path to binary which will be executed.
There is another problem in order to get privilege escalation.
openvpn.exe from given path, service again check if this
exe file is signed by
We can bypass this too. How? Using
OpenVPN signed by
6 DLL (which don’t need to be signed).
So we can copy this signed OpenVPN to our directory and replace one of the external dll, for example
lzo2.dll with our custom dll.
Then, service will allow execution of this signed
openvpn.exe which will load and execute our custom, non signed dll.
Proof of Concept:
Download Visual Studio Project
For injecting into
Viscosity process I use simple C# injector (you need to compile this using x64 architecture):
Injected dll is written in
C (also you need to compile this using x64):
lzo2.dll is also written in
C (but this one is x86):
- 13-01-2017: Discovered
- 13-01-2017: Vendor notified
- 16-01-2017: Version 1.6.8 released, issue resolved