|
@@ -13,95 +13,71 @@
|
|
#include "crypto.h"
|
|
#include "crypto.h"
|
|
|
|
|
|
|
|
|
|
-int replace_packet(flow *f, uint8_t *packet){
|
|
|
|
- const struct ip_header *ip_hdr;
|
|
|
|
- const struct tcp_header *tcp_hdr;
|
|
|
|
|
|
+int replace_packet(flow *f, struct packet_info *info){
|
|
|
|
|
|
- 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){
|
|
|
|
|
|
+ if (info->tcp_hdr == NULL){
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
- p += size_ip; //skip IP header
|
|
|
|
-
|
|
|
|
- tcp_hdr = (struct tcp_header*) p;
|
|
|
|
- int size_tcp = TCP_HEADER_LEN(tcp_hdr);
|
|
|
|
|
|
+#ifdef DEBUG
|
|
|
|
+ fprintf(stderr,"Flow: %d > %d (%s)\n", info->ip_hdr->src.s_addr, info->ip_hdr->dst.s_addr, (info->ip_hdr->src.s_addr != f->src_ip.s_addr)? "incoming":"outgoing");
|
|
|
|
+ fprintf(stderr,"ID number: %u\n", htonl(info->ip_hdr->id));
|
|
|
|
+ fprintf(stderr,"Sequence number: %u\n", htonl(info->tcp_hdr->sequence_num));
|
|
|
|
+ fprintf(stderr,"Acknowledgement number: %u\n", htonl(info->tcp_hdr->ack_num));
|
|
|
|
+#endif
|
|
|
|
|
|
- /*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));*/
|
|
|
|
- int32_t app_data_len = htons(ip_hdr->len) - (size_ip + size_tcp);
|
|
|
|
- printf("app_data length: %u\n", app_data_len);
|
|
|
|
- if(app_data_len <= 0){
|
|
|
|
|
|
+ if(info->app_data_len <= 0){
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
/* if outgoing, decrypt and look at header */
|
|
/* if outgoing, decrypt and look at header */
|
|
- if(ip_hdr->src.s_addr == f->src_ip.s_addr){
|
|
|
|
- read_header(f, packet);
|
|
|
|
|
|
+ if(info->ip_hdr->src.s_addr == f->src_ip.s_addr){
|
|
|
|
+ read_header(f, info);
|
|
return 0;
|
|
return 0;
|
|
} else {
|
|
} else {
|
|
|
|
+
|
|
|
|
+#ifdef DEBUG
|
|
printf("Current sequence number: %d\n", f->seq_num);
|
|
printf("Current sequence number: %d\n", f->seq_num);
|
|
printf("Received sequence number: %d\n", htonl(tcp_hdr->sequence_num));
|
|
printf("Received sequence number: %d\n", htonl(tcp_hdr->sequence_num));
|
|
- uint32_t offset = htonl(tcp_hdr->sequence_num) - f->seq_num;
|
|
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ uint32_t offset = htonl(info->tcp_hdr->sequence_num) - f->seq_num;
|
|
if(offset == 0)
|
|
if(offset == 0)
|
|
- f->seq_num += app_data_len;
|
|
|
|
|
|
+ f->seq_num += info->app_data_len;
|
|
/* if incoming, replace with data from queue */
|
|
/* if incoming, replace with data from queue */
|
|
//if(htonl(tcp_hdr->sequence_num) >= f->seq_num){
|
|
//if(htonl(tcp_hdr->sequence_num) >= f->seq_num){
|
|
- replace_contents(f, p, app_data_len, offset, ip_hdr->src, ip_hdr->dst);
|
|
|
|
|
|
+ replace_contents(f, offset, info);
|
|
//}//TODO: need to do something about replaying packets (maybe store previously sent data??
|
|
//}//TODO: need to do something about replaying packets (maybe store previously sent data??
|
|
|
|
|
|
- p = packet + ETHER_HEADER_LEN;
|
|
|
|
-#ifdef DEBUG
|
|
|
|
- fprintf(stdout, "ip hdr length: %d\n", htons(ip_hdr->len));
|
|
|
|
|
|
+
|
|
|
|
+#ifdef DEBUG //TODO: fix
|
|
|
|
+ uint8_t *p = (uint8_t *) info->tcp_hdr;
|
|
|
|
+ fprintf(stdout, "ip hdr length: %d\n", htons(info->ip_hdr->len));
|
|
fprintf(stdout, "Injecting the following packet:\n");
|
|
fprintf(stdout, "Injecting the following packet:\n");
|
|
- for(int i=0; i< htons(ip_hdr->len); i++){
|
|
|
|
|
|
+ for(int i=0; i< htons(info->ip_hdr->len); i++){
|
|
fprintf(stdout, "%02x ", p[i]);
|
|
fprintf(stdout, "%02x ", p[i]);
|
|
}
|
|
}
|
|
fprintf(stdout, "\n");
|
|
fprintf(stdout, "\n");
|
|
fflush(stdout);
|
|
fflush(stdout);
|
|
#endif
|
|
#endif
|
|
|
|
+
|
|
}
|
|
}
|
|
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);
|
|
|
|
|
|
+int read_header(flow *f, struct packet_info *info){
|
|
|
|
+ uint8_t *p = info->app_data;
|
|
|
|
|
|
- if (ip_hdr->proto != IPPROTO_TCP){
|
|
|
|
|
|
+ if (info->tcp_hdr == NULL){
|
|
return 0;
|
|
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;
|
|
struct record_header *record_hdr = (struct record_header*) p;
|
|
uint32_t record_length = RECORD_LEN(record_hdr);
|
|
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");*/
|
|
|
|
|
|
+ uint8_t *decrypted_data = calloc(1, info->app_data_len);
|
|
|
|
+
|
|
p+= RECORD_HEADER_LEN;
|
|
p+= RECORD_HEADER_LEN;
|
|
|
|
|
|
memcpy(decrypted_data, p, record_length);
|
|
memcpy(decrypted_data, p, record_length);
|
|
@@ -109,15 +85,8 @@ int read_header(flow *f, uint8_t *packet){
|
|
if(!encrypt(f, decrypted_data, decrypted_data, record_length, 0, record_hdr->type, 0)){
|
|
if(!encrypt(f, decrypted_data, decrypted_data, record_length, 0, record_hdr->type, 0)){
|
|
fprintf(stdout,"decryption failed\n");
|
|
fprintf(stdout,"decryption failed\n");
|
|
return 0;
|
|
return 0;
|
|
- } else {
|
|
|
|
- fprintf(stdout, "decryption succeeded!\n");
|
|
|
|
- if(record_hdr->type == 0x17){
|
|
|
|
- decrypted_data+= EVP_GCM_TLS_EXPLICIT_IV_LEN;
|
|
|
|
- fprintf(stdout, "request:");
|
|
|
|
- fprintf(stdout,"%s\n ", decrypted_data);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
}
|
|
}
|
|
|
|
+
|
|
if(record_hdr->type == 0x15){
|
|
if(record_hdr->type == 0x15){
|
|
printf("received alert\n");
|
|
printf("received alert\n");
|
|
for(int i=0; i<record_length; i++){
|
|
for(int i=0; i<record_length; i++){
|
|
@@ -128,8 +97,8 @@ int read_header(flow *f, uint8_t *packet){
|
|
|
|
|
|
/* search through decrypted data for x-ignore */
|
|
/* search through decrypted data for x-ignore */
|
|
regex_t r;
|
|
regex_t r;
|
|
- const uint8_t *regex_text = "x-ignore";
|
|
|
|
- const uint8_t *match = decrypted_data;
|
|
|
|
|
|
+ const char *regex_text = "x-ignore";
|
|
|
|
+ const char *match = (char *) decrypted_data;
|
|
if(regcomp(&r, regex_text, REG_EXTENDED|REG_NEWLINE)){
|
|
if(regcomp(&r, regex_text, REG_EXTENDED|REG_NEWLINE)){
|
|
printf("could not compile regex\n");
|
|
printf("could not compile regex\n");
|
|
return 0;
|
|
return 0;
|
|
@@ -137,7 +106,6 @@ int read_header(flow *f, uint8_t *packet){
|
|
|
|
|
|
regmatch_t m;
|
|
regmatch_t m;
|
|
if(regexec(&r, match, 1, &m, 0)){
|
|
if(regexec(&r, match, 1, &m, 0)){
|
|
- printf("no x-ignore found\n");
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
uint8_t *message = decrypted_data;
|
|
uint8_t *message = decrypted_data;
|
|
@@ -157,8 +125,8 @@ int read_header(flow *f, uint8_t *packet){
|
|
message = decrypted_data;
|
|
message = decrypted_data;
|
|
|
|
|
|
regex_t r2;
|
|
regex_t r2;
|
|
- const uint8_t *regex_text2 = "host";
|
|
|
|
- const uint8_t *match2 = decrypted_data;
|
|
|
|
|
|
+ const char *regex_text2 = "host";
|
|
|
|
+ const char *match2 = (char *) decrypted_data;
|
|
regmatch_t m2;
|
|
regmatch_t m2;
|
|
if(regcomp(&r2, regex_text2, REG_EXTENDED|REG_NEWLINE)){
|
|
if(regcomp(&r2, regex_text2, REG_EXTENDED|REG_NEWLINE)){
|
|
printf("could not compile regex\n");
|
|
printf("could not compile regex\n");
|
|
@@ -194,65 +162,86 @@ int read_header(flow *f, uint8_t *packet){
|
|
printf("error: constructing socket failed\n");
|
|
printf("error: constructing socket failed\n");
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
- printf("constructed socket\n");
|
|
|
|
|
|
+
|
|
struct sockaddr_in dest;
|
|
struct sockaddr_in dest;
|
|
dest.sin_family = AF_INET;
|
|
dest.sin_family = AF_INET;
|
|
dest.sin_port = htons(80);
|
|
dest.sin_port = htons(80);
|
|
dest.sin_addr = *((struct in_addr *) host->h_addr);
|
|
dest.sin_addr = *((struct in_addr *) host->h_addr);
|
|
bzero (&(dest.sin_zero), 8);
|
|
bzero (&(dest.sin_zero), 8);
|
|
- printf("connecting...");
|
|
|
|
|
|
+
|
|
int32_t error = connect (handle, (struct sockaddr *) &dest, sizeof (struct sockaddr));
|
|
int32_t error = connect (handle, (struct sockaddr *) &dest, sizeof (struct sockaddr));
|
|
- printf(" done\n");
|
|
|
|
|
|
+
|
|
if(error <0){
|
|
if(error <0){
|
|
printf("error connecting\n");
|
|
printf("error connecting\n");
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
- int32_t bytes_sent = send(handle, message, strlen(message), 0);
|
|
|
|
|
|
+ int32_t bytes_sent = send(handle, message, strlen((const char *) message), 0);
|
|
if( bytes_sent < 0){
|
|
if( bytes_sent < 0){
|
|
printf("error sending request\n");
|
|
printf("error sending request\n");
|
|
close(handle);
|
|
close(handle);
|
|
return 0;
|
|
return 0;
|
|
- } else if (bytes_sent < strlen(message)){
|
|
|
|
- printf("send partial request\n");
|
|
|
|
|
|
+ } else if (bytes_sent < strlen((const char *) message)){
|
|
close(handle);
|
|
close(handle);
|
|
return 0;
|
|
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];
|
|
|
|
|
|
+
|
|
|
|
+ int32_t bytes_read;
|
|
|
|
+ for(int i=0; i<3; i++){
|
|
|
|
+ uint8_t *buf = calloc(1, BUFSIZ);
|
|
|
|
+ bytes_read = recv(handle, buf, BUFSIZ, 0);
|
|
|
|
+ if(bytes_read <= 0) break;
|
|
|
|
+
|
|
|
|
+ //make a new queue block
|
|
|
|
+ queue_block *new_block = calloc(1, sizeof(queue_block));
|
|
|
|
+ new_block->len = bytes_read;
|
|
|
|
+ new_block->offset = 0;
|
|
|
|
+ new_block->data = buf;
|
|
|
|
+ new_block->next = NULL;
|
|
|
|
+ if(f->censored_queue == NULL)
|
|
|
|
+ f->censored_queue = new_block;
|
|
|
|
+ else{
|
|
|
|
+ queue_block *last = f->censored_queue;
|
|
|
|
+ while(last->next != NULL)
|
|
|
|
+ last = last->next;
|
|
|
|
+ last->next = new_block;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- f->censored_length = bytes_read;
|
|
|
|
|
|
|
|
- //for now, just close socket
|
|
|
|
close(handle);
|
|
close(handle);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
-int replace_contents(flow *f, uint8_t *data, int32_t data_len, int32_t offset, struct in_addr src, struct in_addr dst){
|
|
|
|
-
|
|
|
|
- printf("Replacing contents...\n");
|
|
|
|
- uint8_t *p = data;
|
|
|
|
|
|
+/** Replaces downstream record contents with data from the
|
|
|
|
+ * censored queue, padding with garbage bytes if no more
|
|
|
|
+ * censored data exists.
|
|
|
|
+ *
|
|
|
|
+ * Inputs:
|
|
|
|
+ * f: the tagged flow
|
|
|
|
+ * data: a pointer to the received packet's application
|
|
|
|
+ * data
|
|
|
|
+ * data_len: the length of the packet's application data
|
|
|
|
+ * offset: if the packet is misordered, the number of
|
|
|
|
+ * application-level bytes in missing packets
|
|
|
|
+ *
|
|
|
|
+ * Output:
|
|
|
|
+ * Returns 0 on sucess
|
|
|
|
+ */
|
|
|
|
+int replace_contents(flow *f, int32_t offset, struct packet_info *info){
|
|
|
|
|
|
- struct tcp_header *tcp_hdr = (struct tcp_header*) p;
|
|
|
|
- int size_tcp = TCP_HEADER_LEN(tcp_hdr);
|
|
|
|
- p += size_tcp;
|
|
|
|
|
|
+ uint8_t *p = info->app_data;
|
|
|
|
|
|
- int32_t tmp_len = data_len;
|
|
|
|
|
|
+ int32_t tmp_len = info->app_data_len;
|
|
|
|
|
|
//step 1: replace record contents
|
|
//step 1: replace record contents
|
|
//note: encrypted message will be original message size + EVP_GCM_TLS_EXPLICIT_IV_LEN + 16 byte pad
|
|
//note: encrypted message will be original message size + EVP_GCM_TLS_EXPLICIT_IV_LEN + 16 byte pad
|
|
//first check to see if there's anything in the outbox
|
|
//first check to see if there's anything in the outbox
|
|
if(f->outbox_len > 0){
|
|
if(f->outbox_len > 0){
|
|
- printf("Printing from outbox\n");
|
|
|
|
- if(f->outbox_len < data_len){
|
|
|
|
|
|
+
|
|
|
|
+#ifdef DEBUG
|
|
|
|
+ if(f->outbox_len < info->app_data_len){
|
|
printf("Next record:\n");
|
|
printf("Next record:\n");
|
|
for(int i=0; i< RECORD_HEADER_LEN; i++){
|
|
for(int i=0; i< RECORD_HEADER_LEN; i++){
|
|
printf("%02x ", p[f->outbox_len+i]);
|
|
printf("%02x ", p[f->outbox_len+i]);
|
|
@@ -261,6 +250,7 @@ int replace_contents(flow *f, uint8_t *data, int32_t data_len, int32_t offset, s
|
|
} else {
|
|
} else {
|
|
printf("Outbox takes up entire packet\n");
|
|
printf("Outbox takes up entire packet\n");
|
|
}
|
|
}
|
|
|
|
+#endif
|
|
|
|
|
|
if(tmp_len >= f->outbox_len){
|
|
if(tmp_len >= f->outbox_len){
|
|
memcpy(p, f->outbox, f->outbox_len);
|
|
memcpy(p, f->outbox, f->outbox_len);
|
|
@@ -269,16 +259,13 @@ int replace_contents(flow *f, uint8_t *data, int32_t data_len, int32_t offset, s
|
|
tmp_len -= f->outbox_len;
|
|
tmp_len -= f->outbox_len;
|
|
f->outbox_len = 0;
|
|
f->outbox_len = 0;
|
|
free(f->outbox);
|
|
free(f->outbox);
|
|
- printf("outbox now empty\n");
|
|
|
|
} else {
|
|
} else {
|
|
- printf("Outbox has %d - %d bytes\n", f->outbox_len, tmp_len);
|
|
|
|
memcpy(p, f->outbox, tmp_len);
|
|
memcpy(p, f->outbox, tmp_len);
|
|
uint8_t *tmp = calloc(1, f->outbox_len - tmp_len);
|
|
uint8_t *tmp = calloc(1, f->outbox_len - tmp_len);
|
|
f->outbox_len -= tmp_len;
|
|
f->outbox_len -= tmp_len;
|
|
memcpy(tmp, f->outbox + tmp_len, f->outbox_len);
|
|
memcpy(tmp, f->outbox + tmp_len, f->outbox_len);
|
|
free(f->outbox);
|
|
free(f->outbox);
|
|
f->outbox = tmp;
|
|
f->outbox = tmp;
|
|
- printf(" = %d bytes left in outbox\n", f->outbox_len);
|
|
|
|
tmp_len -= tmp_len;
|
|
tmp_len -= tmp_len;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -287,11 +274,14 @@ int replace_contents(flow *f, uint8_t *data, int32_t data_len, int32_t offset, s
|
|
|
|
|
|
struct record_header *record_hdr = (struct record_header*) p;
|
|
struct record_header *record_hdr = (struct record_header*) p;
|
|
uint32_t record_length = RECORD_LEN(record_hdr);
|
|
uint32_t record_length = RECORD_LEN(record_hdr);
|
|
|
|
+
|
|
|
|
+#ifdef DEBUG
|
|
fprintf(stdout, "Record:\n");
|
|
fprintf(stdout, "Record:\n");
|
|
for(int i=0; i< RECORD_HEADER_LEN; i++){
|
|
for(int i=0; i< RECORD_HEADER_LEN; i++){
|
|
printf("%02x ", p[i]);
|
|
printf("%02x ", p[i]);
|
|
}
|
|
}
|
|
printf("\n");
|
|
printf("\n");
|
|
|
|
+#endif
|
|
|
|
|
|
p += RECORD_HEADER_LEN;
|
|
p += RECORD_HEADER_LEN;
|
|
if(record_hdr->type != 0x17){
|
|
if(record_hdr->type != 0x17){
|
|
@@ -306,128 +296,72 @@ int replace_contents(flow *f, uint8_t *data, int32_t data_len, int32_t offset, s
|
|
memcpy(new_record, p, record_length);
|
|
memcpy(new_record, p, record_length);
|
|
uint8_t *tmp_p = new_record;
|
|
uint8_t *tmp_p = new_record;
|
|
|
|
|
|
-
|
|
|
|
- /*// BEGIN TEST CODE //
|
|
|
|
-
|
|
|
|
- //Print original record
|
|
|
|
- printf("Original record (%d bytes):\n", record_length);
|
|
|
|
- for(int i=0; i< record_length; i++){
|
|
|
|
- printf("%02x ", p[i]);
|
|
|
|
- }
|
|
|
|
- printf("\n");
|
|
|
|
-
|
|
|
|
- //print few bytes of next record (if present)
|
|
|
|
- if(data_len > record_length + RECORD_HEADER_LEN){
|
|
|
|
- printf("Next record:\n");
|
|
|
|
- for(int i=0; i< RECORD_HEADER_LEN; i++){
|
|
|
|
- printf("%02x ", p[record_length+i]);
|
|
|
|
- }
|
|
|
|
- printf("\n");
|
|
|
|
- } else {
|
|
|
|
- printf("No extra record: %d = %d + %d\n", data_len, record_length, RECORD_HEADER_LEN);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- //Decrypt record
|
|
|
|
- printf("Decrypting record... ");
|
|
|
|
- int n;
|
|
|
|
- if(!(n = encrypt(f, p, p, record_length, 1, 0x17, 0))){
|
|
|
|
- fprintf(stderr,"failed\n");
|
|
|
|
- return 0;
|
|
|
|
- } else {
|
|
|
|
- fprintf(stderr, "succeeded!\n");
|
|
|
|
- printf("Decrypted record:\n");
|
|
|
|
- for(int i=0; i< record_length; i++){
|
|
|
|
- printf("%02x ", p[i]);
|
|
|
|
- }
|
|
|
|
- printf("\n");
|
|
|
|
- printf("%s\n", p+ EVP_GCM_TLS_EXPLICIT_IV_LEN);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //return seq to what it was
|
|
|
|
- for(int i=7; i>=0; i--){
|
|
|
|
- --f->read_seq[i];
|
|
|
|
- if(f->read_seq[i] >= 0)
|
|
|
|
- break;
|
|
|
|
- else
|
|
|
|
- f->read_seq[i] = 0;
|
|
|
|
- }
|
|
|
|
- printf("seq reverted (%s): ", "read");
|
|
|
|
- for(int i=0; i<8; i++){
|
|
|
|
- printf("%02x ", f->read_seq[i]);
|
|
|
|
- }
|
|
|
|
- printf("\n");
|
|
|
|
-
|
|
|
|
- //Now reposition it to be fed into encrypt function
|
|
|
|
- //memcpy(p, p+ EVP_GCM_TLS_EXPLICIT_IV_LEN, n);
|
|
|
|
-
|
|
|
|
- // END TEST CODE */
|
|
|
|
-
|
|
|
|
- //step 2: figure out what happens if we don't have data
|
|
|
|
tmp_p += EVP_GCM_TLS_EXPLICIT_IV_LEN;
|
|
tmp_p += EVP_GCM_TLS_EXPLICIT_IV_LEN;
|
|
|
|
|
|
struct slitheen_header *sl_hdr = (struct slitheen_header *) tmp_p;
|
|
struct slitheen_header *sl_hdr = (struct slitheen_header *) tmp_p;
|
|
sl_hdr->marker = 0x01;
|
|
sl_hdr->marker = 0x01;
|
|
sl_hdr->version = 0x01;
|
|
sl_hdr->version = 0x01;
|
|
|
|
+ sl_hdr->len = 0x00;
|
|
int32_t remaining = record_length - (SLITHEEN_HEADER_LEN
|
|
int32_t remaining = record_length - (SLITHEEN_HEADER_LEN
|
|
+ EVP_GCM_TLS_EXPLICIT_IV_LEN + 16);
|
|
+ EVP_GCM_TLS_EXPLICIT_IV_LEN + 16);
|
|
- fprintf(stdout, "filling with censored queue data (%d out of %d) at offset %d\n", remaining, f->censored_length-offset, offset);
|
|
|
|
- if(remaining > 0){
|
|
|
|
- if(remaining+offset <= f->censored_length){
|
|
|
|
- fprintf(stdout, "We have enough data to fill the record\n");
|
|
|
|
- for(int i = 0; i< remaining; i++){
|
|
|
|
- tmp_p[SLITHEEN_HEADER_LEN+i] = f->censored_queue[i + offset];
|
|
|
|
- }
|
|
|
|
- //TODO: when I restructure this for more data, figure out freeing these pointers
|
|
|
|
- f->censored_queue += remaining;
|
|
|
|
- f->censored_length -= remaining;
|
|
|
|
- sl_hdr->len = htons(remaining);
|
|
|
|
- fprintf(stdout, "copied %d data\n", ntohs(sl_hdr->len));
|
|
|
|
|
|
+ tmp_p += SLITHEEN_HEADER_LEN;
|
|
|
|
+ //Fill as much as we can from the censored_queue
|
|
|
|
+ while((remaining > 0) && f->censored_queue != NULL){
|
|
|
|
+ int32_t block_length = f->censored_queue->len;
|
|
|
|
+ int32_t offset = f->censored_queue->offset;
|
|
|
|
|
|
|
|
+#ifdef DEBUG
|
|
|
|
+ printf("Censored queue is at %p.\n", f->censored_queue);
|
|
|
|
+ printf("This block as %d bytes left\n", block_length - offset);
|
|
|
|
+ printf("We need %d bytes\n", remaining);
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ if(block_length > offset + remaining){
|
|
|
|
+ //use part of the block, update offset
|
|
|
|
+ memcpy(tmp_p, f->censored_queue->data+offset, remaining);
|
|
|
|
+ f->censored_queue->offset += remaining;
|
|
|
|
+ tmp_p += remaining;
|
|
|
|
+ sl_hdr->len += remaining;
|
|
|
|
+ remaining -= remaining;
|
|
} else {
|
|
} else {
|
|
- int32_t dummy_offset = f->censored_length - offset;
|
|
|
|
- if(dummy_offset < 0) dummy_offset = 0;
|
|
|
|
- fprintf(stdout, "Not enough data (%d bytes)\n", dummy_offset);
|
|
|
|
- for(int i = 0; i< dummy_offset; i++){
|
|
|
|
- tmp_p[SLITHEEN_HEADER_LEN+i] = f->censored_queue[i + offset];
|
|
|
|
- }
|
|
|
|
- //TODO: note, we may also be receiving misordered packets. Take Ian's suggestion into account here
|
|
|
|
- f->censored_queue += dummy_offset;
|
|
|
|
- f->censored_length -= dummy_offset;
|
|
|
|
- sl_hdr->len = htons(dummy_offset);
|
|
|
|
- //TODO: should i < record_length or remaining??
|
|
|
|
- for(int i = dummy_offset; i< remaining; i++){
|
|
|
|
- tmp_p[SLITHEEN_HEADER_LEN+i] = 'A';
|
|
|
|
- }
|
|
|
|
- fprintf(stdout, "copied %d data and %d garbage bytes\n", ntohs(sl_hdr->len), remaining - dummy_offset);
|
|
|
|
|
|
+ //use all of the block and free it
|
|
|
|
+ memcpy(tmp_p, f->censored_queue->data+offset, block_length - offset);
|
|
|
|
+
|
|
|
|
+ free(f->censored_queue->data);
|
|
|
|
+ f->censored_queue = f->censored_queue->next;
|
|
|
|
+
|
|
|
|
+ tmp_p += (block_length - offset);
|
|
|
|
+ sl_hdr->len += (block_length - offset);
|
|
|
|
+ remaining -= (block_length - offset);
|
|
}
|
|
}
|
|
- printf("Slitheen header\n");
|
|
|
|
- for(int i=0; i<4; i++)
|
|
|
|
- printf("%02x ", tmp_p[i]);
|
|
|
|
- printf("\n");
|
|
|
|
}
|
|
}
|
|
- tmp_p -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
|
|
|
|
|
|
+ sl_hdr->len = htons(sl_hdr->len);
|
|
|
|
+ //now, if we need more data, fill with garbage
|
|
|
|
+ if(remaining >0 ){
|
|
|
|
+ //TODO: note, we may also be receiving misordered packets. Take Ian's suggestion into account here
|
|
|
|
+ memset(tmp_p, 'A', remaining);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ tmp_p = new_record;
|
|
|
|
+
|
|
|
|
+#ifdef DEBUG
|
|
|
|
+ fprintf(stdout, "copied %d data and %d garbage bytes\n", ntohs(sl_hdr->len), remaining);
|
|
|
|
+ printf("Slitheen header\n");
|
|
|
|
+ for(int i=0; i<4; i++)
|
|
|
|
+ printf("%02x ", tmp_p[EVP_GCM_TLS_EXPLICIT_IV_LEN+i]);
|
|
|
|
+ printf("\n");
|
|
|
|
+#endif
|
|
|
|
+
|
|
//step 3: encrypt new record
|
|
//step 3: encrypt new record
|
|
- //fprintf(stderr, "computing mac\n");
|
|
|
|
- //int32_t mac_size = mac(f, p, p+(record_length - (EVP_GCM_TLS_EXPLICIT_IV_LEN + 16)), record_length - (EVP_GCM_TLS_EXPLICIT_IV_LEN + 16), 1, 0x17, 1);
|
|
|
|
- //printf(stderr, "mac size: %d\n", mac_size);
|
|
|
|
- //fprintf(stderr, "encrypting\n");
|
|
|
|
int32_t success;
|
|
int32_t success;
|
|
if((success = encrypt(f, tmp_p, tmp_p, record_length-16, 1, 0x17, 1))< 0){
|
|
if((success = encrypt(f, tmp_p, tmp_p, record_length-16, 1, 0x17, 1))< 0){
|
|
fprintf(stdout,"encryption failed\n");
|
|
fprintf(stdout,"encryption failed\n");
|
|
return 0;
|
|
return 0;
|
|
- } else {
|
|
|
|
- fprintf(stdout, "encryption succeeded!\n");
|
|
|
|
- //printf("Encrypted data:\n");
|
|
|
|
- //for(int i=0; i< success; i++){
|
|
|
|
- // printf("%02x ", tmp_p[i]);
|
|
|
|
- //}
|
|
|
|
- //printf("\n");
|
|
|
|
}
|
|
}
|
|
|
|
+
|
|
//copy new record into packet
|
|
//copy new record into packet
|
|
if(record_length +RECORD_HEADER_LEN > tmp_len){
|
|
if(record_length +RECORD_HEADER_LEN > tmp_len){
|
|
//We have a partial record
|
|
//We have a partial record
|
|
- printf("Warning: partial record\n");
|
|
|
|
memcpy(p, new_record, tmp_len - RECORD_HEADER_LEN);
|
|
memcpy(p, new_record, tmp_len - RECORD_HEADER_LEN);
|
|
f->outbox_len = record_length - (tmp_len - RECORD_HEADER_LEN);
|
|
f->outbox_len = record_length - (tmp_len - RECORD_HEADER_LEN);
|
|
//save left-overs in outbox
|
|
//save left-overs in outbox
|
|
@@ -435,15 +369,14 @@ int replace_contents(flow *f, uint8_t *data, int32_t data_len, int32_t offset, s
|
|
memcpy(f->outbox, new_record + (tmp_len - RECORD_HEADER_LEN),
|
|
memcpy(f->outbox, new_record + (tmp_len - RECORD_HEADER_LEN),
|
|
f->outbox_len);
|
|
f->outbox_len);
|
|
free(new_record);
|
|
free(new_record);
|
|
- printf("Outbox has %d = %d - %d bytes\n", f->outbox_len, record_length+RECORD_HEADER_LEN, tmp_len);
|
|
|
|
} else {
|
|
} else {
|
|
memcpy(p, new_record, record_length);
|
|
memcpy(p, new_record, record_length);
|
|
free(new_record);
|
|
free(new_record);
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
|
|
+#ifdef DEBUG
|
|
//check to see if next record still exists
|
|
//check to see if next record still exists
|
|
- if(data_len > record_length + RECORD_HEADER_LEN){
|
|
|
|
|
|
+ if(info->app_data_len > record_length + RECORD_HEADER_LEN){
|
|
printf("Next record:\n");
|
|
printf("Next record:\n");
|
|
for(int i=0; i< RECORD_HEADER_LEN; i++){
|
|
for(int i=0; i< RECORD_HEADER_LEN; i++){
|
|
printf("%02x ", p[record_length+i]);
|
|
printf("%02x ", p[record_length+i]);
|
|
@@ -452,18 +385,14 @@ int replace_contents(flow *f, uint8_t *data, int32_t data_len, int32_t offset, s
|
|
} else {
|
|
} else {
|
|
printf("No extra record: %d <= %d + %d\n", data_len, record_length, RECORD_HEADER_LEN);
|
|
printf("No extra record: %d <= %d + %d\n", data_len, record_length, RECORD_HEADER_LEN);
|
|
}
|
|
}
|
|
|
|
+#endif
|
|
|
|
+
|
|
tmp_len -= record_length+ RECORD_HEADER_LEN;
|
|
tmp_len -= record_length+ RECORD_HEADER_LEN;
|
|
p += record_length;
|
|
p += record_length;
|
|
|
|
|
|
}
|
|
}
|
|
//step 4: recompute TCP checksum
|
|
//step 4: recompute TCP checksum
|
|
- p = data;
|
|
|
|
- p[16] = 0; p[17] = 0;//zero out checksum
|
|
|
|
- uint16_t chksm = tcp_checksum(p, data_len, src, dst);
|
|
|
|
- p[17] = chksm & 0xFF;
|
|
|
|
- p[16] = chksm >> 8;
|
|
|
|
- fprintf(stdout, "Checksum: 0x%0x%0x\n", p[16], p[17]);
|
|
|
|
- fflush(stdout);
|
|
|
|
|
|
+ tcp_checksum(info);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -483,16 +412,17 @@ int replace_contents(flow *f, uint8_t *data, int32_t data_len, int32_t offset, s
|
|
* | zero | PTCL | TCP Length |
|
|
* | zero | PTCL | TCP Length |
|
|
* +--------+--------+--------+--------+
|
|
* +--------+--------+--------+--------+
|
|
*/
|
|
*/
|
|
-uint16_t tcp_checksum(uint8_t *data, int32_t data_len, struct in_addr src, struct in_addr dst){
|
|
|
|
|
|
+uint16_t tcp_checksum(struct packet_info *info){
|
|
|
|
|
|
- uint8_t *p = data;
|
|
|
|
-
|
|
|
|
- struct tcp_header *tcp_hdr = (struct tcp_header*) p;
|
|
|
|
- int size_tcp = TCP_HEADER_LEN(tcp_hdr);
|
|
|
|
- //Construct pseudo-header
|
|
|
|
- uint16_t tcp_length = data_len + size_tcp;
|
|
|
|
|
|
+ uint16_t tcp_length = info->app_data_len + info->size_tcp_hdr;
|
|
|
|
+ struct in_addr src = info->ip_hdr->src;
|
|
|
|
+ struct in_addr dst = info->ip_hdr->dst;
|
|
uint8_t proto = IPPROTO_TCP;
|
|
uint8_t proto = IPPROTO_TCP;
|
|
- fprintf(stdout, "summing pseudoheader\n");
|
|
|
|
|
|
+
|
|
|
|
+ //set the checksum to zero
|
|
|
|
+ info->tcp_hdr->chksum = 0;
|
|
|
|
+
|
|
|
|
+ //sum pseudoheader
|
|
uint32_t sum = (ntohl(src.s_addr)) >> 16;
|
|
uint32_t sum = (ntohl(src.s_addr)) >> 16;
|
|
sum += (ntohl(src.s_addr)) &0xFFFF;
|
|
sum += (ntohl(src.s_addr)) &0xFFFF;
|
|
sum += (ntohl(dst.s_addr)) >> 16;
|
|
sum += (ntohl(dst.s_addr)) >> 16;
|
|
@@ -500,17 +430,26 @@ uint16_t tcp_checksum(uint8_t *data, int32_t data_len, struct in_addr src, struc
|
|
sum += proto;
|
|
sum += proto;
|
|
sum += tcp_length;
|
|
sum += tcp_length;
|
|
|
|
|
|
- //now sum the text
|
|
|
|
- for(int i=0; i< tcp_length-1; i+=2){
|
|
|
|
|
|
+ //sum tcp header (with zero-d checksum)
|
|
|
|
+ uint8_t *p = (uint8_t *) info->tcp_hdr;
|
|
|
|
+ for(int i=0; i < info->size_tcp_hdr; i+=2){
|
|
sum += (uint16_t) ((p[i] << 8) + p[i+1]);
|
|
sum += (uint16_t) ((p[i] << 8) + p[i+1]);
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ //now sum the application data
|
|
|
|
+ p = info->app_data;
|
|
|
|
+ for(int i=0; i< info->app_data_len-1; i+=2){
|
|
|
|
+ sum += (uint16_t) ((p[i] << 8) + p[i+1]);
|
|
}
|
|
}
|
|
- if(tcp_length %2 != 0){
|
|
|
|
- sum += (uint16_t) (p[tcp_length - 1]) << 8;
|
|
|
|
|
|
+ if(info->app_data_len %2 != 0){
|
|
|
|
+ sum += (uint16_t) (p[info->app_data_len - 1]) << 8;
|
|
}
|
|
}
|
|
//now add most significant to last significant bits
|
|
//now add most significant to last significant bits
|
|
sum = (sum >> 16) + (sum & 0xFFFF);
|
|
sum = (sum >> 16) + (sum & 0xFFFF);
|
|
//now subtract from 0xFF
|
|
//now subtract from 0xFF
|
|
sum = 0xFFFF - sum;
|
|
sum = 0xFFFF - sum;
|
|
|
|
+
|
|
|
|
+ //set chksum to calculated value
|
|
|
|
+ info->tcp_hdr->chksum = ntohs(sum);
|
|
return (uint16_t) sum;
|
|
return (uint16_t) sum;
|
|
}
|
|
}
|