더 구체적 내용은 아래 링크 KLDP 문서 참조:
http://wiki.kldp.org/wiki.php/DocbookSgml/ChrootAPM



예전에 tip&tech 에 올린 글 중에 제 서버에 올려놓은 파일로
링크걸어놓은 것이 몇건 있었는데요. 접속이 안된다고 메일 주신 분들이 몇분 계십니다.


제 서버가 해킹당해서 웹서비스를 내려놓은 상태입니다. ㅠ.ㅠ
이놈저놈 많이도 와서 한것 같은데 완전 다시까는 수밖에 없다는 생각입니다.


제일 짜증나는 넘이 제로보드 헛점을 타고 들어와서 /tmp 에 perl 스크립트 올려놓고
스팸메일 보내는 브라질 넘들입니다.(회사 서버도 한번 당했습니다. ㅠ.ㅠ)


근데 회사에 매인 몸이다보니 시간도 여의치 않고,
한번 이렇게 당하고 보니 대충 해선 안되겠다는 생각에
보다 안전한 서버 구성에 대해서 생.각.만 하고 있는 중입니다.
(나중에 구현이 완료되면 실전 세팅도 정리해서 올리도록 하겠습니다.)


주로 chroot 에 기반한 방법을 생각중입니다.(예전에도 한번 해본적이 있다보니)
세련된 방법은 아니지만 unix 역사상 오랬동안 사용되온 방법이고
상당한 효과를 거둘수 있는 방법이라고 생각합니다.


초기 설정시에 노가다성 작업은 많지만, 약간의 개념만 잡고 있으면 도전해 볼 만하구요.
또 설정해 가는 과정에서 unix 동작 방식에 대해서 많은 것을 배우게 됩니다.
어떤 파일이 어떤데 쓰이는 것인가 하는 것을 말이죠..


selinux 도 관심을 가지고 봤는데 아직 너무 새로운 놈이라 자료도 별로 없고..
보안 모델 등 개념 자체부터 상당히 복잡해서 실전에 적용하기가 쉽지 않네요.


추가/딴지 등 좋은 의견이 있으면 리플달아주시면 감사겠습니다.


아래 내용을 이해하시려면 chroot 개념과 jail 구성하는 방법에 대한 이해가
있어야 될것입니다. 참고 링크로 마땅한게 별로 없네요.. 죄송


1. 시스템 공격 시나리오 및 대책


1.1. 공격 단계


1) 웹 스크립트, 서비스 데몬의 버그를 이용 공격
2) 해킹 툴 업로드/설치
3) 해킹 툴을 이용하여 시스템 권한 취득
4) 백도어 설치(숨겨진 Process, 계정 생성 등)
5) 무언가 관리자가 원하지 않는 작업을 수행
6) 증거인멸(로그 파일 삭제)


※ 요즘 가장 흔한 공격/침투 경로입니다.
※ '무언가 관리자가 원하지 않는 작업'은 시스템/데이터 파괴,
   다른 서버 해킹(중계거점), 비밀데이터 유출, 스팸메일 발송 등등


2.2. 단계별 방어 대책


1) 웹 스크립트, 서비스 데몬의 버그를 이용 공격


대책: 최대한 주의를 기울이고 부지런해야 한다는 말밖에는…


– 웹사이트 개발 시점부터 스크립트(특히 PHP) 보안 검토 철저
– 보안 뉴스를 확인하고 시스템 업데이트 철저히 관리
– 외부에서 접속이 꼭 필요 없는 서비스는 죽이거나 방화벽 등을 이용하여 차단한다.


2) 해킹 툴 업로드/설치


대책: CHROOT 환경 구성


– jail 안에서는 개발 도구(perl, 컴파일러)를 사용 못하게 함


※ 대부분의 해킹 툴이 C 또는 perl로 되어있음.
   perl 과 C언어(gcc)는 일단 시스템에 들어오기만 하면 바로 해커들의 무기가 되므로
   설치여부를 신중하게 고려해야 한다.
