同交换机下劫持通信方法:ARP欺骗和组播源冒充

在全国第五届工控系统信息安全攻防竞赛中遇到了这么一个情景:

  • 篡改DCS仿真机发送给DCS工程师站的modbus数据,但client端和server端通讯正常
  • 篡改DCS仿真机发送给DCS工程师站的DCS数据,但client端和server端通讯正常
  • 接入点为跟二者同一个交换机下,可以攻击DCS工程师站的本机,但是不能直接攻击DCS仿真机的PC系统

给的网络拓扑图如下:

image

所以这个任务简单的说就是:在同交换机下劫持两台主机的通信,基本思路就是中间人攻击

攻击者位置

在网络层次的攻击模型中,首先要明确攻击者的位置,一般有如下三种:

  • In Path :攻击者是具有较强的攻击能力,可以直接拦截并且修改通信双方的流量
  • On Path :攻击者不能拦截或者修改流量,但是攻击者可以向网络中注入流量
  • Off Path :攻击者不在链路上,但是攻击者单独和通信双方进行流量的通信

image

流量捕获与劫持

首先是流量的捕获,这里有很多种情景:

  • 如果是个人WPA2加密的无线局域网,并且已知共享秘钥,则可以将目标利用WIFI掉线攻击打下线,在802.11网卡侦听模式下,待其重新连接时即可捕获握手包,即可解密流量。例如可以在kali中使用aricrack-ng这个套件中的airtun-ng工具进行嗅探(off path)

  • 如果是无线/有限局域网,并且攻击者可以直接接管路由器,则可以直接在路由器上进行抓包以及劫持流量。不过需要路由器有对应的功能支持,常见于对于IOT设备进行测试的场景(in path)

  • 如果是无线/有限局域网,并且攻击者已经连入网络中,则可以用arp欺骗目标主机,宣称自己是默认的网关,即可捕获流量。(on path)

在kali中可以直接利用arpspoof这个工具来完成arp欺骗

echo "1" > /proc/sys/net/ipv4/ip_forward        # 如果不开启转发,则效果为断网攻击
arpspoof -i eth0 -t 192.168.1.X 192.168.1.1     # 192.168.1.X 为被欺骗的目标主机
arpspoof -i eth0 -t 192.168.1.1 192.168.1.X     # 如果没有这条,则只能劫持单向的流量

或者利用中间人攻击工具(Xerosploit)

  • 如果没有网关,直接是交换机下的通信,攻击者和目标处于同一个交换机下,则可以直接对通信双方分别进行arp欺骗,方可劫持流量(on path)

在kali中可以直接利用arpspoof这个工具来完成arp欺骗

echo "1" > /proc/sys/net/ipv4/ip_forward
arpspoof -i eth0 -t 192.168.1.2 192.168.1.3
arpspoof -i eth0 -t 192.168.1.3 192.168.1.2

或者在kali里直接用ettercap的arp劫持的功能:

ettercap -i eth0 -T -M arp:remote /192.168.1.2/192.168.1.3/
  • 直接攻击目标主机本身,getshell后本地抓包

本题解法:ARP欺骗

  • DCS仿真机:192.168.9.203
  • DCS工程师:192.168.9.204

这里是同一个交换机下,而且没有网关参与,所以这里就用ARP欺骗的方法拦截了DCS仿真机和DCS工程师间的通信:

# arpspoof -i eth0 -t 被欺骗的目标主机 本机要伪造的主机
# 这条命令就是告诉192.168.9.203我是192.168.9.204
# 所以203发给204的所有流量都会发到你的本机,即可拦截成功
$ arpspoof -i eth0 -t 192.168.9.203 192.168.9.204

劫持后发现modbus服务的数据确不再更新了,出现了连接错误的提示信息,但是这个DCS服务的数据两侧还在同步的更新,按道理我应该已经把所有的DCS仿真机发送给DCS工程师站的数据拦截掉了,但是看起来居然还能通信,真是百思不得其解。我在我的本地用wireshark抓包,看到了很多203发给204的tcp错误的包,这个是比较正常的,因为tcp过程被我打断了。但是还看到了一些172开头ip的组播包,不知道是干嘛的,也不知道为什么会出现在这里。后来发现给的手册里,这两个机器给了两个ip,难道是双网卡?

  • DCS仿真机:192.168.9.203 172.109.1.203
  • DCS工程师:192.168.9.204 172.109.1.204

