Me encuentro con el siguiente problema: se "ha colado" un script hecho en Perl en el servidor y la tarea de encontrarlo se está complicando bastante (el servidor tiene alojados bastantes alojamientos con cerca de 2 millones de ficheros).
El caso es bastante "tipico", script en Perl subido por alguna vulnerabilidad conocida de algún CMS, tipo phpBB, Wordpress, etc.. que se está ejecutando con los mismos permisos que Apache y luego ejecuta un "UDP flood" o similar contra otra máquina.
Es el típico script que modifica algunas variables para complicar mas su busqueda, me refiero a las variables como el cmdline, el PPID, variables de entorno, etc.. ahora mismo no tengo a mano un enlace que explica como llevar a cabo esta tarea como ejemplo, pero no es nada complicado y es bastante facil pasar desapercibido ante "ps", "top", etc.. con estas técnicas.
El PID del proceso "perl" es el 31160, investigando por /proc vemos lo siguiente:
- Código: Seleccionar todo
# ls -l
total 0
-r-------- 1 www-data www-data 0 Nov 9 01:48 auxv
-r--r--r-- 1 www-data www-data 0 Nov 9 01:48 cmdline
lrwxrwxrwx 1 www-data www-data 0 Nov 9 01:48 cwd -> /
-r-------- 1 www-data www-data 0 Nov 9 01:48 environ
lrwxrwxrwx 1 www-data www-data 0 Nov 9 01:48 exe -> /usr/bin/perl
dr-x------ 2 www-data www-data 0 Nov 9 01:44 fd
-r--r--r-- 1 www-data www-data 0 Nov 9 01:48 maps
-rw------- 1 www-data www-data 0 Nov 9 01:48 mem
-r--r--r-- 1 www-data www-data 0 Nov 9 01:48 mounts
-r-------- 1 www-data www-data 0 Nov 9 01:48 mountstats
-rw-r--r-- 1 www-data www-data 0 Nov 9 01:48 oom_adj
-r--r--r-- 1 www-data www-data 0 Nov 9 01:48 oom_score
lrwxrwxrwx 1 www-data www-data 0 Nov 9 01:48 root -> /
-r--r--r-- 1 www-data www-data 0 Nov 9 01:48 smaps
-r--r--r-- 1 www-data www-data 0 Nov 9 01:42 stat
-r--r--r-- 1 www-data www-data 0 Nov 9 01:48 statm
-r--r--r-- 1 www-data www-data 0 Nov 9 01:48 status
dr-xr-xr-x 3 www-data www-data 0 Nov 9 01:44 task
-r--r--r-- 1 www-data www-data 0 Nov 9 01:48 wchan
La primera curiosidad es el que "cmdline" está modificado para engañar a ps, top y compañia (fijaros en el detalle de que además se insertan caracteres en blanco para dificultar mas...):
- Código: Seleccionar todo
# cat cmdline
shellbot
# cat cmdline | tr \\0 B
shellbotBBBBBBB
La variable CWD esta cambiada tambien ya que el usuario de Apache no podría hacer esta tarea.. tambien se han eliminado las variables de entorno por si pudieran dar alguna pista, environ está vacio.
Si nos adentramos en "/proc/31160/fd" veremos un listado de los descriptores de ficheros abiertos por el script, malas noticias no tenemos ninguna pista de la ruta al script implicado:
- Código: Seleccionar todo
# ls -larth | egrep -v log
total 3.7M
dr-xr-xr-x 4 www-data www-data 0 Nov 8 19:01 ..
dr-x------ 2 www-data www-data 0 Nov 9 01:58 .
lr-x------ 1 www-data www-data 64 Nov 9 01:59 0 -> /dev/null
l-wx------ 1 www-data www-data 64 Nov 9 01:59 8 -> pipe:[169162335]
lr-x------ 1 www-data www-data 64 Nov 9 01:59 7 -> pipe:[169162335]
lrwx------ 1 www-data www-data 64 Nov 9 01:59 4 -> socket:[167704784]
lrwx------ 1 www-data www-data 64 Nov 9 01:59 3 -> socket:[167704783]
l-wx------ 1 www-data www-data 64 Nov 9 01:59 1 -> pipe:[169282437]
lrwx------ 1 www-data www-data 64 Nov 9 01:59 3785 -> socket:[169282509]
lrwx------ 1 www-data www-data 64 Nov 9 01:59 3784 -> socket:[169275238]
lrwx------ 1 www-data www-data 64 Nov 9 01:59 3783 -> socket:[169282354]
lrwx------ 1 www-data www-data 64 Nov 9 01:59 3782 -> /tmp/ZCUDQaGd5w (deleted)
lr-x------ 1 www-data www-data 64 Nov 9 01:59 3777 -> /opt/casp/asp-server-3001/casp.cnfg
Lo intentamos con la ayuda de la utilidad lsof:
- Código: Seleccionar todo
# lsof -p 31160 | egrep -v log
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
perl 31160 www-data cwd DIR 8,4 4096 2 /
perl 31160 www-data rtd DIR 8,4 4096 2 /
perl 31160 www-data txt REG 8,4 1057324 10944664 /usr/bin/perl
perl 31160 www-data mem REG 0,0 0 [heap] (stat: No such file or directory)
perl 31160 www-data mem REG 8,4 64924 5871168 /lib/tls/libresolv-2.3.2.so
perl 31160 www-data mem REG 8,4 13976 5871162 /lib/tls/libnss_dns-2.3.2.so
perl 31160 www-data mem REG 8,4 34748 5871163 /lib/tls/libnss_files-2.3.2.so
perl 31160 www-data mem REG 8,4 22284 10944696 /usr/lib/perl/5.8.4/auto/Socket/Socket.so
perl 31160 www-data mem REG 8,4 18876 5871156 /lib/tls/libcrypt-2.3.2.so
perl 31160 www-data mem REG 8,4 1254660 5871155 /lib/tls/libc-2.3.2.so
perl 31160 www-data mem REG 8,4 78233 5867284 /lib/tls/libpthread-0.60.so
perl 31160 www-data mem REG 8,4 134496 5871158 /lib/tls/libm-2.3.2.so
perl 31160 www-data mem REG 8,4 9872 5871157 /lib/tls/libdl-2.3.2.so
perl 31160 www-data mem REG 8,4 17920 10944690 /usr/lib/perl/5.8.4/auto/IO/IO.so
perl 31160 www-data mem REG 8,4 90248 5195799 /lib/ld-2.3.2.so
perl 31160 www-data 0r CHR 1,3 3525483 /dev/null
perl 31160 www-data 1w FIFO 0,5 169282437 pipe
perl 31160 www-data 3u IPv4 167704783 TCP *:www (LISTEN)
perl 31160 www-data 4u IPv4 167704784 TCP *:https (LISTEN)
perl 31160 www-data 7r FIFO 0,5 169162335 pipe
perl 31160 www-data 8w FIFO 0,5 169162335 pipe
perl 31160 www-data 3777r REG 8,4 1819 11730995 /opt/casp/asp-server-3001/casp.cnfg
perl 31160 www-data 3782u REG 8,2 0 14291 /tmp/ZCUDQaGd5w (deleted)
perl 31160 www-data 3783u sock 0,4 169282354 can't identify protocol
perl 31160 www-data 3784u unix 0xc3ef5500 169275238 socket
perl 31160 www-data 3785u IPv4 169282509 TCP xxx:50687->yyy:3333 (ESTABLISHED)
Ahora queda mas claro todavía que se trata de un script en Perl que hace uso de modulos relaciones con funciones de red.. y la ultima linea lo aclara todo, se trata de un ataque contra el puerto 3333 contra la máquina destino.
Hacemos otra prueba, ahora con "pmap" que nos saca un "mapa" de las zonas de memoria en uso por el proceso:
- Código: Seleccionar todo
# pmap -d 31160
31160: shellbot
Address Kbytes Mode Offset Device Mapping
08048000 996 r-x-- 0000000000000000 008:00004 perl
08141000 36 rw--- 00000000000f9000 008:00004 perl
0814a000 2912 rw--- 000000000814a000 000:00000 [ anon ]
b7d1d000 60 r-x-- 0000000000000000 008:00004 libresolv-2.3.2.so
b7d2c000 4 rw--- 000000000000f000 008:00004 libresolv-2.3.2.so
b7d2d000 8 rw--- 00000000b7d2d000 000:00000 [ anon ]
b7d2f000 12 r-x-- 0000000000000000 008:00004 libnss_dns-2.3.2.so
b7d32000 4 rw--- 0000000000003000 008:00004 libnss_dns-2.3.2.so
b7d33000 36 r-x-- 0000000000000000 008:00004 libnss_files-2.3.2.so
b7d3c000 4 rw--- 0000000000008000 008:00004 libnss_files-2.3.2.so
b7d44000 24 r-x-- 0000000000000000 008:00004 Socket.so
b7d4a000 4 rw--- 0000000000005000 008:00004 Socket.so
b7d4b000 136 rw--- 00000000b7d4b000 000:00000 [ anon ]
b7d6d000 20 r-x-- 0000000000000000 008:00004 libcrypt-2.3.2.so
b7d72000 4 rw--- 0000000000004000 008:00004 libcrypt-2.3.2.so
b7d73000 156 rw--- 00000000b7d73000 000:00000 [ anon ]
b7d9a000 1192 r-x-- 0000000000000000 008:00004 libc-2.3.2.so
b7ec4000 36 rw--- 0000000000129000 008:00004 libc-2.3.2.so
b7ecd000 8 rw--- 00000000b7ecd000 000:00000 [ anon ]
b7ecf000 48 r-x-- 0000000000000000 008:00004 libpthread-0.60.so
b7edb000 4 rw--- 000000000000c000 008:00004 libpthread-0.60.so
b7edc000 8 rw--- 00000000b7edc000 000:00000 [ anon ]
b7ede000 132 r-x-- 0000000000000000 008:00004 libm-2.3.2.so
b7eff000 4 rw--- 0000000000020000 008:00004 libm-2.3.2.so
b7f00000 4 rw--- 00000000b7f00000 000:00000 [ anon ]
b7f01000 8 r-x-- 0000000000000000 008:00004 libdl-2.3.2.so
b7f03000 4 rw--- 0000000000002000 008:00004 libdl-2.3.2.so
b7f06000 16 r-x-- 0000000000000000 008:00004 IO.so
b7f0a000 4 rw--- 0000000000004000 008:00004 IO.so
b7f0b000 4 rw--- 00000000b7f0b000 000:00000 [ anon ]
b7f0c000 88 r-x-- 0000000000000000 008:00004 ld-2.3.2.so
b7f22000 4 rw--- 0000000000015000 008:00004 ld-2.3.2.so
bfdfc000 84 rw--- 00000000bfdfc000 000:00000 [ stack ]
ffffe000 4 ----- 0000000000000000 000:00000 [ anon ]
mapped: 6068K writeable/private: 3432K shared: 0K
Esta aplicación tampoco dice nada.. veamos el contenido de los ficheros "stat", "statm" y "status":
- Código: Seleccionar todo
# cat stat
31160 (perl) S 1 15792 15792 0 -1 8396864 7740 0 0 0 1330956 1178990 0 0 25 0 1 0 308333893 6209536 1042 4294967295 134512640 135530560 3219195008 3219194400 3085351416 0 0 86659 0 0 0 0 17 3 0 0
# cat statm
1516 1042 300 249 0 830 0
# cat status
Name: perl
State: S (sleeping)
SleepAVG: 0%
Tgid: 31160
Pid: 31160
PPid: 1
TracerPid: 0
Uid: 33 33 33 33
Gid: 33 33 33 33
FDSize: 4096
Groups: 33 2523
VmPeak: 6092 kB
VmSize: 6064 kB
VmLck: 0 kB
VmHWM: 4168 kB
VmRSS: 4168 kB
VmData: 3236 kB
VmStk: 84 kB
VmExe: 996 kB
VmLib: 1636 kB
VmPTE: 24 kB
Threads: 1
SigQ: 0/33792
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000015283
SigCgt: 0000000080000000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
Nada relevante como curiosidad parece que han podido cambiar el PPID del proceso.. no tiene lógica de que sea el padre del script Perl el proceso "init" ¿?
Llevo varias horas "grepeando" logs, contenidos de alojamientos, etc.. tirando de aplicaciones tipo strace, pmap, lsof, etc.. pero no encuentro el script... ¿Alguna idea, aplicación, para encontrar la ruta completa a ese script en ejecución al que parece que le han modificado todo?
Tambien sería de interés si alguien conoce las técnicas usadas para modificar estos parámetros sin ser root.. como decia no es nada complicado y he tenido script que lo hacían hasta poco, pero los borré...
Gracias