Advertisement
Guest User

Untitled

a guest
Sep 15th, 2019
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.10 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <cstring>
  4. #include <unistd.h>
  5. #include <sys/un.h>
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8. #include <arpa/inet.h>
  9. #include <netinet/ip.h>
  10. #include <netinet/in.h>
  11. #include <netinet/udp.h>
  12. #include <netinet/ip_icmp.h>
  13. #include <netdb.h>
  14. #include <iostream>
  15. #include <string.h>
  16. #include <vector>
  17. #include <regex>
  18. #include <sstream>
  19.  
  20. // ---------- HELPER STRUCTS ----------
  21. struct port_message {
  22. int port;
  23. std::string message;
  24. };
  25.  
  26. struct pseudo_header {
  27. u_int32_t source_address;
  28. u_int32_t dest_address;
  29. u_int8_t placeholder;
  30. u_int8_t protocol;
  31. u_int16_t udp_length;
  32. };
  33. // ---------- GLOBAL VARIABLES ----------
  34. #define BUFFERSIZE 1024
  35. std::vector<port_message> ports;
  36. int socketDGRM;
  37. int socketRAW;
  38. int socketICMP;
  39. int srcPort = 5600;
  40. struct sockaddr_in client;
  41. struct sockaddr_in serverAddress;
  42. char srcIP[32] = "192.168.1.5";
  43.  
  44. // ---------- SMALL HELPER FUNCTIONS ----------
  45.  
  46. // get local ip, source: https://bit.ly/2kiprB4
  47. void getLocalIp(char * buffer, int socketDGRM) {
  48. socketDGRM = socket(AF_INET, SOCK_DGRAM, 0);
  49.  
  50. const char* kGoogleDnsIp = "8.8.8.8";
  51. int dns_port = 53;
  52.  
  53. struct sockaddr_in serv;
  54.  
  55. memset(&serv, 0, sizeof(serv));
  56. serv.sin_family = AF_INET;
  57. serv.sin_addr.s_addr = inet_addr(kGoogleDnsIp);
  58. serv.sin_port = htons(dns_port);
  59.  
  60. int err = connect(socketDGRM,(const struct sockaddr*) &serv , sizeof(serv));
  61.  
  62. struct sockaddr_in name;
  63. socklen_t namelen = sizeof(name);
  64. err = getsockname(socketDGRM, (struct sockaddr*) &name, &namelen);
  65.  
  66. const char *p = inet_ntop(AF_INET, &name.sin_addr, buffer, 100);
  67. close(socketDGRM);
  68. }
  69.  
  70. // Creates a new DGRAM socket
  71. void createSocketDGRM() {
  72. if((socketDGRM = socket(AF_INET , SOCK_DGRAM , IPPROTO_UDP)) == -1) {
  73. perror("creating udp socket failed");
  74. exit(0);
  75. }
  76. }
  77. // Creates a new RAW socket
  78. void createSocketRAW() {
  79. if((socketRAW = socket(AF_INET , SOCK_RAW , IPPROTO_RAW)) == -1) {
  80. perror("creating raw socket failed");
  81. exit(0);
  82. }
  83. int on = 1;
  84. if((setsockopt(socketRAW, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on))) == -1) {
  85. perror("setsockopt on raw socket failed");
  86. exit(0);
  87. }
  88. }
  89. // Creates a new ICMP socket
  90. void createSocketICMP() {
  91. if((socketICMP = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1) {
  92. perror("creating raw socket failed");
  93. exit(0);
  94. }
  95. }
  96. // Binds given socket
  97. void bindSocket(int socket, struct sockaddr_in s) {
  98. if(bind(socket, (struct sockaddr*)&s, sizeof(s)) == -1) {
  99. perror("binding socket failed");
  100. exit(0);
  101. }
  102. }
  103. // Assigns addresses for both sending and receiving
  104. void assignAddress(char *argv[]) {
  105. serverAddress.sin_family = AF_INET;
  106. serverAddress.sin_addr.s_addr = inet_addr(argv[1]);
  107.  
  108. client.sin_family = AF_INET;
  109. client.sin_addr.s_addr = INADDR_ANY;
  110. client.sin_port = htons(srcPort);
  111. }
  112. // Extracts port from given message
  113. int extractPort(std::string message) {
  114. int i;
  115. for (i = 0; i < message.length(); i++ ){
  116. if ( isdigit(message[i]) ) {
  117. break;
  118. }
  119. }
  120. message = message.substr(i, message.length() - i);
  121. return atoi(message.c_str());
  122. }
  123. // Extracts secret phrase from message
  124. std::string extractSecretPhrase(std::string message) {
  125. char buffer[256];
  126. char *subString;
  127.  
  128. strcpy(buffer, message.c_str());
  129.  
  130. subString = strtok(buffer,"\"");
  131. subString = strtok(NULL,"\"");
  132.  
  133. return subString;
  134. }
  135. // Calculates the checksum for a custom packet
  136. unsigned short csum(unsigned short *ptr,int nbytes) {
  137. unsigned long sum = 0;
  138. unsigned short oddbyte;
  139. unsigned short answer;
  140.  
  141. while(nbytes>1) {
  142. sum+=(*ptr++);
  143. nbytes-=2;
  144. }
  145. if(nbytes==1) {
  146. oddbyte=0;
  147. *((u_char*)&oddbyte)=*(u_char*)ptr;
  148. sum+=(oddbyte);
  149. }
  150. sum = (sum>>16)+(sum & 0xffff);
  151. sum = sum + (sum>>16);
  152. answer=(short)~sum;
  153. return (answer);
  154. }
  155. // Calculates data for packet from two checksums
  156. unsigned short desiredData(unsigned short currentCsum, int dSum) {
  157. unsigned short desiredCsum = htons(dSum);
  158. unsigned short desiredTsum = ~desiredCsum;
  159. unsigned short currentTsum = ~currentCsum;
  160. unsigned short diff = desiredTsum - current Tsum;
  161. return htons(diff);
  162. }
  163. // ---------- SEND AND RECEIVE FUNCTIONS ----------
  164. // sends package to given port
  165. void sendToPort(int socket, struct sockaddr_in serverAddress, const char *package, size_t packageSize) {
  166. // sending message to server
  167. if (sendto(socket, package, packageSize, 0, (const struct sockaddr *)&serverAddress, sizeof(serverAddress)) == -1) {
  168. perror("sendto failed");
  169. exit(0);
  170. }
  171. }
  172. // Listens to given port for UDP packets for a certain amount of time
  173. port_message receiveFromPort(int socket, struct sockaddr_in serverAddress, int port) {
  174. // setting timeout limit
  175. struct timeval time;
  176. time.tv_sec = 0;
  177. time.tv_usec = 200000;
  178. fd_set fdSet;
  179. FD_ZERO(&fdSet);
  180. FD_SET(socket, &fdSet);
  181. socklen_t recvAddrSize;
  182. char buffer[BUFFERSIZE];
  183. if(select(socket + 1, &fdSet, NULL, NULL, &time) > 0) {
  184. memset(buffer, 0, BUFFERSIZE);
  185. // waiting to receive message from server
  186. if(recvfrom(socket, buffer, sizeof(buffer), 0, (struct sockaddr *)&serverAddress, &recvAddrSize) == -1) {
  187. perror("recvfrom failed");
  188. exit(0);
  189. }
  190. port_message m;
  191. m.port = port;
  192. m.message = buffer;
  193. return m;
  194. }
  195. port_message m;
  196. m.port = port;
  197. m.message = "no answer from port";
  198. return m;
  199. }
  200. // Listens to given port for ICMP packets for a certain amount of time
  201. port_message receiveICPMFromPort(int socket, struct sockaddr_in serverAddress, int port) {
  202. // setting timeout limit
  203. struct timeval time;
  204. time.tv_sec = 0;
  205. time.tv_usec = 200000;
  206. fd_set fdSetICMP;
  207. FD_ZERO(&fdSetICMP);
  208. FD_SET(socket, &fdSetICMP);
  209. socklen_t recvAddrSize;
  210. char buffer[BUFFERSIZE];
  211. if(select(socket + 1, &fdSetICMP, NULL, NULL, &time) > 0) {
  212. memset(buffer, 0, BUFFERSIZE);
  213. // waiting to receive message from server
  214. if(recvfrom(socket, buffer, sizeof(buffer), 0, (struct sockaddr *)&serverAddress, &recvAddrSize) == -1) {
  215. perror("recvfrom failed");
  216. exit(0);
  217. }
  218. struct ip *ipheader = (struct ip*)buffer;
  219. int iplen = ipheader->ip_hl << 2;
  220. struct icmp *icmp = (struct icmp*)(buffer + iplen);
  221. if((icmp->icmp_type == ICMP_UNREACH) && (icmp->icmp_code == ICMP_UNREACH_PORT)) {
  222. port_message m;
  223. m.port = port;
  224. m.message = "unreachable port";
  225. return m;
  226. }
  227. }
  228. port_message m;
  229. m.port = port;
  230. m.message = "no answer from port";
  231. return m;
  232. }
  233. // ---------- UDP PORT SCANNER ----------
  234. // Scans given port range and saves their messages
  235. void scanPorts(int lowPort, int highPort) {
  236. // assigning sockets
  237. createSocketDGRM();
  238. createSocketICMP();
  239. const char *package = "knock";
  240. port_message m1, m2;
  241. int count = 0;
  242. // checking all the ports in port range
  243. for(int i = lowPort; i <= highPort; i++) {
  244. serverAddress.sin_port = htons(i);
  245. sendToPort(socketDGRM, serverAddress, package, strlen(package));
  246. m2 = receiveICPMFromPort(socketICMP, serverAddress, i);
  247. if(m2.message == "no answer from port") {
  248. m1 = receiveFromPort(socketDGRM, serverAddress, i);
  249. if(m1.message != "no answer from port" || count > 3) {
  250. if(m1.message.find("oracle")) {
  251. ports.insert(ports.begin(), m1);
  252. } else {
  253. ports.push_back(m1);
  254. }
  255. count = 0;
  256. }
  257. else {
  258. count++;
  259. i--;
  260. }
  261. }
  262. else {
  263. count = 0;
  264. }
  265. }
  266. std::cout << "---- all ports in range ----" << std::endl;
  267. for(port_message p : ports) {
  268. std::cout << "port: " << p.port << " | " << p.message << std::endl;
  269. }
  270. close(socketDGRM);
  271. close(socketICMP);
  272. }
  273. // ---------- FUNCTIONS FOR MAKING PACKETS ----------
  274. // Creates a custom udp packet with given variables
  275. char* createPacket(struct sockaddr_in serverAddress, int dstPort, char *myData, u_short ipOff) {
  276. char packet[4096], *data, *pseudogram;
  277. memset (packet, 0, 4096);
  278. // IP header of packet
  279. struct ip *iph = (struct ip *) packet;
  280. // UDP header of packet
  281. struct udphdr *udph = (struct udphdr *) (packet + sizeof (struct ip));
  282. // Data of packet
  283. data = packet + sizeof(struct ip) + sizeof(struct udphdr);
  284. strcpy(data , myData);
  285. // Assigning IP header
  286. iph->ip_hl = 5;
  287. iph->ip_v = 4;
  288. iph->ip_tos = 0;
  289. iph->ip_len = sizeof (struct ip) + sizeof (struct udphdr) + strlen(data);
  290. iph->ip_id = 0;
  291. iph->ip_off = ipOff;
  292. iph->ip_ttl = 255;
  293. iph->ip_p = IPPROTO_UDP;
  294. iph->ip_sum = 0;
  295. iph->ip_src.s_addr = inet_addr (srcIP);
  296. iph->ip_dst.s_addr = serverAddress.sin_addr.s_addr;
  297. // Assigning UDP header
  298. udph->uh_sport = htons(srcPort);
  299. udph->uh_dport = htons(dstPort);
  300. udph->uh_ulen = htons(8 + strlen(data));
  301. udph->uh_sum = 0;
  302. // Creating pseudo header for calculating checksum
  303. struct pseudo_header psh;
  304. psh.source_address = inet_addr(srcIP);
  305. psh.dest_address = serverAddress.sin_addr.s_addr;
  306. psh.placeholder = 0;
  307. psh.protocol = IPPROTO_UDP;
  308. psh.udp_length = htons(sizeof(struct udphdr) + strlen(data));
  309. int psize = sizeof(struct pseudo_header) + sizeof(struct udphdr) + strlen(data);
  310. pseudogram = (char *)malloc(psize);
  311. memcpy(pseudogram , (char*) &psh , sizeof (struct pseudo_header));
  312. memcpy(pseudogram + sizeof(struct pseudo_header) , udph , sizeof(struct udphdr) + strlen(data));
  313. // Calculate udp checksum
  314. udph->uh_sum = csum( (unsigned short*) pseudogram , psize);
  315. return packet;
  316. }
  317. // Creates packet with empty data and calculates data from its checksum and a given checksum
  318. unsigned short makeDataForPacket(struct sockaddr_in serverAddress, int dstPort, int dSum) {
  319. char packet[4096], *data, *pseudogram;
  320. memset (packet, 0, 4096);
  321. // UDP header of packet
  322. struct udphdr *udph = (struct udphdr *) (packet + sizeof (struct ip));
  323. // Data of packet
  324. data = packet + sizeof(struct ip) + sizeof(struct udphdr);
  325. strcpy(data , "");
  326. // Assigning udp header
  327. udph->uh_sport = htons(srcPort);
  328. udph->uh_dport = htons (dstPort);
  329. udph->uh_ulen = htons(12 + strlen(data));
  330. udph->uh_sum = 0;
  331. // Creating pseudo header for calculating checksum
  332. struct pseudo_header psh;
  333. psh.source_address = inet_addr(srcIP);
  334. psh.dest_address = serverAddress.sin_addr.s_addr;
  335. psh.placeholder = 0;
  336. psh.protocol = IPPROTO_UDP;
  337. psh.udp_length = htons(sizeof(struct udphdr) + strlen(data));
  338. int psize = sizeof(struct pseudo_header) + sizeof(struct udphdr) + strlen(data);
  339. pseudogram = (char *)malloc(psize);
  340. memcpy(pseudogram , (char*) &psh , sizeof (struct pseudo_header));
  341. memcpy(pseudogram + sizeof(struct pseudo_header) , udph , sizeof(struct udphdr) + strlen(data));
  342. // Calculate udp checksum
  343. unsigned short checksum = csum( (unsigned short*) pseudogram , psize);
  344. return desiredData(checksum, dSum);
  345. }
  346. //---------- FUNCTIONS FOR SENDING TO SPECIFIC PORTS ----------
  347. // Gets port from evil port
  348. int evilPort(int dstPort) {
  349. serverAddress.sin_port = htons(dstPort);
  350. char *data = "So you have chosen... death.";
  351. char *packet = createPacket(serverAddress, dstPort, data, 0x8000);
  352. port_message m;
  353. createSocketRAW();
  354. sendToPort(socketRAW, serverAddress, packet, (sizeof(struct ip) + sizeof(struct udphdr) + strlen(data)));
  355. createSocketDGRM();
  356. bindSocket(socketDGRM, client);
  357. m = receiveFromPort(socketDGRM, client, dstPort);
  358. std::cout << "---- EVIL PORT ----" << std::endl;
  359. std::cout << "port: " << m.port << " | " << m.message << std::endl;
  360. close(socketRAW);
  361. close(socketDGRM);
  362. return extractPort(m.message);
  363. }
  364. // Gets secret message from udp checksum port
  365. std::string udpChecksumPort(int dstPort, int desiredChecksum) {
  366. serverAddress.sin_port = htons(dstPort);
  367. unsigned short sData = makeDataForPacket(serverAddress, dstPort, desiredChecksum);
  368. char nData[3];
  369. nData[0] = sData >> 8;
  370. nData[1] = sData & 0xfffff;
  371. nData[2] = '\0';
  372. char *data = nData;
  373. char *packet = createPacket(serverAddress, dstPort, data, 0);
  374. port_message m;
  375. createSocketRAW();
  376. sendToPort(socketRAW, serverAddress, packet, (sizeof(struct ip) + sizeof(struct udphdr) + strlen(data)));
  377. createSocketDGRM();
  378. bindSocket(socketDGRM, client);
  379. m = receiveFromPort(socketDGRM, client, dstPort);
  380. std::cout << "---- UDP CHECKSUM PORT ----" << std::endl;
  381. std::cout << "port: " << m.port << " | " << m.message << std::endl;
  382. close(socketRAW);
  383. close(socketDGRM);
  384. std::cout << "LALALALLALALALAL" << std::endl;
  385. return extractSecretPhrase(m.message);
  386. }
  387. // Gets secret ports from the oracle
  388. void oraclePort(int dstPort, int port1, int port2, std::string secretMessage) {
  389. serverAddress.sin_port = htons(dstPort);
  390. std::string oracleMessage = std::to_string(port1) + "," + std::to_string(port2);
  391. const char *package = oracleMessage.c_str();
  392. std::cout << package << std::endl;
  393. port_message m;
  394. createSocketDGRM();
  395. sendToPort(socketDGRM, serverAddress, package, strlen(package));
  396. m = receiveFromPort(socketDGRM, serverAddress, dstPort);
  397. std::cout << "---- ORACLE PORT ----" << std::endl;
  398. std::cout << "port: " << m.port << " | " << m.message << std::endl;
  399. /*extracting ports from oracle message*/
  400. std::vector<int> oraclePorts;
  401. std::stringstream ss(m.message);
  402. for (int i; ss >> i;) {
  403. oraclePorts.push_back(i);
  404. if (ss.peek() == ',')
  405. ss.ignore();
  406. }
  407. const char *data = "knock";
  408. for(int &port : oraclePorts) {
  409. serverAddress.sin_port = htons(port);
  410. if(&port == &oraclePorts.back()) {
  411. const char *message = secretMessage.c_str();
  412. dstPort = port;
  413. sendToPort(socketDGRM, serverAddress, message, strlen(message));
  414. std::cout << dstPort << " | " << message << std::endl;
  415. }
  416. else {
  417. sendToPort(socketDGRM, serverAddress, data, strlen(data));
  418. }
  419. }
  420. m = receiveFromPort(socketDGRM, serverAddress, dstPort);
  421. std::cout << "---- SECRET PORT ----" << std::endl;
  422. std::cout << "port: " << m.port << " | " << m.message << std::endl;
  423. close(socketDGRM);
  424. }
  425. // Finds ports in port vector and sends the correct message to each one
  426. void sendToPorts() {
  427. int thisIsPort, evilP;
  428. std::string secretMessage;
  429. for(port_message p: ports) {
  430. if (p.message.find("evil") != std::string::npos) {
  431. evilP = evilPort(p.port);
  432. }
  433. if(p.message.find("checksum") != std::string::npos) {
  434. int dSum = extractPort(p.message);
  435. secretMessage = udpChecksumPort(p.port, dSum);
  436. }
  437. if(p.message.find("This is the port") != std::string::npos) {
  438. thisIsPort = extractPort(p.message);
  439. }
  440. if(p.message.find("oracle") != std::string::npos) {
  441. std::cout << "oracle!" << std::endl;
  442. oraclePort(p.port, evilP, thisIsPort, secretMessage);
  443. }
  444. }
  445. }
  446.  
  447.  
  448.  
  449.  
  450. int main(int argc, char* argv[]) {
  451. // what port we want to scan from
  452. int lowPort = std::stoi (argv[2]);
  453. // what port we want to scan to
  454. int highPort = std::stoi (argv[3]);
  455. //initializing localIp
  456. //getLocalIp(srcIP, socketDGRM);
  457. assignAddress(argv);
  458. // ---- PART 1A ----
  459. scanPorts(lowPort, highPort);
  460. std::cout <<" printing ip" << std::endl;
  461. // for(int i = 0; i < strlen(srcIP); i++) {
  462. // std::cout << srcIP[i];
  463. // }
  464. // ---- PART 1B AND 1C ----
  465. sendToPorts();
  466. return 0;
  467. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement