리눅스 해킹사고 분석 및 대응절차

by 조쉬 posted Feb 27, 2014
?

단축키

Prev이전 문서

Next다음 문서

ESC닫기

크게 작게 위로 아래로 댓글로 가기 인쇄
리눅스 해킹 사고시 구체적인 대응방법을 모르는 초보 관리자라면 다음과 같은 절차를 통해서 피해 시스템을 분석하는것도 하나의 도움이 될 수 있다. 실제 해킹된 서버 예를 들어서 아래의 대응 절차를 이용하여 피해 시스템을 분석해 보고 대응 방법을 논의해 보자.

리눅스 해킹 사고 분석 및 대응 절차
1. 해킹 의심 상황 포착
2. 외부에서 nmap 명령어로 포트 스캔
3. chkrootkit, rootkit hunter등으로 명령어 변조와 rootkit 존재 여부확인
4. 해커가 시스템의 권한을 어느정도까지 확보했는지 확인
5. 변조된 파일 복구
6. 시스템 상황 파악 및 백도어 제거
7. 어떤 취약성을 이용하여 권한을 획득하였는지 확인후 취약성 패치 및 대책 수립

1. 해킹 의심 상황 포착 (ls, ps, pstree, netstat, lsattr, find)
해커가 서버를 해킹한 후에는 가능하면 서버의 해킹 흔적을 지우려고 한다. 잡힐 것이 두려워서가 아니라(신문에 보도될 정도의 보안 사고가 아니라면 잡을 방법이 거의 없다.) 힘들게 해킹한 서버를 이용하지 못할지도 모르기 때문이다. 때문에 서버관리자는 사소한 사항에도 주의를 기울여야 한다. 서버의 작동이 이상하다면 자신의 감을 믿고 조사하는것이 나을 때가 있다.
구체적인 해킹 징후를 몇가지 나열한다면 다음과 같다.

시스템 명령어가 이상하게 실행이 되거나 작동이 되지 않을경우
나도 모르게 파일의 퍼미션이 변조되어 있을 경우
ps, pstree, lsof, netstat 명령어로 보았을때 이상한 프로세스나 수상한 포트가 오픈되어 있을 경우
로그파일이 지워져 있거나 로그가 쌓이지 않을 경우
history 명령어로 보았을때 지난 history가 보이지 않을 경우
last, 혹은 w 명령어로 보았을때 수상한 접속기록이 보일 경우
/dev, /var/tmp, /tmp 디렉터리에 수상한 파일이나 디렉터리가 있을 경우

/dev  디렉터리는 다음 명령어로 수상한 파일이나 디렉터리를 찾을 수 있다.
# find /dev -type f
/var/tmp /tmp디렉터리에는 숨김파일이나 디렉터리를 많이 만들므로 확인 할때 점(.)으로 시작하는 파일이나 디렉터리가 있는지 확인해야 한다.

여기서 주의할 점은 해커가 최상의 루트 권한을 얻었을 경우는 바이너리 명령어를 변조해서 ps나 pstree명령어를 이용해서도 수상한 점을 감지하기가 힘들다는 점이다. 이럴경우 미리 바이너리 파일의 변조여부부터 점검해야 한다.

다음은 실제 해킹된 서버의 상황이다. 해당 서버는 특정 실행 파일의 퍼미션 변조와 로그가 쌓이지 않는 증상이 있었다.  로그가 쌓이지 않아 syslogd를 리스타트 했으나 제대로 실행되지 않았다.
# /etc/init.d/syslog restart
Shutting down kernel logger: [ OK ]
Shutting down system logger: [ OK ]
Starting system logger: [FAILED]
Starting kernel logger: [ OK ]

top 명령어가 다음과 같은 에러를 내면서 실행 되지 않는다.
# top
top: error while loading shared libraries: libncurses.so.4: cannot open shared object file: No such file or directory

보통 해커들은  변조된 실행파일들이 다시 바뀌지 않게 해당 명령어에 속성을 걸어 놓는다. lsattr 명령어로 확인 할 수 있다.
# lsattr /usr/bin/top
suS-iadAc---- /usr/bin/top
이 이외에도 lsattr로 확인해 본결과 /bin, /usr/bin, /sbin 디렉터리에  다수의 실행 파일이 변조 된 것을 확인 할 수 있다.

