본문 바로가기
프로그래밍/NETWORK HACKING

[네트워크 보안] 파이썬3 UDP 프로토콜 클래스 정의 및 packet.py / sniffer.py 수정

by B T Y 2017. 6. 21.
반응형

파이썬3 UDP 프로토콜 클래스 정의 및 packet.py / sniffer.py 수정에 대해서 정리한다.

 

 

  * udp 헤더의 크기 = udp 헤더(고정) + 데이터의 크기(가변)


  * UDP 세그먼트에서 data 부분을 가져올때 방법
  -  udp.data.decode( errors='ignore' )
  -  struct.unpack( '!' + str(20) + 'B', data )

     ( struct.unpack()을 할때 포맷문자 부분은 문자열이라는 부분을 이용해서 데이터 길이만 추출해내면 된다 )

 


  - 전체적 패킷 구조: ethernet + ip + udp


 

헤더의 역할?
  - 전송되는 데이터의 정보가 담겨있다.

 

 

계층별 프로토콜 헤더
  - 계층에서 사용되는 정보


 

네트워크란?
  - 사용되는 장치들이 유무선으로 연결되어 있는 것
  - 호스트, 스위치(허브, 라우터, 로드밸런스, ...)

  - 장치들이 이해할 수 있는 규칙 -> 프로토콜 -> 헤더정보로 표현

  - 네트워크의 규모가 커지다보니 분할 -> 계층

 


운영체제 -> 인터럽트(방해하다)

  게임을 플레이 -> 패킷 수신 -> 게임을 중단 -> 패킷 처리 -> 게임을 플레이

  -> 패킷이 너무 수신 -> 인터럽트가 계속 발생 -> 성능 저하
  --> 디도스

 

 

 

※ UDP 프로토콜 클래스 정의 및 packet.py / sniffer.py 수정

  ( packet.py / sniffer.py 코드에서 수정된 부분은 분홍색으로 구분해서 표시 되어있다 )

 

udp.py

 

class Udp:

 

  def __init__( self, raw=None ):
    if raw != None:
      self._src = raw[:2]
      self._dst = raw[2:4]
      self._length = raw[4:6]
      self._check_sum = raw[6:8]
      self._data = raw[8:]

 

  @property
  def header( self ):
    return self._src + self._dst + self._length + self._check_sum + self._data

 

  @property
  def src( self ):
    (src,) = struct.unpack('!H', self._src)
    return src

 

  @property
  def dst( self ):
    (dst,) = struct.unpack('!H', self._dst)
    return dst

 

  @property
  def length( self ):

    (length,) = struct.unpack('!H', self._length)

    return length

 

packet.py

 

from header.eth import *
from header.ip import *
from header.udp import *

 

class Packet:

 

  def __init__( self, raw ):

    self._eth = Eth( raw[:14] )

    if self._eth.type == 0x0800:
      self.analyze_ip( raw[14:] )

 

  def analyze_ip( self, raw ):
    self._ip = Ip( raw )
    if self._ip.type == 17:
      self.analyze_udp( raw[20:] )

 

  def analyze_udp( self, raw ):
    self._udp = Udp( raw )

 

  @property
  def eth( self ):
    return self._eth

 

  @property
  def ip( self ):
    return self._ip

 

  @property

  def udp( self ):

    return self._udp

 

sniffer.py

 

import socket
import struct
import time
from header.packet import *

 

raw = socket.socket( socket.PF_PACKET, socket.SOCK_RAW )
raw.bind( ('eth0', socket.SOCK_RAW) )

 

while True:
  data, addr = raw.recvfrom( 65535 )
  packet = Packet( data )

 

  if (packet.eth.type == 0x0800 and packet.ip.type == 17) and \
     (packet.udp.src == 10000 or packet.udp.dst == 10000):

    print("data: ", data)
    print( packet.eth.src + ' -> ' + packet.eth.dst + 'type: ' + hex(packet.eth.type) )
    print( packet.ip.src + ':' + str(packet.udp.src) + ' -> ' + \
           packet.ip.dst + ':' + str(packet.udp.dst) )
    print( 'data: ' + packet.udp.data )
    print()

 

 

( sniffer.py를 실행하고 전에 만들었던 udp_server.py와 udp_client.py를 통해 통신해보면 통신 패킷을 알아보기 쉽게

출력 해주고 sniffer.py 코드에서 필터링을 처리하는 부분이 있어서 10000번 포트가 아니라면 해당 패킷의 내용을 출력하지 않는다 )

 

 

반응형

댓글