98..Etc/Security2008. 7. 24. 11:49
반응형

TCP Wrapper (source: 카이스트)

 

initAd();


1. What's TCP Wrapper ?
2. Why TCP Wrapper is used ?
3. How does it work?
4. How to install and use TCP Wrapper
5. Reference



 1. What's TCP Wrapper.

 TCP Wrapper 란 현재의 시스템에서 SYSTAT, FINGER, FTP, TELNET, RLOGIN, RSH, EXEC, TFTP,TALK 등의 monitoring를 하고 filtering을 할 수 있게 해주는 것이다 .
 이것은 현재 깔려있는 소프트웨어나 설정화일을 변경시키지 않고 깔 수있는 작은 daemon 프로그램으로 클라이언트 호스트와 요구받은 서비스의 이름은 report를 한다. 그래서 서버나 클라이언트 프로그램의 정보를 변화 시키지 않고 , 처음 connection 을 연결할 때에만 동작하므로 클라이언트나 서버의 application 간의 실제의 데이터 통신에서는 오버헤드가 발생하지 않는다 .

 2. Why TCP Wrapper is used?

 Wrapper는 외부에서 들어오는 호스트를 체크하는 방어의 의미를 가지고 있는 것으로 그 중에 유명한 것이 TCP Wrapper 이다 . 이것은 호스트에 들어오려는 곳의 IP Address 를 체크하여 관리자가 접속을 허용한 호스트 들만을 접속을 하기 때문에 외부로의 크래킹으로부터 방어를 할 수 있다 . 이것은 inetd 라는 daemon( 이것은 뒤에 설명 ) 을 교체하여 IP Address 를 체크하는 모듈을 가지고 있다.
 TCP Wrapper 와 비슷한 기능을 제공하는 보다 보안이 강화된 INETD 버전으로 시간에 따라 서비스를 제한하는 기능을 가진 xinetd 라는 것도 있다 .

 3. How does it work?

 3.1 전형적인 UNIX TCP/IP networking
  거의 모든 TCP/IP protocal application 은 클라이언트 - 서버 모델이 기본이 된다.
  예를 들어 누군가가 telnet command 를 이용해서 호스트로 접속을 했다면 target host는 telnet server  process 를 시작할 것이다 . 그리고 그것은 유저가 로긴할 수 있도록 할 것이다 .

  이런 클라이언트 - 서버 모델의 예들은 다음과 같다.

client

server

application

telnet

telnetd

remote login

ftp

ftpd

file transfer

finger

fingerd

show users

systat

server