그러나 pstree나 ps, netstat명령어로도 특별한 이상점을 찾을수 없었다. 다만 pstree명령어를 실행시켰을 경우
xinetd로 110번 포트(pop3)를 서비스 하고 있었으나 pstree명령에는 xinetd가 보이지 않았다. 즉 해커는 바이너리 명령어를 변조 시켜 시스템 상황을 숨기고 있는 것이다.
# pstree
init-+-avsms
     |-crond
     |-events/0
     |-httpd---18*[httpd]
     |-khelper
     |-khubd
     |-9*[kjournald]
     |-klogd
     |-kseriod
     |-ksoftirqd/0
     |-kswapd0
     |-kthread-+-aio/0
     |         |-ata/0
     |         |-kacpid
     |         |-kblockd/0
     |         |-2*[pdflush]
     |         `-rpciod/0
     |-5*[mingetty]
     |-minilogd
     |-safe_mysqld---mysqld
     |-scsi_eh_0
     |-scsi_eh_1
     |-scsi_eh_2
     |-scsi_eh_3
     |-secure-mcserv
     |-3*[sendmail]
     |-sendmail---sendmail
     |-snmpd
     |-sshd-+-4*[sshd---bash]
     |      `-sshd---bash---pstree
     |-syslogd
     |-udevd
      `-vsftpd

2. 외부에서 nmap 명령어로 포트 스캔 (nmap, telnet)
일단 해킹된 서버에서는 정확한 정보를 얻을 수 없으니 외부에서 nmap명령어를 통해서 백도어 포트가 열려 있지 않는지 확인해 본다.
# nmap -sT -p 1-65535 타켓서버아이피

21/tcp    open  ftp
22/tcp    open  ssh
25/tcp    open  smtp
80/tcp    open  http
110/tcp   open  pop3
3306/tcp  open  mysql
4482/tcp  open  unknown

정상적인 서비스 포트외에도 4482라는 수상한 포트를 발견할  수 있다.
#telnet 해당서버아이피 4482
telnet 명령어로 한번 접속을 시도해 보자.

Trying xxx.xxx.xxx.xxx...
Connected to xxx.xxx.xxx.xxx
Escape character is '^]'.
SSH-1.5-1.2.25
백도어 프로세스가 현재 서버에 실행중인것을 확인 할 수 있다.

3. chkrootkit, rootkit hunter등으로 명령어 변조와 rootkit 존재 여부확인(rpm, lsattr, chattr)
일반적으로 바이너리 변조나 루트킷 탐지에 많이 사용하는 보안 툴은 chkrootkit과 rootkit hunter가 있다.
다음 url에서 이 두가지  툴을 다운 받을 수 있다.

http://www.chkrootkit.org/
http://www.rootkit.nl/projects/rootkit_hunter.html

여기서는 chkrootkit 을 이용해서 점검해 보았다. 다음과 같이 변조된 바이너리 파일목록을 출력해준다.

Checking `ls'... INFECTED
Checking `lsof'... INFECTED
Checking `mail'... INFECTED
Checking `mingetty'... INFECTED
Checking `netstat'... INFECTED

아래는 rootkit hunter로 검사한 결과이다.
File properties checks...
    Required commands check failed
    Files checked: 128
    Suspect files: 11
Rootkit checks...
    Rootkits checked : 118
    Possible rootkits: 3
    Rootkit names    : Flea Linux Rootkit, SHV4 Rootkit, SunOS Rootkit
Applications checks...
    Applications checked: 6
    Suspect applications: 2

여기서 주의할 점이 있다. 변조가 심한 시스템에서는 chkrootkit아니 rootkit hunter가 제대로 설치가 되지 않거나
동작이 되지 않을 수 있다. 그렇다면 굳이 동작을 시킬려고 하지 말고 다음 단계의 조치를 바로 취해야 한다.

4. 해커가 시스템의 권한을 어느정도까지 확보했는지 확인
한가지 짚고 넘어가야 할 점은 리눅스상에서는 권한 이상의 일은 할 수가 없다는 것이다. 바이너리 파일까지 변조된 것을 확인한 이상 이미 해커는 시스템 최상위 권한을 획득했다는 뜻이므로 가능한 빠른 시간내에 자료 백업 및 시스템 재설치를 서둘러야 한다. 마음만 먹는다면 해커는 서버상의 모든 자료를 파괴할 수 있다.
그렇지 않다면 변조된 파일의 퍼미션이나 돌고 있는 프로세스의 권한을 보고 해커가 어느정도까지 시스템의 권한을 획득했는지 확인하고 조치를 취하면 된다.

