보안세상
TCP체크섬 계산방법 본문
개념
TCP는 TCP Segment data 송신도중 발생될 수 비트 오류를 검출하기 위해 체크섬을 사용한다.
송신자는 체크섬 계산알고리즘에 의해 계산한 체크섬을 TCP 체크섬 헤더에 삽입하여 송신하게 되며,
수신자는 동일 알고리즘즘으로 수신받은 데이터를 검사해 봄으로써 오류여부를 파악한다.
TCP 체크섬은 TCP 체크섬 계산에 사용되는 헤더 및 데이터를 16비트 단위로 분할하여 비트 합을 구한뒤, 이에대한 1의 보수를 취함으로써 계산된다.
비트합 계산중 carry가 발생될 경우에는 warp around를 적용한다.
체크섬 계산에 사용되는 간단한 원리는 다음과 같다.
아래 3바이트를 예로 들면 (계산의 단순화를 위하여 8비트 단위로 나누었다)
00110011
11001100
11100110
처음 두개 바이트의 비트 합은
00110011
+11001100
———————
11111111
이며 carry는 발생되지 않았다.
이 계산 결과와 마지막 1바이트의 계산 합을 구해보면
11111111
+11100110
————————
111100101
이며 carry가 발생되었다 따라서 warp around를 적용하면,
11100101
+ 1
———————
11100110
위와 같은 계산 결과를 얻을 수 있고 이 결과에 대한 1의 보수는 00011001 이며 이것이 체크섬 값이 된다.
송신자는 원본 데이터와 체크섬을 함께 전달하게 되며 수신자는 데이터와 체크섬을 모두 더한다.
이 결과 모든 비트가 1일경우는 정상 어느 하나라도 0 비트가 있을 경우 데이터가 변조된 것을 알 수 있다. (n + 1의보수(n) = 1 이므로)
TCP 체크섬 계산 예제 패킷 소개
이해하기 쉬운 TCP 체크섬 계산 법을 설명하기 위해 아래와 같은 sample data를 예를 들어 설명하겠다.
참고로 초록색은 이더넷 헤더, 파란색은 IP헤더, 붉은 색은 TCP헤더이며 검정색은 TCP DATA이다.
(아래 데이터는 웹서버(192.168.246.130)가 클라이언트(192.168.246.129)에게 HTTP Response(200 OK)를 송신한 패킷이다.
— Sample Data ----------------------------------------------------
0000 00 0c 29 48 9a f2 00 0c 29 b1 45 1f 08 00 45 00
0010 00 fa 67 04 40 00 40 06 64 a4 c0 a8 f6 82 c0 a8
0020 f6 81 00 50 c0 6e fb 1d 71 30 0a 92 df 90 50 18
0030 06 c0 c7 18 00 00 48 54 54 50 2f 31 2e 31 20 32
0040 30 30 20 4f 4b 0d 0a 44 61 74 65 3a 20 4d 6f 6e
0050 2c 20 31 31 20 44 65 63 20 32 30 30 36 20 30 31
0060 3a 30 38 3a 31 33 20 47 4d 54 0d 0a 53 65 72 76
0070 65 72 3a 20 4d 69 63 72 6f 73 6f 66 74 2d 49 49
0080 53 2f 35 2e 30 0d 0a 58 2d 50 6f 77 65 72 65 64
0090 2d 42 79 3a 20 50 48 50 2f 35 2e 31 2e 32 0d 0a
00a0 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20
00b0 32 0d 0a 4b 65 65 70 2d 41 6c 69 76 65 3a 20 74
00c0 69 6d 65 6f 75 74 3d 35 2c 20 6d 61 78 3d 31 30
00d0 30 0d 0a 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 4b
00e0 65 65 70 2d 41 6c 69 76 65 0d 0a 43 6f 6e 74 65
00f0 6e 74 2d 54 79 70 65 3a 20 74 65 78 74 2f 68 74
0100 6d 6c 0d 0a 0d 0a 61 0a
—————————————————————————
o 총 길이 : 264 byte + 이더넷 : 14 byte + IP : 20 byte + TCP : 230 byte - TCP Header : 20 byte (붉은색) - TCP Data : 210 byte (검정색) |
<Wireshark를 통한 예제 패킷 캡쳐 화면>
체크섬 계산 순서
1. Pseudo header 생성
TCP는 TCP 세그먼트 데이터로만 체크섬을 계산하지 않으며, 체크섬 계산전 TCP pseudo header 라는것을 만들어 체크섬 계산에 활용한다. (계산시에만 활용되며 실제 전송되는 헤더는 아니다)
pseudo header는 총 12바이트 길이로써 일부 IP Header를 참조하여 만들어 지고 포맷은 아래와 같다.
필드명 | 크기(바이트) | 설명 |
Source IP | 4 | 출발지 IP |
Destination IP | 4 | 목적지 IP |
Reserved (항상 0) | 1 | 8비트 항상 0 이다. |
프로토콜 | 1 | IP에더에서 알아낸 프로토콜 필드 값 으로써, TCP 체크섬의 경우는 TCP프로토콜을 의미하는 6이 된다. |
TCP 길이 | 2 | TCP 헤더 + DATA의 총 길이(바이트) |
Sample 데이터를 기반으로 pseudo header를 만들경우 아래와 같이 만들수 있다. 맨끝 TCP 길이 부분 2바이트(00e6)는 TCP 세그먼트 총 길이(230 byte)의 HEX표현임을 참고하라.
pseudo header : c0 a8 f6 82 c0 a8 f6 81 00 06 00 e6
참고로 이 패킷의 IP 헤더는 아래와 같다
45 00
0010 00 fa 67 04 40 00 40 06 64 a4 c0 a8 f6 82 c0 a8
0020 f6 81
2. 만들어진 pseudo header 및 TCP Segment의 16비트 단위 합을 구한다. (warp around 적용)
2-1 pseudo header 합
C0A8 F682 C0A8 F681 0006 00E6) |
C0A8 -> 1100 0000 1010 1000 F682 -> 1111 0110 1000 0010 1B72A -> 1 1011 0111 0010 1010 - (carry) |
1B72A -> 1 1011 0111 0010 1010 B72B -> 1011 0111 0010 1011 - result (wrapped around) |
B72B -> 1011 0111 0010 1011 C0A8 -> 1100 0000 1010 10001 77D3 -> 1 0111 0111 1101 0011 - (carry) |
177D3 -> 1 0111 0111 1101 0011 77D4 -> 0111 0111 1101 0100 - result (wrapped around) |
77D4 -> 0111 0111 1101 0100 F681 -> 1111 0110 1000 00011 6E55 -> 1 0110 1110 0101 0101 - (carry) |
16E55 -> 1 0110 1110 0101 0101 6E56 -> 0110 1110 0101 0110 - result (wrapped around) |
6E56 -> 0110 1110 0101 0110 0006 -> 0000 0000 0000 0110 6E5C -> 0110 1110 0101 1100 - result |
6E5C -> 0110 1110 0101 1100 00E6 -> 0000 0000 1110 0110 6F42 -> 0110 1111 0100 0010 - final result |
2-2. TCP Segement의(Header + Data) 합
TCP 헤더와 DATA에 대한 16비트 단위 합을 구한다 이때 TCP 헤더의 체크섬 부분은 0으로 초기화 하여 계산한다.
예제 데이터의 경우 TCP 헤더는 붉은색 부분이며, 체크섬은 아래 노란색 음영 부분이다. (TCP 헤더 구조 참조)
00 50 c0 6e fb 1d 71 30 0a 92 df 90 50 18 06 c0 c7 18 00 00
예제 데이터는 이미 수신받은 패킷이므로 송신측에서 계산한 체크섬 C7 18이 기록된 상태이지만,
송신자가 송신전에 체크섬을 만들 당시에는 이 필드의 데이터는 0 으로 세팅하여 계산한 다는 것을 명심해야 한다.
아래의 데이터가 계산에 사용되는 TCP Segement 데이터 이며 warp around를 적용하여 합을 구하면 c9a4 값을 구할 수 있다.
00 50 c0 6e fb 1d 71 30 0a 92 df 90 50 18
0030 06 c0 00 00 00 00 48 54 54 50 2f 31 2e 31 20 32
0040 30 30 20 4f 4b 0d 0a 44 61 74 65 3a 20 4d 6f 6e
0050 2c 20 31 31 20 44 65 63 20 32 30 30 36 20 30 31
0060 3a 30 38 3a 31 33 20 47 4d 54 0d 0a 53 65 72 76
0070 65 72 3a 20 4d 69 63 72 6f 73 6f 66 74 2d 49 49
0080 53 2f 35 2e 30 0d 0a 58 2d 50 6f 77 65 72 65 64
0090 2d 42 79 3a 20 50 48 50 2f 35 2e 31 2e 32 0d 0a
00a0 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20
00b0 32 0d 0a 4b 65 65 70 2d 41 6c 69 76 65 3a 20 74
00c0 69 6d 65 6f 75 74 3d 35 2c 20 6d 61 78 3d 31 30
00d0 30 0d 0a 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 4b
00e0 65 65 70 2d 41 6c 69 76 65 0d 0a 43 6f 6e 74 65
00f0 6e 74 2d 54 79 70 65 3a 20 74 65 78 74 2f 68 74
0100 6d 6c 0d 0a 0d 0a 61 0a
2-3. pseudo header 16비트 합 + TCP Segment 16비트 합
2-1, 2-2 단계를 통해 pseudo header 16비트 합(6f42)와 tcp segment 16비트 합(c9a4)을 확보 하였고 이를 합하면
6F42 -> 0110 1111 0100 0010C9A4 -> 1100 1001 1010 01001 38E6 -> 1 0011 1000 1110 0110 - (carry) |
38E7 -> 0011 1000 1110 0111 - result (wrapped around) |
3. 합 결과에 1의 보수를 적용하여 체크섬 계산을 완료 한다.
38E7 -> 0011 1000 1110 0111
C718 -> 1100 0111 0001 1000 (1의 보수)
이 경우 C718이 체크섬 이며 이는 TCP 헤더의 체크섬 필드에 기록된 데이터와 같음을 확인할 수 있다.
'공부' 카테고리의 다른 글
Syn flooding 공격과 syn cookie 방어로직 (0) | 2015.01.09 |
---|---|
IPTABLES 명령어 (0) | 2015.01.09 |
보안 관련 (0) | 2015.01.05 |
3way hand shake (0) | 2014.04.19 |
리버싱 (0) | 2014.01.21 |