-
-
Notifications
You must be signed in to change notification settings - Fork 257
DLL Agent
jm33-m0 edited this page Jan 22, 2025
·
10 revisions
From version v1.49.0, emp3r0r supports DLL agent and Linux shared object agent. This is a new type of agent that can be loaded into a target process, and it's more stealthy than the traditional agent.
When generating a DLL agent, you need to set payload_type
to windows_dll
or linux_so
and run
it normally. You will get a DLL file to deliver to the target machine. The DLL agent can be loaded into a target process using rundll32
or regsvr32
, and it will connect back to the C2 server.
The DLL will be huge, you can pack it with upx
or use your stager to compress it before delivery.
Call main
function exported by the DLL/SO.
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <path_to_shared_object>\n", argv[0]);
return EXIT_FAILURE;
}
const char *so_path = argv[1];
void *handle = dlopen(so_path, RTLD_LAZY);
if (!handle) {
fprintf(stderr, "Error opening shared object: %s\n", dlerror());
return EXIT_FAILURE;
}
void (*main_func)();
*(void **)(&main_func) = dlsym(handle, "main");
if (!main_func) {
fprintf(stderr, "Error finding main function: %s\n", dlerror());
dlclose(handle);
return EXIT_FAILURE;
}
main_func();
dlclose(handle);
return EXIT_SUCCESS;
}
This is a very basic example of how to use teh DLL agent. You can also use rundll32
to load the DLL into a target process.
package main
import (
"C"
"fmt"
"os"
"plugin"
)
func main() {
if len(os.Args) < 2 {
fmt.Fprintf(os.Stderr, "Usage: %s <path_to_shared_object> [args...]\n", os.Args[0])
os.Exit(1)
}
soPath := os.Args[1]
// Load the shared object file
p, err := plugin.Open(soPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Error loading shared object: %s\n", err)
os.Exit(1)
}
// Lookup the 'main' function
symMain, err := p.Lookup("main")
if err != nil {
fmt.Fprintf(os.Stderr, "Error finding 'main' in shared object: %s\n", err)
os.Exit(1)
}
// Assert the type of the 'main' function
soMain, ok := symMain.(func(argc int, argv []string) int)
if !ok {
fmt.Fprintf(os.Stderr, "Invalid 'main' function signature\n")
os.Exit(1)
}
// Prepare arguments for the SO's main function
soArgc := len(os.Args) - 1
soArgv := os.Args[1:]
// Call the main function of the shared object
exitCode := soMain(soArgc, soArgv)
os.Exit(exitCode)
}