슈퍼유저 권한을 빼앗긴것을 확인했다면 가능하면 네트워크를 차단하고 싱글모드에서 복구작업을 하는것이 좋다. 네트워크 차단이 불가능할 경우 iptables같은 방화벽을 통해 엄격한 접근차단 정책을 설정하고 작업을 해야 한다. 시스템 설치가 최선책이나 일단 시간이 걸린다면 다음 단계로 넘어가 시스템을 복구해야 한다.

5. 변조된 파일 복구(rpm, lsattr, chattr, strace)
접근 차단 정책을 설정했으면 해커에 의해 변조된 파일을 복구 시켜야 한다.
변존된 파일은 앞서 루트킷 탐지툴로도 확인이 가능하나 rpm명령으로도 확인 할 수 있다.

# rpm -qf /bin/login
util-linux-2.12a-24.5
먼저 -qf 옵션을 줘서 해당 파일이  어떤 rpm에 속해 있는지 확인한다.
#rpm -qV util-linux-2.12a-24.5
-qV 옵션을 주면 해당 바이너리의 변조 상태를 확인 할수 있다.
S.5..UG.    /bin/login
정상이면 아무런 출력도 없다. 변조가 되었다면 위와 같이 변조된 상태를 출력해 준다.
이제는 변조된 파일을 정상 파일로 교체 해야 한다. 정상적인 rpm을 받아서 덮어 씌워주면 된다. 다음 url에서 정상 rpm을 다운받을수 있다. 리눅스 배포본 별로 rpm을 검색해서 다운 받을 수 있다. 해당 OS에 받는 버전을 다운받아 재설치 한다.

http://rpm.pbone.net/

# rpm -Uvh --force util-linux-2.12a-24.5.i386.rpm
Preparing...                ########################################### [100%]
   1:util-linux             ########################################### [100%]
error: unpacking of archive failed on file /bin/login: cpio: rename failed - Operation not permitted

# lsattr /bin/login
suS-iadAc---- /bin/login
# chattr -suSiadAc /bin/login

--force 옵션을 주어서 재설치 하면 된다. 위에서는 재설치 오류가 나는데, 해커가 변조된 파일을 다시 교체 할수 없게 속성을 걸어 놓은 것이다. lsattr명령으로 확인할 수 있으며 chattr명령으로 해제한후 재 설치 해준다. 이와 같이 변조된 파일을 모두 복구시켜 줘야 한다. 특히 ls, ps, top, syslogd, netstat, ifconfig, pstree 명령어와 ssh, pam, passwd, login등의 인증관련 명령어는 꼼꼼히 살펴야 한다.

6. 시스템 상황 파악 및 백도어 제거(fuser, pstree, lsof, netstat)
앞서 nmap으로 서버에서 실행중인 수상한 포트를 탐지 했으나 실제 해킹된 서버에서는 의심스러운 프로세스나 포트를 탐지 할 수 없었다. ps나 ls, pstree같은 명령어가 변조 되었기 때문이다.
strace를 이용하면 더욱 분명해 진다.
아래와 같이 실행하면 netstat 명령어가 수상한 파일을 참조하고 있다는 것을 알 수 있다.
/usr/include/hosts.h 파일을 한번 보자.
# strace -e trace=open netstat -nlp

open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/lib/tls/libc.so.6", O_RDONLY)    = 3
open("/usr/include/hosts.h", O_RDONLY)  = 3

# cat /usr/include/hosts.h
2 64.228
2 199
2 64
3 7000
4 7000
3 6667
4 6667
2 64.220
2 82.177
2 5412
4 5412
2 81.190
2 81.15
3 6666
4 6666
3 4482
4 4482
위에 적인 포트들은 netstat 명령으로 탐지 할 수 없다. netstat 명령어를 재설치하거나 위에 파일에서 nmap에서 발견한 4482포트를 지워버리면  다음과 같이 백도어 프로세스를 발견 할 수 있다.

tcp        0      0 0.0.0.0:4482                0.0.0.0:*                   LISTEN      1919/xntps

pstree 명령어를 재 설치 하면 이제 백도어 프로세스가 pstree에도 잡힐 것이다.

# strace -e trace=open ls
open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/lib/tls/libc.so.6", O_RDONLY)    = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3
open("/usr/include/file.h", O_RDONLY)   = 3

