본문 바로가기

[☩ Security ☩]

TCP 통신 차단 기법을 이용한 인터넷 서비스 차단

  회사나 학교 같은 단체에서 P2P, 유해 사이트 같은 인터넷 서비스를 차단하는 것은 이미 보편화되어 있다. 실제로 많은 업체에서 이러한 기능을 많이 요구하고 있고 그와 관련된 제품이 계속 출시되는 상황이다. 요즘 인터넷 서비스는 기존의 단순한 차단 기법을 우회할 수 있도록 지능화되어 가고 있기 때문에 이러한 서비스를 차단하려면 고가의 장비를 도입해야만 해결할 수 있는 것으로 알고 있다. 하지만 TCP라는 범용 프로토콜에 대한 이해를 조금만 가지고 있다면 큰 비용을 들이지 않고도 비슷한 효과를 낼 수 있는 다양한 방법이 있다는 사실을 아는 사람은 많지 않은 것 같다. 이번 연재에서는 필자가 그동안 알아 온 이러한 지식들을 독자들과 공유해 보고자 한다.

  인터넷 서비스를 차단하기 위한 구조는 브리지(bridge) 방식과 미러링(mirroring) 방식이 있다. 브리지 방식이란 말 그대로 차단 시스템이 네트워크 통로에 있어서 직렬적인 곳에 위치하여 반드시 거쳐 가야 하는 방식을 얘기하는 것으로 방화벽, 라우터, L7 스위치 등 장비(하드웨어) 기반 제품의 일반적인 네트워크 구성 방식으로 이해하면 된다. 미러링 방식이란 기존 네트워크 구성에 아무런 변경 없이 단순히 스위치나 라우터에서 미러링을 받아서 모든 패킷을 볼 수 있는 병렬적인 곳에 위치하는 방식을 말하며, 일반적으로 소프트웨어 기반의 차단 모듈이 여기에 속하는 경우가 많다.

  브리지 방식은 해당 차단 모듈의 시스템이 다운되는 경우 인터넷 서비스가 어렵게 되며 네트워크 트래픽을 저하시키지 않기 위해 고성능으로 처리해야 하는 단점을 내포하고 있다. 반면에 미러링 방식은 차단 시스템이 다운되는 경우라 해도 본래의 네트워크 서비스에 지장을 주지 않는 이점을 가지고 있다. 이번 연재에서 설명하는 대부분의 차단 방식은 미러링 방식임을 미리 밝혀 둔다. 참고로 브리지 방식과 미러링 방식을 혼용하는 장비도 있음을 참고하기 바란다.

TCP 헤더 중 플래그 필드
TCP 프로토콜을 이해하기 위해 TCP 헤더를 설명하는 부분은 많이 언급되어 온 사항이며, 이 중에서 특별히 플래그(flag)라는 필드에 대한 이해가 필수적이다. <그림 2>와 <표 1>을 이용하여 TCP 헤더 중 플래그 필드에 대해 살펴보자.



URG 플래그는 신속한 처리를 해야 한다는 의미를 가지나 일반적인 네트워크 장비(스위치, 라우터 등)에서는 URG 플래그를 보고 우선적으로 처리해 주는 기능을 지원하지 않는 것이 일반적이다. 오히려 특정 패킷이 어떤 서비스를 하고 있는지를 판단하여(IP나 포트 번호 등을 살펴보고 업무적인 패킷인지, 아니면 엔터테인먼트적인 패킷인지) 라우팅의 우선순위를 변경해 주는 식의 기능을 갖는 것이 요즘 네트워크 장비의 추세다.



ACK 플래그는 응답의 의미이며 ACK 플래그가 세트(set)되어 있을 때 수신 호스트에서는 Acknowledgment Number 필드를 보고 올바르지 않은 값인 경우에는 패킷을 처리하지 않는 데 사용된다.
PSH는 데이터 송신을 뜻하며, RST/SYN/FIN 플래그는 TCP 연결 및 연결 해제를 할 때 사용되는 플래그다. 이 플래그 중에 가장 눈 여겨 봐야 할 플래그가 있는데 바로 RST 플래그다. RST 플래그는 비정상적으로 연결을 종료해야 할 때 상대방 호스트에 전송하는 데 사용되는 플래그로 TCP 연결이 갑작스럽게 끊어질 때 주로 시스템(운영체제) 차원에서 많이 사용하는 플래그로 기억해 두면 이해가 쉬울 것이다.