※ 웹서비스용 jail 은 대부분 php, java 등이 있어야 하고,
   메일 서비스용 jail 은 perl 이 필요하다.(대부분의 메일 관련 툴들이 perl 을 필요로 하기 때문에)
   이처럼 대부분 프로그램 언어 설치가 불가피하지만 최대한 제거하도록 노력할 필요가 있다.
   예를들면 cli용 php 바이너리는 jail 안에는 설치하지 않고
   jail 밖에서만 사용할 수 있도록하면 php 스크립트를 실행하려고 해도
   웹서버를 통해야 하므로 nobody 권한 밖에 가질 수 없다.


3) 해킹 툴을 이용하여 시스템 권한 취득


대책: CHROOT 환경 구성


– 시스템 권한을 취득하더라도 해당 jail 안에 묶어놓을 수 있다.
  다른 jail 이나 전체 파일시스템에 접근할 수 없다.


4) 백도어 설치(숨겨진 Process, 계정 생성 등)


대책: CHROOT 환경 구성


– 프로세스를 숨긴다는 것은 관리자가 ps 명령으로 확인할 때 표시되지 않는다는 것을 의미한다.
  이렇게 하기위해서는 ps 프로그램을 해킹 프로세스를 숨기도록 수정된 버전으로 교체해야 한다.
  (그리고 netstat -a 를 했을 때 LISTEN 포트가 나오지 않도록 netstat 명령을 교체해야 한다.)
– root 권한까지 취득했다면 /bin/ps 를 교체할 수 있다. 그러나 chroot 환경에서는
  jail 안에 /bin/ps 가 있을리도 없고, 관리자가 사용하는 것은 jail 외부의 /bin/ps 이므로 안심.
– 혹은 대담하게도 계정을 생성(/etc/passwd를 수정)하고 telnet 또는 ssh 접속을 하려 할 수도 있다.
– 그러나 telnet/ssh 서비스는 jail 외부에서 실행되므로 jail 안의 /etc/passwd 를 수정해 봤자 소용이 없다.


※ [참고] 해킹 당한 서버에 교체된 주요 명령들. ㅠ.ㅠ (소유자가 root 가 아님. 해커가 생성한 계정은 삭제했음)
   아래의 교체 당한 명령의 결과는 신뢰할 수 없다.


root@thrall:~]# find /bin -nouser -exec ls -l {} \;
-rwxr-xr-x   1 122      114         54152 Feb 11  2003 /bin/netstat
-rwxr-xr-x   1 122      114         39696 Feb 19  2003 /bin/ls
-rwxr-xr-x   1 122      114         62920 Feb 20  2003 /bin/ps
root@thrall:~]# find /usr/bin -nouser -exec ls -l {} \;
-rwxr-xr-x   1 122      114         12340 Jan 25  2003 /usr/bin/pstree
-rwxr-xr-x   1 122      114         59536 Jan 25  2003 /usr/bin/find
-rwxr-xr-x   1 122      114         39696 Feb 19  2003 /usr/bin/dir
-rwxr-xr-x   1 122      114         31452 Feb 19  2003 /usr/bin/md5sum
-rwxr-xr-x   1 122      114         33992 Feb 20  2003 /usr/bin/top
-rwxr-xr-x   1 122      114         23560 Feb 20  2003 /usr/bin/slocate


위 명령들을 사용하지 않고 숨겨진 프로세스를 확인하는 방법은 /proc 디렉토리를 사용한다.


cd /proc
for p in *; do \
    if [ -f $p/cmdline ]; then \
        if ps ax | egrep -q "^ *$p "; then \
            echo $p: `cat $p/cmdline`; \
        else \
            echo $p: HINNEN: `cat $p/cmdline`; \
        fi; \
    fi; \
done


5) 관리자가 원하지 않는 작업을 수행


대책: CHROOT 환경 구성