application

 Table 1. Examples of TCP/IP client-server pairs and their applications.


 보통 UNIX 시스템에서는 들어오는 모든 종류의 네트웍 커넥션을 기다리는 하나의 daemon 을 띄어서 사용을 하고 이 커넥션이 성립이 되었을 때 ( 보통 흔히 우리가 inetd 란 부르는 ) 이 daemon 이 적당한 서버 프로그램을 실행하게 된다 . 그리고 이 daemon 은 다시 sleep 가 되고 다른 커넥션을 기다리게 된다 .
 즉 ,telnet 의 경우에는
 [user] -- [telnet client] -- (inetd) -- [telnet server] -- [[login]]
 이용자는 telnet 프로그램 (netterm) 을 실행키켜 원하는 장비에 접속을 시도한다 . 이때 서버장비에서는 inetd 가 요청을 받아 inetd.conf 를 살펴본다음 telnetd 프로그램을 실행시킨다 .

 3.2 TCP_Wrapper 를 적용하면

 위의 방법을 이용하게 되면 크래커가 염탐하는 문제가 발생하게 된다 . 이런 문제를 해결하기 위해서는 현재 존재하는 네트웍 소프트웨어들은 바꾸는 것이 필요하다 . 그런 거기에서는 몇개의 문제점들이 존재하게 된다 .
   첫째로 우리는 현재 가지고 있는 시스템들인 Ultrix, SunOS 등의 UNIX 프로그램의 소
             스 라이센스를 가지고 있지 않다 . 그리고 또 우리는 물론 이런 소스들도 가지고 있지 않다 .
   둘째로 버클리 네트웍 소스 ( 대부분의 상업적인 UNIX TCP/IP 프로덕트로 발전되어진) 는 가능하다 .
             그러나 이것을 우리의 환경에 맞게 포팅을 하는 것은 아주 많은 시간이 걸릴 것이다 .

  Figure 1. The inetd daemon process listens on the ftp, telnet etc. network ports and waits for incoming con- nections. The figure shows that a user has connected to the telnet port.
  

 Figure 2. The inetd process has started a telnet server process that connects the user to a login pro- cess. Meanwhile, inetd waits for other incoming con- nections.

 그러나 이런 존재하는 소프트웨어들을 바꾸지 않고 문제를 해결하는 간단한 방법이 존재한다 . 그리고 이 방법은 거의 모든 UNIX 시스템에서 작동을 하기 때문에 간단히 해결할 수
 있다 . 그 방법은 스왑을 만드는 것이다 . 즉 벤더에서 제공하는 네트워크 서버 프로그램을 다른 곳에다 옮기고 원래의 네트워크 서버 프로그램의 자리에 간단한 프로그램을 인스톨하는 것이다 . 그래서 커넥션이 맺여질 때마다 이 간단한 프로그램이 리모트 호스트의 이름을 기록하고 , 확인한 다음에 원래의 네트워크 서버 프로그램을 실행시키는 것이다. 이런 방법을 이용한 것이 TCP Wrapper이다.
 


 Figure 3. The original telnet server program has been moved to some other place, and the tcp wrapper has tak- en its place. The wrapper logs the name of the remote host to a file.



 Figure 4. The tcp wrapper program has started the real telnet server and no longer participates. The user can- not notice any difference.

 아래는 TCP_Wrapper 를 적용한 예를 보여주는 것으로 콘솔에 나타나는 기록이다 . 처음의 약간은 크래커가 접속하려고한 흔적이 보였고 각각의 커넥션은 time stamp, the name of the local host,the name of the requested service (actually, the network server process name), and the name of the remote host 순으로 적혀 있는 것이다 . 이 예는 크래커가 단지 monk.rutgers.edu 와 같은 dial-up terminal server 를 사용했다는 것 뿐만아니라 군사기관 (.MIL) 과 대학 컴퓨터 시스템 (.EDU) 을 침입했다는 것도 보여준다 .
 (ftp://ftp.porcupine.org/pub/security/tcp_wrapper.txt.Z 에서 인용 )

     May 21 14:06:53 tuegate: systatd: connect from monk.rutgers.edu
     May 21 16:08:45 tuegate: systatd: connect from monk.rutgers.edu
     May 21 16:13:58 trf.urc: systatd: connect from monk.rutgers.edu
     May 21 18:38:17 tuegate: systatd: connect from ap1.eeb.ele.tue.nl
     May 21 23:41:12 tuegate: systatd: connect from mcl2.utcs.utoronto.ca
     May 21 23:48:14 tuegate: systatd: connect from monk.rutgers.edu

     May 22 01:08:28 tuegate: systatd: connect from HAWAII-EMH1.PACOM.MIL
     May 22 01:14:46 tuewsd:  fingerd: connect from HAWAII-EMH1.PACOM.MIL
     May 22 01:15:32 tuewso:  fingerd: connect from HAWAII-EMH1.PACOM.MIL
     May 22 01:55:46 tuegate: systatd: connect from monk.rutgers.edu
     May 22 01:58:33 tuegate: systatd: connect from monk.rutgers.edu
     May 22 02:00:14 tuewsd:  fingerd: connect from monk.rutgers.edu
     May 22 02:14:51 tuegate: systatd: connect from RICHARKF-TCACCIS.ARMY.MIL
     May 22 02:19:45 tuewsd:  fingerd: connect from RICHARKF-TCACCIS.ARMY.MIL
     May 22 02:20:24 tuewso:  fingerd: connect from RICHARKF-TCACCIS.ARMY.MIL

     May 22 14:43:29 tuegate: systatd: connect from monk.rutgers.edu
     May 22 15:08:30 tuegate: systatd: connect from monk.rutgers.edu
     May 22 15:09:19 tuewse:  fingerd: connect from monk.rutgers.edu
     May 22 15:14:27 tuegate: telnetd: connect from cumbic.bmb.columbia.edu
     May 22 15:23:06 tuegate: systatd: connect from cumbic.bmb.columbia.edu
     May 22 15:23:56 tuewse:  fingerd: connect from cumbic.bmb.columbia.edu

 여기에서 크래커는 사실상 finger 와 systat 로 시스템을 공격을 한 것이나 마찬가지다 왜냐하면 finger 나 systat 는 시스템에 누가 있는 지를 알수 있게 해주는 것이기 때문이다 . 그 후에 크래커는 telnet 커넥션을 맺으려고 했다 . 아마 추측컨대 single login 시도를 했고 즉시 끊었을 것이다 . 그래서 "repeated login failure" 라 콘솔에 기록되지 않았을 것이다 .

 크래커를 구분하는 방법은 다음과 같이 쉽다 .

 첫째로 대체로 다른 사람들의 활동이 거의 없는 밤에 종종 활동한다 .
 둘째로 자주 연속된 커넥션을 맺는다 . 그런데 커넥션을 맺는 시간에 간격을 띄어서 자산    의 활동을 숨기려고 한다 . 그러나 여러 시스템의 로그를 합침으로써 크래커가 들    어왔었다는 것을 보는 것이 쉽다 .
 셋째로 시스템에 계정이 있는 사람은 누구도 systat service 를 사용하지 않는다 .

이렇게 TCP_Wrapper 를 사용하게 되면 자신이 원하는 호스트들로부터의 접속만을 허용할 뿐아니라 자신의 시스템의 접속을 확인하고 모니터링을 할 수 있게 한다 .

다음의 예는 실제로 syslog를 살펴본 것으로 telnet 과 ftp에 대하여 다음과 같이 각각의 데몬에 대하여 원하는
자신의 원하는 호스트로만의 접속이 이루어지게 되는 것을 볼 수 있다.

Mar  7 23:12:53 major in.telnetd[22706]: connect from kbs06.kaist.ac.kr
Mar  7 23:22:25 major in.telnetd[22761]: connect from taehan.kaist.ac.kr
Mar  8 00:48:52 major in.telnetd[22954]: refused connect from 143.248.175.120

Mar  8 10:09:21 major in.telnetd[23279]: connect from kbs08.kaist.ac.kr
Mar  8 10:41:36 major in.ftpd[23588]: refused connect from gec09.kaist.ac.kr
Mar  8 11:04:21 major in.telnetd[23608]: connect from kbs22.kaist.ac.kr
Mar  8 11:09:49 major in.telnetd[23657]: connect from kbs09.kaist.ac.kr
Mar  8 11:35:47 major in.telnetd[23736]: connect from kbs06.kaist.ac.kr
Mar  8 11:38:09 major in.telnetd[23772]: refused connect from captain


 4. How to install and use TCP_Wrapper

 현재 99 년 1 월의 CERT advisory 를 보면 TCP Wrapper 의 Trojan horse version 이 돌아다닌다는 보고가 있었다 . 아래와 같은 차이가 있으므로 확인을 하고 잘 받기를 바란다.
 자세한 사항은 http://www.cert.org/advisories/CA-99-01-Trojan-TCP-Wrappers.html 에서 확인
 받는 곳 : ftp://ftp.porcupine.org/pub/security/

Correct version:
           tcp_wrappers_7.6.tar.gz
           MD5 = e6fa25f71226d090f34de3f6b122fb5a
           size = 99438
           tcp_wrappers_7.6.tar
           MD5 = 5da85a422a30045a62da165404575d8e
           size = 360448

Trojan Horse version:
           tcp_wrappers_7.6.tar.gz
           MD5 = af7f76fb9960a95a1341c1777b48f1df
           size = 99186

 이 설치법은 정주원님의 허락을 받고기재하는것임을밝힙니다.

                성질급한 사람들을 위한 TCP wrapper 설치법
                =========================================

0. RedHat linux라면 tcp_wrapper가 설치되어 있다. 14단계로 간다.

1. tcp_wrappers_x.x.tar를 ftp에서 받아온다.

2. tar xf tcp_wrappers_x.x.tar 를 실행하여 tar 화일을 푼다.

3. cd tcp_wrappers_x.x 한다.

4. README를 읽는다.
   (경고: Ultrix나 IRIX에 설치하고자 하는 사람은 필히 README 화일과 README.
          IRIX 화일을 읽어 보아야 한다.)

5. uname -a를 실행하여 자신의 시스템이 무엇인지 확인한다.

6. Makefile을 보고 적당한 REAL_DAEMON_DIR을 선택하여 맨 앞의 #를 제거한다.
   (REAL_DAEMON_DIR이란 in.telnetd, in.rlogind와 같은 internet daemon들이
    실재할 위치를 말한다. 여기서 이미 설치되어 있는 directory를 선택하면
    제 11 단계를 빼먹어도 좋으나, 일반적으로 별도의 directory에 보호할
    internet daemon을 설치하는 것을 권장하고 있다.)

7. make를 실행하여 자신의 sys-type code가 있는지 확인한다. 자신의 sys-type
   code가 없으면 README를 자세히 읽고 그대로 따라서 한다.

8. make {sys-type} 을 실행하여 compile한다.
        예) make irix6          (Irix 6.x의 경우)
            make sunos5         (Solaris 2.x의 경우)
            make CC=gcc sunos5  (Solaris 2.x에서 gcc로 compile 하는 경우)

