줄기세포

[Linux] 트로이 목마 당한 썰 푼다 - CPU high, CPU 사용 프로세서 조회 안되는 상황 해결 본문

Linux

[Linux] 트로이 목마 당한 썰 푼다 - CPU high, CPU 사용 프로세서 조회 안되는 상황 해결

줄기세포(Stem_Cell) 2022. 8. 30. 18:02

왜 트로이목마를 의심했나?

  • 현상
    • bash 명령어 수행하는데 서버가 너무 버벅거린다.
    • nmon과 top로 조회시 User CPU 사용량 100%
    • 프로세스 중에서는 cpu가 1~2% 이상 넘어가는 프로세스가 없었다.
    • 유저별 crontab -l 확인해봤는데 특별한 것이 없었다.

바로 적용하는 CPU 사용하는 프로세서 정지 방법

ntpdate라는 service를 system 데몬에 등록하여 CPU를 사용중이었다.
그래서 CPU 자원을 사용중인 프로세스에 조회가 안되었나 싶다

$ systemctl status ntpdate

ntpdate.service - ntpdate
   Loaded: loaded (/etc/systemd/system/ntpdate.service; disabled; vendor preset: disabled)
   Active: active (running) since Tue 2022-08-30 10:27:34 KST; 9s ago
  Process: 26144 ExecStart=/bin/entpdate (code=exited, status=0/SUCCESS)
 Main PID: 26169 (busybox)
   CGroup: /system.slice/ntpdate.service
           └─26169 kthreadd

Aug 30 10:27:34 server1 systemd[1]: Starting ntpdate...
Aug 30 10:27:34 server1 systemd[1]: Started ntpdate.

**$ systemctl stop ntpdate
$ systemctl disable ntpdate**
$ systemctl status ntpdate
● ntpdate.service - ntpdate
   Loaded: loaded (/etc/systemd/system/ntpdate.service; disabled; vendor preset: disabled)
   Active: inactive (dead)

Aug 30 10:27:34 server1  systemd[1]: Starting ntpdate...
Aug 30 10:27:34 server1  systemd[1]: Started ntpdate.
Aug 30 10:27:57 server1  systemd[1]: Stopping ntpdate...
Aug 30 10:27:57 server1  systemd[1]: Stopped ntpdate.

 

완전히 삭제해보자

  • 트로이목마가 작동하는 곳은 꽤나 여러곳에 등록이 되어있었다.
  • 아래 리스트를 삭제하면 된다
**/etc/init.d/ntpdate
/etc/rc.d/rc0.d/K60ntpdate -> /etc/init.d/ntpdate
/etc/rc.d/rc2.d/S90ntpdate -> /etc/init.d/ntpdate
/etc/rc.d/rc6.d/K60ntpdate -> /etc/init.d/ntpdate
/etc/rc.d/rc3.d/S90ntpdate -> /etc/init.d/ntpdate
/etc/rc.d/rc1.d/K60ntpdate -> /etc/init.d/ntpdate
/etc/rc.d/rc4.d/S90ntpdate -> /etc/init.d/ntpdate
/etc/rc.d/rc5.d/S90ntpdate -> /etc/init.d/ntpdate

/etc/cron.d/ntpdate
/etc/cron.hourly/ntpdate
/etc/cron.daily/ntpdate
/etc/cron.weekly/ntpdate
/etc/cron.monthly/ntpdate

/etc/systemd/system/ntpdate.service
/usr/lib/systemd/system/ntpdate.service

/bin/ntpdate 
/bin/entpdate
/bin/lntpdate
/bin/busybox

/bin/crondr
/bin/sysdr
/bin/initr

