slitheen-proxy.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  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. void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
  13. void check_handshake(const struct tcp_header *tcp_hdr, flow f, unsigned char *p, u_short length);
  14. void *sniff_packets(void *);
  15. void process_packet(const u_char *packet);
  16. /** Checks a handshake message to see if it is tagged or a
  17. * recognized flow.
  18. * Inputs: The tcp header for the message, its associated flow,
  19. * a pointer to the handshake header, and the length of
  20. * the record.
  21. */
  22. void check_handshake(const struct tcp_header *tcp_hdr, flow f, unsigned char *ptr, u_short length){
  23. FILE *fp;
  24. int res, i, code;
  25. //u_int size_hs;
  26. unsigned char *p;
  27. unsigned char *hello_rand;
  28. const struct handshake_header *handshake_hdr;
  29. byte privkey[PTWIST_BYTES];
  30. byte key[16];
  31. p = ptr;
  32. handshake_hdr = (struct handshake_header*) p;
  33. code = handshake_hdr->type;
  34. //size_hs = HANDSHAKE_MESSAGE_LEN(handshake_hdr);
  35. if (code == 0x01){
  36. p += CLIENT_HELLO_HEADER_LEN;
  37. //now pointing to hello random :D
  38. hello_rand = p;
  39. p += 4; //skipping time bytes
  40. /* Load the private key */
  41. fp = fopen("privkey", "rb");
  42. if (fp == NULL) {
  43. perror("fopen");
  44. exit(1);
  45. }
  46. res = fread(privkey, PTWIST_BYTES, 1, fp);
  47. if (res < 1) {
  48. perror("fread");
  49. exit(1);
  50. }
  51. fclose(fp);
  52. /* check tag*/
  53. res = check_tag(key, privkey, p, (const byte *)"context", 7);
  54. if (res) {
  55. printf("Untagged\n");
  56. } else {
  57. fp = fopen("tags", "wb");
  58. if (fp == NULL) {
  59. perror("fopen");
  60. exit(1);
  61. }
  62. //Write tag to file
  63. for(i=0; i< 28; i++){
  64. fprintf(fp, "%02x ", p[i]);
  65. }
  66. fclose(fp);
  67. //Write key to file
  68. fp = fopen("sharedkey", "wb");
  69. if (fp == NULL) {
  70. perror("fopen");
  71. exit(1);
  72. }
  73. for(i=0; i<16;i++){
  74. fprintf(fp, "%02x", key[i]);
  75. }
  76. fclose(fp);
  77. /* Save flow in table */
  78. flow *flow_ptr = add_flow(f);
  79. for(int i=0; i<16; i++){
  80. flow_ptr->key[i] = key[i];
  81. }
  82. printf("KEY \n");
  83. for(int i=0; i< 16; i++){
  84. printf("%02x ", flow_ptr->key[i]);
  85. }
  86. printf("\n");
  87. memcpy(flow_ptr->client_random, hello_rand, SSL3_RANDOM_SIZE);
  88. printf("Saved new flow\n");
  89. }
  90. }
  91. }
  92. void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet){
  93. pcap_t *handle;
  94. char errbuf[BUFSIZ];
  95. char *writedev = (char *) args;
  96. unsigned char *p;
  97. const struct ip_header *ip_hdr;
  98. //const struct tcp_header *tcp_hdr;
  99. handle = pcap_open_live(writedev, BUFSIZ, 1, 1000, errbuf);
  100. if (handle == NULL){
  101. fprintf(stderr, "Couldn't open device %s: %s\n", writedev, errbuf);
  102. }
  103. p = (unsigned char *) packet;
  104. p += ETHER_HEADER_LEN; //skip ethernet header
  105. ip_hdr = (struct ip_header*) p;
  106. p += IP_HEADER_LEN(ip_hdr);//TODO: remove
  107. //tcp_hdr = (struct tcp_header*) p;//TODO: remove
  108. /* Check to make sure it is an IP packet */
  109. if( (ip_hdr->versionihl >>4) != 4)
  110. goto end;
  111. /* Packet may be split over multiple frames. In this case,
  112. * reconstruct the packet before trying to read TLS records
  113. */
  114. if((htons(ip_hdr->flagsoff)&MF) || (htons(ip_hdr->flagsoff) &0x1fff) ){ /* this is a fragment */
  115. printf("MF: %d, OFF: %d.\n", htons(ip_hdr->flagsoff)&MF, htons(ip_hdr->flagsoff)&0x1fff);
  116. printf("Received packet fragment.\n");
  117. printf("%d packet bytes: \n", IP_HEADER_LEN(ip_hdr));
  118. for(int i=0; i< IP_HEADER_LEN(ip_hdr); i++){
  119. printf("%02x ", p[i]);
  120. }
  121. printf("\n");
  122. u_char *complete_packet;
  123. //save packet fragment
  124. complete_packet = malloc(65535);
  125. int success = report_fragment(p, complete_packet, header->len);
  126. if(success){
  127. process_packet(complete_packet);
  128. }
  129. /* TODO: handle errors */
  130. } else { /*not a fragment, add to packet chain */
  131. process_packet(packet);
  132. }
  133. end:
  134. /* Hand packet to relay module */
  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. //printf("record type: %d.\n", record_hdr->type);
  243. //printf("record version(major): %d.\n", (record_hdr->version&0xFF00)>>8);
  244. //printf("record version(minor): %d.\n", record_hdr->version&0xFF);
  245. //printf("record length: %d.\n", RECORD_LEN(record_hdr));
  246. //printf("record header bytes:\n");
  247. //for(i=0; i<RECORD_HEADER_LEN; i++){
  248. // printf("%02x ", p[i]);
  249. //}
  250. //printf("\n");
  251. p += RECORD_HEADER_LEN;
  252. check_handshake(tcp_hdr, newFlow, p, RECORD_LEN(record_hdr));
  253. //printf("Length of packet: %d.\n", htons(ip_hdr->len));
  254. }
  255. }
  256. /* Now if flow is in table, update state */
  257. if((index = check_flow(newFlow))){
  258. flow *observed = get_flow(index-1);
  259. /* Pass data to packet chain */
  260. add_packet(observed, packet);
  261. /* Update flow state */
  262. if(observed->packet_chain != NULL){
  263. update_flow(observed);
  264. }
  265. /* Update TCP state */
  266. if(tcp_hdr->flags & (FIN | RST) ){
  267. /* Remove flow from table, connection ended */
  268. remove_flow(index);
  269. }
  270. /* Check to see if TLS finished message has passed */
  271. if(observed->state == TLS_FINISHED){
  272. //decrypt packet?
  273. printf("TLS finished received.\n");
  274. } else {
  275. //check to see if tls_finished message
  276. if(observed->in_encrypted && observed->out_encrypted){ /* decrypt tls finished message */
  277. printf("MESSAGE ENCRYPTED\n");
  278. }
  279. }
  280. }
  281. }