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

[네트워크 보안] 파이썬3 클래스로 각 프로토콜 헤더를 정의( packet.py, eth.py, ip.py, sniffer.py )

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

파이썬3 클래스로 각 프로토콜 헤더를 정의에 대해서 정리한다.

 

 

바이트 -> 정수, 문자
문자, 정수 -> 바이트

 

객체지향을 제대로 사용해보려면 프로젝트 규모가 좀 커야지 좋다.
( 객체지향 -> 아주 약간만 커도 굉장히 유용 )


클래스로 각 프로토콜 헤더를 정의

 

1. has-a

 패킷 클래스():
   이더넷
   아이피
   유디피
   ...
 

 

* 기본적으로 멤버들은 바이트 형태를 유지
* getter를 통해 가져오거나 setter를 통해서 입력할 때 변환

* setter, getter, 클래스의 캡슐화


 

2. is-a

 이더넷 클래스

 아이피 클래스( 이더넷 클래스 ):

 

* 프로토콜 헤더를 익히는게 목적


지난 시간: 변환
오늘 : 클래스 정의

아이피 헤더에 대한 클래스 정의

 


 - 각 클래스 정의

 

eth.py

 

import struct

 

class Eth:

 

  def __init__( self, raw=None ):
    if raw != None:
      self._dst = raw[:6]
      self._src = raw[6:12]
      self._type = raw[12:14]

 

  @property
  def header( self ):
    return self._dst + self._src + self._type

 

  @property
  def dst( self ):
    dst = struct.unpack('!6B', self._dst)
    dst = '%02x:%02x:%02x:%02x:%02x:%02x' % dst

    return dst

 

  @property
  def src( self ):
    src = struct.unpack('!6B', self._src)
    src = '%02x:%02x:%02x:%02x:%02x:%02x' % src

    return src

 

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

 

ip.py

 

import struct

 

class Ip:

 

  def __init__( self, raw=None ):
    if raw != None:
      self._verlen = raw[:1]
      self._service = raw[1:2]
      self._total = raw[2:4]
      self._id = raw[4:6]
      self._flag_and_offset = raw[6:8]
      self._ttl = raw[8:9]
      self._type = raw[9:10]
      self._check_sum = raw[10:12]
      self._src = raw[12:16]
      self._dst = raw[16:20]

 

  @property
  def header( self ):
    return self._verlan + self._service + self._total + self._id + self._flag_and_offset + self._ttl + self._type + self._check_sum + self._src + self._dst

 

  @property
  def ver( self ):
    (ver,) = struct.unpack('!B', self._verlen)
    ver = verlen >> 4
    retrun ver

 

  @property
  def length( self ):
    (len,) = struct.unpack('!B', self._verlen)

 

  @property
  def service( self ):
    (service,) = struct.unpack('!B', self._service)
    return service

 

  @property
  def total( self ):
    (total,) = sturct.unpack('!H', self._total)
    return total

 

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

 

  @property
  def flag( self ):
    (flag,) = struct.unpack('!H', self._flag_and_offset)
    flag = flag >> 13
    return flag

 

  @property
  def offset( self ):
    (offset,) = struct.unpack('!H', self._flag_and_offset)
    offset = (offset & 0x1FFF) << 2
    return offset

 

  @property
  def ttl( self ):
    (ttl,) = struct.unpack('!B', self._ttl)
    return ttl

 

  @property
  def type( self ):
    (type,) = struct.unpack('!B', self._type)

 

  @property
  def check_sum( self ):
    (check_sum,) = struct.unpack('!H', self._check_sum)

 

  @property
  def src( self ):
    src = struct.unpack('!4B', self._src)
    src = '%d.%d.%d.%d' % src

    return src

 

  @property
  def dst( self ):
    dst = struct.unpack('!4B', self._dst)
    dst = '%d.%d.%d.%d' % dst

    return dst

 

packet.py

 

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

 

class Packet:

 

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

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

 

  def analyze_ip( self, raw ):
    self._ip = Ip( raw )

 

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

 

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

 

sniffer.py

 
import struct
import time

import socket
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 )
  print("data: ", data)

  packet = Packet( data )
  print( packet.eth.src + ' -> ' packet.eth.dst + ' type: ' + hex(packet.eth.type) )


 

  if packet.eth.type == 0x0800:
    print( packet.ip.src + ' -> ' + packet.ip.dst )
  print()

 

  time.sleep(1)

 

 

 

* eth.py / ip.py / packet.py를 header 디렉터리에 패키지로 묶었다.

 

 

( 스니퍼를 실행하면 bytes형 데이터에서 도착/출발 MAC주소와 이더넷 타입,

출발/도착 아이피주소와 프로토콜 타입을 필터링해서 보여준다 )

 

 

 

반응형

댓글