#include #include #include #include #include #include #include #include #include #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; }