2010년 10월 22일 금요일

TCP/IP 프로토콜 제작 / 파싱 및 Auditing 강좌 - 2

약속 드렸던 대로 먼저 기본이론에 대해서 정리 하도록 하겠습니다.

사실, 글을 쓰기 전에 쓸 내용을 머리속에 떠올리다가 보니 자세하게 하자면 한도끝도 없이 이론만 주구장창 설명해야 할 것 같아 고민이 많이 되었습니다만, 그냥 편하게 생각하기로 했습니다.

아무튼 여기 설명되는 내용은 정말 필요한 내용을 이해하기 위해서 개인적으로 쓴 글이기 때문에 전문성을 기대하지는 않으시는 편이 정신건강에 도움이 될 것 같습니다.

 

읽어 보시고 궁금하신 내용이나 틀린 부분이 있다면 게시판을 이용 해 주시거나, 아니면 제 메일로 보내시면 되겠습니다. 혹은 더 설명이 필요하다고 생각되는 부분이 있다면 저도 자료를 찾아서 보충내용을 올리도록 하겠습니다.

참고로 제 메일 주소는 ihopi73골뱅이gmail.com 입니다.

 

흠.. 안전벨트 매셨죠? 그럼 갑니다 ^^

 

목차

 

1. 기본 이론

    1.1 프로토콜이란?

    1.2 파싱이란?

    1.3 네트워크 패킷?

    1.4 헥사 코드보기

 

1.1 프로토콜이란?

 

쉽습니다. 서로간에 통신 규약이라고 생각하시면 됩니다.

예를 들어서 같은 나라에 사는 동일한 언어를 사용하는 사람들이라도, 업무에 따라서 서로가 이해해야 하는 언어가 다릅니다.

짜장면 집에 가서 짜곱 2개요! 하고 외쳐도 알아듣는 그 무엇이란거죠. (사실 정해지지 않은 규약은 프로토콜이 아닙니다만.. ㅎㅎ)

 

가상의 예를 한 번 들어보도록 하지요.

통신보안이 무척 필요한 곳에 전화가 걸려옵니다. 그럴 경우 전화를 해도 될 사람인지 아닌지를 판단하기 위해서 다음의 절차를 거치게 됩니다.

 

질 - 통신보안! 소속과 암호를 대주세요.

답 - 통신보안! 아무개 과 김대리입니다.

질 - 해당 팀 오늘의 접속코드를 불러 주시기 바랍니다.

답 - 네. 무엇무엇 무엇입니다.

질 - 어떤일로 전화를 하셨습니까?

답 - 네. 본 부서에서 누구누구 사원에 대한 정보를 알고 싶은데요...

 

사실, 간단하게 쓴 글이긴 합니다만, 실제로 SSL 통신 같은 곳에서 인증을 위해 사용되는 방식을 글로 적은 것입니다.

SSL(Secure Socket Layer)에 대해서는 별도 설명드리지 않겠습니다만, 기회가 된다면 강좌에 포함하고 싶은 항목이기도 합니다.

위와 같은 통신 규약을 정해놓고 그에 따라 적절히 응대를 하였을 경우 통신을 할 수 있도록 만들어 주는 규약이라고 생각하시면 됩니다.

 

두산 동아백과사전에 보면 이렇게 나오네요.

 

'정보기기 사이 즉 컴퓨터끼리 또는 컴퓨터와 단말기 사이 등에서 정보교환이 필요한 경우, 이를 원활하게 하기 위하여 정한 여러 가지 통신규칙과 방법에 대한 약속 즉, 통신의 규약을 의미한다.'

 

그러니까 앞으로 프로토콜 이라고 하면 기기간의 통신 등을 하기 위한 규약이다, 라고 생각 하시면 되겠습니다.

 

1.2 파싱이란?

 

음, 사실 쉽게 생각하면 쉽고, 어렵게 풀어쓰자면 어려워지는 제목이네요.

좀 쉽게 설명하자면 다음으로 축약될 수 있을 것 같습니다.

 

- 어떤 데이터를 원하는 모양으로 만들어 내는 것