3웨이 핸드셰이크 연결
통상 TCP 프로그램을 작성한다는 것은 네트워크 커널에서 제공하는 connect라는 API를 이용해 상대방 호스트에 연결하고 그 다음에 send, recv라는 API를 이용해 데이터를 송수신하는 프로그램을 작성하는 것을 일컫는다. TCP는 연결 지향(connection oriented) 프로토콜(호스트끼리 통신을 하기 위해서는 우선 서로 연결해 놓아야 통신이 가능한 프로토콜)이며, 3웨이 핸드셰이크(handshake)를 통해 연결이 이루어진다는 얘기는 많이 들어 봤을 것이다. 그렇다면 이 3웨이 핸드셰이크를 통해 연결이 이루어지는 과정을 직접 스니핑을 통해 확인해 보자.
<그림 3>은 ‘telnet www.snoopanalyzer.com 80’ 명령을 이용하여 TCP 연결이 정상적으로 이루어지는 경우를 나타낸다. A는 2번 패킷을 받은 경우 연결이 이루어진 것으로, B는 3번 패킷을 받은 경우 연결이 이루어진 것으로 간주한다. 간혹 3번 패킷이 B에 전달되지 않은 경우가 있는데 이런 경우 B는 잠시 동안 불안정한 상태로 남게 되며 정상적인 작동을 하지 못할 수도 있게 된다.



<그림 4>는 ‘telnet www.snoopanalyzer.com 23’ 명령을 이용하여 B가 실제적으로 23번 포트 번호로 바인드(bind)하지 않은 상태(서버 소켓을 열어 놓지 않은 상태)이기 때문에, A로부터의 연결 시도에 대해 B가 RST 패킷으로 응답하는 것을 나타내고 있다. A는 연결에 실패했다고 판단하면(RST 패킷을 수신했으면), 똑같은 시도를 몇 차례 더 하게 되고 계속 연결이 실패하게 되면 소켓 에러 10061번을 낸다.



<그림 5>는 ‘telnet 1.1.1.1 80’ 명령을 이용하여 인터넷에 실제로 존재하지 않은 IP(1.1.1.1)로 연결 시도를 하는 경우다. 이런 경우에 A는 어떤 응답 패킷도 받을 수 없게 되며, 내부적인 시간 초과를 통해 몇 번 더 연결을 시도한 다음, 연결이 실패하게 되면(시간이 지나도 아무런 반응이 없으면) 소켓 에러 10060번을 내게 된다.



대표적인 소켓 에러에 대해 스니핑 차원의 분석은 <표 2>와 같다.



참고로 TCP 통신은 연결을 시도할 때만 핸드셰이크 기법을 이용하는 것이 아니라, 데이터를 받았을 때도 상대방 호스트에 ‘데이터를 잘 받았다’는 신호를 보내게 된다. 이러한 과정을 통해 TCP 통신은 응용 프로그램 차원에서 별도로 데이터 송수신을 확인해야 하는 과정을 거치지 않아도 네트워크 커널 레벨에서 그러한 과정을 다 처리하게끔 되어 있는 프로토콜이다.

RST 패킷
RST 플래그는 상대방으로부터의 연결 시도에 대해 거절(deny)하는 경우에도 사용되지만, 연결이 이루어져 한창 통신하는 도중에도 사용될 수 있다. 예를 들면 프로세스가 비정상적인 작동 때문에 운영체제에 위배되는 행동을 했을 경우 운영체제는 그 프로세스를 강제적으로 종료시키게 되고, 해당 프로세스와 관련된 TCP 세션에 대해 상대방 호스트에 끊겼다는 것을 알려 주기 위해 RST 패킷을 날려야 한다. 당연히 이 기능(RST 패킷을 날리는)은 운영체제가 담당해야 하며 요즘 사용되는 대부분의 운영체제는 이러한 기능을 제공하고 있다(예전 운영체제에서는 이러한 기능을 제공하지 않는 경우도 있다).



<화면 1>은 텔넷으로 연결되어 있는 상태의 프로세스를 작업 관리자를 통해 해당 프로세스를 강제적으로 종료하는 경우 RST 패킷이 상대방 호스트에 전달되는 것을 나타내고 있다. 1~3번 패킷은 telnet 프로세스에 의해 생성되는 패킷이며, 네 번째 패킷은 해당 프로세스를 강제적으로 종료하는 시점에서 운영체제(telnet 프로세스가 아닌)가 생성하는 패킷이다. 네 번째 패킷이 상대방 호스트에 전달되면 상대방 호스트는 연결이 끊겼다고 인지하게 된다.

