slitheen-proxy.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. #include <pcap.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. #include <pthread.h>
  7. #include <openssl/ssl.h>
  8. #include "rserv.h"
  9. #include "flow.h"
  10. #include "slitheen.h"
  11. #include "util.h"
  12. #include "relay.h"
  13. void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
  14. void check_handshake(const struct tcp_header *tcp_hdr, flow f, unsigned char *p, u_short length);
  15. void *sniff_packets(void *);
  16. void process_packet(const u_char *packet);
  17. /** Checks a handshake message to see if it is tagged or a
  18. * recognized flow.
  19. * Inputs: The tcp header for the message, its associated flow,
  20. * a pointer to the handshake header, and the length of
  21. * the record.
  22. */
  23. void check_handshake(const struct tcp_header *tcp_hdr, flow f, unsigned char *ptr, u_short length){
  24. FILE *fp;
  25. int res, i, code;
  26. //u_int size_hs;
  27. unsigned char *p;
  28. unsigned char *hello_rand;
  29. const struct handshake_header *handshake_hdr;
  30. byte privkey[PTWIST_BYTES];
  31. byte key[16];
  32. p = ptr;
  33. handshake_hdr = (struct handshake_header*) p;
  34. code = handshake_hdr->type;
  35. //size_hs = HANDSHAKE_MESSAGE_LEN(handshake_hdr);
  36. if (code == 0x01){
  37. p += CLIENT_HELLO_HEADER_LEN;
  38. //now pointing to hello random :D
  39. hello_rand = p;
  40. p += 4; //skipping time bytes
  41. /* Load the private key */
  42. fp = fopen("privkey", "rb");
  43. if (fp == NULL) {
  44. perror("fopen");
  45. exit(1);
  46. }
  47. res = fread(privkey, PTWIST_BYTES, 1, fp);
  48. if (res < 1) {
  49. perror("fread");
  50. exit(1);
  51. }
  52. fclose(fp);
  53. /* check tag*/
  54. res = check_tag(key, privkey, p, (const byte *)"context", 7);
  55. if (res) {
  56. printf("Untagged\n");
  57. } else {
  58. fp = fopen("tags", "wb");
  59. if (fp == NULL) {
  60. perror("fopen");
  61. exit(1);
  62. }
  63. //Write tag to file
  64. for(i=0; i< 28; i++){
  65. fprintf(fp, "%02x ", p[i]);
  66. }
  67. fclose(fp);
  68. //Write key to file
  69. fp = fopen("sharedkey", "wb");
  70. if (fp == NULL) {
  71. perror("fopen");
  72. exit(1);
  73. }
  74. for(i=0; i<16;i++){
  75. fprintf(fp, "%02x", key[i]);
  76. }
  77. fclose(fp);
  78. /* Save flow in table */
  79. flow *flow_ptr = add_flow(f);
  80. for(int i=0; i<16; i++){
  81. flow_ptr->key[i] = key[i];
  82. }
  83. /*printf("KEY \n");
  84. for(int i=0; i< 16; i++){
  85. printf("%02x ", flow_ptr->key[i]);
  86. }
  87. printf("\n");*/
  88. memcpy(flow_ptr->client_random, hello_rand, SSL3_RANDOM_SIZE);
  89. printf("Saved new flow\n");
  90. }
  91. }
  92. }
  93. void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet){
  94. pcap_t *handle;
  95. char errbuf[BUFSIZ];
  96. char *writedev = (char *) args;
  97. unsigned char *p;
  98. const struct ip_header *ip_hdr;
  99. //const struct tcp_header *tcp_hdr;
  100. handle = pcap_open_live(writedev, BUFSIZ, 1, 1000, errbuf);
  101. if (handle == NULL){
  102. fprintf(stderr, "Couldn't open device %s: %s\n", writedev, errbuf);
  103. }
  104. p = (unsigned char *) packet;
  105. p += ETHER_HEADER_LEN; //skip ethernet header
  106. ip_hdr = (struct ip_header*) p;
  107. p += IP_HEADER_LEN(ip_hdr);//TODO: remove
  108. //tcp_hdr = (struct tcp_header*) p;//TODO: remove
  109. // Check to make sure it is an IP packet
  110. if( (ip_hdr->versionihl >>4) != 4)
  111. goto end;
  112. // Packet may be split over multiple frames. In this case,
  113. // reconstruct the packet before trying to read TLS records
  114. //
  115. if((htons(ip_hdr->flagsoff)&MF) || (htons(ip_hdr->flagsoff) &0x1fff) ){ /* this is a fragment */
  116. printf("MF: %d, OFF: %d.\n", htons(ip_hdr->flagsoff)&MF, htons(ip_hdr->flagsoff)&0x1fff);
  117. printf("Received packet fragment.\n");
  118. printf("%d packet bytes: \n", IP_HEADER_LEN(ip_hdr));
  119. for(int i=0; i< IP_HEADER_LEN(ip_hdr); i++){
  120. printf("%02x ", p[i]);
  121. }
  122. printf("\n");
  123. u_char *complete_packet;
  124. //save packet fragment
  125. complete_packet = malloc(65535);
  126. int success = report_fragment(p, complete_packet, header->len);
  127. if(success){
  128. process_packet(complete_packet);
  129. }
  130. /* TODO: handle errors */
  131. } else { /*not a fragment, add to packet chain */
  132. process_packet(packet);
  133. }
  134. end:
  135. if((pcap_inject(handle, packet, header->len)) < 0 ){
  136. fprintf(stderr, "Error: %s\n", pcap_geterr(handle));
  137. }
  138. pcap_close(handle);
  139. }
  140. void usage(void){
  141. printf("Usage: slitheen-proxy [internal network interface] [NAT interface]\n");
  142. }
  143. int main(int argc, char *argv[]){
  144. pthread_t t1, t2;
  145. char filter1[33] = "ether src host 08:00:27:e8:9d:d4";
  146. char filter2[33] = "ether src host 08:00:27:e8:9d:d4";
  147. char *dev1 = NULL; /* Device that leads to the internal network */
  148. char *dev2 = NULL; /* Device that leads out to the world */
  149. struct sniff_args outbound;
  150. struct sniff_args inbound;
  151. if (argc != 3) {
  152. usage();
  153. return(2);
  154. }
  155. dev1 = argv[1];
  156. dev2 = argv[2];
  157. snprintf(filter1, 33, "ether src host %s", macaddr);
  158. snprintf(filter2, 33, "ether dst host %s", macaddr);
  159. init_flow_table();
  160. init_fragment_table();
  161. /* Create threads */
  162. outbound.readdev = dev1;
  163. outbound.writedev = dev2;
  164. outbound.filter = filter1;
  165. inbound.readdev = dev2;
  166. inbound.writedev = dev1;
  167. inbound.filter = filter2;
  168. pthread_create(&t1, NULL, sniff_packets, (void *) &outbound);
  169. pthread_create(&t2, NULL, sniff_packets, (void *) &inbound);
  170. pthread_join(t1, NULL);
  171. pthread_join(t2, NULL);
  172. return(0);
  173. }
  174. void *sniff_packets(void *args){
  175. pcap_t *handle;
  176. char errbuf[BUFSIZ];
  177. struct bpf_program fp;
  178. bpf_u_int32 mask;
  179. bpf_u_int32 net;
  180. char *readdev, *writedev, *filter;
  181. struct sniff_args *arg_st = (struct sniff_args *) args;
  182. readdev = arg_st->readdev;
  183. writedev = arg_st->writedev;
  184. filter = arg_st->filter;
  185. if (pcap_lookupnet(readdev, &net, &mask, errbuf) == -1){
  186. fprintf(stderr, "Can't get netmask for device %s\n", readdev);
  187. exit(2);
  188. }
  189. handle = pcap_open_live(readdev, BUFSIZ, 1, 1000, errbuf);
  190. if (handle == NULL){
  191. fprintf(stderr, "Couldn't open device %s: %s\n", readdev, errbuf);
  192. }
  193. if(pcap_datalink(handle) != DLT_EN10MB) {
  194. fprintf(stderr, "Device %s does not provide Ethernet headers - not supported\n", readdev);
  195. exit(2);
  196. }
  197. if(pcap_compile(handle, &fp, filter, 0 , net) == -1){
  198. fprintf(stderr, "Couldn't parse filter %s: %s\n", filter, pcap_geterr(handle));
  199. exit(2);
  200. }
  201. if (pcap_setfilter(handle, &fp) == -1) {
  202. fprintf(stderr, "Couldn't install filter %s: %s\n", filter, pcap_geterr(handle));
  203. exit(2);
  204. }
  205. /*callback function*/
  206. pcap_loop(handle, -1, got_packet, (unsigned char *) writedev);
  207. /*Sniff a packet*/
  208. pcap_close(handle);
  209. return NULL;
  210. }
  211. /* This function receives a full ip packet and then:
  212. * 1) identifies the flow
  213. * 2) adds the packet to the flow's data chain
  214. * 3) updates the packet's state
  215. */
  216. void process_packet(const u_char *packet){
  217. unsigned char *p;
  218. int index;
  219. const struct ip_header *ip_hdr;
  220. const struct tcp_header *tcp_hdr;
  221. const struct record_header *record_hdr;
  222. u_int size_ip;
  223. u_int size_tcp;
  224. flow newFlow;
  225. p = (unsigned char *) packet;
  226. p += ETHER_HEADER_LEN; //skip ethernet header
  227. ip_hdr = (struct ip_header*) p;
  228. size_ip = IP_HEADER_LEN(ip_hdr);
  229. if (ip_hdr->proto == IPPROTO_TCP){
  230. p += size_ip; //skip IP header
  231. tcp_hdr = (struct tcp_header*) p;
  232. size_tcp = TCP_HEADER_LEN(tcp_hdr);
  233. p += size_tcp;
  234. newFlow.src_ip = ip_hdr->src;
  235. newFlow.dst_ip = ip_hdr->dst;
  236. newFlow.src_port = tcp_hdr->src_port;
  237. newFlow.dst_port = tcp_hdr->dst_port;
  238. newFlow.seq_num = tcp_hdr->sequence_num;
  239. record_hdr = (struct record_header*) p;
  240. /* Checks to see if this is a possibly tagged hello msg */
  241. if (record_hdr->type == HS){ /* This is a TLS handshake */
  242. p += RECORD_HEADER_LEN;
  243. check_handshake(tcp_hdr, newFlow, p, RECORD_LEN(record_hdr));
  244. }
  245. }
  246. /* Now if flow is in table, update state */
  247. if((index = check_flow(newFlow))){
  248. flow *observed = get_flow(index-1);
  249. if(observed->application){
  250. replace_packet(observed, packet);
  251. } else {
  252. /* Pass data to packet chain */
  253. add_packet(observed, packet);
  254. /* Update flow state */
  255. if(observed->packet_chain != NULL){
  256. //fork off a thread to update the flow
  257. //pid_t pid = fork();
  258. //if(pid == 0){//child
  259. update_flow(observed);
  260. // exit(0);
  261. //}
  262. }
  263. }
  264. /* Update TCP state */
  265. if(tcp_hdr->flags & (FIN | RST) ){
  266. /* Remove flow from table, connection ended */
  267. remove_flow(index);
  268. }
  269. }
  270. }