- 입력된 데이터를 분석하는 것

- 소스코드의 문장구조를 분석하는 작업

 

즉, 특별한 데이터를 분해하고, 분리해서 원하는 형태로 가공하는 것 정도로 생각하면 되겠지요.

 

코딩을 처음 시작할 때 파싱한다, 토큰이다, 라는 말 등이 무척 어렵게 느껴졌을 때가 있었기 때문에 제 설명이 충분하게 될 지는 미지수입니다만, 여하튼 파싱이란 위에 설명된 것이라고 생각하시면 됩니다.

 

단, 향후 사용되는 파싱이라는 용어는 강좌인 프로토콜에 한정되어져 있기 때문에, 프로토콜을 파싱한다.. 라는 용도로 사용됨을 알려드립니다.

 

1.3 네트워크 패킷?

 

네트워크 패킷이란 무엇일까요?

실제로 설명드리기 위해서는 아주 깊~숙하고 근본적인 얘기까지 파고들어야 될 위험이 있어서 정말 간단하게 설명드리고자 합니다.

단 여기에서 설명되는 내용을 이해하기 위해서 기본적인 이론은 OSI 7 Layer 등이나 TCP/IP 프로토콜을 설명한 책을 꼭 한번 읽어보시길 권해드립니다.

 

컴퓨터와 컴퓨터가 통신을 하기 위해서는 통신규약, 즉 프로토콜을 사용한다고 말씀드렸습니다.

대표적인 것으로는 TCP/IP, UDP 등이 있겠지요.

본 강좌의 중심인 TCP/IP를 보자면, 대충 Application 에서 통신하기 위해서 다음의 절차를 거칩니다.

 

예를 들어 A 컴퓨터에서 B 컴퓨터로 '지금 바빠?' 라는 메시지를 보낸다고 하지요.

그러면, 이런 메시지를 A 컴퓨터에서 보내기 위해서는 B 컴퓨터의 정보를 미리 알아야 하겠지요. 일단 알고 있다고 가정하고..

 

그러면 A 컴퓨터에서 SEND를 눌렀을 경우 데이터가 감싸져서 네트워크 카드를 통해서 발사됩니다. 네트워크 카드를 통해서 나간 데이터가 제대로 B 컴퓨터를 찾아가기 위해서 데이터 덩어리 앞단에 B 컴퓨터의 주소를 넣어서 보내게 되겠지요.

자, 여기에서 나온 용어가 바로 주소 등을 기록하는 머릿부분인 헤더와 실제 내용인 바디 부분으로 나뉘게 됩니다. 이것 전체를 '패킷' 이라고 부르게 됩니다.

 

자, 그럼 이론은 여기까지 하고, 굳이 네트워크 패킷을 설명 한 이유가 무엇일까요?

 

사실, wireshark를 이용한다거나 한 부분에서 벌써 패킷 스니핑을 이용한 capture를 한다는 것 쯤은 눈치 채신 분 계신가요?

즉, 본 강좌의 핵심 중 하나인 Auditing(감사) 부분은 Packet Sniffing 기법으로 처리하려고 합니다.

그렇기 때문에 패킷을 설명 드렸던 것이고 우리가 알아야 할 중요한 것만 적고서 끝내겠습니다.

 

자, 우리가 앞으로 보게 될 데이터는 패킷 데이타란 겁니다. 즉, 헥사 코드만 열라게 들여댜 봐야 한단 소리죠.

자, 샘플입니다.

 

00 1a 4d 52 3e 5a 00 02 b3 af d1 f7 08 00 45 00

00 32 95 8f 40 00 80 06 df 0f c0 a8 02 67 c0 a8

02 6f 75 31 c0 de b3 76 8d 7e c5 4b a9 6b 50 18

ff 9a a9 e7 00 00 00 00 00 00 37 2e 33 2e 30 00

 

아아.. 벌써 머리가 아픈 분이 계시지 않나요?

우리는 저것이 먼소린지를 알아야만 합니다!!

 

도저히 들여다 볼 생각이 안드시는 분은 이쯤에서 코멘트에 '훗, 내 체질이 아니야' 라고 외치신 후에 자게에 분풀이를 하시면 됩니다.

 