스니핑을 통한 RST 패킷 송신
지금까지 설명한 내용을 이해했다면 지금부터 설명하는 ‘스니핑을 통해 TCP 연결을 차단하는 방식’에 대해서도 어느 정도 이해할 수 있을 것이다. 즉, 스니핑 프로그램을 통해 방금 스니핑된 TCP 세션에 대해 TCP 연결을 끊어 버리고 싶다면, 운영체제가 RST 패킷을 보내 주는 것과 똑같은 형태로 프로그램 차원에서 RST 패킷을 보내면 되는 것이다.
<그림 6>은 이러한 과정을 나타내고 있다. 1번 정상 패킷을 스니핑했을 때 스니핑 프로그램이 2번 RST 패킷을 B에 보내면, B는 A와의 TCP 연결이 끊긴 것으로 간주하게 되고, 이후의 A로부터 요청되는 TCP 통신에 대해서는 전부 거절하게 되며 따라서 TCP 세션은 연결이 자동으로 끊기게 된다.
이러한 RST 패킷을 생성하는 스니핑 프로그램은 A 컴퓨터에서 실행해도 작동하지만, <그림 7>과 같이 같은 네트워크에서 호스트들의 패킷을 볼 수 있도록 미러링 환경을 설정한 상태(혹은 더미 허브 환경)에서 스니핑 프로그램을 실행하면 미러링 환경 내의 모든 컴퓨터에 대해 차단 효과를 볼 수 있다. 즉 A에 어떤 스니핑과 관련된 모듈(스니핑 드라이버나 스니핑 프로그램)을 설치하지 않아도 작동될 수 있다는 장점이 있다. 이러한 형식의 차단은 ISP나 일부 업체에서 유해 사이트 차단 같은 서비스나 특정 인터넷 서비스(메신저, P2P 등)를 차단하는 데 많이 사용되는 추세다.