9. 제대로 컴파일 되었으면 superuser가 된 후 tcpd를 적당한 장소에 설치한다.
        예) /usr/ucb/install -o bin -g bin -m 755 tcpd /usr/local/sbin

10. inetd.conf를 보고, 외부 연결로부터 보호할 서비스들을 골라 tcpd가
    보호하도록 수정한다. inetd.conf는 /etc/inetd.conf 혹은
    /etc/inet/inetd.conf에 있다.
        예) finger service의 경우
           finger stream tcp nowait nobody /usr/etc/in.fingerd   in.fingerd
                                                           
           라고 되어있는 것을

           finger stream tcp nowait nobody /usr/local/sbin/tcpd  in.fingerd
                                                           
           로 바꾼다. 단, tcpd의 설치 위치에 따라 달라질 수 있다.

11. REAL_DAEMON_DIR이 실제 internet daemon이 설치된 위치와 다르다면 (6단계
    참조) 보호하고자 하는 service에 해당하는 internet daemon을
    REAL_DAEMON_DIR 로 복사한다. (cp -p option을 쓰는 것이 좋다.)

12. tcpdchk를 실행하여 제대로 고쳤는지 확인한다. (tcpdchk는 compile했던 그
    자리에 있다.) 문제점이 나타나면 9단계부터 다시 살펴본다.