## 이 아래는 ntpdate로 위장한 트로이목마가 아니라 
## ntp와 같이 설치되는 것이니 삭제하지 말 것!**
~~/var/lib/yum/yumdb/n/d40942ab713f3ddb558371615aef2dacb75748fc-ntpdate-4.2.6p5-29.el7.centos.2-x86_64
/usr/share/doc/ntpdate-4.2.6p5/
/usr/share/doc/ntpdate-4.2.6p5/COPYRIGHT
/usr/share/man/man8/ntpdate.8.gz
/usr/sbin/ntpdate
/usr/libexec/ntpdate-wrapper
/etc/sysconfig/ntpdate~~  <- 살짝 햇갈림..

아래 처럼 삭제가 안되는 경우 아래와 같이 시도해보자

$ rm /bin/sysdr -f
rm: cannot remove ‘/bin/sysdr’: Operation not permitted

$ lsattr /bin/sysdr
----ia-------e-- sysdr
$ chattr -ia /bin/sysdr
$ lsattr /bin/sysdr
-------------e-- sysdr

$ rm /bin/sysdr -f

systemd 밑에 service 파일을 지운 후 daemon을 reload를 해준다

$ systemctl daemon-reload

 


 

트로이목마(ntpdate)의 구조를 정리해보자

어떻게 동작하는지 궁금해서 이것저것 까보면서 정리했다

  • 세 가지에 등록되어 있으며 - init.d / cron.d / systemd
  • 어떻게든 하나 죽어도 다시 살리겠다는 의지가 강하더라..
  • 한 개 발견하여 삭제하여도 계속 실행될 가능성이 높다.

systemd에 등록된 스크립트 확인

$ cat /etc/systemd/system/ntpdate.service 

[Unit]
Description=ntpdate

Wants=network.target
After=syslog.target network-online.target

[Service]
Type=forking
ExecStart=**/bin/entpdate**
Restart=always
KillMode=process

[Install]
WantedBy=multi-user.target
  • systemctl에 등록된 start는 entpdate를 수행하였다.

entpdate의 내용

  • bin 경로의 sysdr을 busybox로 복사하여 수행
  • 그리고 busybox를 삭제해버린다
  • 참고로 sysdr은 binary화 된 파일이어서 내용 확인이 어려웠다.
$ cat /bin/entpdate

#!/bin/bash
cd /bin
cp -f -r -- sysdr busybox 2> /dev/null
./busybox -c   >/dev/null 2>&1
rm -rf -- busybox 2> /dev/null

/usr/lib/systemd에 등록된 스크립트 확인

  • entpdate 대신 lntpdate를 사용하는 것 이외에 다른점이 없었다.
  • systemd와 크게 차이는 없었다.
$ cat /usr/lib/systemd/system/ntpdate.service

[Unit]
Description=ntpdate

Wants=network.target
After=syslog.target network-online.target

[Service]
Type=forking
ExecStart=**/bin/lntpdate**
Restart=always
KillMode=process

[Install]
WantedBy=multi-user.target
$ cat /bin/lntpdate

#!/bin/bash
cd /bin
cp -f -r -- sysdr busybox 2> /dev/null
./busybox -c   >/dev/null 2>&1
rm -rf -- busybox 2> /dev/null

/etc/cron.d/ntpdate 내용 확인

## 아래 파일의 내용은 모두 같음
/etc/cron.d/ntpdate
/etc/cron.hourly/ntpdate
/etc/cron.daily/ntpdate
/etc/cron.weekly/ntpdate
/etc/cron.monthly/ntpdate

$ cat /etc/cron.d/ntpdate
#!/bin/bash
	cd /bin
	cp -f -r -- crondr busybox 2> /dev/null
	./busybox -c   >/dev/null 2>&1
	rm -rf -- busybox 2> /dev/null
  • bin 경로의 crondr을 busybox로 복사하여 수행
  • 그리고 busybox 삭제

/etc/init.d/ntpdate 내용 확인

  • sysdr이나 crondr 대신 initr을 사용중이었다.