– jail 안에는 해당 서비스와 관계 없는 파일은 최대한 제거하여
  별로 할 수 있는 것이 없도록 해야 한다.


※ 몇가지 예를들면..
telnet, ssh 등 네트워크 접속 툴을 jail 안에 두지 않으면
다른 서버로 접속할 수 없으므로 해킹 중계 거점으로 사용할 수 없다.
(perl, php, java 등은 네트워크 기능이 있으므로 가능할수도 있다. ㅠ.ㅠ)
웹사이트에서 메일보내는 기능이 필요 없다면 웹 jail 에서 /usr/bin/sendmail 을 제거할 수 있다.
그러면 웹 jail을 공격해서 뚫었다고 하더라도 sendmail 이 없으므로 스팸메일을 발송할 수는 없다.


6) 증거인멸(로그 파일 삭제)


대책: CHROOT 환경 구성


– 시스템 로그는 syslogd 에 의해서 jail 외부에 쌓이므로 jail 안에서는 로그를 지울 수 없다.


2. CHROOT 를 이용한 시스템 구성 방안


※ 전체적으로 아직은 구상 수준입니다.


2.0. 요구사항


– MySQL 4.0
– MySQL 4.1
– Apache 1.3
– PHP 4
– PHP 5
– J2SE 1.4
– J2SE 5
– Tomcat 5
– Postfix
– Cyrus IMAP
– BIND 9


※ 특정한 서비스를 위한것이 아니라 개인용 서버라 이것저것 다 깔 계획입니다.
※ 참고로 말씀드리면 우리나라에 많이 소개되지는 않은 조합입니다만..
   저는 메일서비스에 postfix + cyrus-imapd 조합을 즐겨 사용하는데
※ 특히 cyrus는 여러가지 이점이 많습니다. 가장 중요한 점이 기본적으로 시스템 계정을
   사용하지 않고 별도의 계정을 사용한다는 것입니다.
   qmail이 보안이 우수하다고 하지만 Maildir이 홈디렉토리가 있어야 하므로
   누군가에게 메일서비스를 제공하기 위해서는 시스템 계정을 발급해야 합니다.
   (복잡하게 패치하고 설정하면 가상계정이나 MySQL 등으로 서비스가 가능은 하겠지만요..)
   cyrus 는 메일 아이디/비밀번호가 유출되어도 시스템 계정이 아니므로
   시스템 접근이 불가능합니다. 그 사람 메일만 볼 수 있을 뿐이죠.
   또한 기본적으로 가상 계정이므로 MySQL 이나 다른 DB와 연동해서
   사용자 관리할 수 있게 구성하기가 쉽습니다.


2.1. 디렉토리 구성


/
    chroot/
        bin/                                # chroot utilities
        www1/                               # 웹서비스용 jail #1
            home/
                yidigun.com/                # ~yidigun (virtual host user)
            www1/                           # apache2, php5, tomcat5
        www2/                               # 웹서비스용 jail #2
            home/
                yscript.com/                # ~yscript (virtual host user)
            www2/                           # apache13, php4, tomcat4
        mail/                               # 메일 서비스용 jail
            mail/                           # postfix, cyrus-imapd
            var/
                spool/
                    postfix/
                    cyrus/
                    imap/
        named/                              # DNS 서비스용 jail
            named/                          # bind 9
            var/
                named/
    data/
        mysql/                              # mysql data files
            mysql40/
            mysql41/
    home/
        dagui/                              # ~dagui (non chroot user)
        yidigun.com@ -> /chroot/www1/home/yidigun.com/
        yscript.com@ -> /chroot/www2/home/yscript.com/
    tmp/
        mysql.sock=
    usr/
        local/
            mysql@ -> mysql41/
            mysql40/                        # mysql 4.0
            mysql41/                        # mysql 4.1
            www0/                           # apache 2 (static, proxy)
            www1/                           # apache2, php5, tomcat5
            www2/                           # apache13, php4, tomcat4
    var/
        named@ -> /chroot/named/var/named/
        spool/
            postfix@ -> /chroot/mail/var/spool/postfix/
            cyrus@ -> /chroot/mail/var/spool/cyrus/
            imap@ -> /chroot/mail/var/spool/imap/
    www0@ -> usr/local/www0/
    www1@ -> usr/local/www1/
    www2@ -> usr/local/www2/
    mail@ -> chroot/mail/mail/
    named@ -> chroot/named/named/