测试发现:

  • 192.168.9.203和172.109.1.203的mac地址均为:00:50:c2:43:e9:ee
  • 192.168.9.204和172.109.1.204的mac地址均为:00:e0:4c:68:01:73

所以是双IP,而并不是双网卡,而且如果是双网卡的话,主机上应该有两根网线,或者交换机上有两根线连到同一个机器上,很显然给我的环境里没有这么复杂的设置。于是尝试用172的这个ip去拦截流量:

$ arpspoof -i eth0 -t 172.109.1.203 172.109.1.204

发现没有任何效果,modbus的通信也不会被打断。抓包过滤这两个ip地址,能看到一堆发往228.9.0.1组播,不知道是干嘛的,但是发现了172.109.1.1的这个地址。真的是让我更加百思不得其解,如图:

image

求助出题人

本身情景里可以去攻击DCS工程师站,但是攻击的两个目标服务均是启动在docker里的,打进去后看不到这个DCS的目标软件的进程,也就无法知道其对应的进程和绑定的端口,尝试docker逃逸也没有成功。再因为诸多原因,没有在继续进行比赛,索性直接问了这道题的思路。

出题人说,这里有单播,组播,广播。存在一个数据源,看没看到172.109.1.1的那台机器,他以组播的方式,向203,204发送数据,即203,204都是接受方。但是题目明明写着篡改DCS仿真机发送给DCS工程师站的DCS数据啊,没说有第三个啊!出题人说,这个数据源和DCS仿真机是在一个主机上的。也就是说DCS仿真机的ip是:

  • 192.168.9.203
  • 172.109.1.203
  • 172.109.1.1

这台DCS仿真机的1个网卡上3个IP,检查一下这三个ip的mac地址,真的都是00:50:c2:43:e9:ee,好吧,出题人你赢了。不过出题人说,我当时研究这个软件的时候也很奇怪他是怎么做到劫持掉了arp还能通信的,这个通信的机制很有意思。所以这道题目的通信过程画图表示是这样的:

image

所以打modbus的攻击方式解释arp欺骗然后中间人修改流量,打DCS的攻击方式就是冒充组播的数据源:

image

这里交换机处理组播就跟处理广播是相同的,所以我能直接看到发送到组播的流量:

image

组播源冒充

组播和广播流量都是UDP,所以直接向226.9.0.1:7001发送数据,参考脚本如下:

python组播通信

import socket

mcast_group_ip = '226.9.0.1'
mcast_group_port = 7001
 
def sender():
    send_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    while True:
        message = "09010101f916da5ddf0200004401cde53a000000a7b81844000000000a000000488acd430000000002000000252c6143000000003b0000003a752145000000000b0000007d7fcd43000000000300000016466941000000003c0000009ec1ab43000000000c00000067decc430000000004000000e24a1344000000003d000000c2bf30450000000035000000b658b542000000000d000000c028ff430000000005000000f4900644000000003e000000d2daec42000000003600000034047a44000000000e0000006bdcfe430000000006000000a085114300000000370000001399f941000000000f000000094dff430000000007000000aa4f124100000000380000005b3b16440000000020000000363fd140000000001000000031caff4300000000080000008e169f4100000000390000005e5c18440000000011000000d763c14200000000090000003963cd4300000000"
        send_sock.sendto(message.decode("hex"), (mcast_group_ip, mcast_group_port))

if __name__ == "__main__":
    sender()

运行还是没有什么效果,抓包发现没有本机有线网卡到226.9.0.1的流量,后来发现当时我是双网卡,猜测这个组播选择了无线网卡的路由,关闭wifi后再次运行,发现DCS工程师站和DCS仿真机上的DCS软件的数据终于停止更新了,劫持成功。

组播原理

对于组播的原理并不是很懂,看到一张图:

image

也就是说对于一个组播发送数据相当于对一个固定的mac地址发送,接受一个组播的数据,相当于给自己的机器注册一个相应的mac地址,也许大概是这样吧,下次有机会继续研究吧!