slitheen-proxy.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include <pcap.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include "ptwist.h"
  5. #include "rserv.h"
  6. #define macaddr "08:00:27:e8:9d:d4"
  7. //Definitions for parsing packet data
  8. #define ETHER_ADDR_LEN 6
  9. #define ETHER_HDR_LEN 2*ETHER_ADDR_LEN + 2
  10. #define RECORD_HDR 5
  11. #define CLIENT_HELLO_HDR 4
  12. #define CLIENT_HELLO_RAND 32
  13. void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
  14. //TODO: look for slitheen tag. The ClientHello message starts at offset 0x4d of packet after TCP 3-way handshake and has flag [P.].
  15. //For now, write *all* clientHello msgs to a file
  16. void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet){
  17. pcap_t *handle;
  18. char errbuf[BUFSIZ];
  19. char *writedev = args;
  20. int i, res;
  21. const unsigned char *p;
  22. FILE *fp;
  23. byte privkey[PTWIST_BYTES];
  24. byte key[16];
  25. handle = pcap_open_live(writedev, BUFSIZ, 1, 1000, errbuf);
  26. if (handle == NULL){
  27. fprintf(stderr, "Couldn't open device %s: %s\n", writedev, errbuf);
  28. }
  29. /* check for clientHello */
  30. p = packet;
  31. p += ETHER_HDR_LEN; //skip ethernet header
  32. p += (p[0] & 0x0f)*4; //skip IP header
  33. p += 12; //skip first part of TCP header
  34. p += (p[0] >> 4)*4 - 12; //skip rest of TCP header
  35. //check for handshake message
  36. if (p[0] == 0x16){
  37. p += RECORD_HDR;
  38. if (p[0] == 0x01){
  39. p += CLIENT_HELLO_HDR;
  40. p += 2; //dunno what these are
  41. //now pointing to hello random :D
  42. p += 4; //skipping time bytes
  43. /* Load the private key */
  44. fp = fopen("privkey", "rb");
  45. if (fp == NULL) {
  46. perror("fopen");
  47. exit(1);
  48. }
  49. res = fread(privkey, PTWIST_BYTES, 1, fp);
  50. if (res < 1) {
  51. perror("fread");
  52. exit(1);
  53. }
  54. fclose(fp);
  55. /* check tag*/
  56. res = check_tag(key, privkey, p, (const byte *)"context", 7);
  57. if (res) {
  58. printf("Untagged\n");
  59. } else {
  60. fp = fopen("tags", "wb");
  61. if (fp == NULL) {
  62. perror("fopen");
  63. exit(1);
  64. }
  65. //Write tag to file
  66. for(i=0; i< 28; i++){
  67. fprintf(fp, "%02x ", p[i]);
  68. }
  69. fclose(fp);
  70. }
  71. }
  72. }
  73. if((pcap_inject(handle, packet, header->len)) < 0 ){
  74. fprintf(stderr, "Error: %s\n", pcap_geterr(handle));
  75. }
  76. pcap_close(handle);
  77. }
  78. int usage(void){
  79. printf("Usage: slitheen-proxy [internal network interface] [NAT interface]\n");
  80. }
  81. int main(int argc, char *argv[]){
  82. pid_t pid;
  83. char filter1[33] = "ether src host 08:00:27:e8:9d:d4";
  84. char filter2[33] = "ether src host 08:00:27:e8:9d:d4";
  85. char *dev1 = NULL; /* Device that leads to the internal network */
  86. char *dev2 = NULL; /* Device that leads out to the world */
  87. if (argc != 3) {
  88. usage();
  89. return(2);
  90. }
  91. dev1 = argv[1];
  92. dev2 = argv[2];
  93. snprintf(filter1, 33, "ether src host %s", macaddr);
  94. snprintf(filter2, 33, "ether dst host %s", macaddr);
  95. pid = fork();
  96. if (pid < 0) {
  97. fprintf(stderr, "Fork call failed.\n");
  98. return(2);
  99. }
  100. if (pid == 0) {
  101. sniff_packets(dev1, dev2, filter1);
  102. } else {
  103. sniff_packets(dev2, dev1, filter2);
  104. }
  105. return(0);
  106. }
  107. int sniff_packets(char *readdev, char *writedev, char *filter){
  108. pcap_t *handle;
  109. char errbuf[BUFSIZ];
  110. struct bpf_program fp;
  111. bpf_u_int32 mask;
  112. bpf_u_int32 net;
  113. if (pcap_lookupnet(readdev, &net, &mask, errbuf) == -1){
  114. fprintf(stderr, "Can't get netmask for device %s\n", readdev);
  115. return(2);
  116. }
  117. handle = pcap_open_live(readdev, BUFSIZ, 1, 1000, errbuf);
  118. if (handle == NULL){
  119. fprintf(stderr, "Couldn't open device %s: %s\n", readdev, errbuf);
  120. }
  121. if(pcap_datalink(handle) != DLT_EN10MB) {
  122. fprintf(stderr, "Device %s does not provide Ethernet headers - not supported\n", readdev);
  123. return(2);
  124. }
  125. if(pcap_compile(handle, &fp, filter, 0 , net) == -1){
  126. fprintf(stderr, "Couldn't parse filter %s: %s\n", filter, pcap_geterr(handle));
  127. return(2);
  128. }
  129. if (pcap_setfilter(handle, &fp) == -1) {
  130. fprintf(stderr, "Couldn't install filter %s: %s\n", filter, pcap_geterr(handle));
  131. return(2);
  132. }
  133. /*callback function*/
  134. pcap_loop(handle, -1, got_packet, writedev);
  135. /*Sniff a packet*/
  136. pcap_close(handle);
  137. return(0);
  138. }