※ 파일 이름 뒤의 /(directory), @(symbolic link), |(named pipe), =(socket) 등의 기호는
   ls -F 할때 나오는 것입니다. (ls 매뉴얼 참조)
※ 잘 아시겠지만 /bin, /lib, /usr/bin, /usr/lib, /dev, /etc, /tmp 등은
   각각의 jail 에도 기본적으로 필요합니다.(너무 당연한 것은 생략함)
※ apache, php 등 서비스용 프로그램을 jail 의 내부와 외부에 /www1 에 중복해서
   설치하는 것, /home 밑에 링크를 거는 것 등의 이유는
   jail 내부나 외부나 파일의 위치가 동일하게 하기 위함입니다.
※ apache, php 등을 설치할 때 /usr/local/www1 에는 전체 패키지를 설치하고
   /chroot/www1/www1 에는 웹서버 실행시 필요한 것만 설치합니다.
   (cli php 실행파일, include 파일, *.a 파일 등등은 제거함)


2.2. 공격 가능 경로


2.2.1. TCP/IP port


Port                        Service         ROOT
TCP
    0.0.0.0:21              proftpd         /
    0.0.0.0:22              ssh             /
    0.0.0.0:80              apache(http)    /
    0.0.0.0:443             apache(https)   /
    0.0.0.0:53              named(domain)   /chroot/named
    0.0.0.0:25              postfix(smtp)   /chroot/mail
    0.0.0.0:60025           postfix(smtp)   /chroot/mail
    0.0.0.0:110             cyrus(pop3)     /chroot/mail
    0.0.0.0:995             cyrus(pop3s)    /chroot/mail
    0.0.0.0:143             cyrus(imap)     /chroot/mail
    0.0.0.0:993             cyrus(imaps)    /chroot/mail
    127.0.0.1:3306          mysql(4.1)      /
    127.0.0.1:53306         mysql(4.0)      /
    127.0.0.1:953           named(rndc)     /chroot/named
    127.0.0.1:50080         apache(http)    /chroot/www1
    127.0.0.1:50081         tomcat(ajp)     /chroot/www1
    127.0.0.1:60080         apache(http)    /chroot/www2
    127.0.0.1:60081         tomcat(ajp)     /chroot/www2
UDP
    0.0.0.0:123             ntpd            /
    0.0.0.0:53              named(domain)   /chroot/named


※ ROOT는 서비스 데몬 프로세스가 인식하는 / 디렉토리입니다.
   즉, 해커가 Service에 있는 데몬을 통해서 시스템 권한을 취득했을 때
   해당 디렉토리 이하가 위험해진다는 것입니다.


2.2.2. 열린 unix 소켓 또는 named pipe