아무튼, 패킷을 분석하기 때문에 중요한 사항은 다음과 같습니다.

 

- 패킷은 전송하기 쉬운 형태로 쪼개어져서 보내진다. 이것을 MTU라고 하는데, 기본적으로는 1500 Byte이지만 변경이 가능하다.

- 사실 Application에서 MTU 사이즈를 조정해서 보내어져도, 라우터 등에서 못받아주는 경우도 있다. 그러므로 1500을 기억하자.

- 물론 1500 바이트가 넘는 데이터를 보냈을 경우 그것이 쪼개져 있다는 것을 알아내고서 우리가 합쳐줘야 한다.

 

흠, 가장 중요한 내용을 적은 것 같네요. 네, 사실은 컴퓨터에서 하는 모든 일들을 우리가 해야 하는거죠.

즉, 패킷을 쪼개고 다시 합치는 일은 컴퓨터에서 알아서 다 해 주는 것입니다만, 실제로 패킷스니핑을 하게 될 경우 가공되지 않은 데이터, 즉 RAW 데이터가 올라오게 된다는 겁니다. 우리가 이것을 파싱하기 위해서는 RAW 데이터를 가공해야 한다는 의미란 거죠.

 

데이터를 합치기 위해서는 TCP/IP의 프로토콜 문서를 볼 줄 알아야 합니다. 기본적인 이론을 알고 있어야 한단 얘기지요.

네. 거짓말이 아닙니다. 그러나, 강좌 마지막 부분에 되도록이면 많은 부분을 풀어서 알아야 할 부분에 대해서는 알 수 있도록 해 드리고, wireshark를 이용하거나 crowback__님이 제공 해 주실 유틸리티에는 이 헤더정보가 graphical 하게 보여지고 있으므로 굳이 신경쓰지 않아도 되는 부분이 있습니다. (이 자리를 빌어 crowback__님께 다시한 번 감사의 인사를)

 

자꾸 글이 길어집니다. 이만 마쳐야지 다음것으로 넘어가겠네요.

모르겠으면 자꾸 질문을 해 보세요. 그러면 숨겨진 고수분들이 불쑥불쑥 나타나서 아주 시원한 해답을 주실겁니다.

단, 본인도 어느정도 노력을 하고 자료를 찾아보는 수고는 거치셔야겠죠?

 

1.4 헥사 코드보기

 

음, 위의 샘플에 잠깐 등장했던 헥사 코드를 보기 위해서는 어떠한 정보를 알고 있어야 하나요?

 

요놈도 사실 깊게 가면 한도끝도 없이 설명해야 할 것 같아서, 정말 필요한 내용만을 간단히 설명합니다.

순서대로 갑니다. 하나하나 따라오세요.

 

BIT

 

컴퓨터는 0과 1로 이루어진 숫자를 이해한다고 하지요? 들어보셨죠?

그럼 비트에서 우리가 알아야 할 것은 무엇인가요?

 

- 한 바이트는 8개의 비트로 구성되어져 있다.

- 계산할 때는 짝수의 배수로 생각하면 쉽다.

 

1 바이트는 8개의 비트라는 것이 매우 중요합니다.

즉 한 바이트가 표현할 수 있는 비트의 최대는 1111 1111 이란 것입니다.

실제 바이트 데이터를 보고서 값을 어케 읽나? 하는 것은 다음을 기억하세요.

 

0000 0001 일 경우 1 입니다.

0000 0010 일 경우 2 입니다.

0000 0100 일 경우 4 입니다.

0000 1000 일 경우 8 입니다.

 

자 그럼 1이 맨 앞에 있는 경우는? 쉽게 128이 되겠지요.

그러면 모두가 1111 1111인 경우는? 모두를 다 더해버리면 됩니다.

 

128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255 입니다. 어디서 많이 본 숫자 아닌가요?

모두가 0인 경우를 포함해서 한 바이트가 가질 수 있는 최대의 숫자는 256이 되겠지요.

 