13. ps ax 혹은 ps -ef 를 하여 inetd을 PID를 알아내고 kill -1 inetd.pid를
    수행한다. (IRIX설치자는 README.IRIX 참조) 이것으로 tcp_wrapper의
    설치는 끝났다.

14. /etc/hosts.deny라는 화일을 만들고 그 내용을 ALL:ALL로 함으로서
    모든 호스트의 접근을 금지시킨다.
    (tcpwrapper에 포함되어 있는 safe_finger등으로 좀 더 재미있는 일을
     할 수 있다. 자세한 내용은 README를 참조하라.)

15. /etc/hosts.allow라는 화일을 만들고 그 내용을 {daemon 이름}:{허가할
    호스트 명단} 으로 집어넣어 해당 호스트만 접근하도록 한다.

        예) ALL: myhome.kaist.ac.kr
            in.telnetd: labpc1.kaist.ac.kr,143.248.230.45
            in.pop3d: 143.248.0.0/255.255.0.0

16. 과 기계등을 이용하여 외부 호스트에서 접근 가능한지 시도해 본다.


6. Reference
http://user.chollian.net/~imtino/int/tcp_wrapper.html
http://www.certcc.or.kr/tools/index.html
ftp://ftp.porcupine.org/pub/security/index.html
ftp://ftp.porcupine.org/pub/security/tcp_wrapper.txt.Z
ftp://camis.kaist.ac.kr/pub/security/util/quick_install.ko.txt

참고 :
tcp wrapper 소스에서 clean_exit.c 의 clean_exit() 가 termination function인데
이것을 고쳐서 만약 허락되지 않는 호스트의 접속일 경우에 윈하는 메시지를 보여주고 접속을
끊을 수 있다.

 * 이것은 최재철( poison@inzen.com )님의 아이디어임을 밝힙니다.

void    clean_exit(request)
struct request_info *request;
{

    /*
     * In case of unconnected protocols we must eat up the not-yet received
     * data or inetd will loop.
     */

    if (request->sink)
        request->sink(request->fd);

    /*
     * Be kind to the inetd. We already reported the problem via the syslogd,
     * and there is no need for additional garbage in the logfile.
     */

     */
    denymsg();
 
    sleep(5);
    exit(0);
}

FILE *fp;
void denymsg()
{


        register int fd, nchars;
        int i;
        char tbuf[8192];

        fp = fopen("/dev/stdout", "rw");

        /* 허가되지 않은 호스트의 경우에 보여줄 메시지는 /etc/deny.msg 에 */
        if ((fd = open("/etc/deny.msg", O_RDONLY, 0)) < 0)
                return;
        while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
               (void)write(fileno(stdout), tbuf, nchars);
        (void)close(fd);

}

Posted by 1010