호우동의 개발일지

Today :

article thumbnail

TCP 연결 관리

  • 일반적인 네트워크 공격의 대부분은 TCP 연결 관리의 취약점을 악용
    • SYN 플러드(flood) 공격 등

 


TCP 연결 설정의 자세한 과정

  • 가정
    • 호스트(클라이언트)에서 운영되는 프로세스가 다른 호스트(서버)의 프로세스와 연결 설정을 원함
      → 클라이언트 TCP에게 연결 설정을 원하다는 사실을 알린다.
      → 클라이언트 TCP는 TCP를 이용해 서버와 TCP 연결 설정을 시작함

  • 연결 설정을 위해 두 호스트 사이에서 3개의 패킷이 송신됨 → 세 방향 핸드 셰이크

TCP 세방향 핸드셰이크

 

세 방향 핸드셰이크 1단계

  1. 클라이언트 측 TCP는 서버 TCP에게 SYN 세그먼트를 송신
    • SYN 세그먼트
      • 애플리케이션 계층 데이터를 포함하지 않는다.
      • SYN 비트라고 불리는 하나의 비트 플래그를 1로 설정
        → SYN 세그먼트라고 불리는 이유

  2. 추가로 클라이언트는 최초의 순서 번호(client_isn)를 임의로 선택하고,
    최초의 TCP SYN 세그먼트의 순서 번호 필드에 이 번호를 넣는다.
    • SYN 세그먼트는 IP 데이터그램 안에서 캡슐화되고 서버로 송신된다.
      • 특정 보안 공격을 피하고자 client_isn의 선택을 적절히 임의 추출하는 것에 유의해야 함

 

세 방향 핸드셰이크 2단계

  1. 서버는 데이터그램으로부터 TCP SYN 세그먼트를 추출
    • TCP SYN 세그먼트를 포함하는 IP 데이터그램이 서버 호스트에 도착한 뒤

  2. 연결에 TCP 버퍼와 변수를 할당
  3. 클라이언트 TCP로 연결 승인 세그먼트를 송신
    • 연결 승인 세그먼트는 애플리케이션 계층 데이터를 포함하지 않는다.
    • 해당 세그먼트 헤더 안에 중요한 3개의 정보를 포함
      1. SYN 비트는 1로 설정
      2. TCP 세그먼트 헤더의 확인응답 필드는 client_isn+1로 설정
        • 당신의 최초 순서 번호 client_isn을 가지고 연결을 시작하자는 당신의 SYN 패킷을 수신했다.
    • 연결 승인 세그먼트는 SYNACK 세그먼트라고 불림

 

세 방향 핸드셰이크 3단계

  1. 연결 승인 세그먼트를 수신하면, 클라이언트는 연결에 버퍼와 변수를 할당
  2. 그다음 클라이언트 호스트는 서버로 또 다른 세그먼트를 송신
    • 이 마지막 세그먼트가 서버의 연결 승인 세그먼트를 확인함
      • 클라이언트 TCP 세그먼트 헤더의 확인응답 필드 안에 server_isn+1 값을 넣음

  3. 연결이 설정되었기 때문에 SYN 비트는 0으로 설정됨
  • 세 번째 단계에서 클라이언트에서 서버로의 데이터를 세그먼트 페이로드에서 운반할 수 있다.

 

세 방향 핸드셰이크 이후(연결 이후)

  • 클라이언트와 서버 호스트들은 각각 서로에게 데이터를 포함하는 세그먼트를 보낼 수 있다.
    • 이 각각의 다음 세그먼트에서 SYN 비트는 0으로 설정됨

 


TCP 연결 종료

  • TCP 연결에 참여하는 두 프로세스 중 하나가 연결을 끝낼 수 있다.
  • 연결이 끝날 때, 호스트의 자원(버퍼와 변수)은 회수된다.

 

TCP 연결 종료 예시

연결 종료 과정
연결 종료 과정

  • 클라이언트가 연결 종료를 결정한다고 가정
  • 과정
    1. 클라이언트 애플리케이션 프로세스는 종료 명령을 내린다.
      → 클라이언트 TCP가 서버 프로세스에게 특별한 TCP 세그먼트를 보내도록 한다.
      • 이 세그먼트는 1로 설정된 FIN 비트라 불리는 플래그 비트를 세그먼트에 포함하고 있음

    2. 서버가 이 세그먼트를 수신하면, 서버는 클라이언트에게 확인응답 세그먼트를 보낸다.
    3. 그다음, FIN 비트가 1로 설정된 서버 자신의 종료 세그먼트를 송신한다.
    4. 마지막으로, 클라이언트는 서버의 종료 세그먼트에 확인응답한다.
      • 이 시점에서 두 호스트의 모든 자원은 할당이 해제된다.

 


