对mDNS的一些研究
mDNS简介
mDNS(Multicast DNS)指的是多播DNS,就像之前说的,这个包也是在内网中为了知道各主机的ip地址而存在的,大概是广播我是谁,我在什么什么地址,而收到的主机也会响应一个mDNS包告诉对方自己是谁,自己在什么什么地方。它和dns包差不多,域名为主机名.local
。
mDNS用于在局域网中发现设备,跟zeroconf协议的用处相近(zeroconf主要用于在没有DNS的网络中发现设备,主要用于linux和mac中)。感觉更常用于手机,网上能搜到的有关mDNS的,多为小程序的开发,诸如一些拿来发现局域网设备的微信小程序。
类似这篇文章小程序开发必备的高级能力之四:mDNS
我们可以看到,它轻易的获取到了设备名,ip地址和服务类型
这对于内网渗透中信息收集无疑是有作用的,这就细嗦它的工作原理了。
mDNS工作原理
mDNS也是基于DNS协议的协议,与DNS有高度的相似性,也是用于在无传统DNS服务器的网络中发现设备。
先说说发现设备相关的问题
就比如一台刚进入局域网的计算机,它没有局域网中其他设备,那怎么去获取呢?
这里靠的就是广播,比如ARP协议,就是靠广播去发现加入了组播的主机,ARP负责mac地址和ip地址的解析。
而零配置网络的目的就是在局域网中发现服务,这里先提一下,后面会详细说。
再说说在有传统DNS服务器的网络中解析的方法,按照以下顺序寻找一个域名
- 本地hosts文件解析
- 使用DNS解析
- 使用LLMNR解析
- 使用NBNS解析
实际上,自从mDNS加入了windows后,windows也会默认用mDNS进行查询,顺序在步骤2和步骤3之间。
在没有DNS服务器的网络中,很显然我们无法靠DNS解析域名。作为DNS的替代,mDNS就发挥了作用。
我们可以看看ping一个不存在的域名会发生什么
在不存在DNS服务器的局域网中
它会先后用mDNS,LLMNR,NBNS去尝试解析域名(前面的arp协议是为了去找局域网内的网关)
这里还存在一个说法,因为mDNS并不是windows本来的东西,所以windows的规则也和MAC不同,即windows是通过主机名加.local构成查询请求,mac是直接用主机名构成查询请求,虽然最终都会回归到xxxxx.local
而在存在DNS服务器的局域网里它会先尝试去寻找xxxxxxx.lan的解析地址,再用这三种去寻找。
mDNS工作过程
然后是工作过程,mdns有两个作用,一个是作为解析计算机名(就像上面ping的时候会发送查询包一样),一个是作为解析服务名。在windows中以解析计算机名为主要作用。
解析计算机名
在计算机需要解析一个计算机名时,它会向mDNS的广播地址发送查询请求包,将欲查询计算机名.local
作为域名去解析地址,该计算机名的主机在收到查询包后会将返回包广播出来,让局域网内主机都能接收到。
解析服务名
这又要说回mac中的bonjour,bonjour提供了零配置网络的设备发现方式,其中的dns-sd注册服务,发现服务,即是用的mdns来完成。
首先mDNS工作于5353端口,向224.0.0.251广播地址发送数据包,广播给组播地址中的主机。
内容为查询请求,其他主机收到后,如果有,则也会向广播地址进行广播。
还有就是,在具有mDNS协议的设备进入局域网时候,它也会广播一个请求包
内容为自己的服务名,ip地址和服务类型。
我们可以用dns-sd -R <名称> <协议类型> <域名> <端口> 来注册一个服务
,我们注册一个服务同时会向局域网中广播我们所具有的服务
下为主机中使用dns-sd注册了一个fucktrump的服务
上为虚拟机中使用dns-sd查找本地服务
两台计算机就在局域网中实现了服务的注册与发现。
下为整个交互过程的数据包
0到9是本机在注册服务,过程基本如下
注册服务时,生成三个相关的dns记录:
- 服务记录srv
- 指针记录ptr
- 文本记录txt
srv包含主机名和端口号,使用者记录该名字以便于长期访问,目的在于将一个服务名指向一个主机名和其端口号。
fucktrump._http._tcp.local: type SRV, class IN, cache flush, priority 0, weight 0, port 280, target DESKTOP-XXXXXXX.local
则把fucktrump._http._tcp.local
解析到了DESKTOP-XXXXXXX.local
的280端口上。这里虽然有权重和优先级的概念存在,但实际上是没有使用的,所以下面会提到,修改权重并不会影响服务解析。
ptr在dns中是域名反向解析,负责把ip反向解析为域名,这里是将某服务类型解析到一个服务上。比如
_http._tcp.local. 280 PTR fucktrump._http._tcp.local.
意思就是创建了一个基于tcp协议和http协议的服务,反向解析到了后面那个域名上
txt包含一些特殊描述(可以为空白),用于标识一些其他信息
mdns使用TTL来控制服务的存活时间,之前介绍过mdns的结构,我也蛮好奇的为什么dns-sd注册了服务还不能退出终端,一退服务就会消失,mdns中的TTL也有时间限制,一般注册服务会带有一个2分钟的TTL,每隔一到两分钟就会重新发包表示服务还存活,如果中途退出了终端,则会发一个TTL为0的mdns数据包,表示服务停止了。
发现服务时,发现方用注册时指定的dns记录来发起一个ptr记录问询,收到后,具有该服务的主机返回一个ptr记录
mDNS协议对于零配置局域网来说是非常方便的,譬如在与打印机互通,连接局域网中电脑或手机,只要连入同一网络,就可以很快的发现对方的服务并与之通信。arp协议负责的是ip与mac地址的解析,而mDNS负责的是ip与域名的解析。
mDNS存在的安全问题
信息泄露
这个可能不算是安全问题,但是可以作为一种信息收集的手段,mDNS用广播发现设备就注定会暴露一些东西。
以下是包括的能收集到的信息:
-
ip地址(包括ipv4和ipv6)
-
服务名(有些服务直接以主机名命名
-
传输协议以及端口服务
个人认为主要取决于主机运行的服务,比如:
nvstream似乎是nvidia的一个服务,ni_logos则更是不知名了。
另外就是根据质询包猜测可能存在的服务,mDNS交互过程会记录存在的协议(即srv记录),在下一次ptr质询时直接质询存在的协议及服务
这是实验室中抓取的质询,我们可以大致猜测一下,有几个苹果设备的相关协议,包括前面那些apple-pairable,airport,airplay等等,sleep-proxy是macos待机时候bonjour发出的协议;有几个打印机的相关服务,像是ipp,ipps,printer那些,smb各位师傅应该都熟悉,rfb也是个远程连接的协议。
mDNS欺骗
有没有对224.0.0.251很眼熟?对,LLMNR的广播地址是224.0.0.252,熟悉的过程,熟悉的地址,熟悉的广播,我们有理由相信这给是可以进行欺骗的。
LLMNR毒化的常用工具有个responder,其中有一项就是mDNS毒化。不过它归类到的是DNS中,简单抓个包就能发现,它是作为解析域名的方式进行毒化,靠的是在无DNS服务器的局域网内解析地址(这里可以看出在windows中LLMNR和MDNS的关系,MDNS从加入windows到不断更新,比重都在增大)
mdns的另外一个功能,是否也可以进行欺骗呢?即对方机器查询本地网络中的服务,我收到组播后进行欺骗,诱使对方连接或进行其他操作。
mdns使用TTL来控制服务的存活时间,之前介绍过mdns的结构,我也蛮好奇的为什么dns-sd注册了服务还不能退出终端,一退服务就会消失,mdns中的TTL也有时间限制,一般注册服务会带有一个2分钟的TTL,每隔一到两分钟就会重新发包表示服务还存活,如果中途退出了终端,则会发一个TTL为0的mdns数据包,表示服务停止了。
有关欺骗伪造同名服务的探究
若两台机器注册相同服务,按照官方文档来说,只有当创建服务时发出的广播包无响应,服务才会创建成功,但实际上,这里也存在一点问题。windows和mac还有一定的区别。
或许是windows的bonjour还不完善,windows中的mdns系统并不怎么回应响应包,比如,在原有的交互过程中,若mac先注册服务,windows再注册服务,在windows发出注册的广播包时,mac会很积极的广播自己服务的广播包,但window似乎并不买帐,我行我素,依然每两分钟广播一次。
图为windows例行发送数据包,被mac疯狂问候
这是可以印证的。若mac下注册的服务遇到了大量同名服务数据包,它是会放弃注册转而注册xxxx(2).local
,比如下图
这里有几个值得注意的点,如下
-
你仅需要发送同名服务的广播数据包,就能得到3倍或更多的数据包返回(即mac问候windows那张图,经测试能确定并不是1等1的流量包发送,具体发送多少似乎并不确定,但是发送太多会导致原服务重新注册改名。发送太快反射的也会越来越少),这我觉得是可以引发反射式泛洪攻击的,且为广播非单播。(对于ddos的确定标准不太熟悉,但至少实测能堵塞网络。)
-
windows的bonjour注册的服务会被mac注册的服务覆盖掉,虽然windows还是在定时发送它的数据包,不过解析者在解析数据包时,mac的bonjour正在疯狂问候windows全家,解析者自然也就把服务解析到了mac上。这不仅说明windows注册的服务甚至可以伪造同名的,也说明如果我们和mac进行条件竞争,是有机会使使用者需要的服务解析到我们这儿来的。
-
是否想过伪造一个ttl=0s的对方服务的广播包来停掉对方服务?实际上,对于mac来说,是办不到的。每当有一个同名服务的广播包在局域网中出现,bonjour都会做出回应,能做到的只是干扰服务的正常运行。但是,我们说过windows存在的问题,windows对于同名数据包并不会做出回应,这会导致在伪造windows同名服务后,再结束掉该服务,在windows下一次发送2分钟一次的定期数据包之前,不会有用户解析到这个服务的存在。
图右侧为伪造的结束数据包,左侧为mac对结束数据包做出的回应。
有关直接伪造服务的探究
mac中很多其他应用也用了这个服务,比如打印机服务(对mac不太了解,资料说的是很多苹果设备互相连接都靠bonjour去发现,这里我只尝试了打印机)
这是我打开打印机服务准备查找局域网内可能存在的打印机的过程,mac在不断广播查询请求
这时如果我们构造假数据包进行欺骗,是不是可以达到伪造一个打印机服务的效果?
我们可以看到它广播的查询包,比如第一个有_ipp_tls._tcp.local
这样一个字段,前一段代表的是使用ipp-tls协议(一个打印机协议),tcp代表的用于传输数据的协议
我们同样去注册一个这个服务
mac中成功解析了这个服务,
用脚本也可以完成,就像介绍的时候说的,三个记录,ptr,svc,txt,去创建一个服务。此时mac完成了打印机服务的发现,还需要地址去完成解析。它查询地址的方式就是普通的dns的方式,type A和AAAA。我们只需要响应一个type A的包即可。完成解析后,mac会和服务方进行tcp握手并进行后续操作。
经典tcp三次握手不再介绍,需要注意的是不需要自己去构造第二次握手的包,由于端口未开放,系统会自动回复rst导致我们交互不正常。socket创建一个需要的端口就能完成握手,又或者是nc一个端口进行监听。
下图为nc监听端口的情况:
红圈部分为tcp握手,后面即为要打印的数据。
当然,是否能拿到数据也和协议有关系,主流的打印机协议大致有LPD(主要用于unix),IPP(主要由linux的CUPS和windows的互联网打印支持),还有大部分网络打印机都直接通过TCP协议发送postscript,即上图的情况,打开数据包看data就会发现全是postscript语言的脚本。
这和构造的时候用到的协议也有关系,比如xxx._ipp._tcp.local
就直接用ipp协议了,又像是xxx._ipp-tls._tcp.local
,则会开启ssl证书验证,传输加密流量(算是个踩的坑)。不同的服务名会导致系统用不同的方法去处理。
下图为ssl验证,客户端在握手成功后发送的client hello。
下图为ipp协议交互。
综合一下上面的欺骗,考虑一下可能存在的过程,a想用局域网内的打印机服务,于是开启打印机服务查找,这时我们进行欺骗,伪造了一个打印机,a发现有一个可用服务,于是用它进行了连接…
欺骗的手段包括以下:
- 创建同名服务,解析到本机,经测试大概2秒一个包,能在不顶掉原服务的情况下将服务解析到本机,当然,这和下面说的方法都有一个相同之处。就是要看服务使用时解析的到底是正常的服务发的包,还是我们伪造的服务发的包。
下面为试验:
红圈为创建一个打印机服务模拟正常打印机,然后mac用这个bonjour服务创建打印机。我们再监听对应端口。
此时,我们在攻击机上开启脚本发送伪造包并监听对应端口,可以看到,mac创建的服务并未被顶掉。我们再在mac上打印数据,如图中所示,本次打印地址解析到了我们攻击机上,数据也就发送到了攻击机的对应端口上。
- 直接顶掉原有服务,如下图
如同之前所说,在同名服务数据包过多的情况下,mac的服务结束了自己原本创建的服务,转而注册了名称 (2)._ipp._tcp.local
。但是我们用的是原有名称创建的打印机服务,寻找也是寻找的原有名称,自然而然就解析到了我们这里。
- 使用ttl=0的数据包,使原服务不能正常运行
还是看解析的时候到底解析的是谁的数据包的问题,不过一个while True循环能大概率使解析服务时认为服务已经结束。我如果作为使用者,我肯定会怀疑打印机是不是出了问题,转而换其他的或重新创建,这时候我们再伪造一个服务让其连接。
以上是三个思路,或许还有其他的,但本人思路有限,暂时只想到这三个。
另外,不仅是打印机,safari也曾支持bonjour发现局域网内的web服务(safari 11 后就删除了该功能,不过app store中仍有相关的扩展,包括zeroconf browser
,localsite
等等…用于从bonjour服务中解析web服务,老穷逼了买不起),类似的欺骗手段我们在其他中间人攻击中也见多了,创建一个web服务,伪造一个bonjour服务并引导到对应端口上,等待鱼上钩。又比如如果有查找局域网内ssh服务存在的应用(暂未发现,但mac os中支持对_ssh._tcp.local
的解析,也就是说可能会存在某个服务使用),进行欺骗后可以尝试ssh中间人攻击。包括之前信息收集里提到的有解析到smb协议的存在,也可以联系到smb下的ntlm-relay相关的东西。
所以说能具体使用的方面应该还蛮广的,主要基于使用bonjour的服务。
有关反射式泛洪攻击
测试了关于反射式泛洪攻击相关的内容,通过测试结果判断bonjour是通过一段时间内收到的同名数据包的量来判断是否重新注册新服务的(大概五秒内3个包?)。所以若局域网内只存在一个服务,想要通过这个方式触发流量就较小。服务越多,能翻倍的流量也越多。
除此之外,通过查询请求进行反射式泛洪也有相同的作用,同样也是服务越多能得到的流量也越多。但也很容易暴露,因为一眼望去就能看出谁是发送查询请求的人。
结尾
由于这种两台机器之间不能互相确认信任的网络中,中间人攻击是必然会存在的,只是该如何构造和如何利用的问题,所以像kerberos,ssl这种第三方可信认证的方式才会出现。
我也考虑过为什么arp欺骗存在了那么久都没有从根本上解决问题的方法,大概是因为协议比较底层,用的也非常广泛,如果直接修改协议会导致很多更大的问题。所以防御中间人攻击的最好办法还是仅和局域网内可信,最安全的主机进行通讯。
综上,这或许是一个新的可利用的点,同大多数的中间人攻击相同,都需要对方来主动上钩。目前还是在mac os中使用bonjour的应用比较多,但也不算太广泛,所以利用范围比较有限,应该说,有利用bonjour的地方应该就能造成伪造。但是有扩展的趋势,查资料的过程中也看到过windows正在逐步放弃LLMNR转而使用MDNS的趋势,苹果也有专门的bonjour SDK for windows,使得bonjour在windows可用,又比如之前找到的nvstream服务,就是windows上使用的mdns服务之一。未来可期。
mDNS — 224.0.0.251 5353端口
SSDP — 239.255.255.250
答复多播
dns-sd -R fucktrump _http._tcp . 280
dns-sd -R fuckfuck _universal._sub._ipp._tcp.local . 9100