Faxhell – A Bind Shell Using The Fax Service And A DLL Hijack
A Proof-of-Concept bind shell using the Fax
service and a DLL hijack based on Ualapi.dll
.
See our writeup at: https://windows-internals.com/faxing-your-way-to-system/
How to use
- Build
Ualapi.dll
and place inc:windowssystem32
- Start the
Fax
service, which will load the DLL and call the exportUalStart
.UalStart
will queue a thread pool work item that will open a handle toRpcSs
, find aSYSTEM
token, and then impersonate it. Afterward, it will create a socket on the local endpoint address, bind it to port9299
, and then asynchronously wait for a connection using a thread pool I/O completion port. - Connect to the socket on port 9299 using your favorite client (such
nc(at).exe <ip> 9299
) and then typelet me in
and pressENTER
. If you’re writing custom code, make sure to send the stringlet me inn
. - The I/O completion packet will then wake up the thread pool callback, which will start a
Cmd.exe
process under theDcomLaunch
service withSYSTEM
privileges, binding its input and output handles to the newly created socket. - Win!
EDR / AV evasion
- Uses a service that is not commonly known and not monitored or flagged as suspicious by EDR vendors.
- Uses the Windows thread pool API to do setup, making stacks harder to read, offloading work through multiple threads, and avoiding easy “hints” that something suspicious is happening.
- The lifetime of the impersonated tokens is very small, and only the worker thread ever runs as
SYSTEM
, reverting back toNETWORK SERVICE
very quickly and after only doing one API call. This helps reduce the chance of getting caught by various scanners. - Uses uncommon socket APIs that make the import table less suspicious and avoids EDR detections, IOCTL hooks, and LSPs.
- Creates the bind shell under the
DcomLaunch
service (which is already aSYSTEM
service) and not under theFax
service, making it look a lot more natural and avoiding a very suspicious-looking process tree. - Leverages a Windows bug that makes it look as if our socket belongs to the
Fax
service, and not toDcomLaunch
orCmd.exe
. If we kill theFax
service it looks like socket belongs toSystem
.
Caveats
This isn’t meant to be a drop-in, undetectable, malicious, weaponized shell:
- It is only a bind shell, which most firewalls will prevent. Opening firewall rules, or using a reverse bind shell, or doing communications over a common port such as
80
or443
would work better. - Other services, notably the
Spooler
, also loadUalapi.dll
. While the system behaves fine if theFax
service is “stuck” in theSERVICE_START_PENDING
state, this will cause issues inSpoolsv.exe
. - There’s probably bugs/memory leaks in the PoC — we tried our best to make things production quality, but we did not run things through Application Verifier or asan.
Download Faxhell
If you like the site, please consider joining the telegram channel or supporting us on Patreon using the button below.