TCP 상태 전이(TCP State)

  • TCP 연결이 존재하는 동안, TCP 프로토콜은 다양한 TCP 상태를 두루 전이한다.

 

클라이언트 TCP에서 TCP 상태 변이의 일반적인 순서

TCP 클라이언트와 서버의 상태 전이
TCP 클라이언트와 서버의 상태 전이

  1. CLOSED : 클라이언트 TCP는 CLOSED 상태에서 시작한다.
  2. SYN_SENT : 클라이언트 TCP가 서버 TCP에게 SYN 세그먼트를 송신한 뒤, SYN_SENT상태로 들어감
    • 클라이언트 측의 애플리케이션은 이 새로운 TCP 연결을 할 때 SYN 세그먼트를 송신함
    • SYN_SENT에 있는 동안, 클라이언트 TCP는 서버 TCP로부터 1로 설정된 SYN 비트와
      클라이언트의 이전 세그먼트에 대한 확인응답을 가진 세그먼트를 기다림

  3. ESTABLISHED : 이전 세그먼트에 대한 확인응답을 가진 세그먼트를 수신하면, 이 상태로 전이
    • 이 상태 동안, TCP 클라이언트는 페이로드 데이터를 포함하는 TCP 세그먼트를 송신 및 수신 가능

  4. FIN_WAIT_1 : 클라이언트 TCP가 1로 설정된 FIN 비트를 포함하는 TCP 세그먼트를 송신
    • 클라이언트 애플리케이션이 연결 종료를 희망할 때,
    • 이 상태 동안, 클라이언트 TCP는 서버로부터 확인응답을 포함하는 TCP 세그먼트를 기다림

  5. FIN_WAIT_2 : FIN_WAIT_1에서 확인응답 세그먼트를 수신하면 이 상태로 전이됨
    • 이 상태 동안, 클라이언트는 서버로부터 1로 설정된 FIN 비트를 포함하는 다른 세그먼트를 기다린다.

  6. TIME_WAIT : 5에서 원하는 세그먼트를 수신 후, 클라이언트 TCP는 서버의 세그먼트에 확인응답 전송
    • 이 상태는 TCP 클라이언트가 ACK가 손실되면 마지막 확인응답을 재송신하도록 한다.
    • TIME_WAIT 상태에서 소비되는 시간은 구현에 의해 달라질 수 있다.
      • 대체로 30초, 1분, 2분 정도
      • 대기시간이 끝나면 연결은 정식으로 종료
        → 클라이언트 측의 (포트 번호를 포함한) 모든 자원이 해제된다.

 

호스트가 TCP 통신과 관련 없는 TCP 세그먼트를 수신한 경우

  • 가정
    • 목적지 포트 80을 포함하는 TCP SYN 패킷을 수신하지만,
      호스트는 포트 80에서 연결을 수락하지 않고 있다고 가정
      → 즉, 포트 80에서 웹 서버로 동작하지 않는다.

  • 동작
    • 호스트는 출발지로 특별한 리셋 세그먼트를 보낸다.
      • 이 TCP 세그먼트는 1로 설정한 RST 플래그 비트를 갖는다.

    • 호스트가 이 리셋 세그먼트를 출발지에게 전송
      → 출발지에게 그 세그먼트에 대한 소켓은 없으니, 세그먼트 재전송 하지 말라고 알림

  • 호스트가 진행되는 UDP 소켓과 관계없는 목적지 포트 번호를 갖는 UDP 패킷을 수신하는 경우
    ICMP 데이터그램을 전송한다.

 

nmap 포트 스캐닝 도구의 동작

  • 가정
    • 목표 호스트의 특정 TCP 포트(포트 6789)를 살펴본다.
    • nmap은 호스트에 목적지 포트 6789를 가진 TCP SYN 세그먼트를 보낼 것이다.

  • 세 가지 가능한 결과
    1. 출발지 호스트가 목표 호스트로부터 TCP SYNACK 세그먼트를 수신
      • 애플리케이션 목표 호스트상에서 TCP 포트 6789를 가지고 실행되는 것을 의미
        → nmap은 ‘open’을 반환

    2. 출발지 호스트가 목표 호스트로부터 TCP RST 세그먼트를 받는다.
      • SYN 세그먼트가 목표 호스트에 달성했으나,
        목표 호스트가 TCP 포트 6789를 가진 애플리케이션을 실행하지 않는 것을 의미
      • 공격자는 해당 포트를 목적지로 하는 세그먼트 경로 상에는 방화벽이 없다는 사실을 알게 됨

    3. 출발지가 아무것도 받지 않는다.
      • SYN 세그먼트가 중간에 있는 방화벽에 의해 차단
        → 목표 호스트에 전혀 도달하지 않는다는 것을 의미