티스토리 뷰

--> 타입이 없는 소켓

ip나 프로토콜이 아니라 장치로 들어오는 것을 확인 할 수 있음


#vi sniffer.py


import socket

sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW)
sock.bind(('eth0', socket.SOCK_RAW))

data = sock.recvfrom(65535)
print(data)





>> 목표


-sniffer 에서 udp 통신을 하는 내용을 찾아 내는 과정


>#python3 sniffer.py > log.txt 를 실행시킨 상태에서 udp_server와 udp_client 사이의 정보 교환 log를 얻어낸다

>#vi log.tx //데이터 추출


<데이터 >


b"\w00PV\xcc\xcc \x00\x0c) \x10\01\x08\x08\00E\x00\00!\x00\x00@\x11\xb0y\xc0\xa8\x041
\xc0\xa8\x04\x9a\xa0\x12'\x10\x00\rj\x88hello

--> 총 47바이트

--> 전기 신호로 변환(변/복조) -> 전선을 통한 전기적인 송 /수신

--> 하위 4 계층에 포함된 모든 내용이 포함되어 있음

!(4계층 --> 2계층으로 분석하며 내려갔다가 만들면서 올라옴


**바이트 계산 (python 참조)


ex)  \w00 --> 한 바이트 (16진수 이스케이프)

네글자가 아닌 한글자
(\x 한바이트 숫자 )_
P 한문자
V 한문자
ex) \rj
\r 한문자
j 한문자



--> 송/수신 하려는 데이터에 관한 정보


IANA : 네트워크 표준 관리 기구




b"\x00PV\xcc\xcc \x00\x0c) \x10\01\x08\x08\00E\x00\00!\x00\x00@\x11\xb0y\xc0\xa8\x041
\xc0\xa8\x04\x9a\xa0\x12'\x10\x00\rj\x88hello


- 데이터를 제외한 8바이트 : UDP에 관한 헤더

- 전송 방식을 결정

- 오류 정정, 흐름제어, 신뢰성 (<-- tcp에서 지원하는 내용 )

- 주소 체계 :PORT

(1~65535) : ;한 서버에서 육만개 이상의 서버를 구성할 수 없다

(1~1024) : well-known 포트 -> 잘 알려진 포트

- PDU(Protocol Data Unit / 프로토콜 데이터 단위 ) : 세그먼트 (segment)


!protocol

-통신하기 위한 규약

- 택배 전송 , 편지


!protocol header

- 실제 전송되는 데이터

- 프로토콜에 관련된 정보를 담고 있는 테이블



1) UDP (User Daatagram Protocol)헤더 정보

\xa0\x12'\x10\x00\rj\x88

hex(16진수)->dec(10진수)

  1> 출발지 포트 번호가 들어있음 (2byte)

                             : \xa0\x12 => 40978
  2> 도착지 포트 번호가 들어있음 (2byte)

                             : '\x10 => 10000  // ' 아스키 코드 확인 0x27
  3> 데이터의 크기 (2byte)

                             : \x00\r -> \x00\x0d =>13

(udp header length + data length)

  4> 체크섬(2byte)

                     : j\x88
                      0x6A0X88 -->27272

                checksum -> check + sum
   --> 가장 쉽게 할 수 있는 방식 중 하나 완벽하게 체크할 순 없다


 >> 가변크기 : 헤더 8바이트 + 데이터 
            header(8byte) +data(5byte) = total(13byte)


  5> 데이터


!에러 검증

- 체크섬 (checksum)

- CRC 에러체크

- 패리티 부호


!바이트 오더

- 0x12 34 56 78 (4byte)

1. little endian -> 0x78 56 34 12 ( 읽어 들인 거꾸로 읽음 )

2. big endian -> 0x12 34 56 78 (읽어 들인 그대로 )



! : little endian : 시스템 메모리에서 데이터를 읽는 방식  ( 1byte씩 역순으로 읽는 방식 )

B : 1byte 크기의 바이트형 변환

H : 2byte 크기의 바이트형 변환

L : 4byte 크기의 바이트형 변환




! pack/unpack


struck.unpack('형식',변환할 데이터)

: 데이터의 개수화 형식의 개수는 일치 해야함


>>> import struct
>>> struct.unpack('!HHHH',b"\xa0\x12'\x10\x00\rj\x88")
(40978, 10000, 13, 27272)
>>> struct.unpack('!4H',b"\xa0\x12'\x10\x00\rj\x88")
(40978, 10000, 13, 27272)
>>> struct.unpack('!BBBBBBBB',b"\xa0\x12'\x10\x00\rj\x88")
(160, 18, 39, 16, 0, 13, 106, 136)
>>> struct.unpack('!8B',b"\xa0\x12'\x10\x00\rj\x88")
(160, 18, 39, 16, 0, 13, 106, 136)
>>> struct.unpack('!2L',b"\xa0\x12'\x10\x00\rj\x88")
(2685544208, 879240)     // 크기가 안맞으면 안됨
>>> struct.unpack('!L',b"\xa0\x12'\x10\x00\rj\x88")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
struct.error: unpack requires a buffer of 4 bytes
     // 번역하려는 크기와 뒤의 크기가 일치해야함 일치하지 않으면 위처럼 오류가 남


▷dec ->hex

>>> struct.pack('!HHHH',40978,10000,13,27272)
b"\()xa0\x12'\x10\x00\rj\x88"

▷hex ->dex

>>> struct.unpack('!HHHH',b"\xa0\x12'\x10\x00\rj\x88")
(40978, 10000, 13, 27272)



[헤더 분석 과정]


1) 가상 머신에서 파이썬을 실행시킨후 struct모튤을  import 시킴

2) 헤더의 정보를 가져옴

3) 각 헤더별로 분리한 후 바이트 크기에 맞춰서 unpack 시킴 (bytes -> 숫자 (10진수))














'Network Security > Network' 카테고리의 다른 글

Layer 3 /IP Header(IP 헤더 )  (0) 2017.12.14
Layer 3/IPv4  (0) 2017.12.14
TCP socket Programming  (0) 2017.12.12
UDP socket Programming  (0) 2017.12.12
01. 네트워크(Network)-소켓 (socket)  (0) 2017.12.11
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함