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