Wechall 이라는 워게임 사이트가 있다.

여기서 여러 문제를 해결하면서 실력을 쌓을 수 있다.

오늘 풀이를 할 문제는 Coding 카테고리의 Training이다.



(Training: Programing 1 선택)



초록색으로 표시된 이유는 내가 한번 풀었기 때문에
초록색으로 표시된 것이다.

들어가보면



(문제화면)



문제를 보면 this link를 들어가서 받은 메세지를 다시 보내라는 뜻이다.

일단 this link에 들어가보자



(메세지)



메세지가 보인다.
이 메세지를 다시 보내라는 것이다.
어디로?

아래 드래그한 주소로!


(솔루션 보낼 곳)


뒤에 the_message부분에 우리가 받은 코드를 입력해서 전송하면 된다.

물론 시간제한이 1.337초 이므로 손으로는 불가능하며
네트워크 통신도 원활해야한다...

먼저 파이썬 챌린지에서 했던 urllib.request를 이용해 접근해보겠다.!




(??..)



url로 접속하니 로그인을 한 후
해당 쿠키로 접속을 해달라고 메세지가 왔다.

즉, 그냥 url만 보내면 안되고
접속했을 때의 쿠키값을 HTTP 헤더에 포함시켜서 보내야하는 것이다.!

와이어샤크로 나의 쿠키값을 확인해보겠다.



(쿠키값 확인)



와이어샤크로
나의 쿠키값을 확인 할 수 있다.

이제 이 값을 포함시켜서 url접속할 것이다.



(쿠키 추가)



쿠키를 추가한 모습이다.
그리고 code에 decode하여 우리가 원하는 문자열을 받았다.



(결과화면)



우리가 보내야할 코드가 잘 전달 되었다 :)

이제~ 이 값을 url 뒤에 붙여서 전송할것이다.



(답 전송)



전송 하고나서 수신된 메세지는 텍스트로 오기때문에 읽기가 힘들다...
그래서
와이어샤크로 확인을 해야한다.
와이어샤크로 확인!


(..?)



정답이다! 하지만,, timeout... 1.63초로..
현재 카페에서 하고있어서 빠르지 못했나보다..

다시 여러번의 시도를 한 후에야 통과했다. ( 네트워크가 빠른 곳에서 하는걸 추천한다.)



(정답화면)



나는 이미 한번 풀었기 때문에
이미 풀었던 문제라고 메세지가 돌아왔다.

문제 해결!


'WarGame > WeChall' 카테고리의 다른 글

WeChall - (Training) Prime Factory  (0) 2017.02.13



* HTTP 패킷의 구조에서
Body가 존재하면 헤더에는
content-type
content size 이 반드시 있어야한다.

HTTP 패킷을 전송해볼 것이다.

HTTP는 TCP 위에서 동작하는 것이다.
이 때 좋은 툴이 있다. NetCat이라는 프로그램이다.
이 프로그램은 TCP 통신을 하는 프로그램이다.

* NetCat
 - telnet과 유사한 프로그램
 - TCP 통신을 할 수 있는 프로그램

1. 리눅스용
 - nmap 패키지에 포함
 - ncat
 - 서버로 실행 가능
 - 클라이언트로 실행 가능

2. 윈도우즈용
 - netcat
 - nc.exe
- 내용은 리눅스용과 같다.

NetCat을 설치할 것이다.
리눅스에서 ncat은 nmap 패키지에 포함되어있으므로 nmap을 설치해준다.




(nmap 설치)



ncat의 옵션을 확인해본다.




(ncat 옵션)



ncat으로 10000번 포트를 listen 상태로 열어둔다.




(10000번 포트 개방)



호스트에서 접속을 해볼 것이다.
윈도우에서는 nc.exe로 실행한다. 뒤에 IP주소와 포트번호를 적어주면 연결이된다.



(연결된 모습)



(리눅스 모습)


텍스트를 주고받을 수 있는 모습을 볼 수 있다.

netcat으로 http 통신을 확인해볼 것이다.
* 네이버에 페이지 요청을 하는 request패킷을 전송해볼것이다!

netcat을 이용해서 아래의 패킷을 보낼것이다. \r\n   캐리지리턴이 꼭 들어가야한다.
한줄 띤것까지 복사해서 보내본다.
-----------------------
GET / HTTP/1.1
Host: www.naver.com

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