Socket                                  Service     ROOT
/
    dev/log=                            syslogd     /
    tmp/
        mysql.sock=                     mysql(4.1)  /
        mysql-40.sock=                  mysql(4.0)  /
    chroot/
        named/
            dev/log=                    syslogd     /
        mail/
            dev/log=                    syslogd     /
            var/
                imap/socket/lmtp=       cyrus       /chroot/mail
                saslauthd/mux=          saslauthd   /
                spool/postfix/
                    private/
                        bounce=         postfix     /chroot/mail
                        bsmtp=          postfix     /chroot/mail
                        cyrus=          postfix     /chroot/mail
                        defer=          postfix     /chroot/mail
                        error=          postfix     /chroot/mail
                        ifmail=         postfix     /chroot/mail
                        lmtp=           postfix     /chroot/mail
                        local=          postfix     /chroot/mail
                        maildrop=       postfix     /chroot/mail
                        old-cyrus=      postfix     /chroot/mail
                        proxymap=       postfix     /chroot/mail
                        relay=          postfix     /chroot/mail
                        rewrite=        postfix     /chroot/mail
                        smtp=           postfix     /chroot/mail
                        uucp=           postfix     /chroot/mail
                        virtual=        postfix     /chroot/mail
                    public/
                        cleanup=        postfix     /chroot/mail
                        flush=          postfix     /chroot/mail
                        pickup|         postfix     /chroot/mail
                        qmgr|           postfix     /chroot/mail
                        showq=          postfix     /chroot/mail
        www1/
            dev/log=                    syslogd     /
        www2/
            dev/log=                    syslogd     /


※ postfix 는 내부적으로 unix socket을 많이 사용합니다. ^^
※ unix domain socket이나 named pipe는 일단 네트워크를 통해 접속할 수는 없으므로
   (로컬에서만 접근 가능하므로) TCP/IP 포트보다는 덜 중요하지만,
   일단 해커가 어떤 jail 침투에 성공한다면
   다른 jail 이나 전체 시스템으로 침투하는 경로가 될 수 있습니다.


0.0.0.0:80 (php)                        PHP 스크립트 헛점을 이용, www1 jail 침입.
    127.0.0.1:953 (rndc)                BIND 9 버그를 공격 named jail 침입
                                        (127.0.0.1으로 접속 가능)
    /chroot/www1/dev/log= (syslogd)     syslogd 버그를 이용하여 /(전체 시스템)에 침입
                                        (로컬 파일시스템 접속 가능)


※ syslogd 나 BIND 9 가 버그가 있어서 바로 뚫린다는 말은 아닙니다.
   (언젠가 잠재되어 있던 버그가 발견되서 그렇게 될 가능성이 있다는 말이죠.)
※ 하나의 jail 이 뚫리면 간단하지는 않지만 다른 jail 이나
   시스템 전체로 진출할 가능성이 아예 없는 것은 아니란 점을 주의해야 함.



   pppp    05-07-23 04:57  
http://doc.kldp.org/wiki.php/DocbookSgml/ChrootAPM


좀더 상세한 논의및 토론이 있으면 좋겠네요. 
 
<TEXTAREA id="save_comment_41503" style="DISPLAY: none">http://doc.kldp.org/wiki.php/DocbookSgml/ChrootAPM 좀더 상세한 논의및 토론이 있으면 좋겠네요.</TEXTAREA>
 
   이대규    05-07-23 05:25  
안그래도 아까 kldp도 찾아볼라고 했었는데..
kldp 에 무슨 문제가 있는건지 저희사무실에서는 도무지 접속인 안되네요.. 
 
<TEXTAREA id="save_comment_41504" style="DISPLAY: none">안그래도 아까 kldp도 찾아볼라고 했었는데.. kldp 에 무슨 문제가 있는건지 저희사무실에서는 도무지 접속인 안되네요..</TEXTAREA>
 
   낭망백수    05-07-23 09:49  
혹시 jail 링크는  없나요? 꾸벅~! 
 
<TEXTAREA id="save_comment_41505" style="DISPLAY: none">혹시 jail 링크는 없나요? 꾸벅~!</TEXTAREA>
 
   이대규    05-07-23 11:06  
그러니까 jail 은 chroot 로 만들어진 격리된 공간입니다.
(영어로 감옥이란 뜻입니다.) 다른 말로 샌드박스라고도 한다더군요.
하지만 대부분의 chroot 와 관련된 문서를 보면 항상 chroot jail 이라고 표현을 하더군요. 
 