예제 프로그램 작성 및 테스트
TCP 패킷을 스니핑하고 RST 패킷을 송신하여 TCP 세션을 끊어 버리는 예제를 만들어 보자. 예제는 WinPcap 패킷 캡처 드라이버를 기반으로 하고 있기 때문에, 우선 WinPcap 사이트(http://winpcap.polito.it)에서 드라이버를 다운받아 설치하기 바란다.
예제를 컴파일하기 위해서는 델파이 환경에서 WinPcap을 사용할 수 있는 Snoop 컴포넌트를 설치해야 한다(http://www.snoopanalyzer.com). 드라이버와 컴포넌트가 설치되면 델파이에서 <화면 2>와 같은 폼을 작성하고 <리스트 1, 2, 3>에 있는 소스를 이용해 프로그램을 작성하도록 한다. 프로그램을 실행하여 <화면 3>과 같이 웹 브라우저를 실행하여 웹 사이트가 차단되는지를 확인해 본다. 예제는 이달의 디스켓을 참고하기 바란다.









원하는 패킷만 차단하기
WinPcap이라는 패킷 캡처 드라이버는 필터라는 기능을 제공하여 모든 패킷을 전부 스니핑하는 것이 아니라 자신이 원하는 패킷만을 스니핑할 수 있다. 이 필터 기능을 이용해 특정 서비스만을 차단할 수도 있다.



<화면 4>는 포트 번호가 4661번 및 4662번인 패킷만을 스니핑해서 P2P 서비스를 차단하는 예제를 보여 주고 있다. <표 3>에서는 유명한 인터넷 서비스에 대해 차단하거나 제한할 수 있는 간단한 필터들을 정리해 보았다. 이 필터들은 정확한 내용도 아니고 100% 차단되지는 않으며 대부분 필자의 경험적인 내용이다.



요즘 인터넷 서비스는 차단하는 방식을 우회하여 접속이 가능할 수 있도록 점점 지능화되어 가는 추세에 있기 때문에 단순한 IP나 포트 번호만을 판별해 차단하기는 점점 힘들어지고 있다. 특히 MSN 메신저 서비스는 접속이 불가능한 네트워크 환경인 경우 80번 포트(HTTP)까지 사용하기 때문에 단순히 IP나 포트 번호 정보만을 이용해서는 안 되며, 응용 프로그램 레이어의 내용까지 검토해 봐야 차단이 가능한 실정이다.

각종 인터넷 서비스 차단하기
지능화되어 있는 인터넷 서비스를 차단하려면 결국 각각의 서비스별로 별도의 프로그래밍을 하여 차단할 수밖에 없다. 가장 널리 쓰이고 있는 MSN 메신저를 예로 들어 간략하게 설명해 보고자 한다.
MSN 서비스는 우선 1863 포트 번호를 이용하여 서버에 접속을 시도한다. 1863 포트 번호를 이용하여 서버로 접속되지 않는 경우 다시 포트 번호 80번을 사용하여 접속을 시도하여 HTTP 프로토콜로 통신한다. 일반적으로 회사나 공공기관에서 HTTP 통신을 차단하기가 현실적으로 어렵다는 점을 이용한 것이다.
하지만 이런 경우에도 이 패킷이 일반적인 웹 통신인지 아니면 MSN 패킷인지를 구별할 수 있는 방법이 여러 가지가 있는데 가장 좋은 방법 중 하나가 User-Agent 값을 확인해 보는 것이다. MSN에서 HTTP 통신을 하는 경우 User-Agent 부분에 ‘MSN Messenger’라는 문자열이 포함되어 있다. 이 스트링이 포함된 HTTP 통신인 경우 RST 패킷을 보내는 방법을 이용하면 된다.
개인적으로 ‘회사에서 쓸려고 하는데 이런 서비스를 막아주는 프로그램 좀 만들어 주세요’라는 요청을 많이 받는 편이다. ‘단순히 IP나 포트로만 막을 수 없다면 결국에는 TCP 레이어 위에 있는 응용 프로그램 레이어의 내용까지 봐야 합니다’라고 응답을 하는데, 기본적인 TCP의 성격이나 전문적인 프로그래밍의 실력을 갖추고 있는 네트워크 관리자를 보유하고 있는 업체가 드문 편이라서 어려움을 많이 겪을 것이다. 이번 연재를 통해 네트워크 관리자들에게 조금이나마 도움이 됐으면 하는 바람이다. 연재와 관련된 프로그램 등의 자료는 필자의 개인 홈페이지(http://www.gilgil.co.kr)에 올려놓고 있으므로, 관심 있는 독자는 한번 들러주기를 바란다.
개인적인 생각으로 TCP/IP라는 프로토콜이 엉터리라고 보지는 않지만 오랜 기간을 거쳐서 충분히 검토되어 온 완벽한 프로토콜이라고 보기도 어렵다. 오히려 많은 네트워크 벤더들이 OSI 모델보다는 TCP/IP 모델을 기반으로 하는 제품들을 출시해 왔기 때문에 TCP/IP가 세계적으로 표준화된 프로토콜이 되어 버렸다고 보는 것이 맞을 것이다.

사실 내부적으로 보면 현재 잘 사용하지 않는 필드들도 있으며, 결국 이러한 필드 사용의 축적은 네트워크 장비를 복잡하게 하고 쓸모없는 네트워크 트래픽만을 야기한다고 해도 틀린 말은 아닐 것이다(큰 문제가 될 정도로 심각하지는 않지만). 그렇다고 해서 우리나라에서 TCP를 대처하는 새로운 프로토콜을 만들어 보자는 현실성 없는 얘기를 하는 것은 아니다.
IPv6 인터넷 환경은 점차 확산되고 있다. 새로 접해야 하는 표준 프로토콜에 대해 어떤 것이 옳고 그른지 판단하기 위해, 개선적인 방향으로 나아가기 위해, 이미 만들어진 그들만(?)의 프로토콜을 이해하기 위해 스니핑을 사용하는 행위 자체가 단지 해킹의 범주만은 아니라는 인식이 일반화되어야 한다는 것이 필자의 바람임을 조심스럽게 얘기해 본다.

정리 | 전만환 | mhjun@korea.cnet.com


'[☩ Security ☩]' 카테고리의 다른 글

CISSP 기본자료  (0) 2008.02.16
CCNA 640-802  (18) 2008.02.16
라우터 불필요한 서비스 막기  (0) 2008.02.13
SNORT로 IDS구축하기  (0) 2008.02.13
무선랜 테스트 동영상  (0) 2008.02.13