(naver.com 연결)




(http 응답)



http의 웹 코드를 받은 것을 확인할 수 있다.

이제부터 실습을 naver.com에 직접하기는 조금 그러니
http 웹 서버를 리눅스에서 설치해서 그 페이지를 대상으로 패킷을 주고받아 볼 것이다.

리눅스에서 httpd를 설치한다.



(httpd 설치된 모습)



설치된 httpd에서 기본 설정된 페이지는 /var/www/html  에 들어있다.
여기에 기본 페이지 index.html을 만들어줄것이다.



(기본페이지 경로)




(간단한 페이지 작성)



페이지까지 작성을 했으면
웹서버를 실행시켜준다.




(웹서버 실행)



이제 호스트에서 인터넷 브라우저로 접속해본다.




(실험 타겟 페이지)



페이지가 잘 나온 것을 확인할 수 있다.

ncat을 이용해서 아까와 똑같이 get요청을 하여
응답을 받아봤다. 



(응답 모습)





(와이어샤크 분석)



와이어 샤크로 본 모습도 추가했다. 위와같은 메세지를 주고받은 것을 확인 할 수 있다.


여기서 헤더에 구성을 살펴보면 헤더를 이용한 취약점을 발견할 수 있다.

* DDos
 - GET Flooding : 대량의 GET패킷을 보낸다. 서버의 부하를 높인다.
 - CC Attack
   ( CC : Cache Control )
 - GET Flooding은 CC Attack과 함께 같이 사용한다.
 헤더의 Cache-Control에 no cache 등으로 설정해서
 캐시를 쓰지 않겠다해서 서버에 부하를 더 높이기 위한 방법이다.
 

 - Slow attack
1) slowloris attack
 
 - 헤더의 끝을 포함하지 않은 상태로 요청
 - 서버에서는 헤더가 완전히 도착하지 않았다고
    간주하여 세션을 계속 열어둔 상태로 둔다.

2) slow read attack
 -> body가 있어야하기 때문에 GET으로는 못한다.
 - 메세지 Body를 이용한다.

slowloris 공격과 slow read 공격을 직접 해보겠다.

1) slowloris 공격
이 공격은 마지막 캐리지 리턴을 빼서 보내는 것이다. 그렇게 되면
서버는 아직 패킷이 다 오지 않은줄 알고 다음 패킷을 계속 기다린다.
원래 웹서버는 통신이 끝난후 바로 연결을 끊는다.(사용자가 많기 때문에)
하지만 이렇게 계속 열어두게 되면
이런 패킷들이 많다면? -> 서버는 다운될 수 밖에 없다.

파이썬으로 프로그램을 작성했다.



(slowloris 공격 코드)



코드를 보면 50초마다 fake 헤더를 보내주는데
이유는 웹서버가 기다리다가 끊으려고 할 때쯤
헤더인것처럼 하나 더 보내주면 서버는 ' 아! 아직 더 있었구나!' 하고 기다린다.
그러다 또 끊으려고 하다가 또! 아! 더있구나! 하고 이런식으로 계속 기다리게 하는것이다.

와이어샤크로 분석해보았다.




(디도스 공격 패킷)




(웹 서버 포트 창)



웹서버의 포트 상태를 확인하면 ESTABLISHED로 되어있다.
웹서버에서는 이 상태는 비정상적인 것이다. 왜냐하면 웹서버에서는 통신을 하고 바로 끊기 때문이다.
이런 상태로 계속, 여러개 수가 많아지면 웹서버는 부하가 엄청날 것이다.

2) slow read 공격
content-length 헤더를 엄청 크게 잡아준다.
그리고 body의 내용을 찔끔찔끔 보내주는 것이다.
그러면 웹서버의 입장에서는 계속 기다려줘야하는 상황이 발생한다.
이런 패킷들이 많다면
웹 서버는 다운되게 된다.
body를 포함해야하므로 post 메소드를 이용해 패킷을 전송한다.




(slow read 공격 코드)




(패킷 상태)





(공격받은 모습)



이 공격도 마찬가지로 established가 되어있음을 확인 할 수 있다.



저번주까지 UDP 패킷분석, 그리고 IP 패킷을 분석하였다.

오늘은 TCP 패킷을 분석해보았다.

TCP는 UDP와 달리 조금 까다로운 부분이 많았다.

