A fiber is a unit of execution that must be manually scheduled by the application rather than rely on the priority-based scheduling mechanism built into Windows. Fibers are often called lightweight threads.
For more detailed information about what are and how fibers work consult the official documentation. Fibers allow to have multiple execution flows in a single thread, each one with its own registers’ state and stack. On the other hand, fibers are invisible to the kernel, which makes them a stealthier (and cheaper) method to execute in-memory code than spawning new threads.
One thread can create multiple fibers, and switch between them at desire by calling the SwitchToFiber function. Before that, the current thread itself must have become a fiber by calling ConvertThreadToFiber since only a fiber can create other fibers.
Finally, in order to create a fiber that, when scheduled, executes an in-memory code (for example, after reflectively loaded a PE or some shellcode) it is just needed to make a call to CreateFiber.
The SwitchToFiber function is the most important part of this process and where all the magic occurs. This function allows to schedule one fiber or another, all happening on user space. According to the official documentation, “the SwitchToFiber function saves the state information of the current fiber and restores the state of the specified fiber”.
This mean that when this function is called, the registers’ values and the stack are switched from the current fiber state to the target fiber state, allowing to “hide” the stack of the current fiber once the process is completed. This also allows to continue the execution of the target fiber from the same point where the execution was stopped (the same way that it happens when the scheduler switches between threads according to its own priority logic).
And this is exactly what this simple PoC does:
run()
function exported by the manually mapped dll. This fiber will be known as the payload fiber from now on.This process repeats indefinitely.
The use of fibers may be advantageous for some types of payloads (like a C2 beacon) for some of these reasons:
JMP
or CALL
from the loader pointing to unbacked memory regions.Since we are using LITCRYPT plugin to obfuscate string literals, it is required to set up the environment variable LITCRYPT_ENCRYPT_KEY before compiling the code:
C:\Users\User\Desktop\Fiber> set LITCRYPT_ENCRYPT_KEY="yoursupersecretkey"
After that, simply compile both the payload and the loader and run the last one:
C:\Users\User\Desktop\Fiber\payload> cargo build --release
C:\Users\User\Desktop\Fiber\loader> cargo build --release
C:\Users\User\Desktop\Fiber\loader\target\release> loader.exe
There is not much mistery on this PoC execution. All it has to be done is to run the loader and use any tool like ProcessHacker to inspect the thread stack. Since the payload switches back to the control fiber before sleeping, the payload fiber’s stack remains hidden most of the time. You will see in the output how the two fibers are consecutively scheduled following the already commented logic.
The code is commented to show how to use, create and schedule fibers. You will notice that both the loader and the payload offered as example are “stuck” on an infinite loop, which allows to indefinitely switch between fibers and continue the execution.
If a different payload wants to be tested, just modify the path located on line 32 of the file src::main.rs of the loader. In that case, the new dll has to export a run(PVOID)
function that will receive as input parameter the address of the control fiber. This function has to switch back to the control fiber in order to call the Sleep function, although you can modify this behavior at will to fit your requirements.
Another way to test this tool with a random payload is to perform IAT hooking to redirect any call to the Sleep function (or any other imported function) made by the payload to a function located on the loader, allowing to switch back to the control fiber when this call occurs. Up to you.
In the following screenshots we can see how the stack of the current threat moves from one private memory region to another as we switch fibers:
Please consider following and supporting us to stay updated with the latest info
This repo contains all variants of information security & Bug bounty & Penetration Testing write-up…
site:*/sign-in site:*/account/login site:*/forum/ucp.php?mode=login inurl:memberlist.php?mode=viewprofile intitle:"EdgeOS" intext:"Please login" inurl:user_login.php intitle:"Web Management Login" site:*/users/login_form site:*/access/unauthenticated site:account.*.*/login site:admin.*.com/signin/…
Matrix is an open network for secure and decentralized communication. Users from every Matrix homeserver…
Linux Security And Monitoring Scripts are a collection of security and monitoring scripts you can…
XSS Exploitation Tool is a penetration testing tool that focuses on the exploit of Cross-Site…
Prompt injection is a type of security vulnerability that can be exploited to control the…