[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I propose a patch, which adds a client and a server to trinity to be able send the arguments of syscall() over TCP. The server logs the inbound data to a header like file. The reason for this is to replicate the bugs found by trinity.

Thanks,
Tudor

---
 network.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 network.h |  24 +++++++
 params.c  |  26 ++++++-
 syscall.c |   4 ++
 trinity.c |   7 ++
 5 files changed, 288 insertions(+), 1 deletion(-)

diff --git a/network.c b/network.c
index e69de29..f0869b0 100644
--- a/network.c
+++ b/network.c
@@ -0,0 +1,228 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <time.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+
+#include <arpa/inet.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
+#include "params.h"
+#include "network.h"
+
+struct network_s *network;
+
+FILE *raw_syscalls_file;
+
+void create_tcp_socket(void) {
+
+	int return_value;
+
+	int flag = 1;
+
+	network = (struct network_s *) malloc(sizeof(struct network_s));
+	if (network == NULL ) {
+		perror("create_tcp_socket() network malloc() failed");
+		exit(EXIT_FAILURE);
+	}
+
+	network->network_port = logserver_port;
+	if (network_server == TRUE) {
+		network->network_address = NULL;
+	} else {
+		network->network_address = logserver_address;
+	}
+
+	network->server = (struct sockaddr_in *) malloc(sizeof(struct sockaddr_in));
+	if (network->server == NULL ) {
+		perror("create_tcp_socket() network->server malloc() failed");
+		exit(EXIT_FAILURE);
+	}
+
+	network->server->sin_family = AF_INET;
+	if (network_server == TRUE) {
+		network->server->sin_addr.s_addr = INADDR_ANY;
+	} else {
+		network->server->sin_addr.s_addr = inet_addr(network->network_address);
+	}
+	network->server->sin_port = htons(network->network_port);
+
+	network->connected_socketfd = socket(AF_INET, SOCK_STREAM, 0);
+	if (network->connected_socketfd == -1) {
+		perror("create_tcp_socket() socket() failed");
+		exit(EXIT_FAILURE);
+	}
+
+	return_value = setsockopt(network->connected_socketfd, IPPROTO_TCP,
+			TCP_NODELAY, (char *) &flag, sizeof(int));
+	if (return_value == -1) {
+		perror("create_tcp_socket() setsockopt() failed");
+		exit(EXIT_FAILURE);
+	}
+}
+
+void create_client(void) {
+
+	int return_value;
+
+	create_tcp_socket();
+
+	printf("creating client\n");
+
+	return_value = connect(network->connected_socketfd,
+			(struct sockaddr_in *) network->server, sizeof(*network->server));
+	if (return_value == -1) {
+		(void) close(network->connected_socketfd);
+		perror("create_client() connect() failed");
+		exit(EXIT_FAILURE);
+	}
+}
+
+void signal_handler() {
+	int return_value;
+
+	printf("\n");
+	printf("ctrl-c caught\n");
+
+	fprintf(raw_syscalls_file, "%s", "{0, 0LU, 0LU, 0LU, 0LU, 0LU, 0LU} }; \n");
+	fprintf(raw_syscalls_file, "%s", "#endif /* RAW_SYSCALLS_H_ */ \n");
+
+	printf("flushing streams\n");
+	return_value = fflush(raw_syscalls_file);
+	if (return_value == EOF)
+		perror("signal_handler() fflush() failed");
+
+	printf("closing file\n");
+	return_value = fclose(raw_syscalls_file);
+	if (return_value == EOF)
+		perror("signal_handler() fclose() failed");
+
+	printf("closing socket\n");
+	return_value = close(network->connected_socketfd);
+	if (return_value == -1)
+		perror("signal_handler() close() failed");
+
+	printf("freeing memory\n");
+	free(network->server);
+	free(network);
+	exit(EXIT_SUCCESS);
+}
+
+void create_server(void) {
+
+	int return_value;
+	int listening_socketfd;
+
+	int buffer_length = 256;
+	char buffer[buffer_length];
+
+	socklen_t client_size;
+	time_t current_time;
+
+	char raw_syscalls_filename[64];
+
+	struct sockaddr_in *client;
+
+	struct sigaction ctrl_c_Handler;
+	ctrl_c_Handler.sa_handler = signal_handler;
+	sigemptyset(&ctrl_c_Handler.sa_mask);
+	ctrl_c_Handler.sa_flags = 0;
+
+	sigaction(SIGINT, &ctrl_c_Handler, NULL );
+
+	create_tcp_socket();
+
+	printf("server is listening on %d\n", network->network_port);
+
+	return_value = bind(network->connected_socketfd,
+			(struct sockaddr_in*) network->server, sizeof(*network->server));
+	if (return_value == -1) {
+		perror("create_server() bind() failed");
+		exit(EXIT_FAILURE);
+	}
+
+	return_value = listen(network->connected_socketfd, SOMAXCONN);
+	if (return_value == -1) {
+		perror("create_server() bind() failed");
+		exit(EXIT_FAILURE);
+	}
+
+	client = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
+	if (client == NULL ) {
+		perror("create_server() client malloc() failed");
+		exit(EXIT_FAILURE);
+	}
+
+	current_time = time(NULL );
+	sprintf(raw_syscalls_filename, "%s_%d.%c", "raw_syscalls",
+			(int) current_time, 'h');
+	raw_syscalls_file = fopen(raw_syscalls_filename, "a");
+	if (raw_syscalls_file == NULL ) {
+		perror("create_server() fopen() failed");
+	}
+	fprintf(raw_syscalls_file, "%s", "#ifndef RAW_SYSCALLS_H_ \n");
+	fprintf(raw_syscalls_file, "%s", "#define RAW_SYSCALLS_H_ \n");
+	fprintf(raw_syscalls_file, "%s", "unsigned long raw_syscalls[][7] = { \n");
+
+	client_size = sizeof(*client);
+	listening_socketfd = accept(network->connected_socketfd,
+			(struct sockaddr_in *) client, &client_size);
+	if (listening_socketfd == -1) {
+		perror("create_server() accept() failed");
+		exit(EXIT_FAILURE);
+	}
+
+	while (1) {
+		return_value = read(listening_socketfd, buffer, buffer_length);
+		if (return_value == -1) {
+			return_value = close(listening_socketfd);
+			if (return_value == -1)
+				perror("create_server() close() failed");
+			perror("create_client() read() failed");
+			exit(EXIT_FAILURE);
+		}
+
+		fprintf(raw_syscalls_file, "%s", buffer);
+		return_value = fflush(raw_syscalls_file);
+		if (return_value == EOF) {
+			perror("create_server() fflush() failed");
+			exit(EXIT_FAILURE);
+		}
+		memset(buffer, 0, buffer_length);
+	}
+}
+
+void send_away(int nr, unsigned long a1, unsigned long a2, unsigned long a3,
+		unsigned long a4, unsigned long a5, unsigned long a6) {
+
+	ssize_t return_value;
+	int ret;
+
+	useconds_t usec = 1000;
+
+	int buffer_length = 256;
+	char buffer[buffer_length];
+
+	sprintf(buffer, "{%d, %luLU, %luLU, %luLU, %luLU, %luLU, %luLU},\n", nr, a1, a2, a3, a4, a5, a6);
+	return_value = write(network->connected_socketfd, buffer, buffer_length);
+	if (return_value == -1) {
+		perror("send_away() write() buffer failed");
+		exit(EXIT_FAILURE);
+	}
+
+	memset(buffer, 0, buffer_length);
+
+	ret = usleep(usec);
+	if (ret == -1) {
+		perror("send_away() usleep() failed");
+		exit(EXIT_FAILURE);
+	}
+}
diff --git a/network.h b/network.h
index e69de29..2a96353 100644
--- a/network.h
+++ b/network.h
@@ -0,0 +1,24 @@
+#ifndef NETWORK_H_
+#define NETWORK_H_
+
+extern bool network_client;
+extern bool network_server;
+extern bool list;
+extern char *logserver_address;
+extern int logserver_port;
+
+void create_tcp_socket(void);
+void create_client(void);
+void signal_handler();
+void create_server(void);
+void send_away(int, unsigned long, unsigned long, unsigned long, unsigned long,
+		unsigned long, unsigned long);
+
+struct network_s {
+	char* network_address;
+	int network_port;
+	int connected_socketfd;
+	struct sockaddr_in *server;
+};
+
+#endif /* NETWORK_H_ */
diff --git a/params.c b/params.c
index c2c3f70..ef7a927 100644
--- a/params.c
+++ b/params.c
@@ -42,6 +42,12 @@ char *specific_proto_optarg;
 
 char *victim_path;
 
+bool network_client = FALSE;
+bool network_server = FALSE;
+bool list = FALSE;
+char *logserver_address = NULL;
+int logserver_port = 0;
+
 static void usage(void)
 {
 	fprintf(stderr, "%s\n", progname);
@@ -59,6 +65,11 @@ static void usage(void)
 	fprintf(stderr, " --syslog,-S: log important info to syslog. (useful if syslog is remote)\n");
 	fprintf(stderr, " --verbose,-v: increase output verbosity.\n");
 	fprintf(stderr, " --victims,-V: path to victim files.\n");
+	fprintf(stderr, "Network mode\n");
+	fprintf(stderr, " --client,-t <ip>:<port>: send the output in real-time to a log server\n");
+	fprintf(stderr, " --server,-e <port>: use trinity as a log server\n");
+	fprintf(stderr, "	./trinity -t 192.168.100.1:12345\n");
+	fprintf(stderr, "	./trinity -e 12345\n");
 	fprintf(stderr, "\n");
 	fprintf(stderr, " -c#: target specific syscall (takes syscall name as parameter).\n");
 	fprintf(stderr, " -N#: do # syscalls then exit.\n");
@@ -84,6 +95,8 @@ static const struct option longopts[] = {
 	{ "quiet", no_argument, NULL, 'q' },
 	{ "syslog", no_argument, NULL, 'S' },
 	{ "victims", required_argument, NULL, 'V' },
+	{ "client", required_argument, NULL, 't' },
+	{ "server", required_argument, NULL, 'e' },
 	{ "verbose", no_argument, NULL, 'v' },
 	{ NULL, 0, NULL, 0 } };
 
@@ -92,7 +105,7 @@ void parse_args(int argc, char *argv[])
 {
 	int opt;
 
-	while ((opt = getopt_long(argc, argv, "c:C:dDg:hIl:LN:mnP:pqr:s:SV:vx:", longopts, NULL)) != -1) {
+	while ((opt = getopt_long(argc, argv, "c:C:dDg:hIl:LN:mnP:pqr:s:SV:vx:t:e:", longopts, NULL)) != -1) {
 		switch (opt) {
 		default:
 			if (opt == '?')
@@ -208,6 +221,17 @@ void parse_args(int argc, char *argv[])
 			do_exclude_syscall = TRUE;
 			toggle_syscall(optarg, FALSE);
 			break;
+
+		case 't':
+			network_client = TRUE;
+			logserver_address = strtok(optarg, ":");
+			logserver_port = atoi(strtok(NULL, ":"));
+			break;
+
+		case 'e':
+			network_server = TRUE;
+			logserver_port = atoi(optarg);
+			break;
 		}
 	}
 	if (quiet_level > MAX_LOGLEVEL)
diff --git a/syscall.c b/syscall.c
index 61431f2..4a9a60c 100644
--- a/syscall.c
+++ b/syscall.c
@@ -22,6 +22,7 @@
 #include "params.h"
 #include "maps.h"
 #include "trinity.h"
+#include "network.h"
 
 #define __syscall_return(type, res) \
 	do { \
@@ -84,6 +85,9 @@ static unsigned long do_syscall(int childno, int *errno_saved)
 
 	errno = 0;
 
+	if( network_client == TRUE )
+		send_away(nr, a1, a2, a3, a4, a5, a6);
+
 	if (shm->do32bit[childno] == FALSE)
 		ret = syscall(nr, a1, a2, a3, a4, a5, a6);
 	else
diff --git a/trinity.c b/trinity.c
index 0b88150..197c181 100644
--- a/trinity.c
+++ b/trinity.c
@@ -32,6 +32,7 @@
 #include "syscall.h"
 #include "ioctls.h"
 #include "config.h"	// for VERSION
+#include "network.h"
 
 char *progname = NULL;
 
@@ -170,6 +171,12 @@ int main(int argc, char* argv[])
 
 	setup_shm_postargs();
 
+	if (network_client == TRUE)
+		create_client();
+
+	if (network_server == TRUE)
+		create_server();
+
 	if (logging == TRUE)
 		open_logfiles();
--
--
To unsubscribe from this list: send the line "unsubscribe trinity" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux SCSI]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux