Browse Source

replacement code

cbocovic 9 years ago
parent
commit
b7ffbb1176
6 changed files with 224 additions and 9 deletions
  1. 2 2
      server/Makefile
  2. 1 0
      server/flow.c
  3. 1 0
      server/flow.h
  4. 205 0
      server/relay.c
  5. 10 0
      server/relay.h
  6. 5 7
      server/slitheen-proxy.c

+ 2 - 2
server/Makefile

@@ -4,12 +4,12 @@ TARGETS=slitheen-proxy
 
 all: $(TARGETS)
 
-slitheen-proxy.o flow.o rserv.o ptwist168.o util.o crypto.o:: ptwist.h rserv.h flow.h slitheen.h util.h crypto.h
+slitheen-proxy.o flow.o rserv.o ptwist168.o util.o crypto.o relay.o:: ptwist.h rserv.h flow.h slitheen.h util.h crypto.h relay.h
 
 rserv: rserv.o ptwist168.o
 	gcc -g -o $@ $^ -lssl -lcrypto
 
-slitheen-proxy: slitheen-proxy.o flow.o rserv.o ptwist168.o util.o crypto.o crypto.h util.h ptwist.h rserv.h flow.h slitheen.h
+slitheen-proxy: slitheen-proxy.o flow.o rserv.o ptwist168.o util.o crypto.o relay.o relay.h crypto.h util.h ptwist.h rserv.h flow.h slitheen.h
 	gcc -g -o $@ $^ -I/home/slitheen/Documents/include/openssl libssl.a libcrypto.a -lpcap -lpthread -ldl
 
 clean:

+ 1 - 0
server/flow.c

@@ -42,6 +42,7 @@ flow *add_flow(flow newFlow) {
 	newFlow.out_encrypted = 0;
 	newFlow.application = 0;
 	newFlow.packet_chain = NULL;
+	newFlow.censored_queue = calloc(1,2048);
 	newFlow.finish_md_ctx = EVP_MD_CTX_create();
 	const EVP_MD *md = EVP_sha384();
 	EVP_DigestInit_ex(newFlow.finish_md_ctx, md, NULL);

+ 1 - 0
server/flow.h

@@ -43,6 +43,7 @@ typedef struct flow_st {
 	int out_encrypted;		/* indicates whether outgoing flow is encrypted */
 	int application; /* indicates handshake is complete */
 	packet *packet_chain; /* currently held data */
+	uint8_t *censored_queue;
 	DH *dh;
 
 	uint8_t handshake_hash[EVP_MAX_MD_SIZE];

+ 205 - 0
server/relay.c

@@ -0,0 +1,205 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <regex.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <unistd.h>
+#include "relay.h"
+#include "slitheen.h"
+#include "flow.h"
+#include "crypto.h"
+
+
+int replace_packet(flow *f, uint8_t *packet){
+	const struct ip_header *ip_hdr;
+	const struct tcp_header *tcp_hdr;
+
+	uint8_t *p = packet;
+
+	p += ETHER_HEADER_LEN; //skip ethernet header
+	ip_hdr = (struct ip_header*) p;
+	int size_ip = IP_HEADER_LEN(ip_hdr);
+
+	if (ip_hdr->proto != IPPROTO_TCP){
+		return 0;
+	}
+
+	p += size_ip;	//skip IP header
+
+	tcp_hdr = (struct tcp_header*) p;
+	int size_tcp = TCP_HEADER_LEN(tcp_hdr);
+	p += size_tcp;
+
+	/*fprintf(stderr,"Flow: %d > %d (%s)\n", ip_hdr->src.s_addr, ip_hdr->dst.s_addr, (ip_hdr->src.s_addr != f->src_ip.s_addr)? "incoming":"outgoing");
+	fprintf(stderr,"ID number: %u\n", htonl(ip_hdr->id));
+	fprintf(stderr,"Sequence number: %u\n", htonl(tcp_hdr->sequence_num));
+	fprintf(stderr,"Acknowledgement number: %u\n", htonl(tcp_hdr->ack_num));*/
+	int app_data_len = htons(ip_hdr->len) - (size_ip + size_tcp);
+	if(app_data_len <= 0){
+		return 0;
+	}
+
+	/* if outgoing, decrypt and look at header */
+	if(ip_hdr->src.s_addr == f->src_ip.s_addr){
+		read_header(f, packet);
+		return 0;
+	}
+	return 0;
+
+}
+
+int read_header(flow *f, uint8_t *packet){
+	const struct ip_header *ip_hdr;
+	const struct tcp_header *tcp_hdr;
+
+	uint8_t *p = packet;
+
+	p += ETHER_HEADER_LEN; //skip ethernet header
+	ip_hdr = (struct ip_header*) p;
+	int size_ip = IP_HEADER_LEN(ip_hdr);
+
+	if (ip_hdr->proto != IPPROTO_TCP){
+		return 0;
+	}
+
+	p += size_ip;	//skip IP header
+
+	tcp_hdr = (struct tcp_header*) p;
+	int size_tcp = TCP_HEADER_LEN(tcp_hdr);
+	p += size_tcp;
+	int app_data_len = htons(ip_hdr->len) - (size_ip + size_tcp);
+
+	struct record_header *record_hdr = (struct record_header*) p;
+	uint32_t record_length = RECORD_LEN(record_hdr);
+	uint8_t *decrypted_data = calloc(1, app_data_len);
+
+	/*fprintf(stderr,"record:\n");
+	for(int i=0; i< RECORD_HEADER_LEN; i++){
+		fprintf(stderr,"%02x ", p[i]);
+	}
+	fprintf(stderr,"\n");*/
+	p+= RECORD_HEADER_LEN;
+
+	memcpy(decrypted_data, p, record_length);
+
+	if(!encrypt(f, decrypted_data, decrypted_data, record_length, 0, 0x17)){
+		fprintf(stderr,"decryption failed\n");
+		return 0;
+	} else {
+		fprintf(stderr, "decryption succeeded!\n");
+		decrypted_data+= EVP_GCM_TLS_EXPLICIT_IV_LEN;
+		fprintf(stderr, "request:");
+		fprintf(stderr,"%s\n ", decrypted_data);
+	}
+
+	/* search through decrypted data for x-ignore */
+	regex_t r;
+	const uint8_t *regex_text = "x-ignore";
+	const uint8_t *match = decrypted_data;
+	if(regcomp(&r, regex_text, REG_EXTENDED|REG_NEWLINE)){
+		printf("could not compile regex\n");
+		return 0;
+	}
+
+	regmatch_t m;
+	if(regexec(&r, match, 1, &m, 0)){
+		printf("no x-ignore found\n");
+		return 0;
+	} 
+	uint8_t *message = decrypted_data;
+	//remove escape characters
+	for(int i=m.rm_eo+2; i< strlen(match); i++){
+		if(match[i] != '\\'){
+			*(message++) = match[i];
+		} else if (match[i+1] == 'r') {
+			*(message++) = '\r';
+			i++;
+		} else if (match[i+1] == 'n') {
+			*(message++) = '\n';
+			i++;
+		}
+	}
+	*message = '\0';
+	message = decrypted_data;
+
+	regex_t r2;
+	const uint8_t *regex_text2 = "host";
+	const uint8_t *match2 = decrypted_data;
+	regmatch_t m2;
+	if(regcomp(&r2, regex_text2, REG_EXTENDED|REG_NEWLINE)){
+		printf("could not compile regex\n");
+		return 0;
+	}
+	if(regexec(&r2, match2, 1, &m2, 0)){
+		printf("no host found\n");
+		return 0;
+	}
+	uint8_t server[50];
+	for(int i=m2.rm_eo+2; i< strlen(match2); i++){
+		if(match2[i] != '\n'){
+			server[i-m2.rm_eo-2] = match2[i];
+		} else {
+			server[i-m2.rm_eo-2] = '\0';
+			break;
+		}
+	}
+
+	/* Send GET request to site */
+	printf("sending request to site: %s\n", server);
+
+	struct hostent *host;
+	host = gethostbyname((const char *) server);
+
+	if(host == NULL){
+		printf("gethostbyname failed\n");
+		return 0;
+	}
+
+	int32_t handle = socket(AF_INET, SOCK_STREAM, 0);
+	if(handle < 0){
+		printf("error: constructing socket failed\n");
+		return 0;
+	}
+	printf("constructed socket\n");
+	struct sockaddr_in dest;
+	dest.sin_family = AF_INET;
+	dest.sin_port = htons(80);
+	dest.sin_addr = *((struct in_addr *) host->h_addr);
+	bzero (&(dest.sin_zero), 8);
+	printf("connecting...");
+	int32_t error = connect (handle, (struct sockaddr *) &dest, sizeof (struct sockaddr));
+	printf(" done\n");
+	if(error <0){
+		printf("error connecting\n");
+		return 0;
+	}
+	int32_t bytes_sent = send(handle, message, strlen(message), 0);
+	if( bytes_sent < 0){
+		printf("error sending request\n");
+		close(handle);
+		return 0;
+	} else if (bytes_sent < strlen(message)){
+		printf("send partial request\n");
+		close(handle);
+		return 0;
+	}
+
+	printf("sent request!\n");
+	//change this to realloc and loop later
+	uint8_t *buf = calloc(1, 2048);
+	memset(buf, 0, 2048);
+	int32_t bytes_read = recv(handle, buf, 2048, 0);
+	printf("Received message:\n %s\n", buf);
+	for(int i=0; i< bytes_read; i++){
+		f->censored_queue[i] = buf[i];
+	}
+
+	//for now, just close socket
+	close(handle);
+
+	return 0;
+
+}

+ 10 - 0
server/relay.h

@@ -0,0 +1,10 @@
+#ifndef _RELAY_H_
+#define _RELAY_H_
+
+#include "flow.h"
+#include <stdint.h>
+
+int replace_packet(flow *f, uint8_t *packet);
+int read_header(flow *f, uint8_t *packet);
+
+#endif /* _RELAY_H_ */

+ 5 - 7
server/slitheen-proxy.c

@@ -109,16 +109,15 @@ void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *pa
 	pcap_t *handle;
 	char errbuf[BUFSIZ];
 	char *writedev = (char *) args;
-	//unsigned char *p;
+	unsigned char *p;
 
-	//const struct ip_header *ip_hdr;
+	const struct ip_header *ip_hdr;
 	//const struct tcp_header *tcp_hdr;
 
 	handle = pcap_open_live(writedev, BUFSIZ, 1, 1000, errbuf);
 	if (handle == NULL){
 		fprintf(stderr, "Couldn't open device %s: %s\n", writedev, errbuf);
 	}
-/*
 	p = (unsigned char *) packet;
 	p += ETHER_HEADER_LEN; //skip ethernet header
 	ip_hdr = (struct ip_header*) p;
@@ -132,7 +131,7 @@ void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *pa
 	// Packet may be split over multiple frames. In this case,
 	 // reconstruct the packet before trying to read TLS records
 	 //
-	if((htons(ip_hdr->flagsoff)&MF) || (htons(ip_hdr->flagsoff) &0x1fff) ){ /* this is a fragment 
+	if((htons(ip_hdr->flagsoff)&MF) || (htons(ip_hdr->flagsoff) &0x1fff) ){ /* this is a fragment */
 		printf("MF: %d, OFF: %d.\n", htons(ip_hdr->flagsoff)&MF, htons(ip_hdr->flagsoff)&0x1fff);
 		printf("Received packet fragment.\n");
 		printf("%d packet bytes: \n", IP_HEADER_LEN(ip_hdr));
@@ -148,14 +147,13 @@ void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *pa
 		if(success){
 			process_packet(complete_packet);
 		}
-		/* TODO: handle errors 
+		/* TODO: handle errors */
 		
-	} else { /*not a fragment, add to packet chain 
+	} else { /*not a fragment, add to packet chain */
 		process_packet(packet);
 	}
 	
 end:
-*/
 	if((pcap_inject(handle, packet, header->len)) < 0 ){
 		fprintf(stderr, "Error: %s\n", pcap_geterr(handle));
 	}