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

[네트워크 보안] ARP 클래스 setter 추가 / arping.py

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

ARP 클래스 setter 추가 / arping.py에 대해서 정리한다.

 


1. ARP Request

 

2. ARP Reply

 

  eth + arp header


* 헤더의 구조는 동일

* ARP Class에 setter를 추가

 

 

ARP 요청이 왔을때 이게 진짜 sender가 보낸걸까?

 

* ARP 헤더 내용(sender ip, sender_mac, ...)을 고쳐서 보내도 인증을 하지 않는 부분을 이용해 Cache Poisoning이 가능

 

* 최근에는 악성코드를 패딩에 실어서 보내는 방법도 사용한다고 한다.

  ( 보통 탐지 프로그램이 패딩을 잘라서 검사한다는 부분을 이용한 것 )

 

 

 

- ARP 클래스 setter 추가 / arping.py

  ( arp.py / sniffer.py에 추가된 내용은 분홍색으로 구분 )

 

  * ARP 클래스에 setter를 추가하고 arping.py를 하나 만들어 그 안에서 패킷( eth헤더 + arp헤더)를 만들어 보낼수 있도록 한다.

 

arp.py

 

import struct

 

class Arp:

 

  def __init__( self, raw=None ):
    if raw != None:
      self._hard_type = raw[:2]
      self._proto_type = raw[2:4]
      self._hard_len = raw[4:5]
      self._proto_len = raw[5:6]
      self._opcode = raw[6:8]
      self._sender_mac = raw[8:14]
      self._sender_ip = raw[14:18]
      self._target_mac = raw[18:24]
      self._target_ip = raw[24:28]

 

  @property
  def header( self ):
    return self._hard_type + self._proto_type + self._hard_len + self._proto_len \
           + self._opcode + self._sender_mac + self._sender_ip + self._target_mac \
           + self._target_ip

 

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

 

  @hard_type.setter
  def hard_type( self, type ):
    type = struct.pack('!H', type)
    self._hard_type = type

 

  @property
  def proto_type( self ):
    (proto_type,) = struct.unpack('!H', self._proto_type)

 

  @proto_type.setter
  def proto_type( self, type ):
    type = struct.pack('!H', type)
    self._proto_type = type

 

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

 

  @hard_len.setter
  def hard_len( self, len ):
    len = struct.pack('!B', len )
    self._hard_len = len

 

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

 

  @proto_len.setter
  def proto_len( self, len ):
    len = struct.pack('!B', len)
    self._proto_len = len

 

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

 

  @opcode.setter
  def opcode( self, opcode ):
    opcode = struct.pack('!H', opcode)
    self._opcode = opcode

 

  @property
  def sender_mac( self ):
    sender_mac = struct.unpack('!6B', self._sender_mac)
    sender_mac = '%02x:%02x:%02x:%02x:%02x:%02x' % sender_mac
    return sender_mac

 

  @sender_mac.setter
  def sender_mac( self, mac ):
    mac = mac.split(':')
    for i in range( len(mac) ):
      mac[i] = int( mac[i], 16 )

 

    self._sender_mac = b''
    for i in range( len(mac) ):
      self._sender_mac += struct.pack('!B', mac[i])

 

  @property
  def sender_ip( self ):
    sender_ip = struct.unpack('!4B', self._sender_ip)
    sender_ip = '%d.%d.%d.%d' % sender_ip
    return sender_ip

 

  @sender_ip.setter
  def sender_ip( self, ip ):
    ip = ip.split('.')
    for i in range( len(ip) ):
      ip[i] = int( ip[i] )

 

    self._sender_ip = b''
    for i in range( len(ip) ):
      self._sender_ip += struct.pack('!B', ip[i])

 

  @property
  def target_mac( self ):
    target_mac = struct.unpack('!6B', self._target_mac)
    target_mac = '%02x:%02x:%02x:%02x:%02x:%02x' % target_mac
    return target_mac

 

  @target_mac.setter
  def target_mac( self, mac ):
    mac = mac.split(':')
    for i in range( len(mac) ):
      mac[i] = int( mac[i], 16 )

 

    self._target_mac =b''
    for i in range( len(mac) ):
      self._target_mac += struct.pack('!B', mac[i])

 

  @property
  def target_ip( self ):
    target_ip = struct.unpack('!4B', self._target_ip)
    target_ip = '%d.%d.%d.%d' % target_ip
    return target_ip

 

  @target_ip.setter
  def target_ip( self, ip):
    ip = ip.split('.')
    for i in range( len(ip) ):
      ip[i] = int( ip[i] )

 

    self._target_ip = b''
    for i in range( len(ip) ):
      self._target_ip += struct.pack('!B', ip[i])

 

arping.py

 


from header.eth import *
from header.arp import *

 

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

 

#ethernet header

eth = Eth()
arp = Arp()

eth.dst = 'FF:FF:FF:FF:FF:FF'
eth.src = '00:50:56:3B:25:F8'
eth.type = 0x0806

 

# data

arp.hard_type = 1
arp.hard_len = 6
arp.proto_type = 0x0800
arp.proto_len = 4
arp.opcode = 1
arp.sender_mac = '00:50:56:3B:25:F8'
arp.sender_ip = '192.168.1.172'
arp.target_mac = '00:00:00:00:00:00'
arp.target_ip = '192.168.1.110'

sock.send( eth.header + arp.header )

 

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 == 0x0806 and \
    (packet.arp.target_ip == '192.168.1.110' or packet.arp.sender_ip == '192.168.1.110):

    print("data: ", data)
    print( packet.eth.src + ' -> ' + packet.eth.dst + 'type: ' + hex(packet.eth.type) )
    print( "opcode: ", packet.arp.opcode )
    print( "sender ip: " + packet.arp.sender_ip + " target ip: " + packet.arp.target_ip )
    print( "sender mac: " + packet.arp.sender_mac + " target_mac: " + packet.arp.target_mac )
    print()

 

 

반응형

댓글