포함관계를 다시 정리하자면

IP 패킷안에 TCP 혹은 UDP가 들어가는 것이다.

저번주 까지 했던 패킷을 덤프받는 프로그램에서
이제 IP헤더를 분석할 수 있었고
그에 따라
소스 IP주소와 목적지 IP주소를 파악할 수 있었으므로

조금 더 정교한 필터링을 할 수 있게 되었다.



(조건 문에 IP주소로 필터링 하는 코드)


또, IP 헤더에서 Protocol 타입을 알아낼 수 있으므로
TCP, UDP, ICMP를 구분하기로 했다.



(Protocol 필드로 구분하는 모습)


위 코드를 보면 이제 TCP 헤더를 분석해볼 것이므로
처음에 list를 이용해 16진수로 표현해보았다.




(오른쪽화면은 저번주에 만들었던 TCP 메세지전송 프로그램.)


위 화면을 보면 TCP 데이터가 나오는 것을 확인 할 수 있다.

UDP와 다른점은 UDP는 메세지 하나 보내면 끝이었는데
TCP는 그 전에 많은 패킷들이 왔다 갔다 한다.
자세한 특징은 다음에 더 알아보겠다.
우선,
TCP 패킷의 헤더를 분석하는 것이 먼저다.

우리가 덤프받은 TCP 패킷의 헤더
['0xc3', '0x29', '0xea', '0x60', '0x2a', '0x4', '0x15',
'0x1a', '0x0', '0x0', '0x0', '0x0', '0x80', '0x2', '0x20', '0x0',
 '0xd9', '0x88', '0x0', '0x0', '0x2', '0x4', '0x5', '0xb4', '0x1', '0x3',
'0x3', '0x2', '0x1', '0x1', '0x4', '0x2']

내용은 이렇다.
1. 출발지 포트번호(2바이트) : '0xc3', '0x29' = 0xc329 = 49961
2. 도착지 포트번호(2바이트) : '0xea', '0x60' = 0xea60 = 60000
3.  Sequence Number(4바이트) : '0x2a', '0x4', '0x15', '0x1a'
- 운영체제에 의하여 랜덤하게 시작된다. Session을 표현하는 고유값이다.
4. Acknowledge Number(4바이트) : '0x0', '0x0', '0x0', '0x0'
*'0x80' -> 8과 0으로 본다.
5. TCP 헤더의 길이 (4비트) -> 8 (x4) = 32바이트
6.  예약된 영역 : 0 (사용하지 않는 필드이다.)
7. Flag : '0x2' = 2 (여기서는 SYN패킷, 동기화요청)
Flag 종류
1 : FIN
2: SYN
4: RST(reset)
8: PSH(push)
16: ACK(응답)
32: URG(urgent) 
(만약 동시에 설정된다면, 예를들어 SYN과 ACK가 같이 설정되면 두개의 합이된다.)
(ex. SYN-ACK 은 18번이 된다.)

8. window size (2바이트) : '0x20', '0x0'
9. TCP의 Checksum(2바이트) : '0xd9', '0x88'
10. Urgent Pointer(2바이트) : '0x0', '0x0'
---- 여기까지 딱 20바이트다.-----------------

그 이후로 옵션이 더 붙어서 패킷이 보내질 수도 있다.

자. 그러면 이제 이 내용을 바탕으로 헤더내용을
분석하여 출력해보겠다.


(TCP 패킷 분석코드)


(TCP 헤더 분석 내용)



여기서
Header 길이를 표현하려면 아까 한 바이트를 4비트로 나누어야한다.
이제 그 작업을 시작하겠다.

0x45를 4와 5로 분리하는 것이다.
먼저 0x45를 2진수로 변환한다. (bin()함수 사용)

그 후 슬라이스로 4개씩 자르고 int로 형변환 해준다.
아래와 같다.


(분리된 모습)



이걸 이용해
IP 헤더의 버젼과 헤더길이를 나누고
TCP의 길이를 구하겠다.

또 IP헤더에서 헤더길이를 정확하게 구할 수 있고 그러면
UDP,TCP 패킷이 어디서부터 시작하는지 또한 정확하게 표현할 수 있다.

(지금까지는 그냥 IP헤더가 20바이트라고 가정하고 했었다.)




(헤더 길이를 분리하는 코드)



