RedFiber
Overview
RedFiber is the Red-Team implant for Windows developed and maintained by Retooling. Written in C and compiled for the Intel x64 architecture, it is fully integrated with the Revo platform.
The integration is performed by the RedFiber Translator that interconnects the impant's custom protocol with the Revo's backend translating the messages into the target data model. The communication on the backend is done through the gRPC protocol.
RedFiber components (the implant and the translator) rely on Revo's Offensive Security Data Model (as shown in the figure below). There are no special features offered by the platform that are not exposed to third-party implant developers. This means that any third party implant will play on the same field as RedFiber. However, RedFiber offers several extension points that allow for the extremely faithful reproduction of potentially any threat actor's backdoor.
Build Customization Paths
Each time a Revo's user wants to use our implant in an engagement he has to create a new build. The build is performed on our servers through the RedFiber dedicated BuildBox where the user has several options at his disposal.
RedFiber has several build customization paths, allowing the user to craft an implant that he can adapt to different scenarios (see the BuildPaths figure). Each path moves through different customization layers.
The first customization layer is on the Binary Format. You can decide to build the implant either as an Executable or as a Reflective dll. This flexibility supports different scenarios, whether you need to drop the executable into a folder or inject it into a target process.
The second customization layer concerns the Feature set that you want to include into the build. At this layer, RedFiber has two different options:
- full-fledged, with the whole command set built-in or,
- unplugged, which is equipped only with the core command set which includes (but is not limited to!) the
load
and theinject
commands. The capabilities of unplugged can be extended by using theload
command (see next sections)
The third layer allows to select the Communication channel. Currently RedFiber supports two different communication channels:
- Http: The communication protocol is encapsulated into HTTP messages. This is used for the communication between RedFiber and its Translator
- Pipe: The communication protocol is encapsulated into SMB messages, through Named Pipes. This is used for implant-to-implant communications
RedFiber's Translator interconnects the implant with the Revo's backend.
RedFiber Core
The RedFiber core functionalities include:
- In-memory storage: used to maintain temporary information derived from the execution of tasks or modules
- Task manager: allow to define tasks that span for a user defined time-frame with a user-defined delay
- Injection: allow to inject modules into different processes
- Loader: allows to dynamically load new components into the current process.
In addition to the aforementioned features the RedFiber core implements commonly adopted OPSEC practices to avoid detection/analysis such as code obfuscation, string encryption and dynamic api resolution.
RedFiber modules
A module into RedFiber is an zip archive that contains two files:
- a
manifest.json
that describes the content of the module providing general information such as theversion
number or the moduleid
and, - a
payload
that contains the object that will be sent to RedFiber though theload
command
An overview of the manifest.json
is represented in Figure ManifestOverview. A little clarification before we continue with the discussion: what is presented here are the parts of the manifest that impact or are used by RedFiber or its modules. Note that the manifest can be extended at will when developing a custom implant; however, we do not cover that use case here.
To be correctly processed by Revo, a manifest must contain a set of top-level attributes:
family
: astring
that identifies the implant's family (lowercaseredfiber
in this case). This allows the Revo platform to manage things correctly when handling multiple implant families, such as preventing to load the wrong module (one designed for a different family) to an implantstaticPayloadPath
: astring
containing the path (relative to the archive root) of the payloadversion
: astring
in the formYYYYMMDD
and identify the version of the modulecore
: aboolean
that allows to distinguish among implants and module. This will be typically set tofalse
unless you are developing a custom implant for Revo. Allredfiber
customization paths have this set totrue
type
: identify the type of module implemented by the payload
RedFiber supports several module types:
- Implant: an executable that can communicate with a RedFiber Revo Translator
- Reflective: a reflective implant that can communicate with a RedFiber Revo Translator
- BOF: a Beacon Object File
- Dll: a module that the implant can dynamically load
- Loader: a Dll that implements a custom loader
- Custom: modules that are handled by custom loaders. This allows third-party developers to implement their own custom file format to be delivered to the target. The corresponding Loader will do the magic
- Extension: a special module that provide a custom implementation of a set of commands for an implant. Third party developers can provide their own command sets implementations.
The manifest fields change according to the module type, as shown in Figure ManifestOverview. Each type offers different capabilities in terms of ease of development, payload size, stealthiness, and functionalities.
Type DLL
The RedFiber loader can load standard DLLs. When loaded without parameters, the DLL is loaded directly from memory, and the DllMain
function is invoked. After DllMain
returns, the output is sent back to the Translator, and the DLL is unloaded.
However, RedFiber also supports making a DLL persistent in memory using the --persistence
parameter (or, by enabling the switch button from the web ui). In this case the DLL is not unloaded after the DllMain
returns and its exports can be invoked through the invoke
command.
The same result (loading a dll
and invoking its exports
) can be done from the Revo UI as shown in the following sequence of screens.
The manifest.json
of the dellechoascii module is reported here:
{
"name": "dllechoascii.dll",
"type": "dll",
"version": 20240617,
"persistence": 1,
"desc": "Echo dll ASCII version",
"staticPayloadPath": "dllechoascii.dll",
"family": "redfiber",
"tags": [
""
],
"exports": [
{
"name": "EchoAscii",
"desc": "The EchoAsciiModule",
"prototype": "LPSTR EchoAscii(int dummy, const LPSTR lpString)",
"ordinal": 1,
"params": [
{
"name": "szSize",
"type": "int32",
"default": "0"
},
{
"name": "lpString",
"type": "string",
"mandatory": true,
"desc": "The string to be echoed"
}
]
}
]
}
The group exports
allows to declare the exports of the DLL. For each export the set of params
are defined as a ordered array (the position is relevant and must preserve what is defined in the prototype). Each element of the array represents an argument for the function has its type.
The possible type
values for params are:
ModuleParamTypeInt16 = "int16"
ModuleParamTypeInt32 = "int32"
ModuleParamTypeInt64 = "int64"
ModuleParamTypeBoolean = "bool"
ModuleParamString = "string"
ModuleParamWString = "wstring"
Type Extensions
Extensions in RedFiber are organized into command sets. A command set group together commands that target a specific subsystem (e.g. filesystem vs registry). Each time a new command set is loaded into the implant (typically unplugged), new commands become available into the implant.
The following command sets are present into the platform:
- Info: Implements the process list command
- Filesystem: Implements the filesystem access capabilities (including chunked upload and download of files)
- Inter-process communication: Implements the capability to link to another implant.
- Screenshot: allows to take screenshots of the target machine
- Clipboard: implements clipboard capture
- Execution: allow to create process on the remote machine
- Token: implements the access token manipulation
- Shell: implements an emulated PowerShell console that can be used to run arbitrary commands/scripts on the target
Type Beacon Object File (BOF)
Beacon Object File (BOF) is a specialized form of object file used primarily in the context of penetration testing. The following points summarize BOFs:
Purpose: BOFs are used to extend the functionality of an host implant to implement a feature that is not immediately present on the implant. They can help in maintaining the memory detection surface smaller by exposing only a minimal feature set
Format: BOFs are typically written in C and compiled into position-independent code (PIC), which means they can be loaded at any memory address without modification. This makes them suitable for injection into the host implant.
Advantages:
- Stealth: BOFs are smaller and less likely to be detected than traditional binaries.
- Efficiency: They allow for quick execution of custom code without the overhead of compiling and deploying full binaries.
- Flexibility: Security professionals can rapidly develop and deploy new functionalities tailored to specific engagement requirements.
Development: Writing BOFs involves:
- Creating C code that implements the desired functionality.
- Compiling the C code into a BOF using a cross-compiler or a specialized compiler (such as mingw or others) configuration to ensure the code is position-independent.
RedFiber supports the loading and the execution of BOFs. An interesting thing about The RedFiber BOF loader, consists in the fact that the output provided by a running BOF is captured by RedFiber and than sent back to the Translator in chunks. To obtain this result the behavior of the functions that typically write on the stdout such as BeaconOutput
or BeaconPrintf
have been modified.
This enables to send even binary files (e.g. the memory dump of a target process) back to the Redfiber Translator, no matter what size the output is (up to ~500MB). Also, thanks to its multi-threaded design, RedFiber can run multiple BOFs concurrently and still receive and process built-in commands.
The following snippet contains an example of a BOF manifest that takes in input 5 parameters:
{
"type": "bof",
"version": 20240402,
"name": "reg_query.x64.obj",
"description" : "Query or enumerate a registry path ",
"architecture" : "x64",
"staticPayloadPath": "reg_query.x64.obj",
"family" : "redfiber",
"exports": [ {
"name": "go",
"prototype": "string fn(string Host, int32 Hive, string Path, string Name, bool Recurse)",
"ordinal": 1,
"params": [
{
"name": "Host",
"type": "string",
"description" : "The remote host (leave empty for localhost)"
},
{
"name": "Hive",
"type": "int32",
"description" : "1=HKCU 2=HKLM"
},
{
"name": "Path",
"type": "string",
"description" : "The registry path to query or enum"
},
{
"name": "Name",
"type": "string",
"description" : "The valuename"
},
{
"name": "Recurse",
"type": "bool",
"description" : "(Only if enum) True or False if recursive search should be enabled"
}
]
}]
}
The manifest is very similar to the DLL despite the fact that:
- persistence must be disabled
- only one export can be declared
- the export should be named
go
And this is how it appears into the WebUI:
Communication Channels
HTTP
The communication with the Translator uses a custom protocol based on HTTP. Both http and https are supported.
SMB
A second communication channel is support which is bases on named pipes and the SMB protocol. This enables P2P communication between implants. The communication in this case occur through the SMB protocol.
Channel swap and custom channels
Either if you are in the middle of a Red-Team engagement or if you want to emulate a threat actor you may need to perform a channel swap, namely modify communication protocol and parameters.
In its simplest form, the channel swap can be used to change the parameters of an existing channel that cannot be changed using the standard config
command of the web ui. For instance if you have activated the certificate pinning you cannot change the hash of the translator's certificate at runtime. However channel swap enables a complete substitution of the communication protocol while the implant is running such as moving from an http-based communication to a completely custom transport protocol.
We use it for adversary emulation but this capability is exposed even to third parties. To do this you simply have to create a DLL module with a manifest like the following one:
{
"id": 2000,
"version": 20231218,
"type": "module",
"core": false,
"name": "httpchannel",
"family" : "redfiber",
"description" : "Implements http channel with embedded configuration",
"staticPayloadPath" : "http_dll.dll",
"commands": []
}
Injection techniques
The reflective version can be injected by any of the supported techniques. Both the unplugged and the full version of RedFiber can be injected though the injection form (or, if you prefer the command line, with the inject
command from the console).
The injection techniques are organized into writing and execution primitives. The former specifies how memory should be allocated in the target process, while the latter indicates how execution should be triggered.
The current version supports, the following writing privimitives:
MapViewOfSection
: based on the correspondingWINAPI
VirtualAllocEx
: based on the correspondingWINAPI
DripAllocator
: a custom implementation of the DripLoaderMapViewOfFile
: based on the correspondingWINAPI
along with the following execution primitives:
CreateRemoteThread
: based on the correspondingWINAPI
RtlCreateUserThread
: based on the correspondingWINAPI
TpDirectInsertion
: ThreadPool injection based on the correspondingWINAPI
TpJobInsetion
: ThreadPool injection based on the correspondingWINAPI
TpAlpc
: ThreadPool injection based on the correspondingWINAPI
And, this is the compatibility matrix between writing and execution primitives:
mem/run | MapViewOfFile | MapViewOfSection | VirtualAllocEx | DripAllocator |
---|---|---|---|---|
CreateRemoteThread |
ok | ok | ok | ok |
Zberp |
ok | ok | Unsupported | ok |
RtlCreateUserThread |
Unsupported | ok | ok | ok |
TpDirectInsertion |
Unsupported | ok | Unsupported | Unsupported |
TpJobInsetion |
Unsupported | ok | Unsupported | Unsupported |
TpAlpc |
Unsupported | ok | Unsupported | Unsupported |
note TpDirectInsertion
, TpJobInsetion
, TpAlpc
also requires SeDebugPrivilege
enabled. If the token of the RedFiber process has the SeDebugPrivilege
, the command token-set-privileges
can be used to enable it.
Stomping
Module stomping, also known as DLL hollowing, is a malware technique where an attacker injects malicious code into the memory space of a legitimate DLL, effectively "hollowing out" its original code.
The injection forms allow specifying which DLL to stomp into the target process. This is a safe operation as long as certain rules are respected:
- The target process must not be using the DLL you select as the target for stomping.
- The
.text
section of the target process must be large enough to contain the RedFiber.text
section.
Since the injector implements a Control-Flow Guard (CFG) bypass, you can select any system DLL as the target.
Also, you do not have to worry about scaring RWX
, none of them will be left behind.
Obfuscation
Each time a new build is created through the RedFiber Buildbox, several obfuscation transformations are applied to the implant. These transformation include Control flow Graph flattening, opaque predicates with dead code injection, constant obfuscation with mixed boolean-arithmetic expressions and string encryption. The obfuscation is unique because the obfuscator takes several random choices while performing its duties on a build unit. This make cross-correlation of different builds and the creation of through detection rules more difficult to be done.
Supported Versions
It supports Windows 10 starting from version 1703 and all versions of Windows 11.