<TEXTAREA id="save_comment_41506" style="DISPLAY: none">그러니까 jail 은 chroot 로 만들어진 격리된 공간입니다. (영어로 감옥이란 뜻입니다.) 다른 말로 샌드박스라고도 한다더군요. 하지만 대부분의 chroot 와 관련된 문서를 보면 항상 chroot jail 이라고 표현을 하더군요.</TEXTAREA>
 
   석이    05-07-24 12:57  
리눅스 책에 다 나오는 내용 입니다. 책 한번 보시면 심도있게 볼 수 있을것도 같은데요 ^^ 
 
<TEXTAREA id="save_comment_41507" style="DISPLAY: none">리눅스 책에 다 나오는 내용 입니다. 책 한번 보시면 심도있게 볼 수 있을것도 같은데요 ^^</TEXTAREA>
 
   하하하    05-07-24 18:56  
여기에 더해서 root권한으로도 특정 작업이나 특정 파일접근을 못하도록 하는 LIDS도 있습니다. LIDS는 커널 기반의 IDS입니다. 
 
<TEXTAREA id="save_comment_41508" style="DISPLAY: none">여기에 더해서 root권한으로도 특정 작업이나 특정 파일접근을 못하도록 하는 LIDS도 있습니다. LIDS는 커널 기반의 IDS입니다.</TEXTAREA>
 
   aa    05-07-25 09:55  
하여간 저노무 bind랑 sendmail은 너무 자주 뚫리는듯한 느낌.
qmail이랑 djbdns는 한결 마음이 가볍네요 
 
<TEXTAREA id="save_comment_41509" style="DISPLAY: none">하여간 저노무 bind랑 sendmail은 너무 자주 뚫리는듯한 느낌. qmail이랑 djbdns는 한결 마음이 가볍네요</TEXTAREA>
 
   질문    05-07-27 14:36  
위 명령들을 사용하지 않고 숨겨진 프로세스를 확인하는 방법은 /proc 디렉토리를 사용한다.


cd /proc
for p in *; do \\
    if [ -f $p/cmdline ]; then \\
        if ps ax | egrep -q \"^ *$p \"; then \\
            echo $p: `cat $p/cmdline`; \\
        else \\
            echo $p: HINNEN: `cat $p/cmdline`; \\
        fi; \\
    fi; \\
done
—————————————–
위에파일이 어떻게 사용하는거죠 일일이 치는건 아닐테고
gcc로 컴파일해서 사용하는건가요?? 
 
<TEXTAREA id="save_comment_41510" style="DISPLAY: none">위 명령들을 사용하지 않고 숨겨진 프로세스를 확인하는 방법은 /proc 디렉토리를 사용한다. cd /proc for p in *; do \\ if [ -f $p/cmdline ]; then \\ if ps ax | egrep -q \"^ *$p \"; then \\ echo $p: `cat $p/cmdline`; \\ else \\ echo $p: HINNEN: `cat $p/cmdline`; \\ fi; \\ fi; \\ done —————————————– 위에파일이 어떻게 사용하는거죠 일일이 치는건 아닐테고 gcc로 컴파일해서 사용하는건가요??</TEXTAREA>
 
   이대규    05-07-28 02:29  
일일이 치는 겁니다.^^
/proc 디렉토리를 사용하면 된다는 일종의 아이디어를 제시하기 위한 거구요. 실전에선 입맛에 맞게 손맛에 맞게 쓰시면 됩니다. 
 
<TEXTAREA id="save_comment_41511" style="DISPLAY: none">일일이 치는 겁니다.^^ /proc 디렉토리를 사용하면 된다는 일종의 아이디어를 제시하기 위한 거구요. 실전에선 입맛에 맞게 손맛에 맞게 쓰시면 됩니다.</TEXTAREA>
 
   Konami    05-08-05 10:20  
저도 브라질놈들에게 당했습니다. 커커커
tmp 폴더에 perl스크립트 돌려서 ..
모든 명령을 무력화해버리고
하루에 8만통씩 스팸을 날려버리더군여.. -_-; 

chroot, jail 프로젝트 관련 글

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다