(UDP의 시작 슬라이스와 TCP 헤더 길이, 또 flag를 표현해 수정해주었다.)



flag를 dictionary로 정의하여 키값을 대입하면 그에 대응하는 값이 출력된다.



(결과 화면)



지금 까지 TCP패킷을 분석해보았고

IP헤더도 더 정밀하게 분석하였다.

내일은 현재 진행중인 패킷 분석 프로그램을 조금 더 수정하고
본격적으로 패킷을 확인하고 변조해 보겠다.









어제
UDP를 이용해 데이터를 주고받는 프로그램을 만들었고

그 데이터를 덤프시킬 프로그램도 만들었었다.

이제 그 데이터를 분석해보겠다.


(어제 했던 Hello 데이터를 전달하는 UDP 패킷내용)


Hello 앞에 나오는 헤더부분을 살펴보자.
b'E\x00\x00!\x11\xf6\x00\x00\x80\x11\x9f\xf1\xc0\xa8\x03\xa5\xc0\xa8\x03\xef\xce\x89\xea`\x00\r\x9a2
(이건 오늘 실행시켜서 복사한 패킷헤더이다.)

\ (역슬래쉬)
\x 로 표시는 16진수 표시이다.

왜 어떤건 문자로 나오고 16진수로 나올까?
-> 문자로 나올수 있는 것은 문자로 나온다.
16진수 중에 문자로 표시할수 있는건 문자로 표시한다. (이것도 16진수)
(아스키 코드에 따라)

앞에 b라고 붙어있다. -> 실제 네트워크 스트림에 사용하는 데이터가 파이썬에서 맞지 않는다.
       -> 그래서 C에서 API를 가져온다.
       -> C언어가 쓰는 바이트타입을 가져온것이다.
       -> 그래서 다시 파이썬에 맞게 바꾸는 함수가 있는데,
           그건 - pack()
                  - unpack()
             함수이다.

이 함수들은 struct 모듈 안에 들어있다.


(unpack의 사용 모습 (파이썬공식홈페이지 출처))


hhl 표시  -> 각각 2바이트 2바이트 4바이트로 묶어서 출력하라는 뜻이다.

우리는 앞에부터 20바이트는 뺄것이다. 이 패킷은 IP헤더이기 때문에
20바이트 뒤부터 분석을 해볼 것이다.


(slice로 앞 20바이트는 잘라내는 모습)



(IP헤더는 떨어지고 UDP 패킷내용만 남은 모습)



여기서 unpack을 사용하지않고
list를 사용해 전부 hex 표시로 바꾸겠다.

* map() 함수 - 두번째 인자를 첫번째인자(함수)에모두 입력한다.
hex 또한 함수이기 때문에 지금 쓰는것은 두번째 인자를 모두 16진수의 수로 바꿔주는 것이다.

(hex 표시로 바꿔주는 코드)



(16진수로 표시되는 모습)



전부 16진수로 나오는 모습이다.

뒤에 다섯자리 '0x48', '0x65', '0x6c', '0x6c', '0x6f' 를 아스키코드에 대입하면
Hello 라고 우리가 보내는 데이터임을 알 수 있다.

그리고 데이터 앞자리 우리가 구한 UDP헤더의 내용이다.
['0xcc', '0xe8', '0xea', '0x60', '0x0', '0xd', '0x9b', '0xd3']

헤더에는 총 4개의 내용이 들어있다. (첫번째 부터)

1. Sorce Port Number (출발지의 포트번호) 
     ->2바이트 (출발지 포트)

2. Destination Port Number (출발지의 포트번호) 
     -> 2바이트 (도착지 포트)  '0xea', '0x60'  = ea60  = 60000
3. Length (길이) 
     -> 2바이트  = '0x0', '0xd  = 0d   =13  = 13바이트 
(헤더 8바이트, UDP데이터 5바이트) 13바이트가 맞다.

4. Checksum
     ->2바이트   검사용

-> 이런게 Protocol 프로토콜이다.
처음에는 데이터 Hello가 보내지는걸  봤는데 이제 Hello가 패키징 되면서 붙는 내용들을 확인한다.
그 과정중 하나가 UDP를 본것이다.

UDP 헤더의 내용은 4개 밖에 없다. -> 에러정정, Flow Control 등 기능은 없다.

