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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html