|
@@ -18,6 +18,8 @@
|
|
|
#include "flow.h"
|
|
|
#include "crypto.h"
|
|
|
|
|
|
+#define DEBUG
|
|
|
+
|
|
|
/** Called when a TLS application record is received for a
|
|
|
* tagged flow. Upstream packets will be checked for covert
|
|
|
* requests to censored sites, downstream packets will be
|
|
@@ -37,10 +39,10 @@ int replace_packet(flow *f, struct packet_info *info){
|
|
|
}
|
|
|
|
|
|
#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));
|
|
|
+ fprintf(stdout,"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(stdout,"ID number: %u\n", htonl(info->ip_hdr->id));
|
|
|
+ fprintf(stdout,"Sequence number: %u\n", htonl(info->tcp_hdr->sequence_num));
|
|
|
+ fprintf(stdout,"Acknowledgement number: %u\n", htonl(info->tcp_hdr->ack_num));
|
|
|
#endif
|
|
|
|
|
|
if(info->app_data_len <= 0){
|
|
@@ -54,13 +56,13 @@ int replace_packet(flow *f, struct packet_info *info){
|
|
|
} else {
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
- printf("Current sequence number: %d\n", f->seq_num);
|
|
|
- printf("Received sequence number: %d\n", htonl(tcp_hdr->sequence_num));
|
|
|
+ printf("Current sequence number: %d\n", f->downstream_seq_num);
|
|
|
+ printf("Received sequence number: %d\n", htonl(info->tcp_hdr->sequence_num));
|
|
|
#endif
|
|
|
|
|
|
- uint32_t offset = htonl(info->tcp_hdr->sequence_num) - f->seq_num;
|
|
|
+ uint32_t offset = htonl(info->tcp_hdr->sequence_num) - f->downstream_seq_num;
|
|
|
if(offset == 0)
|
|
|
- f->seq_num += info->app_data_len;
|
|
|
+ f->downstream_seq_num += info->app_data_len;
|
|
|
|
|
|
/* if incoming, replace with data from queue */
|
|
|
//if(htonl(tcp_hdr->sequence_num) >= f->seq_num){
|
|
@@ -68,11 +70,11 @@ int replace_packet(flow *f, struct packet_info *info){
|
|
|
//}//TODO: need to do something about replaying packets (maybe store previously sent data??
|
|
|
|
|
|
|
|
|
-#ifdef DEBUG //TODO: fix
|
|
|
+#ifdef DEBUG2 //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");
|
|
|
- for(int i=0; i< htons(info->ip_hdr->len); i++){
|
|
|
+ for(int i=0; i< htons(info->ip_hdr->len)-1; i++){
|
|
|
fprintf(stdout, "%02x ", p[i]);
|
|
|
}
|
|
|
fprintf(stdout, "\n");
|
|
@@ -138,7 +140,6 @@ int read_header(flow *f, struct packet_info *info){
|
|
|
|
|
|
} else {
|
|
|
//process what we have
|
|
|
- printf("US: %d bytes of packet unused\n", info->app_data_len - f->upstream_remaining);
|
|
|
record_hdr = (struct record_header*) f->upstream_queue->data;
|
|
|
record_length = RECORD_LEN(record_hdr);
|
|
|
record_ptr = calloc(1, record_length+ RECORD_HEADER_LEN);
|
|
@@ -153,6 +154,7 @@ int read_header(flow *f, struct packet_info *info){
|
|
|
}
|
|
|
memcpy(record_ptr+offset, p, f->upstream_remaining);
|
|
|
p = record_ptr;
|
|
|
+ record_hdr = (struct record_header*) p;
|
|
|
f->upstream_remaining = 0;
|
|
|
}
|
|
|
} else {
|
|
@@ -166,7 +168,7 @@ int read_header(flow *f, struct packet_info *info){
|
|
|
uint8_t *block_data = calloc(1, info->app_data_len);
|
|
|
memcpy(block_data, p, info->app_data_len);
|
|
|
|
|
|
- new_block->len = info->app_data_len - RECORD_HEADER_LEN;
|
|
|
+ new_block->len = info->app_data_len;
|
|
|
new_block->offset = record_length; //re-appropriate this for len of record
|
|
|
new_block->data = block_data;
|
|
|
new_block->next = NULL;
|
|
@@ -209,16 +211,17 @@ int read_header(flow *f, struct packet_info *info){
|
|
|
}
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
- printf("Upstream data:\n");
|
|
|
+ printf("Upstream data: (%x:%d > %x:%d )\n",info->ip_hdr->src.s_addr,info->tcp_hdr->src_port, info->ip_hdr->dst.s_addr, info->tcp_hdr->dst_port);
|
|
|
printf("%s\n", decrypted_data+EVP_GCM_TLS_EXPLICIT_IV_LEN);
|
|
|
#endif
|
|
|
|
|
|
- //TODO: re-write this to take a SOCKS connection request
|
|
|
/* search through decrypted data for x-ignore */
|
|
|
- char *header_ptr = strstr((const char *) decrypted_data, "X-Slitheen");
|
|
|
+ char *header_ptr = strstr((const char *) decrypted_data+EVP_GCM_TLS_EXPLICIT_IV_LEN, "X-Slitheen");
|
|
|
|
|
|
uint8_t *upstream_data;
|
|
|
if(header_ptr == NULL){
|
|
|
+ printf("Slitheen header not found(%x:%d > %x:%d) \n",info->ip_hdr->src.s_addr,info->tcp_hdr->src_port, info->ip_hdr->dst.s_addr, info->tcp_hdr->dst_port);
|
|
|
+ fflush(stdout);
|
|
|
if(record_ptr != NULL)
|
|
|
free(record_ptr);
|
|
|
free(decrypted_data);
|
|
@@ -228,8 +231,9 @@ int read_header(flow *f, struct packet_info *info){
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
printf("UPSTREAM: Found x-slitheen header\n");
|
|
|
- fprintf(stdout,"UPSTREAM Flow: %x > %x (%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(stdout, "Sequence number: %d\n", info->tcp_hdr->sequence_num);
|
|
|
+ fflush(stdout);
|
|
|
+ fprintf(stdout,"UPSTREAM Flow: %x:%d > %x:%d (%s)\n", info->ip_hdr->src.s_addr,info->tcp_hdr->src_port, info->ip_hdr->dst.s_addr, info->tcp_hdr->dst_port,(info->ip_hdr->src.s_addr != f->src_ip.s_addr)? "incoming":"outgoing");
|
|
|
+ fprintf(stdout, "Sequence number: %d\n", ntohs(info->tcp_hdr->sequence_num));
|
|
|
#endif
|
|
|
|
|
|
header_ptr += strlen("X-Slitheen: ");
|
|
@@ -247,8 +251,10 @@ int read_header(flow *f, struct packet_info *info){
|
|
|
}
|
|
|
c++;
|
|
|
*c = '\0';
|
|
|
+ printf("UPSTREAM: Found %d messages\n", num_messages);
|
|
|
|
|
|
for(int i=0; i< num_messages-1; i++){
|
|
|
+ printf("Decoding message: %s\n", messages[i]);
|
|
|
char *message = messages[i];
|
|
|
|
|
|
//b64 decode the data
|
|
@@ -272,8 +278,6 @@ int read_header(flow *f, struct packet_info *info){
|
|
|
int32_t output_len = BIO_read(bio, upstream_data, strlen(message));
|
|
|
|
|
|
BIO_free_all(bio);
|
|
|
- if(output_len != decode_len)
|
|
|
- printf("UH OH, lens dont match\n. %d != %d", decode_len, output_len);
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
printf("Decoded to get %d bytes:\n", output_len);
|
|
@@ -297,38 +301,50 @@ int read_header(flow *f, struct packet_info *info){
|
|
|
|
|
|
//If a thread for this stream id exists, get the thread info and pipe data
|
|
|
int32_t stream_pipe = -1;
|
|
|
+ stream *last = streams->first;
|
|
|
+ stream *prev = last;
|
|
|
if(streams->first != NULL){
|
|
|
- stream *last = streams->first;
|
|
|
if(last->stream_id == stream_id){
|
|
|
stream_pipe = last->pipefd;
|
|
|
- }
|
|
|
- while(last->next != NULL){
|
|
|
- last = last->next;
|
|
|
- if(last->stream_id == stream_id){
|
|
|
- stream_pipe = last->pipefd;
|
|
|
- break;
|
|
|
+ } else {
|
|
|
+ while(last->next != NULL){
|
|
|
+ prev = last;
|
|
|
+ last = last->next;
|
|
|
+ if(last->stream_id == stream_id){
|
|
|
+ stream_pipe = last->pipefd;
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if(stream_pipe != -1){
|
|
|
- int32_t bytes_sent = write(stream_pipe, p, stream_len);
|
|
|
- if(bytes_sent < 0){
|
|
|
- printf("Error writing to stream pipe\n");
|
|
|
- fflush(stdout);
|
|
|
+ //check to see if this is a close message
|
|
|
+ if(stream_len == 0){
|
|
|
+ close(stream_pipe);
|
|
|
+ //remove from stream id table
|
|
|
+ if(last == streams->first){
|
|
|
+ streams->first = last->next;
|
|
|
+ printf("streams->first is now %p\n", streams->first);
|
|
|
+ } else {
|
|
|
+ prev->next = last->next;
|
|
|
+ printf("prev->next is now %p\n", prev->next);
|
|
|
+ }
|
|
|
+ printf("freeing %p\n", last);
|
|
|
+ free(last);
|
|
|
+ break;
|
|
|
}
|
|
|
+ int32_t bytes_sent = write(stream_pipe, p, stream_len);
|
|
|
|
|
|
- } else {
|
|
|
+ } else if(stream_len > 0){
|
|
|
|
|
|
/*Else, spawn a thread to handle the proxy to this site*/
|
|
|
- pthread_t *proxy_thread = calloc(1, sizeof(pthread_t));
|
|
|
+ pthread_t proxy_thread;
|
|
|
int32_t pipefd[2];
|
|
|
if(pipe(pipefd) < 0){
|
|
|
- printf("Failed to create pipe for new thread\n");
|
|
|
free(decrypted_data);
|
|
|
if(record_ptr != NULL)
|
|
|
free(record_ptr);
|
|
|
-
|
|
|
return 1;
|
|
|
}
|
|
|
uint8_t *initial_data = calloc(1,stream_len);
|
|
@@ -341,12 +357,15 @@ int read_header(flow *f, struct packet_info *info){
|
|
|
thread_data->stream_id = stream_id;
|
|
|
thread_data->pipefd = pipefd[0];
|
|
|
|
|
|
- pthread_create(proxy_thread, NULL, proxy_covert_site, (void *) thread_data);
|
|
|
+
|
|
|
+ pthread_create(&proxy_thread, NULL, proxy_covert_site, (void *) thread_data);
|
|
|
|
|
|
+ pthread_detach(proxy_thread);
|
|
|
//add stream to table
|
|
|
stream *new_stream = calloc(1, sizeof(stream));
|
|
|
new_stream->stream_id = stream_id;
|
|
|
new_stream->pipefd = pipefd[1];
|
|
|
+ new_stream->next = NULL;
|
|
|
|
|
|
if(streams->first == NULL){
|
|
|
streams->first = new_stream;
|
|
@@ -358,6 +377,8 @@ int read_header(flow *f, struct packet_info *info){
|
|
|
last->next = new_stream;
|
|
|
}
|
|
|
|
|
|
+ } else{
|
|
|
+ break;
|
|
|
}
|
|
|
output_len -= stream_len;
|
|
|
p += stream_len;
|
|
@@ -401,6 +422,8 @@ void *proxy_covert_site(void *data){
|
|
|
struct socks_req *clnt_req = (struct socks_req *) p;
|
|
|
p += 4;
|
|
|
|
|
|
+ int32_t handle = -1;
|
|
|
+
|
|
|
//see if it's a connect request
|
|
|
if(clnt_req->cmd != 0x01){
|
|
|
goto err;
|
|
@@ -440,7 +463,7 @@ void *proxy_covert_site(void *data){
|
|
|
//now set the port
|
|
|
dest.sin_port = *((uint16_t *) p);
|
|
|
|
|
|
- int32_t handle = socket(AF_INET, SOCK_STREAM, 0);
|
|
|
+ handle = socket(AF_INET, SOCK_STREAM, 0);
|
|
|
if(handle < 0){
|
|
|
goto err;
|
|
|
}
|
|
@@ -467,7 +490,7 @@ void *proxy_covert_site(void *data){
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
printf("Bound to %x:%d\n", my_addr.sin_addr.s_addr, ntohs(my_addr.sin_port));
|
|
|
- printf("Downstream response:\n");
|
|
|
+ printf("Downstream response (id %d):\n", stream_id);
|
|
|
for(int i=0; i< 10; i++){
|
|
|
printf("%02x ", response[i]);
|
|
|
}
|
|
@@ -519,17 +542,25 @@ void *proxy_covert_site(void *data){
|
|
|
int32_t bytes_read = read(thread_data->pipefd, buffer, buffer_len);
|
|
|
|
|
|
if(bytes_read > 0){
|
|
|
+#ifdef DEBUG
|
|
|
+ printf("PROXY (id %d): read %d bytes from pipe\n", stream_id, bytes_read);
|
|
|
+ for(int i=0; i< bytes_read; i++){
|
|
|
+ printf("%02x ", buffer[i]);
|
|
|
+ }
|
|
|
+ printf("\n");
|
|
|
+ printf("%s\n", buffer);
|
|
|
+#endif
|
|
|
int32_t bytes_sent = send(handle, buffer,
|
|
|
bytes_read, 0);
|
|
|
if( bytes_sent <= 0){
|
|
|
- printf("error sending request\n");
|
|
|
break;
|
|
|
} else if (bytes_sent < bytes_read){
|
|
|
//TODO: should update buffer and keep
|
|
|
//track of length of upstream data
|
|
|
- printf("sent less than full upstream bytes\n");
|
|
|
break;
|
|
|
}
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -538,12 +569,16 @@ void *proxy_covert_site(void *data){
|
|
|
//we have downstream data read for saving
|
|
|
int32_t bytes_read;
|
|
|
bytes_read = recv(handle, buffer, buffer_len, 0);
|
|
|
- if(bytes_read <= 0){
|
|
|
- break;
|
|
|
- }
|
|
|
if(bytes_read > 0){
|
|
|
uint8_t *new_data = calloc(1, bytes_read);
|
|
|
memcpy(new_data, buffer, bytes_read);
|
|
|
+#ifdef DEBUG
|
|
|
+ printf("PROXY (id %d): read %d bytes from censored site\n",stream_id, bytes_read);
|
|
|
+ for(int i=0; i< bytes_read; i++){
|
|
|
+ printf("%02x ", buffer[i]);
|
|
|
+ }
|
|
|
+ printf("\n");
|
|
|
+#endif
|
|
|
|
|
|
//make a new queue block
|
|
|
new_block = calloc(1, sizeof(queue_block));
|
|
@@ -562,21 +597,69 @@ void *proxy_covert_site(void *data){
|
|
|
last->next = new_block;
|
|
|
}
|
|
|
} else {
|
|
|
- printf("read 0 bytes\n");
|
|
|
+
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
+ //remove self from list
|
|
|
+ stream *last = streams->first;
|
|
|
+ stream *prev = last;
|
|
|
+ if(streams->first != NULL){
|
|
|
+ if(last->stream_id == stream_id){
|
|
|
+ streams->first = last->next;
|
|
|
+ printf("Freeing (2) %p\n", last);
|
|
|
+ free(last);
|
|
|
+ } else {
|
|
|
+ while(last->next != NULL){
|
|
|
+ prev = last;
|
|
|
+ last = last->next;
|
|
|
+ if(last->stream_id == stream_id){
|
|
|
+ prev->next = last->next;
|
|
|
+ printf("Freeing (2) %p\n", last);
|
|
|
+ free(last);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(thread_data->initial_data != NULL){
|
|
|
+ free(thread_data->initial_data);
|
|
|
+ }
|
|
|
free(thread_data);
|
|
|
free(buffer);
|
|
|
close(handle);
|
|
|
+ pthread_exit(NULL);
|
|
|
return 0;
|
|
|
err:
|
|
|
+ //remove self from list
|
|
|
+ last = streams->first;
|
|
|
+ prev = last;
|
|
|
+ if(streams->first != NULL){
|
|
|
+ if(last->stream_id == stream_id){
|
|
|
+ streams->first = last->next;
|
|
|
+ free(last);
|
|
|
+ } else {
|
|
|
+ while(last->next != NULL){
|
|
|
+ prev = last;
|
|
|
+ last = last->next;
|
|
|
+ if(last->stream_id == stream_id){
|
|
|
+ prev->next = last->next;
|
|
|
+ free(last);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
if(thread_data->initial_data != NULL){
|
|
|
free(thread_data->initial_data);
|
|
|
}
|
|
|
- close(handle);
|
|
|
+ free(thread_data);
|
|
|
+ if(handle > 0){
|
|
|
+ close(handle);
|
|
|
+ }
|
|
|
+ pthread_exit(NULL);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -602,6 +685,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
uint8_t *p = info->app_data;
|
|
|
uint32_t remaining_packet_len = info->app_data_len;
|
|
|
|
|
|
+
|
|
|
if(f->remaining_record_len > 0){
|
|
|
//ignore bytes until the end of the record
|
|
|
if(f->remaining_record_len > remaining_packet_len){ //ignore entire packet
|
|
@@ -632,12 +716,14 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
|
|
|
while(remaining_packet_len > 0){ //while bytes remain in the packet
|
|
|
if(remaining_packet_len < RECORD_HEADER_LEN){
|
|
|
- printf("Error: partial record header: \n");
|
|
|
+#ifdef DEBUG
|
|
|
+ printf("partial record header: \n");
|
|
|
for(int i= 0; i< remaining_packet_len; i++){
|
|
|
printf("%02x ", p[i]);
|
|
|
}
|
|
|
printf("\n");
|
|
|
fflush(stdout);
|
|
|
+#endif
|
|
|
f->partial_record_header = calloc(1, RECORD_HEADER_LEN);
|
|
|
memcpy(f->partial_record_header, p, remaining_packet_len);
|
|
|
f->partial_record_header_len = remaining_packet_len;
|
|
@@ -651,14 +737,13 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
memcpy(f->partial_record_header+ f->partial_record_header_len,
|
|
|
p, RECORD_HEADER_LEN - f->partial_record_header_len);
|
|
|
record_hdr = (struct record_header *) f->partial_record_header;
|
|
|
- printf("Using partial record\n");
|
|
|
} else {
|
|
|
|
|
|
record_hdr = (struct record_header*) p;
|
|
|
}
|
|
|
uint32_t record_len = RECORD_LEN(record_hdr);
|
|
|
|
|
|
-//#ifdef DEBUG
|
|
|
+#ifdef DEBUG
|
|
|
fprintf(stdout,"Flow: %x > %x (%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(stdout,"ID number: %u\n", htonl(info->ip_hdr->id));
|
|
|
fprintf(stdout,"Sequence number: %u\n", htonl(info->tcp_hdr->sequence_num));
|
|
@@ -668,7 +753,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
printf("%02x ", ((uint8_t *) record_hdr)[i]);
|
|
|
}
|
|
|
printf("\n");
|
|
|
-//#endif
|
|
|
+#endif
|
|
|
|
|
|
p += (RECORD_HEADER_LEN - f->partial_record_header_len);
|
|
|
remaining_packet_len -= (RECORD_HEADER_LEN - f->partial_record_header_len);
|
|
@@ -720,6 +805,10 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
}
|
|
|
}
|
|
|
remaining_packet_len -= remaining_packet_len;
|
|
|
+ if(f->partial_record_header_len > 0){
|
|
|
+ f->partial_record_header_len = 0;
|
|
|
+ free(f->partial_record_header);
|
|
|
+ }
|
|
|
break;
|
|
|
}
|
|
|
|
|
@@ -729,6 +818,10 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
record_hdr->type, 0);
|
|
|
if(n < 0){
|
|
|
//do something smarter here
|
|
|
+ if(f->partial_record_header_len > 0){
|
|
|
+ f->partial_record_header_len = 0;
|
|
|
+ free(f->partial_record_header);
|
|
|
+ }
|
|
|
return 0;
|
|
|
}
|
|
|
changed = 1;
|
|
@@ -773,6 +866,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
if(len_ptr != NULL){
|
|
|
if(!memcmp(len_ptr + 19, "chunked", 7)){
|
|
|
//now find end of header
|
|
|
+ //printf("chunked encoding\n");
|
|
|
|
|
|
len_ptr = strstr((const char *) p, "\r\n\r\n");
|
|
|
if(len_ptr != NULL){
|
|
@@ -786,6 +880,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
if(len_ptr != NULL){
|
|
|
len_ptr += 15;
|
|
|
f->remaining_response_len = strtol((const char *) len_ptr, NULL, 10);
|
|
|
+ //printf("content-length: %d\n", f->remaining_response_len);
|
|
|
len_ptr = strstr((const char *) p, "\r\n\r\n");
|
|
|
if(len_ptr != NULL){
|
|
|
f->httpstate = MID_CONTENT;
|
|
@@ -793,9 +888,11 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
p = (uint8_t *) len_ptr + 4;
|
|
|
} else {
|
|
|
remaining_record_len = 0;
|
|
|
+ //printf("Missing end of header. Sending to FORFEIT_REST\n");
|
|
|
f->httpstate = FORFEIT_REST;
|
|
|
}
|
|
|
} else {
|
|
|
+ //printf("No content length of transfer encoding field, sending to FORFEIT_REST\n");
|
|
|
f->httpstate = FORFEIT_REST;
|
|
|
remaining_record_len = 0;
|
|
|
}
|
|
@@ -856,6 +953,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
p = (uint8_t *) needle + 2;
|
|
|
} else {
|
|
|
remaining_record_len = 0;
|
|
|
+ printf("Couldn't find chunk, sending to FORFEIT_REST\n");
|
|
|
f->httpstate = FORFEIT_REST;
|
|
|
}
|
|
|
}
|
|
@@ -880,11 +978,11 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
remaining_record_len = 0;
|
|
|
} else {
|
|
|
if(f->replace_response){
|
|
|
- fill_with_downstream(p, remaining_record_len);
|
|
|
+ fill_with_downstream(p, f->remaining_response_len);
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
printf("Replaced with:\n");
|
|
|
- for(int i=0; i< remaining_record_len; i++){
|
|
|
+ for(int i=0; i< f->remaining_response_len; i++){
|
|
|
printf("%02x ", p[i]);
|
|
|
}
|
|
|
printf("\n");
|
|
@@ -892,6 +990,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
}
|
|
|
remaining_record_len -= f->remaining_response_len;
|
|
|
p += f->remaining_response_len;
|
|
|
+ f->remaining_response_len = 0;
|
|
|
f->httpstate = END_CHUNK;
|
|
|
}
|
|
|
break;
|
|
@@ -904,6 +1003,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
remaining_record_len -= 2;
|
|
|
} else {
|
|
|
remaining_record_len = 0;
|
|
|
+ //printf("Couldn't find end of chunk, sending to FORFEIT_REST\n");
|
|
|
f->httpstate = FORFEIT_REST;
|
|
|
}
|
|
|
break;
|
|
@@ -916,6 +1016,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
remaining_record_len -= 2;
|
|
|
} else {
|
|
|
remaining_record_len = 0;
|
|
|
+ //printf("Couldn't find end of body, sending to FORFEIT_REST\n");
|
|
|
f->httpstate = FORFEIT_REST;
|
|
|
}
|
|
|
break;
|
|
@@ -935,6 +1036,10 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
if((n = encrypt(f, record_ptr, record_ptr,
|
|
|
n + EVP_GCM_TLS_EXPLICIT_IV_LEN, 1, record_hdr->type,
|
|
|
1)) < 0){
|
|
|
+ if(f->partial_record_header_len > 0){
|
|
|
+ f->partial_record_header_len = 0;
|
|
|
+ free(f->partial_record_header);
|
|
|
+ }
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -943,7 +1048,6 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
if(f->partial_record_header_len > 0){
|
|
|
f->partial_record_header_len = 0;
|
|
|
free(f->partial_record_header);
|
|
|
- printf("freed partial record\n");
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -1011,13 +1115,18 @@ int fill_with_downstream(uint8_t *data, int32_t length){
|
|
|
}
|
|
|
sl_hdr->len = htons(sl_hdr->len);
|
|
|
|
|
|
-#ifdef DEBUG
|
|
|
+//#ifdef DEBUG
|
|
|
printf("DWNSTRM: slitheen header: ");
|
|
|
for(int i=0; i< SLITHEEN_HEADER_LEN; i++){
|
|
|
printf("%02x ",((uint8_t *) sl_hdr)[i]);
|
|
|
}
|
|
|
printf("\n");
|
|
|
-#endif
|
|
|
+ printf("Sending %d downstream bytes:", ntohs(sl_hdr->len));
|
|
|
+ for(int i=0; i< ntohs(sl_hdr->len); i++){
|
|
|
+ printf("%02x ", ((uint8_t *) sl_hdr)[i+SLITHEEN_HEADER_LEN]);
|
|
|
+ }
|
|
|
+ printf("\n");
|
|
|
+//#endif
|
|
|
}
|
|
|
//now, if we need more data, fill with garbage
|
|
|
if(remaining > SLITHEEN_HEADER_LEN ){
|
|
@@ -1028,13 +1137,13 @@ int fill_with_downstream(uint8_t *data, int32_t length){
|
|
|
sl_hdr->len = htons(remaining);
|
|
|
sl_hdr->garbage = htons(remaining);
|
|
|
|
|
|
-#ifdef DEBUG
|
|
|
+//#ifdef DEBUG
|
|
|
printf("DWNSTRM: slitheen header: ");
|
|
|
for(int i=0; i< SLITHEEN_HEADER_LEN; i++){
|
|
|
printf("%02x ", p[i]);
|
|
|
}
|
|
|
printf("\n");
|
|
|
-#endif
|
|
|
+//#endif
|
|
|
|
|
|
p += SLITHEEN_HEADER_LEN;
|
|
|
memset(p, 'A', remaining);
|