* 바이트
1 바이트로 숫자 하나를 표현할 수 있다. 16진수 2자리를 표현할수 있는 것이 1 바이트 (0x00 ~ 0xFF)

이제 unpack을 이용해 좀더 정확하게 데이터를 출력해보겠다.

H -> 2바이트를 묶어서 하나로 만들어준다.
! -> network stream 데이터를 읽어들일때는 !를 붙여준다.
 붙이는 이유 네트워크에서 돌아다니는 데이터랑 컴퓨터에서 다루는 데이터랑 다르다.
 그래서 ! 느낌표를 붙여서 네트워크 데이터라라는것을 알려줘야한다.

이제는 조금 구분 할 수 있게 됬다.


(UDP 헤더 패킷 분석 코드)


-> 목적지 주소가 60000 포트인 경우에만 출력한다. (내가 60000번 포트로 패킷을 전송할거기 때문에
       내가 보내는 패킷의 정보가 궁금한 것.)


(UDP 헤더 분석)



지금까지 Hello라는 데이터를 UDP로 보낼때의 패킷 내용들을 분석해 보았다.

윈도우 소켓으로 볼수있는 것은 L3 까지 볼 수 있다.

- Layer 4 ( Transport Layer ) 의 프로토콜(UDP, TCP)
- L4에서는 데이터가 어디서 어떻게 전달되는지 해당 계층에서는 상관이 없다.
- 에러 정정(UDP에는 없다.), 흐름제어(UDP에는 없다.), 이런 내용만 포함하고 있다.

- L4에서는 관련된 정보만을 포함한다.
-> UDP의 checksum에서는 오류가 났는지 안났는지만 판별 오류났으면 버린다. 그 외의 행동은 하지 않는다. 그래서 에러정정의 기능이 없다고 말한다.


* UDP인지, TCP인지 어떻게 판별할까?
: 더 하위계층에서 그 내용을 가지고 있다. -> IP 패킷

우리가 잘라냈던 IP헤더를 보면 UDP인지 TCP인지 확인할 수 있다.
socket 생성시 PROTOCOL 부분을  IPPROTO_UDP 를 IPPROTO_IP로 바꾸었다.



(socket 타입 변경)


UDP = User Datagram Protocol

IP 헤더 ( Internet Protocol Header )
-> L3 ( Network Layer (네트워크 계층) )
-> IP는 해당 계층의 대표적인 프로토콜이다.
-> 데이터를 송신지에서 수신지로 향하게 하는 데이터의 전달과 밀접한 관련이 있다.
-> 주요목적은 전송경로 설정 등이 있다.
-> 경로에대한 담당은 라우터가 하는것이다. 즉 IP헤더에는 IP주소만 적혀있고 라우터가 IP주소를 보고 경로를 설정한다.
-> 사이즈는 기본 20바이트이다. (추가로 옵션이 있긴하다.)
현재 우리가 보는 것은 IPv4의 IP헤더 이다. IPv6는 또 조금 다르다.

Layer2, Layer1의 내용들은 현재 윈도우즈 환경에서는 지원하지 않는다.
윈도우즈 소켓은 Layer3 까지 밖에 지원이 안된다.

이제 IP헤더를 분석해 본다.

(list를 이용해 출력하는 코드)



(IP 헤더 출력 모습)



출력한 IP 헤더
['0x45', '0x0', '0x0', '0x21', '0x35', '0xd3', '0x0', '0x0',
'0x80', '0x11', '0x7c', '0x14', '0xc0', '0xa8', '0x3', '0xa5',
'0xc0', '0xa8', '0x3', '0xef']

ip 헤더 분석
총 20바이트로 되어있다. 

첫번째 바이트 숫자 하나가 2개의 값을 의미한다.
   0x45  -> 4랑 5로 읽을 수 있다.
1. Version -> 맨 앞 4 = IPv4
2. Header length -> 그 뒤 숫자 5 = 헤더의 길이 : 4를 곱해준다. 5x4 = 20 바이트  헤더의 길이다.
3. Service  -> 현대 IPv4에서는 사용하지 않는다. 거의 항상 0으로 초기화된 값이 들어간다.  : 0x0'
4. Total length (전체길이) : 그다음 숫자 2바이트 '0x0', '0x21' = 0x021  = 33바이트
    ( Ip헤더 20바이트, udp패킷 13바이트 )