## 아래 파일은 모두 symlink로 /etc/init.d/ntpdate를 바라보고 있었다.
/etc/rc.d/rc0.d/K60ntpdate -> /etc/init.d/ntpdate
/etc/rc.d/rc2.d/S90ntpdate -> /etc/init.d/ntpdate
/etc/rc.d/rc6.d/K60ntpdate -> /etc/init.d/ntpdate
/etc/rc.d/rc3.d/S90ntpdate -> /etc/init.d/ntpdate
/etc/rc.d/rc1.d/K60ntpdate -> /etc/init.d/ntpdate
/etc/rc.d/rc4.d/S90ntpdate -> /etc/init.d/ntpdate
/etc/rc.d/rc5.d/S90ntpdate -> /etc/init.d/ntpdate

$ cat /etc/init.d/ntpdate
#!/bin/bash
#
# ntpdate          Start/Stop the ntpdate clock daemon.
#
# chkconfig: 2345 90 60
# description: ntpdate service
cd /bin
cp -f -r -- initr busybox 2> /dev/null
./busybox -c   >/dev/null 2>&1
rm -rf -- busybox 2> /dev/null

sysdr, initr, crondr, busybox는 모두 같은 파일이었다.

  • 용량도 모두 같았다.
$ cd /bin
$ ls -alrt 
..
-rwxr-xr-x    1 root root    2015472 Aug 30 11:10 busybox
-rwxr-xr-x    1 root root    2015472 Jul 23 18:28 sysdr
-rwxr-xr-x    1 root root    2015472 May 12  2015 initr
-rwxr-xr-x    1 root root    2015472 Jul 23 18:28 crondr

 

 

왜 트로이목마에 당했나?

  1. 개인 테스트 서버라서 firewall에 IP를 0.0.0.0으로 오픈하였고
  2. user의 passwd를 username으로 해버렸기 때문이 가장 크다.

막을 수 있는 보안 방법

이거 찾으려고 이틀을 고생하였으니, 미리 보안을 철저히 하면 좋을 것 같다. 참고로 ssh 포트는 22번 포트가 아닌 다른 포트로 바꿔서 사용중이었다.

  • 접속하는 client의 IP만 open하기
  • user와 passwd 동일하게 하지 않기   <- 여기까진 꼭 해주길
  • key를 사용하면 더욱 좋을 듯 

아래는 특정 IP에서 ssh 연결 거부된 user 목록이다. 트로이 목마 공격을 할 때, 아래 user들로 접속을 시도하는 것 같다.

user     ssh:notty    [IP or Host] Sat Aug 20 19:03 - 19:03  (00:00)    
user     ssh:notty    [IP or Host] Sat Aug 20 19:03 - 19:03  (00:00)    
root     ssh:notty    [IP or Host] Sat Aug 20 19:03 - 19:03  (00:00)    
smos     ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
smos     ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
smos     ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
smos     ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
minersta ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
minersta ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
mos      ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
mos      ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
hive     ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
hive     ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
wang     ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
wang     ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
ypsm     ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
ypsm     ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
wang     ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
wang     ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
user     ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
user     ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
root     ssh:notty    [IP or Host] Sat Aug 20 19:02 - 19:02  (00:00)    
zabbix   ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
weblogic ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
redmine  ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
tomcat   ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
report   ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
lsfadmin ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
tibero1  ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
zabbix   ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
ubuntu   ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
ubuntu   ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
weblogic ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
redmine  ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
tomcat   ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
report   ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
lsfadmin ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)
tibero  ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
tibero1  ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
oracle  ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
oracle1  ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
ubuntu   ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
postgres ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
postgres ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
demo     ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
postgres ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
ubuntu   ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
user     ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
demo     ssh:notty    [IP or Host] Fri Aug 19 00:53 - 00:53  (00:00)    
oracle1  ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
postgres ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
demo     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
postgres ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
postgres ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
user     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
demo     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
demo     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
demo     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
demo     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
demo     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
demo     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
demo     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
demo     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
demo     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
demo     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
demo     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
demo     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
demo     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
test     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
dell     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
spark    ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
test     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
spark    ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
dell     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
root     ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
username ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)    
username ssh:notty    [IP or Host] Fri Aug 19 00:52 - 00:52  (00:00)
Comments