TCP 헤더의 구조와 항목
전송 단위가 세그먼트인 TCP 헤더의 길이는 그림 1-1와 같이 20바이트(160BIT)다. 이때 주의할 점은 UDP 헤더와 달리
TCP 헤더는 TCP 부가 항목에 따라 21바이트 이상의 길이가 가능하다. 다시 말해 UDP 헤더는 정적인 길이지만 TCP 헤더는 동적인 길이다. 아울러 TCP 헤더의 길이 20바이트는 가로 4바이트와 세로 5행을 곱한 결과라는 점도 숙지하길 바란다.
UDP 헤더와 마찬가지로 TCP 헤더 역시 출발지/목적지 포트 번호 항목은 16비트 길이이고
일련번호(Sequence number) 항목, 확인 번호(Acknowledgment number)항목은 각각 32비트이다.
오프셋(offset)항목과 예약(reserved) 항목은 각각 4비트
TCP 플래그 항목은 8비트
윈도우 항목은 16비트이다.
오류 검사 항목은 UDP헤더와 마찬가지로 16비트이고, 긴급 포인터(Urgent pointer) 항목 역시 1비트이다.
이에 TCP 헤더 길이는 총 160비트이다.
오프셋 항목에는 TCP 헤더의 길이 정보(일반적으로 20바이트임)가 있고 예약 항목에는 공백이 있다. 또한
일련 번호 항목 확인 번호 항목 TCP 플래그 항목은 TCP 동작의 3단계 연결 설정(3-way Handshaking), 3단계 연결 종료(3-way Terminating) 등과 관련이 있고
윈도우 항목은 흐름제어와 관련이 있다. 아울러 UDP 헤더와 마찬가지로 TCP 헤더에서도 오류 검사 항목이 활성 상태면 가상 헤더가 붙는다. 이제 파이썬을 이용하여 TCP 헤더 구조를 확인해보자.
실행 결과 출발지 포트 항목은 20번(FTP-DATA)으로 설정이 되어있다. 목적지 포트 번호 항목에는 80번(HTTP)이 설정됐다. TCP 플래그 항목에는 S(SYN을 의미함)신호로 설정됐고, 윈도우 항목에는 8192가 설정됐다.
이런 기본 설정은 TCP 플래그 항목을 제외하고 변경할 수 있다.
위 예제에 dataofs=5(5는 세로 5행을 의미함)는 TCP 헤더의 길이 정보 20바이트(20바이트= 가로 4바이트 세로 5행)를 저장한 오프셋 항목에 대한 설정이다.
그렇다면 기본으로 설정된 TCP 플래그 항목을 변경하고자 한다면 어떻게 해야 될까? scapy모듈에서는 16진수를 이용하면 된다.
기존 SYN이였던 TCP 플래그 항목을 0x01로 설정하여 플래그를 FIN으로 변경하였다.
그럼 만약 ACK SYN플래그로 변경하고 싶다면 어떻게 해야할까?
ACK 플래그에 해당하는 16진수 0x10과 SYN 플래그에 해당하는 16진수 0x02를 더한 값인 0x12를 이용하면 된다.
0x10 + 0x02 = 0x12(ACK SYN 플래그를 합친 16진수)
또한 X-MAS 스캔 방식에서는 URG PSH FIN 플래그를 동시에 설정해 이용한다. 이 경우도 위와 같이 각 플래그 값을 합치면 된다.
URG= 0x20 + PSH=0x08 + FIN =0x01= 0x29
※ 여기서 잠깐
여기서 TCP 헤더 항목을 파이썬 변수로 구현할 때 주의할 항목이 있다. 각각 4비트로 이루어진 오프셋 항목과 예약 항목이다. 왜냐하면 파이썬 변수는 8바트 배수 단위로 설정할 수 있기 때문이다. 이에 따라 파이썬의 변수로 오프셋 항목과 예약 항목을 설정해야 할 경우 일반적으로 아래와 같이 설장한다.
offset=5
offset의 5는 TCP 헤더 길이와 관련해 가로 4바이트와 세로 5행을 곱합 결과가 20바이트라고 했다.
따라서 offset=5가 세로 5행에 해당하고, 이것이 바로 20바이트 길이의 TCP 헤더 정보다. 이때 offset 항목에 대한 변수의 길이는 4비트다.
reserved=0
예약 항목은 0이다 다시 말해 미사용이라는 의미다. 이때 offset 항목에 대한 변수와 마찬가지로 reserved 항목에 대한 변수 역시도 4비트 길이다.
offset_reserved= offset << 4 + reserved
현재 offset 변수와 reserved 변수는 각각 4비트다 아까 말한 것처럼 파이썬은 바이트(8비트) 배수 단위로 데이터를 처리하기 때문에 offset 변수와 reserved 변수를 처리할 수 없다. 그러나 offset 변수와 reserved 변수를 통합하면 처리할 수 있다. 어차피 reserved 변수는 0이기 때문에 사용하지않아 offset 변수만 확장하면 해당 변수를 처리할 수 있다. offset << 4는 1바이트를 기준으로 하위 4비트 부분을 상위 4비트로 좌측 이동하겠다는 설정이다.