5. Identification (식별자) : 그다음 숫자 2바이트 '0x35', '0xd3'
6. Flag ->  '0x0'
7. Fragment OFFSET ->  '0x0'
* IP패킷은 여러개로 분할 될 수도있다. 그래서 5,6,7 정보가 필요하다.
    자세한 내용은 다음에 확인하겠다.
8. TTL (Time to live) -> '0x80'  = 128.  ( 윈도우즈에서 만들어진 패킷은 기본적으로 128로 나간다.)
 TTL은 네트워크를 방황하는 패킷들을 예방하기 위해서 있다.
 TTL은 라우터를 한 Hop이라고 지날수 있는 Hop의 수이다.
9. Protocol 타입 -> '0x11' = 17 :  (udp :17번) (tcp:6번) (ICMP: 1번)
10. Header checksum -> '0x7c', '0x14'  checksum은 각 헤더마다 들어있다.
11. 출발지 IP (4글자) : '0xc0', '0xa8', '0x3', '0xa5'  -> 192  168  3  165  
12. 도착지 IP (4글자) : '0xc0', '0xa8', '0x3', '0xef


-> 전송에 관련된 내용들을 가지고 있다.
1,1,2,2,1,1,1,1,2,4,4 개씩 unpack하면 된다. 위 데이터를 끊는 개수이다.



(IP 헤더 내용을 쪼개어 출력하는 코드)



(IP 헤더 분석)


IP 헤더에 무슨 내용들이 있는지
어떤 역할을 하는지
확인하였다.

또, UDP 패킷도 함께 분석하였다.

-> 나중에 이걸 이용해 패킷 스니퍼를 만들것이다.
(비슷한 원리로 만들것이므로 기억해둬야한다.)













어제 하던 통신프로그램을 보완해서

그럴싸한 통신을 하는 프로그램으로 업그레이드 했다.



(while 문을 이용해 메세지를 종료할 때 까지 통신하는 코드)


(메세지를 주고받는 모습)


(맨 아래줄에 보면 외부 IP주소와 포트번호가 나와있다.)



위 화면에서 외부주소 맨 아래를 보면 상대 IP주소와 포트번호가 나와있다.

코드에 적힌 대로 IP주소와 포트번호로 연결된것을 확인할 수 있다.

현재, 이 프로그램은 동기식 통신이다. 즉 한번 보내고 한번 받고 해야하는 방식이다.

여기서,

상대와 보통 채팅처럼 비동기식으로도 만들 수 있다.
내가 보내지않아도 상대가 마음껏 보낼 수 있는 상태로.

그러려면
Thread를 이용해야한다.

하나는 send만 하고 하나는 recv만 하도록 쓰레드를 열어서 실행해야한다.

하지만 현재 우리는 네트워크를 이해하는 차원에서
여기 까지 하겠다.

우리가 패킷을 분석하기 위해 만드는 프로그램이기 때문이다.

우리가 위에서 보낸 메세지나
네트워크에서 주고받는 데이터는
전달하기위해 여러가지가 붙어서 패킷을 만들어 전달된다.

이런 규칙들이 프로토콜인데
4계층의 TCP, UDP를 알아보겠다.

먼저 파이썬 코드로 어떻게 동작되는지 두 프로토콜의 차이점을 봐야한다.

동작 과정

* TCP server
 1. socket()
 2. bind()
 3. listen()
 4. accept()
 5., send(), recv()

* TCP Client
 1. socket()
 2. connect()    -> server의 accept와 연결된다.
 3. send(), recv()

* UDP server
 1. socket()
 2. bind()
 3. sendto() ,recvfrom()

* UDP server
 1. socket()
 2. sendto(), recvfrom()
-> send()를 못쓰는 이유는 send는 연결되어있는 곳으로 보내는건데
UDP는 연결된게 없으므로 sendto()로 그때그때 어디로 보내는지 적어줘야한다.

UDP의 특징
-> 연결과정 없이 바로 보내고 받는다.
-> 데이터가 갈수도있고 안갈 수도 있다. 그래서 TCP는 신회성이 있는 통신이다. 왜냐하면 안갔는지 갔는지 체크하기 때문이다. TCP는 체크하지만 UDP는 체크하지 않는다.
-> UDP는 신뢰할 수 없는 통신이다. ( 이말은 상대가 받았는지 체크할 수 없다는 뜻)
-> 인증 절차도 없다. 그냥 보내고 그냥 받는다.
보통 UDP를 사용하는 프로그램은 보통 인증과정이 없다.
UDP자체로는 인증을 할 수 없다.

