|
@@ -39,10 +39,11 @@ int replace_packet(flow *f, struct packet_info *info){
|
|
|
}
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
- 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,"Flow: %x:%d > %x:%d (%s)\n", info->ip_hdr->src.s_addr, ntohs(info->tcp_hdr->src_port), info->ip_hdr->dst.s_addr, ntohs(info->tcp_hdr->dst_port), (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));
|
|
|
+ fflush(stdout);
|
|
|
#endif
|
|
|
|
|
|
if(info->app_data_len <= 0){
|
|
@@ -212,7 +213,7 @@ int read_header(flow *f, struct packet_info *info){
|
|
|
}
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
- 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("Upstream data: (%x:%d > %x:%d )\n",info->ip_hdr->src.s_addr,ntohs(info->tcp_hdr->src_port), info->ip_hdr->dst.s_addr, ntohs(info->tcp_hdr->dst_port));
|
|
|
printf("%s\n", decrypted_data+EVP_GCM_TLS_EXPLICIT_IV_LEN);
|
|
|
#endif
|
|
|
|
|
@@ -233,11 +234,17 @@ int read_header(flow *f, struct packet_info *info){
|
|
|
#ifdef DEBUG
|
|
|
printf("UPSTREAM: Found x-slitheen header\n");
|
|
|
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,"UPSTREAM Flow: %x:%d > %x:%d (%s)\n", info->ip_hdr->src.s_addr,ntohs(info->tcp_hdr->src_port), info->ip_hdr->dst.s_addr, ntohs(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: ");
|
|
|
+
|
|
|
+ if(*header_ptr == '\r' || *header_ptr == '\0'){
|
|
|
+ printf("No messages\n");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
int32_t num_messages = 1;
|
|
|
char *messages[50]; //TODO:make not just 10?
|
|
|
messages[0] = header_ptr;
|
|
@@ -282,15 +289,77 @@ int read_header(flow *f, struct packet_info *info){
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
printf("Decoded to get %d bytes:\n", output_len);
|
|
|
- for(int i=0; i< output_len; i++){
|
|
|
- printf("%02x ", upstream_data[i]);
|
|
|
+ for(int j=0; j< output_len; j++){
|
|
|
+ printf("%02x ", upstream_data[j]);
|
|
|
}
|
|
|
printf("\n");
|
|
|
fflush(stdout);
|
|
|
#endif
|
|
|
-
|
|
|
p = upstream_data;
|
|
|
|
|
|
+ if(i== 0){
|
|
|
+ //this is the Slitheen ID
|
|
|
+ printf("Slitheen ID:");
|
|
|
+ for(int j=0; j< output_len; j++){
|
|
|
+ printf("%02x ", p[j]);
|
|
|
+ }
|
|
|
+ printf("\n");
|
|
|
+
|
|
|
+ //find stream table or create new one
|
|
|
+
|
|
|
+ client *last = clients->first;
|
|
|
+ while(last != NULL){
|
|
|
+ if(!memcmp(last->slitheen_id, p, output_len)){
|
|
|
+ f->streams = last->streams;
|
|
|
+ f->downstream_queue = last->downstream_queue;
|
|
|
+ printf("Found client in table!\n");
|
|
|
+ break;
|
|
|
+ } else {
|
|
|
+ for(int j=0; j< output_len; j++){
|
|
|
+ printf("%02x ", last->slitheen_id[j]);
|
|
|
+ }
|
|
|
+ printf(" != ");
|
|
|
+ for(int j=0; j< output_len; j++){
|
|
|
+ printf("%02x ", p[j]);
|
|
|
+ }
|
|
|
+ printf("\n");
|
|
|
+ }
|
|
|
+ last = last->next;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(f->streams == NULL){
|
|
|
+ printf("Making new client\n");
|
|
|
+ //create new client
|
|
|
+ client *new_client = calloc(1, sizeof(client));
|
|
|
+ memcpy(new_client->slitheen_id, p, output_len);
|
|
|
+ new_client->streams = calloc(1, sizeof(stream_table));
|
|
|
+ new_client->streams->first = NULL;
|
|
|
+ new_client->downstream_queue = calloc(1, sizeof(data_queue));
|
|
|
+ new_client->downstream_queue->first_block = NULL;
|
|
|
+
|
|
|
+ new_client->next = NULL;
|
|
|
+
|
|
|
+ //add to client table
|
|
|
+ if(clients->first == NULL){
|
|
|
+ clients->first = new_client;
|
|
|
+ } else {
|
|
|
+ client *last = clients->first;
|
|
|
+ while(last->next != NULL){
|
|
|
+ last = last->next;
|
|
|
+ }
|
|
|
+ last->next = new_client;
|
|
|
+ }
|
|
|
+
|
|
|
+ //set f's stream table
|
|
|
+ f->streams = new_client->streams;
|
|
|
+ f->downstream_queue = new_client->downstream_queue;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ free(upstream_data);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
while(output_len > 0){
|
|
|
struct sl_up_hdr *sl_hdr = (struct sl_up_hdr *) p;
|
|
|
uint8_t stream_id = sl_hdr->stream_id;
|
|
@@ -299,6 +368,7 @@ int read_header(flow *f, struct packet_info *info){
|
|
|
p += sizeof(struct sl_up_hdr);
|
|
|
output_len -= sizeof(struct sl_up_hdr);
|
|
|
|
|
|
+ stream_table *streams = f->streams;
|
|
|
|
|
|
//If a thread for this stream id exists, get the thread info and pipe data
|
|
|
int32_t stream_pipe = -1;
|
|
@@ -356,7 +426,8 @@ int read_header(flow *f, struct packet_info *info){
|
|
|
thread_data->initial_len = stream_len;
|
|
|
thread_data->stream_id = stream_id;
|
|
|
thread_data->pipefd = pipefd[0];
|
|
|
-
|
|
|
+ thread_data->streams = f->streams;
|
|
|
+ thread_data->downstream_queue = f->downstream_queue;
|
|
|
|
|
|
pthread_create(&proxy_thread, NULL, proxy_covert_site, (void *) thread_data);
|
|
|
|
|
@@ -423,6 +494,9 @@ void *proxy_covert_site(void *data){
|
|
|
|
|
|
int32_t bytes_sent;
|
|
|
|
|
|
+ stream_table *streams = thread_data->streams;
|
|
|
+ data_queue *downstream_queue = thread_data->downstream_queue;
|
|
|
+
|
|
|
struct socks_req *clnt_req = (struct socks_req *) p;
|
|
|
p += 4;
|
|
|
data_len -= 4;
|
|
@@ -661,7 +735,7 @@ void *proxy_covert_site(void *data){
|
|
|
pthread_exit(NULL);
|
|
|
return 0;
|
|
|
err:
|
|
|
- //remove self from list
|
|
|
+ //remove self from list
|
|
|
last = streams->first;
|
|
|
prev = last;
|
|
|
if(streams->first != NULL){
|
|
@@ -803,7 +877,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
f->outbox = calloc(1, record_len+1);
|
|
|
f->outbox_len = record_len;
|
|
|
f->outbox_offset = 0;
|
|
|
- fill_with_downstream(f->outbox + EVP_GCM_TLS_EXPLICIT_IV_LEN , record_len - (EVP_GCM_TLS_EXPLICIT_IV_LEN+ 16)); //for now hard coded length of padding. TODO: fix this
|
|
|
+ fill_with_downstream(f, f->outbox + EVP_GCM_TLS_EXPLICIT_IV_LEN , record_len - (EVP_GCM_TLS_EXPLICIT_IV_LEN+ 16)); //for now hard coded length of padding. TODO: fix this
|
|
|
//encrypt
|
|
|
int32_t n = encrypt(f, f->outbox, f->outbox,
|
|
|
record_len - 16, 1,
|
|
@@ -843,7 +917,6 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
|
|
|
|
|
|
//now decrypt the record
|
|
|
- printf("Decrypting %d bytes at %p\n", record_len, record_ptr);
|
|
|
int32_t n = encrypt(f, record_ptr, record_ptr, record_len, 1,
|
|
|
record_hdr->type, 0);
|
|
|
if(n < 0){
|
|
@@ -856,7 +929,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
}
|
|
|
changed = 1;
|
|
|
|
|
|
-#ifdef DEBUG
|
|
|
+#ifdef DEBUG_DOWNSTREAM
|
|
|
printf("Decryption succeeded\n");
|
|
|
printf("Bytes:\n");
|
|
|
for(int i=0; i< n; i++){
|
|
@@ -934,7 +1007,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
//check if content is replaceable
|
|
|
if(f->remaining_response_len > remaining_record_len){
|
|
|
if(f->replace_response){
|
|
|
- fill_with_downstream(p, remaining_record_len);
|
|
|
+ fill_with_downstream(f, p, remaining_record_len);
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
printf("Replaced with:\n");
|
|
@@ -951,7 +1024,7 @@ 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(f, p, remaining_record_len);
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
printf("Replaced with:\n");
|
|
@@ -992,7 +1065,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
case MID_CHUNK:
|
|
|
if(f->remaining_response_len > remaining_record_len){
|
|
|
if(f->replace_response){
|
|
|
- fill_with_downstream(p, remaining_record_len);
|
|
|
+ fill_with_downstream(f, p, remaining_record_len);
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
printf("Replaced with:\n");
|
|
@@ -1008,7 +1081,7 @@ 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, f->remaining_response_len);
|
|
|
+ fill_with_downstream(f, p, f->remaining_response_len);
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
printf("Replaced with:\n");
|
|
@@ -1099,12 +1172,14 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
|
|
|
*
|
|
|
*/
|
|
|
|
|
|
-int fill_with_downstream(uint8_t *data, int32_t length){
|
|
|
+int fill_with_downstream(flow *f, uint8_t *data, int32_t length){
|
|
|
|
|
|
uint8_t *p = data;
|
|
|
int32_t remaining = length;
|
|
|
struct slitheen_header *sl_hdr;
|
|
|
|
|
|
+ data_queue *downstream_queue = f->downstream_queue;
|
|
|
+
|
|
|
//Fill as much as we can from the censored_queue
|
|
|
while((remaining > SLITHEEN_HEADER_LEN) && downstream_queue->first_block != NULL){
|
|
|
queue_block *first_block = downstream_queue->first_block;
|
|
@@ -1145,7 +1220,7 @@ 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]);
|
|
@@ -1156,7 +1231,7 @@ int fill_with_downstream(uint8_t *data, int32_t length){
|
|
|
printf("%02x ", ((uint8_t *) sl_hdr)[i+SLITHEEN_HEADER_LEN]);
|
|
|
}
|
|
|
printf("\n");
|
|
|
-//#endif
|
|
|
+#endif
|
|
|
}
|
|
|
//now, if we need more data, fill with garbage
|
|
|
if(remaining > SLITHEEN_HEADER_LEN ){
|