마찬가지로 ls명령어도  strace로 추적해 보았다.
#cat /usr/include/file.h
.sh
system
tksb
tkp
lblip.tk
tks
ldd.so
srd0
ldlib.5
.config
ld.so.hash
0x88
r00t
synscan
mass_samba
sambal
screen
SCREEN
ss
x
pscan2
go.sh
ssh-scan
gen-pass.sh

file.h에 적힌 해당 파일은 ls명령어로 확인 할 수 없을 것이다.

이제 xntps 백도어 프로세스에 좀 더 관심을 기울여 보자.
 # xntps -?
xntps: invalid option -- ?
sshd version 1.2.25 [i586-unknown-linux]
Usage: xntps [options]
Options:
  -f file    Configuration file (default /lib/security/.config/ssh/sshd_config)
  -d         Debugging mode
  -i         Started from inetd
  -q         Quiet (no logging)
  -p port    Listen on the specified port (default: 22)
  -k seconds Regenerate server key every this many seconds (default: 3600)
  -g seconds Grace period for authentication (default: 300)
  -b bits    Size of server RSA key (default: 768 bits)
  -h file    File from which to read host key (default: /lib/security/.config/ssh/ssh_host_key)
  -V str     Remote version string already read from the socket

xntps ntp 서비스를 위한 데몬이나 여기서는 sshd 프로세스로 바꿔치기 되어 있다.

# cat  /lib/security/.config/ssh/sshd_config
Port 4482
ListenAddress 0.0.0.0
ServerKeyBits 768
LoginGraceTime 600
KeyRegenerationInterval 3600
PermitRootLogin yes
IgnoreRhosts no
StrictModes yes
QuietMode no
X11Forwarding no
X11DisplayOffset 10
FascistLogging no
PrintMotd yes
KeepAlive yes
SyslogFacility DAEMON
RhostsAuthentication no
RhostsRSAAuthentication yes
RSAAuthentication yes
PasswordAuthentication yes
PermitEmptyPasswords yes
UseLogin no

이로써  ssh 백도어 프로세스 인것이 확실시 된다. 4482로 포트를 이용해 sshd 데몬을 하나 더 실행 시킨것이다. 이러한 백도어는 시스템 재부팅시 자동으로 실행 되도록 해놓은 경우가 많으므로 주의 해야 한다. 크론(/var/spool/cron/
)이나 시스템 시작 스크립트에 자동시작 명령이 설정되어 있지 않은지 주의해야 한다. 여기서는 rc.sysinit에 숨겨져 있었다.
# cat /etc/rc.d/rc.sysinit

# Xntps (NTPv3 daemon) startup..
/usr/sbin/xntps -q


7. 어떤 취약성을 이용하여 권한을 획득하였는지 확인후 취약성 패치 및 대책 수립 (tripwire)
다시한번 강조하지만 리눅스에서는 권한이상의 일을 할 수 없다는 것을 향상 명심해야 한다. 침해 사고를 당한 시스템을 분석 할때는 해당 시스템이 웹서버 권한을 얻었는지 혹은 일반 유저권한을 획득했는지 파악하고 이에 대비 해야 한다.

위에서 설명한 피해 서버는 이미 해커가 슈퍼유저권한을 획득한 상황이기 때문에 가능한 빠른시간내에 시스템을 재설치 해야 하는 상황이다.

최근에 발표된 리눅스 커널 취약점은 CVE-2009-2692 이 있다. 해당 서버는 취약점 패치를 하지 않았을 뿐만 아니라 루트 사용자에 대한 엄격한 접근통제를 적용하고 있었으므로 커널 취약점을 통해 슈퍼 유저권한을 얻은후 해킹 흔적을 지우고 백도어를 설치 한것으로 보인다.

리눅스 커널 취약점은 어지간해서는 잘 나오지 않는다. 그러나 한번 발견 될 경우 빠른 시간내에 조치를 취하지 않으면 그 피해가 커질 수 있으므로 리눅스 시스템 관리자는 향상 주의를 기울여야 한다. 미처 조치를 취하기도 전에 해킹을 당할 수도 있으므로 tripwire와 같은 파일 시스템 무결성을 점검해 주는 보안툴을 미리 설치해 운영하거나 중요한 바이너리 파일은 주기적으로 백업해 놓아야 한다.

이상으로 리눅스 침해사고 대응법을 마치고 다음에는  tripwire를 이용한 파일시스템의 무결성 점검에 대해 다루어 보겠다