자 그럼 2 바이트일 경우는 어케 됩니까?

솔직히 적기 무지 귀찮지만, 그래도 적어봅니다. 1이 하나씩 된다고 가정하면 다음의 숫자가 됩니다.

 

256, 512, 1024, 2048,    4096, 8192, 16384, 32768 이 되겠습니다. 앞의 숫자랑 다 더하면 어케 되는지요?

정답은 65535 입니다. 진짜 많이 본 숫자지요?

 

네. 위의 숫자들은 컴퓨터에서 가장 많이 보는 숫자 중의 하나겠지요.

메모리의 숫자라던가, 화면의 해상도라던가.. 하는 곳에서 말이지요.

 

자, 중요한 것은 여기에서 나오게 됩니다.

실제 컴퓨터에서 표기할 때 '65535' 란 값은 어떻게 표기하는게 가장 좋을까요?

 

솔직히 저 같으면 65535라는 값을 그대로 적었으면 좋겠습니다만, 다음을 한 번 생각 해 보시기 바랍니다.

 

65535를 비트로 표현하면 1111 1111  1111 1111 이 됩니다.

10진수로 표현하면 당연히 '65535' 겠지요.

16진수로 표현하면 FF FF 값이 됩니다. (알기 쉽게 0xFF 0xFF 라고 표현하기도 합니다)

 

음, 아쉽지만 승자가 여기에서 가려지게 되는군요.

네트워크 패킷을 전송할 때 가장 적은 코드로 보낼 수 있는 데이터가 된다는 이야기지요.

사실 잘 느낌이 안온다면 4byte의 int가 표현하는 숫자를 생각 해 보시면 됩니다.

 

int가 표현할 수 있는 한계치는 -2,147,483,648 to 2,147,483,647 입니다.

한계치의 값을 표기할 때 FF FF FF FF 이면 되는 값이 10진수로는 너무 길지요?

 

HEX라고 줄여부르는 이 hexadecimal (16진수)는 우리가 사용하는 10진수와 다르게 16까지 하나의 수로 표기합니다.

즉 1 , 2 , 3 ... 8 , 9 , 10, 11 ... 이렇게 두 자리로 넘어가는 것이

1 , 2 , 3 ... 8 , 9 , A , B , C , D , E , F 까지 표기할 수 있는 것이지요.

그러므로 더 많은 데이터를 더 적은 공간에 표현할 수가 있게 되는 것입니다.

 

꼭 알아야 하는 것만 정리하죠.

 

CHAR        - 1 byte    8 bit

SHORT      - 2 byte    16 bit signed

INT            - 4 byte    32 bit signed

DOUBLE     - 8 byte    64 bit signed

 

추가) LONG은 32bit 이며 LONGLONG이 64bit 입니다.

기본 타입은 32bit system의 microsoft windows (2000 이상)라는 가정하에서 작업합니다. 혼동 없으시길 바랍니다.

 

각 타입 별 바이트 길이는 꼭 레퍼런스 자료를 참조 해 보시기 바랍니다. 앞으로 지겹게 보시게 될 테니까요.

signed , unsigned 등은 각자 자료를 찾아보시기 바랍니다.

 

마지막으로 한 가지만 더 언급하고 마쳐야겠네요.

 

실제 프로토콜을 사용하다가 보면 BIT는 flag 방식으로 사용되는 경우가 많습니다.

즉 몇 번째 비트가 '1' 로 되어져 있으면 어떠한 값이 'ON' 되어있다고 생각해라.. 라는 것이지요.

 

실제 코딩을 할 때 가장 많이 접하게 되는 자료이기도 하므로 언급하고 넘어갑니다.

 

 

다음 강좌부턴 좀 정리하고 올리겠습니다. 온라인 상에서 글을 작성하다가 보니 도대체 제대로 적고있는지도 모르겠네요.

의미인 즉슨, 다음번 강좌부터는 조금 기간이 오래 걸려서 나오게 된다는 의미지요 ^^

 

강좌 마지막까지 읽으신 분들께 박수 보내드립니다. 수고하셨습니다.

댓글 없음:

댓글 쓰기