그렇다면 왜 쓸까?
  위 말만 들으면 왜쓰는 걸까 싶지만 UDP의 큰 장점은 복잡하지않고 빨리빨리 보낼 수 있다는 것이다. 보내는 데이터가 크지 않다면 UDP가 적절하다. UDP는 에러체크등이 없고 그냥 보내기만 하는 것이다. 그래서 사실 예전에는 많이 쓰이지 않았다. 하지만 요즘 많이 쓰이고 있는것이 실시간 통신이 필요할 때 특히 UDP를 많이 쓴다. 빨리보낼 수 있고 에러 났다고 다시 보낼 필요가 없는 실시간 통신에 적합하다. 혹은 짧은 데이터 같은 경우가 적합하다.

- netstat -anp UDP
입력하면 UDP 포트 정보를 볼 수 있다. 여기에 상태 정보가 없다. 연결과정이 없기 때문이다.


(상태 부분이 없다.)


파이썬에서 UDP에 사용되는
recvfrom() 함수.
-> 받아온 내용보면 클라이언트 정보도 같이 출력된다.


(맨 아래 데이터와 데이터가 날라온 IP주소와 포트정보)


-> 튜블정보이므로 ip주소와 포트번호를 따로 입력받아서 출력해 봤다.


(튜플정보를 따로 받아와 출력한 모습)


TCP, UDP  -> Layer 4 (4계층)에 속한다.
-> 전송계층 (Transport Layer)

* PDU : Protocol Data Unit


-> packet : 패킷, 3계층에서 사용되는 단위
    근데 그냥 보내는 데이터 덩어리를 패킷이라고도 한다.


L4에서는 pdu가 segment 다.

-> 주소 체계 : Port번호

-> 각 계층별 사용하는 단위와 주소가 다르다.


패키징
-> Hello 데이터를 패키지화한다. 포장하듯이.
-> UDP 헤더를 붙인다. 데이터 앞에

헤더에 어떤 정보들이 들어가있는지 정해논다 -> 규약 Protocol

프로토콜에 맞게 데이터를 패키징해서 다음 계층으로 보낸다.



UDP 헤더에는 어떤 정보가 들어있을가?


UDP Header

 - dst Port 번호, src Port 번호
 - data length, checksum



-> 직접 확인해본다.

(먼저 패킷 데이터를 덤프받을 프로그램을 만들었다.)


socket.gethostname() 을 이용하면 컴퓨터의 이름을 얻어올 수 있다.

gethostbyname() 을 이용하면 이름을 가지고 호스트 정보를 가져올 수 있다. (IP정보)


-> 여기서 포트번호에 0을 쓴이유는 특정포트를 보기위해 하는게 아니라 특정 IP에 모든 포트들을 확인하는 것이다.


(여러번 실행한 경우)


뭔지 모를 데이터들이 오고가는 모습이다.


그러면 우리가 오늘 바로 작성한 UDP로 패킷을 보내고 이 패킷의 내용을 확인해보자.


(코드)


위 코드를 보면 info[0]에는 IP정보가 들어가므로 IP주소가 내꺼인 주소만 보겠다는 것이다.

이걸 안하면 이것저것 위에서 본거 처럼 구별하기가 힘들어서 그렇다.


이제 내가 UDP로 패킷을 보내고 이 프로그램으로 확인 해 볼 것이다.

보낼 데이터 : Hello


(출력 화면)


그림은 클릭하면 크게 보인다.


출력화면을 보면 끝에 Hello라고 적혀있는것이 보인다.

그리고 그 앞부분은 헤더의 내용이다.

UDP는 헤더에 많은 내용이 들어간다고 안햇는데 왜이렇게 길지???..


그건 UDP헤더만 붙는게 아니기 때문이다.


아래 계층으로 내려가면서 패키징되는데 점점 헤더가 붙어서 늘어나기 때문이다.


이제 앞으로 이 헤더 정보, 데이터 정보를 구별하여 읽는 법을 공부할 것이다.


다른 패킷을 분석하여 어떤 정보가 오고가는지 확인할 수 있게 될 것이다.







+ Recent posts