relay.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <regex.h>
  5. #include <sys/socket.h>
  6. #include <sys/types.h>
  7. #include <netinet/in.h>
  8. #include <netdb.h>
  9. #include <unistd.h>
  10. #include "relay.h"
  11. #include "slitheen.h"
  12. #include "flow.h"
  13. #include "crypto.h"
  14. int replace_packet(flow *f, uint8_t *packet){
  15. const struct ip_header *ip_hdr;
  16. const struct tcp_header *tcp_hdr;
  17. uint8_t *p = packet;
  18. p += ETHER_HEADER_LEN; //skip ethernet header
  19. ip_hdr = (struct ip_header*) p;
  20. int size_ip = IP_HEADER_LEN(ip_hdr);
  21. if (ip_hdr->proto != IPPROTO_TCP){
  22. return 0;
  23. }
  24. p += size_ip; //skip IP header
  25. tcp_hdr = (struct tcp_header*) p;
  26. int size_tcp = TCP_HEADER_LEN(tcp_hdr);
  27. /*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");
  28. fprintf(stderr,"ID number: %u\n", htonl(ip_hdr->id));
  29. fprintf(stderr,"Sequence number: %u\n", htonl(tcp_hdr->sequence_num));
  30. fprintf(stderr,"Acknowledgement number: %u\n", htonl(tcp_hdr->ack_num));*/
  31. int32_t app_data_len = htons(ip_hdr->len) - (size_ip + size_tcp);
  32. printf("app_data length: %u\n", app_data_len);
  33. if(app_data_len <= 0){
  34. return 0;
  35. }
  36. /* if outgoing, decrypt and look at header */
  37. if(ip_hdr->src.s_addr == f->src_ip.s_addr){
  38. read_header(f, packet);
  39. return 0;
  40. } else {
  41. printf("Current sequence number: %d\n", f->seq_num);
  42. printf("Received sequence number: %d\n", htonl(tcp_hdr->sequence_num));
  43. uint32_t offset = htonl(tcp_hdr->sequence_num) - f->seq_num;
  44. if(offset == 0)
  45. f->seq_num += app_data_len;
  46. /* if incoming, replace with data from queue */
  47. //if(htonl(tcp_hdr->sequence_num) >= f->seq_num){
  48. replace_contents(f, p, app_data_len, offset, ip_hdr->src, ip_hdr->dst);
  49. //}//TODO: need to do something about replaying packets (maybe store previously sent data??
  50. p = packet + ETHER_HEADER_LEN;
  51. #ifdef DEBUG
  52. fprintf(stdout, "ip hdr length: %d\n", htons(ip_hdr->len));
  53. fprintf(stdout, "Injecting the following packet:\n");
  54. for(int i=0; i< htons(ip_hdr->len); i++){
  55. fprintf(stdout, "%02x ", p[i]);
  56. }
  57. fprintf(stdout, "\n");
  58. fflush(stdout);
  59. #endif
  60. }
  61. return 0;
  62. }
  63. int read_header(flow *f, uint8_t *packet){
  64. const struct ip_header *ip_hdr;
  65. const struct tcp_header *tcp_hdr;
  66. uint8_t *p = packet;
  67. p += ETHER_HEADER_LEN; //skip ethernet header
  68. ip_hdr = (struct ip_header*) p;
  69. int size_ip = IP_HEADER_LEN(ip_hdr);
  70. if (ip_hdr->proto != IPPROTO_TCP){
  71. return 0;
  72. }
  73. p += size_ip; //skip IP header
  74. tcp_hdr = (struct tcp_header*) p;
  75. int size_tcp = TCP_HEADER_LEN(tcp_hdr);
  76. p += size_tcp;
  77. int app_data_len = htons(ip_hdr->len) - (size_ip + size_tcp);
  78. struct record_header *record_hdr = (struct record_header*) p;
  79. uint32_t record_length = RECORD_LEN(record_hdr);
  80. uint8_t *decrypted_data = calloc(1, app_data_len);
  81. /*fprintf(stderr,"record:\n");
  82. for(int i=0; i< RECORD_HEADER_LEN; i++){
  83. fprintf(stderr,"%02x ", p[i]);
  84. }
  85. fprintf(stderr,"\n");*/
  86. p+= RECORD_HEADER_LEN;
  87. memcpy(decrypted_data, p, record_length);
  88. if(!encrypt(f, decrypted_data, decrypted_data, record_length, 0, record_hdr->type, 0)){
  89. fprintf(stdout,"decryption failed\n");
  90. return 0;
  91. } else {
  92. fprintf(stdout, "decryption succeeded!\n");
  93. if(record_hdr->type == 0x17){
  94. decrypted_data+= EVP_GCM_TLS_EXPLICIT_IV_LEN;
  95. fprintf(stdout, "request:");
  96. fprintf(stdout,"%s\n ", decrypted_data);
  97. }
  98. }
  99. if(record_hdr->type == 0x15){
  100. printf("received alert\n");
  101. for(int i=0; i<record_length; i++){
  102. printf("%02x ", decrypted_data[i]);
  103. }
  104. fflush(stdout);
  105. }
  106. /* search through decrypted data for x-ignore */
  107. regex_t r;
  108. const uint8_t *regex_text = "x-ignore";
  109. const uint8_t *match = decrypted_data;
  110. if(regcomp(&r, regex_text, REG_EXTENDED|REG_NEWLINE)){
  111. printf("could not compile regex\n");
  112. return 0;
  113. }
  114. regmatch_t m;
  115. if(regexec(&r, match, 1, &m, 0)){
  116. printf("no x-ignore found\n");
  117. return 0;
  118. }
  119. uint8_t *message = decrypted_data;
  120. //remove escape characters
  121. for(int i=m.rm_eo+2; i< strlen(match); i++){
  122. if(match[i] != '\\'){
  123. *(message++) = match[i];
  124. } else if (match[i+1] == 'r') {
  125. *(message++) = '\r';
  126. i++;
  127. } else if (match[i+1] == 'n') {
  128. *(message++) = '\n';
  129. i++;
  130. }
  131. }
  132. *message = '\0';
  133. message = decrypted_data;
  134. regex_t r2;
  135. const uint8_t *regex_text2 = "host";
  136. const uint8_t *match2 = decrypted_data;
  137. regmatch_t m2;
  138. if(regcomp(&r2, regex_text2, REG_EXTENDED|REG_NEWLINE)){
  139. printf("could not compile regex\n");
  140. return 0;
  141. }
  142. if(regexec(&r2, match2, 1, &m2, 0)){
  143. printf("no host found\n");
  144. return 0;
  145. }
  146. uint8_t server[50];
  147. for(int i=m2.rm_eo+2; i< strlen(match2); i++){
  148. if(match2[i] != '\n'){
  149. server[i-m2.rm_eo-2] = match2[i];
  150. } else {
  151. server[i-m2.rm_eo-2] = '\0';
  152. break;
  153. }
  154. }
  155. /* Send GET request to site */
  156. printf("sending request to site: %s\n", server);
  157. struct hostent *host;
  158. host = gethostbyname((const char *) server);
  159. if(host == NULL){
  160. printf("gethostbyname failed\n");
  161. return 0;
  162. }
  163. int32_t handle = socket(AF_INET, SOCK_STREAM, 0);
  164. if(handle < 0){
  165. printf("error: constructing socket failed\n");
  166. return 0;
  167. }
  168. printf("constructed socket\n");
  169. struct sockaddr_in dest;
  170. dest.sin_family = AF_INET;
  171. dest.sin_port = htons(80);
  172. dest.sin_addr = *((struct in_addr *) host->h_addr);
  173. bzero (&(dest.sin_zero), 8);
  174. printf("connecting...");
  175. int32_t error = connect (handle, (struct sockaddr *) &dest, sizeof (struct sockaddr));
  176. printf(" done\n");
  177. if(error <0){
  178. printf("error connecting\n");
  179. return 0;
  180. }
  181. int32_t bytes_sent = send(handle, message, strlen(message), 0);
  182. if( bytes_sent < 0){
  183. printf("error sending request\n");
  184. close(handle);
  185. return 0;
  186. } else if (bytes_sent < strlen(message)){
  187. printf("send partial request\n");
  188. close(handle);
  189. return 0;
  190. }
  191. printf("sent request!\n");
  192. //change this to realloc and loop later
  193. uint8_t *buf = calloc(1, 2048);
  194. memset(buf, 0, 2048);
  195. int32_t bytes_read = recv(handle, buf, 2048, 0);
  196. printf("Received message:\n %s\n", buf);
  197. for(int i=0; i< bytes_read; i++){
  198. f->censored_queue[i] = buf[i];
  199. }
  200. f->censored_length = bytes_read;
  201. //for now, just close socket
  202. close(handle);
  203. return 0;
  204. }
  205. int replace_contents(flow *f, uint8_t *data, int32_t data_len, int32_t offset, struct in_addr src, struct in_addr dst){
  206. printf("Replacing contents...\n");
  207. uint8_t *p = data;
  208. struct tcp_header *tcp_hdr = (struct tcp_header*) p;
  209. int size_tcp = TCP_HEADER_LEN(tcp_hdr);
  210. p += size_tcp;
  211. int32_t tmp_len = data_len;
  212. //step 1: replace record contents
  213. //note: encrypted message will be original message size + EVP_GCM_TLS_EXPLICIT_IV_LEN + 16 byte pad
  214. //first check to see if there's anything in the outbox
  215. if(f->outbox_len > 0){
  216. printf("Printing from outbox\n");
  217. if(f->outbox_len < data_len){
  218. printf("Next record:\n");
  219. for(int i=0; i< RECORD_HEADER_LEN; i++){
  220. printf("%02x ", p[f->outbox_len+i]);
  221. }
  222. printf("\n");
  223. } else {
  224. printf("Outbox takes up entire packet\n");
  225. }
  226. if(tmp_len >= f->outbox_len){
  227. memcpy(p, f->outbox, f->outbox_len);
  228. p += f->outbox_len;
  229. tmp_len -= f->outbox_len;
  230. f->outbox_len = 0;
  231. free(f->outbox);
  232. printf("outbox now empty\n");
  233. } else {
  234. printf("Outbox has %d - %d bytes\n", f->outbox_len, tmp_len);
  235. memcpy(p, f->outbox, tmp_len);
  236. uint8_t *tmp = calloc(1, f->outbox_len - tmp_len);
  237. f->outbox_len -= tmp_len;
  238. memcpy(tmp, f->outbox + tmp_len, f->outbox_len);
  239. free(f->outbox);
  240. f->outbox = tmp;
  241. printf(" = %d bytes left in outbox\n", f->outbox_len);
  242. tmp_len -= tmp_len;
  243. }
  244. }
  245. while(tmp_len > 0){
  246. struct record_header *record_hdr = (struct record_header*) p;
  247. uint32_t record_length = RECORD_LEN(record_hdr);
  248. fprintf(stdout, "Record:\n");
  249. for(int i=0; i< RECORD_HEADER_LEN; i++){
  250. printf("%02x ", p[i]);
  251. }
  252. printf("\n");
  253. p += RECORD_HEADER_LEN;
  254. if(record_hdr->type != 0x17){
  255. //TODO: might need to decrypt and re-encrypt
  256. printf("received non-application data\n");
  257. tmp_len -= (record_length+ RECORD_HEADER_LEN);
  258. p += record_length;
  259. continue;
  260. }
  261. uint8_t *new_record = calloc(1, record_length);
  262. memcpy(new_record, p, record_length);
  263. uint8_t *tmp_p = new_record;
  264. /*// BEGIN TEST CODE //
  265. //Print original record
  266. printf("Original record (%d bytes):\n", record_length);
  267. for(int i=0; i< record_length; i++){
  268. printf("%02x ", p[i]);
  269. }
  270. printf("\n");
  271. //print few bytes of next record (if present)
  272. if(data_len > record_length + RECORD_HEADER_LEN){
  273. printf("Next record:\n");
  274. for(int i=0; i< RECORD_HEADER_LEN; i++){
  275. printf("%02x ", p[record_length+i]);
  276. }
  277. printf("\n");
  278. } else {
  279. printf("No extra record: %d = %d + %d\n", data_len, record_length, RECORD_HEADER_LEN);
  280. }
  281. //Decrypt record
  282. printf("Decrypting record... ");
  283. int n;
  284. if(!(n = encrypt(f, p, p, record_length, 1, 0x17, 0))){
  285. fprintf(stderr,"failed\n");
  286. return 0;
  287. } else {
  288. fprintf(stderr, "succeeded!\n");
  289. printf("Decrypted record:\n");
  290. for(int i=0; i< record_length; i++){
  291. printf("%02x ", p[i]);
  292. }
  293. printf("\n");
  294. printf("%s\n", p+ EVP_GCM_TLS_EXPLICIT_IV_LEN);
  295. }
  296. //return seq to what it was
  297. for(int i=7; i>=0; i--){
  298. --f->read_seq[i];
  299. if(f->read_seq[i] >= 0)
  300. break;
  301. else
  302. f->read_seq[i] = 0;
  303. }
  304. printf("seq reverted (%s): ", "read");
  305. for(int i=0; i<8; i++){
  306. printf("%02x ", f->read_seq[i]);
  307. }
  308. printf("\n");
  309. //Now reposition it to be fed into encrypt function
  310. //memcpy(p, p+ EVP_GCM_TLS_EXPLICIT_IV_LEN, n);
  311. // END TEST CODE */
  312. //step 2: figure out what happens if we don't have data
  313. tmp_p += EVP_GCM_TLS_EXPLICIT_IV_LEN;
  314. struct slitheen_header *sl_hdr = (struct slitheen_header *) tmp_p;
  315. sl_hdr->marker = 0x01;
  316. sl_hdr->version = 0x01;
  317. int32_t remaining = record_length - (SLITHEEN_HEADER_LEN
  318. + EVP_GCM_TLS_EXPLICIT_IV_LEN + 16);
  319. fprintf(stdout, "filling with censored queue data (%d out of %d) at offset %d\n", remaining, f->censored_length-offset, offset);
  320. if(remaining > 0){
  321. if(remaining+offset <= f->censored_length){
  322. fprintf(stdout, "We have enough data to fill the record\n");
  323. for(int i = 0; i< remaining; i++){
  324. tmp_p[SLITHEEN_HEADER_LEN+i] = f->censored_queue[i + offset];
  325. }
  326. //TODO: when I restructure this for more data, figure out freeing these pointers
  327. f->censored_queue += remaining;
  328. f->censored_length -= remaining;
  329. sl_hdr->len = htons(remaining);
  330. fprintf(stdout, "copied %d data\n", ntohs(sl_hdr->len));
  331. } else {
  332. int32_t dummy_offset = f->censored_length - offset;
  333. if(dummy_offset < 0) dummy_offset = 0;
  334. fprintf(stdout, "Not enough data (%d bytes)\n", dummy_offset);
  335. for(int i = 0; i< dummy_offset; i++){
  336. tmp_p[SLITHEEN_HEADER_LEN+i] = f->censored_queue[i + offset];
  337. }
  338. //TODO: note, we may also be receiving misordered packets. Take Ian's suggestion into account here
  339. f->censored_queue += dummy_offset;
  340. f->censored_length -= dummy_offset;
  341. sl_hdr->len = htons(dummy_offset);
  342. //TODO: should i < record_length or remaining??
  343. for(int i = dummy_offset; i< remaining; i++){
  344. tmp_p[SLITHEEN_HEADER_LEN+i] = 'A';
  345. }
  346. fprintf(stdout, "copied %d data and %d garbage bytes\n", ntohs(sl_hdr->len), remaining - dummy_offset);
  347. }
  348. printf("Slitheen header\n");
  349. for(int i=0; i<4; i++)
  350. printf("%02x ", tmp_p[i]);
  351. printf("\n");
  352. }
  353. tmp_p -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
  354. //step 3: encrypt new record
  355. //fprintf(stderr, "computing mac\n");
  356. //int32_t mac_size = mac(f, p, p+(record_length - (EVP_GCM_TLS_EXPLICIT_IV_LEN + 16)), record_length - (EVP_GCM_TLS_EXPLICIT_IV_LEN + 16), 1, 0x17, 1);
  357. //printf(stderr, "mac size: %d\n", mac_size);
  358. //fprintf(stderr, "encrypting\n");
  359. int32_t success;
  360. if((success = encrypt(f, tmp_p, tmp_p, record_length-16, 1, 0x17, 1))< 0){
  361. fprintf(stdout,"encryption failed\n");
  362. return 0;
  363. } else {
  364. fprintf(stdout, "encryption succeeded!\n");
  365. //printf("Encrypted data:\n");
  366. //for(int i=0; i< success; i++){
  367. // printf("%02x ", tmp_p[i]);
  368. //}
  369. //printf("\n");
  370. }
  371. //copy new record into packet
  372. if(record_length +RECORD_HEADER_LEN > tmp_len){
  373. //We have a partial record
  374. printf("Warning: partial record\n");
  375. memcpy(p, new_record, tmp_len - RECORD_HEADER_LEN);
  376. f->outbox_len = record_length - (tmp_len - RECORD_HEADER_LEN);
  377. //save left-overs in outbox
  378. f->outbox = calloc(1, f->outbox_len);
  379. memcpy(f->outbox, new_record + (tmp_len - RECORD_HEADER_LEN),
  380. f->outbox_len);
  381. free(new_record);
  382. printf("Outbox has %d = %d - %d bytes\n", f->outbox_len, record_length+RECORD_HEADER_LEN, tmp_len);
  383. } else {
  384. memcpy(p, new_record, record_length);
  385. free(new_record);
  386. }
  387. //check to see if next record still exists
  388. if(data_len > record_length + RECORD_HEADER_LEN){
  389. printf("Next record:\n");
  390. for(int i=0; i< RECORD_HEADER_LEN; i++){
  391. printf("%02x ", p[record_length+i]);
  392. }
  393. printf("\n");
  394. } else {
  395. printf("No extra record: %d <= %d + %d\n", data_len, record_length, RECORD_HEADER_LEN);
  396. }
  397. tmp_len -= record_length+ RECORD_HEADER_LEN;
  398. p += record_length;
  399. }
  400. //step 4: recompute TCP checksum
  401. p = data;
  402. p[16] = 0; p[17] = 0;//zero out checksum
  403. uint16_t chksm = tcp_checksum(p, data_len, src, dst);
  404. p[17] = chksm & 0xFF;
  405. p[16] = chksm >> 8;
  406. fprintf(stdout, "Checksum: 0x%0x%0x\n", p[16], p[17]);
  407. fflush(stdout);
  408. return 0;
  409. }
  410. /** Computes the TCP checksum of the data according to RFC 793
  411. * sum all 16-bit words in the segment, padd the last word if
  412. * needed
  413. *
  414. * there is a pseudo-header prefixed to the segment and
  415. * included in the checksum:
  416. *
  417. * +--------+--------+--------+--------+
  418. * | Source Address |
  419. * +--------+--------+--------+--------+
  420. * | Destination Address |
  421. * +--------+--------+--------+--------+
  422. * | zero | PTCL | TCP Length |
  423. * +--------+--------+--------+--------+
  424. */
  425. uint16_t tcp_checksum(uint8_t *data, int32_t data_len, struct in_addr src, struct in_addr dst){
  426. uint8_t *p = data;
  427. struct tcp_header *tcp_hdr = (struct tcp_header*) p;
  428. int size_tcp = TCP_HEADER_LEN(tcp_hdr);
  429. //Construct pseudo-header
  430. uint16_t tcp_length = data_len + size_tcp;
  431. uint8_t proto = IPPROTO_TCP;
  432. fprintf(stdout, "summing pseudoheader\n");
  433. uint32_t sum = (ntohl(src.s_addr)) >> 16;
  434. sum += (ntohl(src.s_addr)) &0xFFFF;
  435. sum += (ntohl(dst.s_addr)) >> 16;
  436. sum += (ntohl(dst.s_addr)) & 0xFFFF;
  437. sum += proto;
  438. sum += tcp_length;
  439. //now sum the text
  440. for(int i=0; i< tcp_length-1; i+=2){
  441. sum += (uint16_t) ((p[i] << 8) + p[i+1]);
  442. }
  443. if(tcp_length %2 != 0){
  444. sum += (uint16_t) (p[tcp_length - 1]) << 8;
  445. }
  446. //now add most significant to last significant bits
  447. sum = (sum >> 16) + (sum & 0xFFFF);
  448. //now subtract from 0xFF
  449. sum = 0xFFFF - sum;
  450. return (uint16_t) sum;
  451. }